Parcourir la source

fix bug with root cm path

mohab metwally il y a 3 ans
Parent
commit
8b004e251c
3 fichiers modifiés avec 65 ajouts et 57 suppressions
  1. 22 2
      src/consensus/ouroboros/epoch.rs
  2. 10 20
      src/crypto/leadcoin.rs
  3. 33 35
      src/zk/circuit/lead_contract.rs

+ 22 - 2
src/consensus/ouroboros/epoch.rs

@@ -26,6 +26,8 @@ use pasta_curves::{
     pallas,
 };
 use rand::{thread_rng, Rng};
+use incrementalmerkletree::Hashable;
+
 
 const PRF_NULLIFIER_PREFIX: u64 = 0;
 const MERKLE_DEPTH: u8 = MERKLE_DEPTH_ORCHARD as u8;
@@ -148,7 +150,7 @@ impl Epoch {
         }
         let mut sks: Vec<SecretKey> = vec![];
         let (root_sks, path_sks) = self.create_coins_sks(&mut sks);
-
+        let mut tree_cm = BridgeTree::<MerkleNode, MERKLE_DEPTH>::new(self.len());
         // matrix of leadcoins, each row has competing coins per slot.
         let _coins: Vec<Vec<LeadCoin>> = vec![];
         for i in 0..self.len() {
@@ -165,6 +167,7 @@ impl Epoch {
                         path_sks[i],
                         seeds[i],
                         sks[i],
+                        &mut tree_cm
                     );
                     slot_coins.push(coin);
                 }
@@ -181,6 +184,7 @@ impl Epoch {
                     path_sks[i],
                     seeds[i],
                     sks[i],
+                    &mut tree_cm
                 );
                 self.coins.push(vec![coin]);
             }
