mohab metwally 4 лет назад
Родитель
Сommit
39c9f3871b
3 измененных файлов с 66 добавлено и 115 удалено
  1. 15 11
      src/blockchain/epoch.rs
  2. 7 12
      src/crypto/leadcoin.rs
  3. 44 92
      src/zk/circuit/lead_contract.rs

+ 15 - 11
src/blockchain/epoch.rs

@@ -182,25 +182,31 @@ impl Epoch {
             //
             //
             let c_root_sk: MerkleNode = root_sks[i];
             let c_root_sk: MerkleNode = root_sks[i];
 
 
-            let c_pk = pedersen_commitment_base(c_tau, mod_r_p(c_root_sk.inner()));
+            let coin_pk_msg = [
+                c_tau,
+                c_root_sk.inner(),
+            ];
+            let c_pk : pallas::Base = poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init().hash(coin_pk_msg);
+            //let c_pk = pedersen_commitment_base(c_tau, mod_r_p(c_root_sk.inner()));
 
 
             let c_seed = pallas::Base::from(seeds[i]);
             let c_seed = pallas::Base::from(seeds[i]);
-            let c_sn = pedersen_commitment_base(c_seed, mod_r_p(c_root_sk.inner()));
-            let c_pk_pt = c_pk.to_affine().coordinates().unwrap();
-            let c_pk_pt_x: pallas::Base = *c_pk_pt.x();
-            let c_pk_pt_y: pallas::Base = *c_pk_pt.y();
+            let sn_msg = [
+                c_seed,
+                c_root_sk.inner(),
+            ];
+            let c_sn : pallas::Base = poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init().hash(coin_pk_msg);
 
 
 
 
             //let lead_coin_msg = [
             //let lead_coin_msg = [
-              //  c_pk_pt_x.clone(),
-                //c_pk_pt_y.clone(),
+              //  c_pk.clone(),
+
                 //c_v,
                 //c_v,
                 // *c_seed_pt.x(), //TODO(fix) will be c_seed(base) only after calculating c_seed as hash
                 // *c_seed_pt.x(), //TODO(fix) will be c_seed(base) only after calculating c_seed as hash
                 //*c_seed_pt.y(),
                 //*c_seed_pt.y(),
             //];
             //];
             //let lead_coin_msg_hash : pallas::Scalar = poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<1>, 3, 2>::init().hash(lead_coin_msg);
             //let lead_coin_msg_hash : pallas::Scalar = poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<1>, 3, 2>::init().hash(lead_coin_msg);
 
 
-            let coin_commit_msg = c_pk_pt_x*c_pk_pt_y*c_v*c_seed;
+            let coin_commit_msg = c_pk*c_v*c_seed;
             let c_cm: pallas::Point = pedersen_commitment_scalar(mod_r_p(coin_commit_msg), c_cm1_blind);
             let c_cm: pallas::Point = pedersen_commitment_scalar(mod_r_p(coin_commit_msg), c_cm1_blind);
             let c_cm_coordinates = c_cm.to_affine().coordinates().unwrap();
             let c_cm_coordinates = c_cm.to_affine().coordinates().unwrap();
             let c_cm_base: pallas::Base = c_cm_coordinates.x() * c_cm_coordinates.y();
             let c_cm_base: pallas::Base = c_cm_coordinates.x() * c_cm_coordinates.y();
@@ -227,7 +233,7 @@ impl Epoch {
             //pallas::Base::one(),
             //pallas::Base::one(),
             //];
             //];
             //let lead_coin_msg_hash : pallas::Base = poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<1>, 3, 2>::init().hash(lead_coin_msg);
             //let lead_coin_msg_hash : pallas::Base = poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<1>, 3, 2>::init().hash(lead_coin_msg);
-            let coin2_commit_msg = c_pk_pt_x*c_pk_pt_y*c_seed2_pt_x*c_seed2_pt_y*c_v;
+            let coin2_commit_msg = c_pk*c_seed2_pt_x*c_seed2_pt_y*c_v;
             let c_cm2 = pedersen_commitment_base(coin2_commit_msg, c_cm2_blind);
             let c_cm2 = pedersen_commitment_base(coin2_commit_msg, c_cm2_blind);
 
 
             let c_root_sk = root_sks[i];
             let c_root_sk = root_sks[i];
@@ -253,8 +259,6 @@ impl Epoch {
                 nonce_cm: Some(c_seed2),
                 nonce_cm: Some(c_seed2),
                 sn: Some(c_sn),
                 sn: Some(c_sn),
                 pk: Some(c_pk),
                 pk: Some(c_pk),
-                pk_x: Some(c_pk_pt_x),
-                pk_y: Some(c_pk_pt_y),
                 root_cm: Some(mod_r_p(c_root_cm.inner())),
                 root_cm: Some(mod_r_p(c_root_cm.inner())),
                 root_sk: Some(c_root_sk.inner()),
                 root_sk: Some(c_root_sk.inner()),
                 path: Some(c_cm_path.as_slice().try_into().unwrap()),
                 path: Some(c_cm_path.as_slice().try_into().unwrap()),

+ 7 - 12
src/crypto/leadcoin.rs

@@ -25,11 +25,9 @@ pub struct LeadCoin {
     pub tau: Option<pallas::Base>,
     pub tau: Option<pallas::Base>,
     pub nonce: Option<pallas::Base>,
     pub nonce: Option<pallas::Base>,
     pub nonce_cm: Option<pallas::Base>,
     pub nonce_cm: Option<pallas::Base>,
-    pub sn: Option<pallas::Point>, // coin's serial number
+    pub sn: Option<pallas::Base>, // coin's serial number
     //sk : Option<SecretKey>,
     //sk : Option<SecretKey>,
-    pub pk: Option<pallas::Point>,
-    pub pk_x: Option<pallas::Base>,
-    pub pk_y: Option<pallas::Base>,
+    pub pk: Option<pallas::Base>,
     pub root_cm: Option<pallas::Scalar>,
     pub root_cm: Option<pallas::Scalar>,
     pub root_sk: Option<pallas::Base>,
     pub root_sk: Option<pallas::Base>,
     pub path: Option<[MerkleNode; MERKLE_DEPTH_ORCHARD]>,
     pub path: Option<[MerkleNode; MERKLE_DEPTH_ORCHARD]>,
@@ -52,8 +50,8 @@ impl LeadCoin {
         let po_cm = self.cm.unwrap().to_affine().coordinates().unwrap();
         let po_cm = self.cm.unwrap().to_affine().coordinates().unwrap();
         let po_cm2 = self.cm2.unwrap().to_affine().coordinates().unwrap();
         let po_cm2 = self.cm2.unwrap().to_affine().coordinates().unwrap();
 
 
-        let po_pk = self.pk.unwrap().to_affine().coordinates().unwrap();
-        let po_sn = self.sn.unwrap().to_affine().coordinates().unwrap();
+        let po_pk = self.pk.unwrap();
+        let po_sn = self.sn.unwrap();
 
 
         let po_cmp = pallas::Base::from(0);
         let po_cmp = pallas::Base::from(0);
         let _zero = pallas::Base::from(0);
         let _zero = pallas::Base::from(0);
@@ -77,10 +75,8 @@ impl LeadCoin {
         };
         };
         let public_inputs: Vec<pallas::Base> = vec![
         let public_inputs: Vec<pallas::Base> = vec![
             po_nonce,
             po_nonce,
-            *po_pk.x(),
-            *po_pk.y(),
-            *po_sn.x(),
-            *po_sn.y(),
+            po_pk,
+            po_sn,
             *po_cm.x(),
             *po_cm.x(),
             *po_cm.y(),
             *po_cm.y(),
             *po_cm2.x(),
             *po_cm2.x(),
@@ -95,8 +91,7 @@ impl LeadCoin {
     {
     {
         let contract = LeadContract {
         let contract = LeadContract {
             path: Value::known(self.path.unwrap()),
             path: Value::known(self.path.unwrap()),
-            coin_pk_x: Value::known(self.pk_x.unwrap()),
-            coin_pk_y: Value::known(self.pk_y.unwrap()),
+            coin_pk: Value::known(self.pk.unwrap()),
             root_sk: Value::known(self.root_sk.unwrap()),
             root_sk: Value::known(self.root_sk.unwrap()),
             sf_root_sk: Value::known(mod_r_p(self.root_sk.unwrap())),
             sf_root_sk: Value::known(mod_r_p(self.root_sk.unwrap())),
             path_sk: Value::known(self.path_sk.unwrap()),
             path_sk: Value::known(self.path_sk.unwrap()),

+ 44 - 92
src/zk/circuit/lead_contract.rs

@@ -90,10 +90,8 @@ impl LeadConfig {
 }
 }
 
 
 const LEAD_COIN_NONCE2_OFFSET: usize = 0;
 const LEAD_COIN_NONCE2_OFFSET: usize = 0;
-const LEAD_COIN_PK_X_OFFSET: usize = 2;
-const LEAD_COIN_PK_Y_OFFSET: usize = 3;
-const LEAD_COIN_SERIAL_NUMBER_X_OFFSET: usize = 4;
-const LEAD_COIN_SERIAL_NUMBER_Y_OFFSET: usize = 5;
+const LEAD_COIN_PK_OFFSET: usize = 2;
+const LEAD_COIN_SERIAL_NUMBER_OFFSET: usize = 4;
 const LEAD_COIN_COMMIT_X_OFFSET: usize = 6;
 const LEAD_COIN_COMMIT_X_OFFSET: usize = 6;
 const LEAD_COIN_COMMIT_Y_OFFSET: usize = 7;
 const LEAD_COIN_COMMIT_Y_OFFSET: usize = 7;
 const LEAD_COIN_COMMIT2_X_OFFSET: usize = 8;
 const LEAD_COIN_COMMIT2_X_OFFSET: usize = 8;
@@ -108,8 +106,7 @@ pub fn concat_u8(lhs: &[u8], rhs: &[u8]) -> Vec<u8> {
 pub struct LeadContract {
 pub struct LeadContract {
     // witness
     // witness
     pub path: Value<[MerkleNode; MERKLE_DEPTH_ORCHARD]>,
     pub path: Value<[MerkleNode; MERKLE_DEPTH_ORCHARD]>,
-    pub coin_pk_x: Value<pallas::Base>,
-    pub coin_pk_y: Value<pallas::Base>,
+    pub coin_pk: Value<pallas::Base>,
     pub root_sk: Value<pallas::Base>, // coins merkle tree secret key of coin1
     pub root_sk: Value<pallas::Base>, // coins merkle tree secret key of coin1
     pub sf_root_sk: Value<pallas::Scalar>, // root_sk as pallas::Scalar
     pub sf_root_sk: Value<pallas::Scalar>, // root_sk as pallas::Scalar
     pub path_sk: Value<[MerkleNode; MERKLE_DEPTH_ORCHARD]>, // path to the secret key root_sk
     pub path_sk: Value<[MerkleNode; MERKLE_DEPTH_ORCHARD]>, // path to the secret key root_sk
@@ -300,17 +297,12 @@ impl Circuit<pallas::Base> for LeadContract {
             config.advices[0],
             config.advices[0],
             self.value,
             self.value,
         )?;
         )?;
-        let coin_pk_x: AssignedCell<Fp, Fp> = self.load_private(
+        let coin_pk: AssignedCell<Fp, Fp> = self.load_private(
             layouter.namespace(|| "load coin time stamp"),
             layouter.namespace(|| "load coin time stamp"),
             config.advices[0],
             config.advices[0],
-            self.coin_pk_x,
+            self.coin_pk,
         )?;
         )?;
 
 
-        let coin_pk_y: AssignedCell<Fp, Fp> = self.load_private(
-            layouter.namespace(|| "load coin time stamp"),
-            config.advices[0],
-            self.coin_pk_y,
-        )?;
 
 
         let _slot = self.load_private(layouter.namespace(|| ""), config.advices[0], self.slot)?;
         let _slot = self.load_private(layouter.namespace(|| ""), config.advices[0], self.slot)?;
 
 
@@ -342,45 +334,29 @@ impl Circuit<pallas::Base> for LeadContract {
         )?;
         )?;
 
 
         // ================
         // ================
-        // coin public key constraints derived from the coin timestamp
+        // coin public key pk=PRF_{root_sk}(tau)
         // ================
         // ================
-
-        // m*G_1
-        let (com, _) = {
-            let coin_pk_commit_v = ValueCommitV;
-            let coin_pk_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), coin_pk_commit_v);
-            let coin_timestamp = ScalarFixedShort::new(
-                ecc_chip.clone(),
-                layouter.namespace(|| "coin_timestamp*1"),
-                (coin_timestamp, one.clone()),
-            )?;
-            coin_pk_commit_v.mul(layouter.namespace(|| "coin_pk commit v"), coin_timestamp)?
-        };
-        // r*G_2
-        let (blind, _) = {
-            let coin_pk_commit_r = OrchardFixedBasesFull::ValueCommitR;
-            let coin_pk_commit_r = FixedPoint::from_inner(ecc_chip.clone(), coin_pk_commit_r);
-            let root_sk = ScalarFixed::new(
-                ecc_chip.clone(),
-                layouter.namespace(|| "root sk scalar"),
-                self.sf_root_sk,
+        let coin_pk_commit : AssignedCell<Fp,Fp> = {
+            let poseidon_message = [
+                coin_timestamp.clone(),
+                _root_sk.clone()
+            ];
+            let poseidon_hasher = PoseidonHash::<_, _, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init(
+                config.poseidon_chip(),
+                layouter.namespace(|| "Poseidon init"),
             )?;
             )?;
-            coin_pk_commit_r.mul(layouter.namespace(|| "coin_pk commit R"), root_sk)?
-        };
-        let coin_pk_commit = com.add(layouter.namespace(|| "coin timestamp commit"), &blind)?;
 
 
+            let poseidon_output =
+                poseidon_hasher.hash(layouter.namespace(|| "Poseidon hash"), poseidon_message)?;
+            let poseidon_output: AssignedCell<Fp, Fp> = poseidon_output;
+            poseidon_output
+        };
         // constrain coin's pub key x value
         // constrain coin's pub key x value
 
 
         layouter.constrain_instance(
         layouter.constrain_instance(
-            coin_pk_commit.inner().x().cell(),
-            config.primary,
-            LEAD_COIN_PK_X_OFFSET,
-        )?;
-        // constrain coin's pub key y value
-        layouter.constrain_instance(
-            coin_pk_commit.inner().y().cell(),
+            coin_pk_commit.cell(),
             config.primary,
             config.primary,
-            LEAD_COIN_PK_Y_OFFSET,
+            LEAD_COIN_PK_OFFSET,
         )?;
         )?;
 
 
         // =================
         // =================
@@ -388,55 +364,37 @@ impl Circuit<pallas::Base> for LeadContract {
         // =================
         // =================
 
 
         // =============
         // =============
-        // constrain coin c1 serial number
+        // constrain coin c1 serial number sn=PRF_{root_sk}(nonce)
         // =============
         // =============
         // m*G_1
         // m*G_1
-
-        let (com, _) = {
-            let sn_commit_v = ValueCommitV;
-            let sn_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), sn_commit_v);
-            let rcv = ScalarFixedShort::new(
-                ecc_chip.clone(),
-                layouter.namespace(|| "coin nonce * 1"),
-                (coin_nonce.clone(), one.clone()),
+        let sn_commit : AssignedCell<Fp,Fp> = {
+            let poseidon_message = [
+                coin_nonce.clone(),
+                _root_sk.clone()
+            ];
+            let poseidon_hasher = PoseidonHash::<_, _, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init(
+                config.poseidon_chip(),
+                layouter.namespace(|| "Poseidon init"),
             )?;
             )?;
 
 
-            sn_commit_v.mul(layouter.namespace(|| "coin serial number commit v"), rcv)?
-        };
-        // r*G_2
-        let (blind, _) = {
-            let sn_commit_r = OrchardFixedBasesFull::ValueCommitR;
-            let sn_commit_r = FixedPoint::from_inner(ecc_chip.clone(), sn_commit_r);
-            let root_sk = ScalarFixed::new(
-                ecc_chip.clone(),
-                layouter.namespace(|| "root sk scalar"),
-                self.sf_root_sk,
-            )?;
-            sn_commit_r.mul(layouter.namespace(|| "coin serial number commit R"), root_sk)?
+            let poseidon_output =
+                poseidon_hasher.hash(layouter.namespace(|| "Poseidon hash"), poseidon_message)?;
+            let poseidon_output: AssignedCell<Fp, Fp> = poseidon_output;
+            poseidon_output
         };
         };
-        //
-        let sn_commit = com.add(layouter.namespace(|| "nonce commit"), &blind)?;
         // constrain coin's pub key x value
         // constrain coin's pub key x value
-
         layouter.constrain_instance(
         layouter.constrain_instance(
-            sn_commit.inner().x().cell(),
+            sn_commit.cell(),
             config.primary,
             config.primary,
-            LEAD_COIN_SERIAL_NUMBER_X_OFFSET,
-        )?;
-        // constrain coin's pub key y value
-        layouter.constrain_instance(
-            sn_commit.inner().y().cell(),
-            config.primary,
-            LEAD_COIN_SERIAL_NUMBER_Y_OFFSET,
+            LEAD_COIN_SERIAL_NUMBER_OFFSET,
         )?;
         )?;
 
 
+        // ================================================
+        // coin commiment H=COMMIT(pk||V||nonce||r)
+        // ================================================
         let coin_val = {
         let coin_val = {
-            let coin_pk_mul = ar_chip.mul(layouter.namespace(|| ""), &coin_pk_y, &coin_pk_x)?;
-            let coin_val_mul = ar_chip.mul(layouter.namespace(|| ""), &coin_pk_mul, &coin_value)?;
-            //let coin_nonce_mul = ar_chip.mul(layouter.namespace(|| ""), &coin_val_mul, coin_nonce)?;
-            let coin_val0 = ar_chip.mul(layouter.namespace(|| ""), &coin_nonce, &coin_val_mul)?;
-            coin_val0
-            //ar_chip.mul(layouter.namespace(|| ""), &coin_val_pt, &coin_val0)?
+            let coin_val_mul = ar_chip.mul(layouter.namespace(|| ""), &coin_pk, &coin_value)?;
+            ar_chip.mul(layouter.namespace(|| ""), &coin_nonce, &coin_val_mul)?
         };
         };
         let (com, _) = {
         let (com, _) = {
             let coin_commit_v = ValueCommitV;
             let coin_commit_v = ValueCommitV;
@@ -483,16 +441,10 @@ impl Circuit<pallas::Base> for LeadContract {
 
 
         let coin2_hash_cm = ar_chip.mul(
         let coin2_hash_cm = ar_chip.mul(
             layouter.namespace(|| ""),
             layouter.namespace(|| ""),
-            &coin_pk_commit.inner().x(),
-            &coin_pk_commit.inner().y(),
-        )?;
-        let coin2_hash_nonce = ar_chip.mul(
-            layouter.namespace(|| ""),
-            &coin2_nonce,
-            &coin2_nonce,
+            &coin_pk_commit,
+            &coin2_nonce
         )?;
         )?;
-        let coin2_hash_mul = ar_chip.mul(layouter.namespace(|| ""), &coin2_hash_cm, &coin2_hash_nonce)?;
-        let coin2_hash = ar_chip.mul(layouter.namespace(|| ""), &coin_value.clone(), &coin2_hash_mul)?;
+        let coin2_hash = ar_chip.mul(layouter.namespace(|| ""), &coin_value.clone(), &coin2_hash_cm)?;
 
 
         let (com, _) = {
         let (com, _) = {
             let coin_commit_v = ValueCommitV;
             let coin_commit_v = ValueCommitV;