@@ -198,6 +202,7 @@ impl Epoch {
         c_path_sk: [MerkleNode; MERKLE_DEPTH_ORCHARD],
         seed: u64,
         sk: SecretKey,
+        tree_cm: &mut BridgeTree::<MerkleNode, MERKLE_DEPTH>,
     ) -> LeadCoin {
         // keypair
         let keypair: Keypair = Keypair::new(sk);
@@ -206,7 +211,7 @@ impl Epoch {
         let one = pallas::Base::one();
         let c_cm1_blind: DrkValueBlind = pallas::Scalar::random(&mut rng);
         let c_cm2_blind: DrkValueBlind = pallas::Scalar::random(&mut rng);
-        let mut tree_cm = BridgeTree::<MerkleNode, MERKLE_DEPTH>::new(self.len());
+
         let c_v = pallas::Base::from(value);
         // coin relative slot index in the epoch
         let c_sl = pallas::Base::from(u64::try_from(i).unwrap());
@@ -241,6 +246,21 @@ impl Epoch {
         let leaf_position = tree_cm.witness();
         let c_root_cm = tree_cm.root(0).unwrap();
         let c_cm_path = tree_cm.authentication_path(leaf_position.unwrap(), &c_root_cm).unwrap();
+        /*
+        let c_root_cm = {
+            let mut current = MerkleNode::from(c_cm_base);
+            let pos = leaf_position.unwrap();
+            for (level, sibling) in c_cm_path.iter().enumerate() {
+                let level = level as u8;
+                current = if pos & (1 << level) == 0 {
+                    MerkleNode::combine(level.into(), &current, sibling)
+                } else {
+                    MerkleNode::combine(level.into(), sibling, &current)
+                };
+            }
+            current
+        };
+        */
 
         let coin_nonce2_msg = [c_seed, c_root_sk.inner()];
         let c_seed2: pallas::Base =

+ 10 - 20
src/crypto/leadcoin.rs

@@ -12,7 +12,7 @@ use crate::{
     zk::circuit::lead_contract::LeadContract,
 };
 
-pub const LEAD_PUBLIC_INPUT_LEN: usize = 7;
+pub const LEAD_PUBLIC_INPUT_LEN: usize = 6;
 
 #[derive(Debug, Default, Clone, Copy)]
 pub struct LeadCoin {
@@ -57,26 +57,16 @@ impl LeadCoin {
         let po_y_y = *po_y_pt.to_affine().coordinates().unwrap().y();
         let y_coord_arr = [po_y_x, po_y_y];
         let po_y: pallas::Base =
-            poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init()
-                .hash(y_coord_arr);
+            poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init().hash(y_coord_arr);
         let cm_pos = self.idx;
-        let cm_root = {
-            let pos: u32 = cm_pos;
-            let c_cm_coordinates = self.cm.unwrap().to_affine().coordinates().unwrap();
-            let c_cm_base: pallas::Base = c_cm_coordinates.x() * c_cm_coordinates.y();
-            let mut current = MerkleNode::from(c_cm_base);
-            for (level, sibling) in self.path.unwrap().iter().enumerate() {
-                let level = level as u8;
-                current = if pos & (1 << level) == 0 {
-                    MerkleNode::combine(level.into(), &current, sibling)
-                } else {
-                    MerkleNode::combine(level.into(), sibling, &current)
-                };
-            }
-            current
-        };
-        let public_inputs: [pallas::Base; LEAD_PUBLIC_INPUT_LEN] =
-            [*po_cm.x(), *po_cm.y(), po_nonce, cm_root.inner(), *po_pk.x(), *po_pk.y(), po_y];
+        let public_inputs: [pallas::Base; LEAD_PUBLIC_INPUT_LEN] = [
+            *po_cm.x(),
+            *po_cm.y(),
+            po_nonce,
+            *po_pk.x(),
+            *po_pk.y(),
+            po_y,
+        ];
         public_inputs
     }
 

+ 33 - 35
src/zk/circuit/lead_contract.rs

@@ -42,7 +42,6 @@ use pasta_curves::group::Curve;
 const WINDOW_SIZE: usize = 3;
 const NUM_OF_BITS: usize = 254;
 const NUM_OF_WINDOWS: usize = 85;
-
 const PRF_NULLIFIER_PREFIX: u64 = 0;
 
 #[derive(Clone, Debug)]
@@ -96,10 +95,9 @@ impl LeadConfig {
 const LEAD_COIN_COMMIT_X_OFFSET: usize = 0;
 const LEAD_COIN_COMMIT_Y_OFFSET: usize = 1;
 const LEAD_COIN_NONCE2_OFFSET: usize = 2;
-const LEAD_COIN_COMMIT_PATH_OFFSET: usize = 3;
-const LEAD_COIN_PK_X_OFFSET: usize = 4;
-const LEAD_COIN_PK_Y_OFFSET: usize = 5;
-const LEAD_Y_COMMIT_BASE_OFFSET: usize = 6;
+const LEAD_COIN_PK_X_OFFSET: usize = 3;
+const LEAD_COIN_PK_Y_OFFSET: usize = 4;
+const LEAD_Y_COMMIT_BASE_OFFSET: usize = 5;
 
 #[derive(Default, Debug)]
 pub struct LeadContract {
@@ -540,12 +538,6 @@ impl Circuit<pallas::Base> for LeadContract {
 
         let coin_cm_root = merkle_inputs
             .calculate_root(layouter.namespace(|| "calculate root"), coin_commit_prod)?;
-
-        layouter.assign_region(||"",
-                               |mut region| {
-                                   region.constrain_equal(coin_cm_root.cell(), root_cm.cell())
-                               }
-        );
         // lhs of the leader election lottery
         // *  y as COMIT(root_sk||nonce, mau_y)
         // beging the commitment to the coin's secret key, coin's nonce, and
@@ -624,7 +616,6 @@ impl Circuit<pallas::Base> for LeadContract {
             layouter.namespace(|| "witness rho"),
             self.rho.map(|x| x.to_affine()),
         )?;
-        rho_commit.constrain_equal(layouter.namespace(|| ""), &rho)?;
         let term1 =
             ar_chip.mul(layouter.namespace(|| "calculate term1"), &sigma1, &coin_value.clone())?;
 
@@ -663,40 +654,47 @@ impl Circuit<pallas::Base> for LeadContract {
             LEAD_COIN_COMMIT_Y_OFFSET,
         )?;
 
-        let ref_coin2_cm = NonIdentityPoint::new(
-            ecc_chip.clone(),
-            layouter.namespace(|| "witness coin2 cm"),
-            self.coin2_commit.map(|x| x.to_affine()),
-        )?;
-
-        coin2_commit.constrain_equal(layouter.namespace(|| ""), &ref_coin2_cm)?;
-
-        layouter.constrain_instance(coin2_nonce.cell(),
-                                    config.primary,
-                                    LEAD_COIN_NONCE2_OFFSET
+        layouter.constrain_instance(
+            coin2_nonce.cell(),
+            config.primary,
+            LEAD_COIN_NONCE2_OFFSET
         )?;
 
-
-        layouter.constrain_instance(coin_pk_x.cell(),
-                                    config.primary,
-                                    LEAD_COIN_PK_X_OFFSET
+        layouter.constrain_instance(
+            coin_pk_x.cell(),
+            config.primary,
+            LEAD_COIN_PK_X_OFFSET
         )?;
-        layouter.constrain_instance(coin_pk_y.cell(),
-                                    config.primary,
-                                    LEAD_COIN_PK_Y_OFFSET
+        layouter.constrain_instance(
+            coin_pk_y.cell(),
+            config.primary,
+            LEAD_COIN_PK_Y_OFFSET
         )?;
 
-        layouter.assign_region(
-            || "",
-            |mut region| region.constrain_equal(sn_commit.cell(), coin1_sn.cell()),
-        );
-
         layouter.constrain_instance(
             y_commit_base.cell(),
             config.primary,
             LEAD_Y_COMMIT_BASE_OFFSET,
         )?;
 
+        rho_commit.constrain_equal(
+            layouter.namespace(||""),
+            &rho
+        )?;
+        let ref_coin2_cm = NonIdentityPoint::new(
+            ecc_chip.clone(),
+            layouter.namespace(|| "witness coin2 cm"),
+            self.coin2_commit.map(|x| x.to_affine()),
+        )?;
+        coin2_commit.constrain_equal(
+            layouter.namespace(||""),
+            &ref_coin2_cm
+        )?;
+        layouter.assign_region(||"", |mut region| {
+            region.constrain_equal(sn_commit.cell(),coin1_sn.cell())?;
+            region.constrain_equal(coin_cm_root.cell(), root_cm.cell())
+        });
+
         Ok(())
     }
 }