Просмотр исходного кода

[zk/lead_contract] used y_commit in place it's coordinates

mohab 4 лет назад
Родитель
Сommit
1aa3e0245c
5 измененных файлов с 116 добавлено и 147 удалено
  1. 3 2
      example/gt.rs
  2. 62 64
      example/lead.rs
  3. 1 0
      src/crypto/mod.rs
  4. 49 81
      src/zk/circuit/lead_contract.rs
  5. 1 0
      src/zk/even_bits.rs

+ 3 - 2
example/gt.rs

@@ -102,7 +102,6 @@ impl Circuit<pallas::Base> for ZkCircuit {
         eb_chip.decompose(layouter.namespace(|| "helper range check"), helper.0)?;
 
         layouter.constrain_instance(greater_than.0.cell(), config.primary, 0)?;
-
         Ok(())
     }
 }
@@ -120,7 +119,9 @@ fn main() {
         f: Some(f),
     };
 
-    let mut public_inputs = vec![c];
+    let mut public_inputs : Vec<pallas::Base> = vec![
+          c,
+    ];
 
     let prover = MockProver::run(k, &circuit, vec![public_inputs]).unwrap();
     assert_eq!(prover.verify(), Ok(()));

+ 62 - 64
example/lead.rs

@@ -48,6 +48,7 @@ pub struct Coin
     sl : Option<pallas::Base>, //slot id
     tau : Option<pallas::Base>,
     nonce : Option<pallas::Base>,
+    nonce_cm : Option<pallas::Point>,
     sn : Option<pallas::Point>, // coin's serial number
     //sk : Option<SecretKey>,
     pk : Option<pallas::Point>,
@@ -97,6 +98,7 @@ fn main()
     //
     let mut tree_cm = BridgeTree::<MerkleNode, 32>::new(LEN);
     let zerou64 : u64 = 0;
+
     for i in 0..LEN {
         let c_v = pallas::Base::from(u64::try_from(i*2).unwrap());
         //random sampling of the same size of prf,
@@ -107,23 +109,8 @@ fn main()
 
         let c_tau  = pallas::Base::from(u64::try_from(i).unwrap()); // let's assume it's sl for simplicity
         let c_root_sk : MerkleNode  = root_sks[i];
-        // =========================
-        //TODO 512 secret-key/public-key to cop with pallas curves
-        // =========================
-        //note! sk is used in MerkleNode takes pallas::Base as input
-        //while the pallas::base is 512, the SecretKey is  of size 256, a larger keyring is needed
-        //TODO what is the endianess of this keyring
-        //let sk_bits = vec![];
-        //sk_bits.append(&mut c_sk.to_le_bytes().to_vec());
-        //sk_bits.append(&mut zerou64.to_le_bytes().to_vec());
-        //sk_bits.append(&mut zerou64.to_le_bytes().to_vec());
-        //sk_bits.append(&mut zerou64.to_le_bytes().to_vec());
-        //let c_pk = PublicKey::from_secret(SecretKey::from_bytes(sk_bits.as_slice().try_into().unwrap()).unwrap());
-        let c_pk = pedersen_commitment_scalar(mod_r_p(c_tau), mod_r_p(c_root_sk.inner()));
-        //
-        // TODO (fix) no use random value for the secret key as random pallas base
-        // =======================
 
+        let c_pk = pedersen_commitment_scalar(mod_r_p(c_tau), mod_r_p(c_root_sk.inner()));
 
         let c_seed  = pallas::Base::from(seeds[i]);
         let c_sn  = pedersen_commitment_scalar(mod_r_p(c_seed), mod_r_p(c_root_sk.inner()));
@@ -133,14 +120,21 @@ fn main()
         let c_cm1_blind = pallas::Base::from(0); //tmp val
         let c_cm2_blind = pallas::Base::from(0); //tmp val
         let c_cm : pallas::Point  = pedersen_commitment_scalar(mod_r_p(c_cm_v), mod_r_p(c_cm1_blind));
-        //TODO (fix) which affine coefficient point to be used a/b ?
-        let c_cm_node = MerkleNode(pallas::Base::from_repr(c_cm.to_bytes()).unwrap());
+        //TODO this return run time error! assertion error, it's out of range most likely
+        //let c_cm_base_bytes : [u8; 32] = c_cm.to_bytes();
+        /*
+        let c_cm_base_bytes : [u8; 32] = c_cm.to_affine()
+            .coordinates()
+            .unwrap()
+            .x().to_repr();
+        let c_cm_base : pallas::Base = pallas::Base::from_repr(c_cm_base_bytes).unwrap();
+        */
+        let c_cm_node = MerkleNode(pallas::Base::from(1)); // this is temporary, shouldn't pass of course
         tree_cm.append(&c_cm_node.clone());
         tree_cm.witness();
         let (leaf_pos, c_cm_path) = tree_cm.authentication_path(&c_cm_node).unwrap();
         let c_root_cm = tree_cm.root();
         // lead coin commitment
-        //TODO this c_v can be
         let c_seed2 = pedersen_commitment_scalar(mod_r_p(c_seed), mod_r_p(c_root_sk.inner()));
         let c_seed2_pt = c_seed2.to_affine().coordinates().unwrap();
         let lead_coin_msg = [*c_pk_pt.x(), *c_pk_pt.y(), c_v, *c_seed2_pt.x(), *c_seed2_pt.y()];
@@ -156,6 +150,7 @@ fn main()
             sl: Some(c_sl),
             tau: Some(c_tau),
             nonce: Some(c_seed),
+            nonce_cm: Some(c_seed2),
             sn:  Some(c_sn),
             //sk: Some(c_sk),
             pk: Some(c_pk),
@@ -174,67 +169,70 @@ fn main()
     // ================
     let coin_idx  = 0;
     let coin = coins[coin_idx];
-    let c0 = pedersen_commitment_scalar(mod_r_p(coin.nonce.unwrap()), coin.root_cm.unwrap())
+
+
+    let po_nonce = coin.nonce_cm
+        .unwrap()
         .to_affine()
         .coordinates()
         .unwrap();
-    let c1 = pedersen_commitment_scalar(mod_r_p(coin.tau.unwrap()), coin.root_cm.unwrap())
+
+    let po_nonce = coin.nonce_cm.unwrap()
         .to_affine()
         .coordinates()
         .unwrap();
 
-    let c2 = pedersen_commitment_scalar(mod_r_p(coin.nonce.unwrap()), coin.root_cm.unwrap())
+    let po_tau = pedersen_commitment_scalar(mod_r_p(coin.tau.unwrap()), coin.root_cm.unwrap())
         .to_affine()
         .coordinates()
         .unwrap();
-   //
-    let c3 = coin.cm.unwrap().to_affine().coordinates().unwrap();
-    let c4 = coin.cm2.unwrap().to_affine().coordinates().unwrap();
 
-    let c7 = coin.pk.unwrap().to_affine().coordinates().unwrap();
-    let c8 = coin.sn.unwrap().to_affine().coordinates().unwrap();
+    let po_cm = coin.cm.unwrap().to_affine().coordinates().unwrap();
+    let po_cm2 = coin.cm2.unwrap().to_affine().coordinates().unwrap();
 
-    //TODO (fix) this need to be replaced by computed final path as pallas::Base
-    let c5 = coin.path.unwrap();
+    let po_pk = coin.pk.unwrap().to_affine().coordinates().unwrap();
+    let po_sn = coin.sn.unwrap().to_affine().coordinates().unwrap();
 
-    let c6 = pallas::Base::from(0);
-    // ===============
 
+    let po_path = coin.path.unwrap();
+
+    let po_cmp = pallas::Base::from(0);
+    // ===============
     let path_sk = path_sks[coin_idx];
-    let contract = LeadContract {
-        path: coin.path,
-        root_sk: coin.root_sk,
-        path_sk: Some(path_sk),
-        coin_timestamp: coin.tau, //
-        coin_nonce: coin.nonce,
-        coin_opening_1: Some(mod_r_p(coin.opening1.unwrap())),
-        value: coin.value,
-        coin_opening_2: Some(mod_r_p(coin.opening2.unwrap())),
-        cm_c1_x: Some(*c3.x()),
-        cm_c1_y: Some(*c3.y()),
-        cm_c2_x: Some(*c4.x()),
-        cm_c2_y: Some(*c4.y()),
-        cm_pos : Some(u32::try_from(coin_idx).unwrap()),
-        //sn_c1: Some(coin.sn.unwrap()),
-        slot: Some(coin.sl.unwrap()),
-        mau_rho: Some(mau_rho.clone()),
-        mau_y: Some(mau_y.clone()),
-        root_cm: Some(coin.root_cm.unwrap()),
-    };
-
-    let mut public_inputs = vec![*c0.x(), *c0.y(),
-                                 *c1.x(), *c1.y(),
-                                 *c2.x(), *c2.y(),
-                                 *c7.x(), *c7.y(),
-                                 *c8.x(), *c8.y(),
-                                 *c3.x(), *c3.y(),
-                                 *c4.x(), *c4.y(),
-                                 c5[31].inner(), //TODO (res) how the path is structured assumed root is last node in the path.
-                                 c6,
-    ];
 
-    let mut vec_inputs = vec![public_inputs];
+   let contract = LeadContract {
+       path: coin.path,
+       root_sk: coin.root_sk,
+       path_sk: Some(path_sk),
+       coin_timestamp: coin.tau, //
+       coin_nonce: coin.nonce,
+       coin_opening_1: Some(mod_r_p(coin.opening1.unwrap())),
+       value: coin.value,
+       coin_opening_2: Some(mod_r_p(coin.opening2.unwrap())),
+       cm_c1_x: Some(*po_cm.x()),
+       cm_c1_y: Some(*po_cm.y()),
+       cm_c2_x: Some(*po_cm2.x()),
+       cm_c2_y: Some(*po_cm2.y()),
+       cm_pos : Some(u32::try_from(coin_idx).unwrap()),
+       //sn_c1: Some(coin.sn.unwrap()),
+       slot: Some(coin.sl.unwrap()),
+       mau_rho: Some(mau_rho.clone()),
+       mau_y: Some(mau_y.clone()),
+       root_cm: Some(coin.root_cm.unwrap()),
+   };
+
+    let mut public_inputs : Vec<pallas::Base> = vec![
+        *po_nonce.x(), *po_nonce.y(),
+        *po_pk.x(), *po_pk.y(),
+        *po_sn.x(), *po_sn.y(),
+        *po_cm.x(), *po_cm.y(),
+        *po_cm2.x(), *po_cm2.y(),
+        po_path[31].inner(), //TODO (res) how the path is structured assumed root is last node in the path.
+        po_cmp,
+    ];
 
-    let prover = MockProver::run(k, &contract, vec_inputs).unwrap();
+    let prover = MockProver::run(k, &contract, vec![public_inputs]).unwrap();
+    //
     assert_eq!(prover.verify(), Ok(()));
+    //
 }

+ 1 - 0
src/crypto/mod.rs

@@ -6,6 +6,7 @@ pub mod keypair;
 //pub mod loader;
 pub mod burn_proof;
 pub mod merkle_node;
+//pub mod point_node;
 pub mod mint_proof;
 pub mod note;
 pub mod nullifier;

+ 49 - 81
src/zk/circuit/lead_contract.rs

@@ -39,6 +39,13 @@ use crate::zk::{
     even_bits::{EvenBitsChip, EvenBitsConfig, EvenBitsLookup},
 };
 
+use pasta_curves::group::Curve;
+use pasta_curves::arithmetic::CurveAffine;
+//use halo2_proofs::arithmetic::CurveAffine;
+use pasta_curves::group::ff::PrimeField;
+use pasta_curves::group::GroupEncoding;
+
+
 const WORD_BITS : u32 = 24;
 
 #[derive(Clone,Debug)]
@@ -95,30 +102,18 @@ impl LeadConfig
     }
 }
 
-
-//
-const LEAD_COIN_PK_X_OFFSET: usize = 0;
-const LEAD_COIN_PK_Y_OFFSET: usize = 1;
-//
-const LEAD_COIN_NONCE2_X_OFFSET: usize = 2;
-const LEAD_COIN_NONCE2_Y_OFFSET: usize = 3;
-
+const LEAD_COIN_NONCE2_X_OFFSET: usize = 0;
+const LEAD_COIN_NONCE2_Y_OFFSET: usize = 1;
+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_COIN2_SERIAL_NUMBER_X_OFFSET: usize = 8;
-const LEAD_COIN2_SERIAL_NUMBER_Y_OFFSET: usize = 9;
-//
-const LEAD_COIN_COMMIT_PATH_OFFSET: usize = 6;
-
-const LEAD_THRESHOLD_OFFSET: usize = 7;
-
-const LEAD_COIN_COMMIT_X_OFFSET : usize = 10;
-const LEAD_COIN_COMMIT_Y_OFFSET : usize = 11;
-
-const LEAD_COIN_COMMIT2_X_OFFSET : usize = 12;
-const LEAD_COIN_COMMIT2_Y_OFFSET : usize = 13;
+const LEAD_COIN_COMMIT_X_OFFSET : usize = 6;
+const LEAD_COIN_COMMIT_Y_OFFSET : usize = 7;
+const LEAD_COIN_COMMIT2_X_OFFSET : usize = 8;
+const LEAD_COIN_COMMIT2_Y_OFFSET : usize = 9;
+const LEAD_COIN_COMMIT_PATH_OFFSET: usize = 10;
+const LEAD_THRESHOLD_OFFSET: usize = 11;
 
 #[derive(Debug,Default)]
 pub struct LeadContract {
@@ -207,12 +202,9 @@ impl Circuit<pallas::Base> for LeadContract {
         let rc_b = lagrange_coeffs[5..8].try_into().unwrap();
 
         meta.enable_constant(lagrange_coeffs[0]);
-        let range_check = LookupRangeCheckConfig::configure(meta, advices[8], table_idx);
+        let range_check = LookupRangeCheckConfig::configure(meta, advices[9], table_idx);
 
-
-        //TODO how many columns needed for the eccChip?
-        //i assumed 5 for constants/private_witnesses
-        let ecc_config = EccChip::<OrchardFixedBases>::configure(meta, advices[0..9].try_into().expect("wrong slice size"), lagrange_coeffs, range_check);
+        let ecc_config = EccChip::<OrchardFixedBases>::configure(meta, advices[0..10].try_into().expect("wrong slice size"), lagrange_coeffs, range_check);
 
         let poseidon_config = PoseidonChip::configure::<P128Pow5T3>(
             meta,
@@ -238,7 +230,7 @@ impl Circuit<pallas::Base> for LeadContract {
         let (sinsemilla_config_2, merkle_config_2) = {
             let sinsemilla_config_2 = SinsemillaChip::configure(
                 meta,
-                advices[5..9].try_into().unwrap(),
+                advices[5..10].try_into().unwrap(),
                 advices[7],
                 lagrange_coeffs[1],
                 lookup,
@@ -249,10 +241,11 @@ impl Circuit<pallas::Base> for LeadContract {
             (sinsemilla_config_2, merkle_config_2)
         };
 
-        let  greaterthan_config = GreaterThanChip::<pallas::Base, WORD_BITS>::configure(meta, advices[10..11].try_into().unwrap(), primary);
+        let  greaterthan_config = GreaterThanChip::<pallas::Base, WORD_BITS>::configure(meta, advices[10..12].try_into().unwrap(), primary);
         let evenbits_config = EvenBitsChip::<pallas::Base, WORD_BITS>::configure(meta);
         let arith_config = ArithmeticChip::configure(meta);
 
+
         LeadConfig {
             primary,
             advices,
@@ -277,6 +270,8 @@ impl Circuit<pallas::Base> for LeadContract {
         let ar_chip = config.arith_chip();
         let ps_chip = config.poseidon_chip();
         let eb_chip = config.evenbits_chip();
+        let greater_than_chip = config.greaterthan_chip();
+
         eb_chip.alloc_table(&mut layouter.namespace(|| "alloc table"))?;
 
         // ===============
@@ -291,22 +286,15 @@ impl Circuit<pallas::Base> for LeadContract {
             self.coin_timestamp,
         )?;
 
-
-
         // root of coin
 
-
         /*
         let root_sk = self.load_private(
             layouter.namespace(|| "load root coin"),
             config.advices[0],
             self.root_sk,
         )?;
-         */
-
-
-
-
+        */
         // coin nonce
 
         let coin_nonce = self.load_private(
@@ -456,6 +444,7 @@ impl Circuit<pallas::Base> for LeadContract {
             nonce2_commit_r.mul(layouter.namespace(|| "nonce2 commit R"), self.root_sk)?
         };
         let coin2_nonce = com.add(layouter.namespace(|| "nonce2 commit"), &blind)?;
+
         layouter.constrain_instance(
             coin2_nonce.inner().x().cell(),
             config.primary,
@@ -467,6 +456,7 @@ impl Circuit<pallas::Base> for LeadContract {
             config.primary,
             LEAD_COIN_NONCE2_Y_OFFSET,
         )?;
+
         // ================
         // coin public key constraints derived from the coin timestamp
         // ================
@@ -486,6 +476,7 @@ impl Circuit<pallas::Base> for LeadContract {
         };
         let coin_pk_commit = com.add(layouter.namespace(|| "coin timestamp commit"), &blind)?;
         // constrain coin's pub key x value
+
         layouter.constrain_instance(
             coin_pk_commit.inner().x().cell(),
             config.primary,
@@ -498,7 +489,6 @@ impl Circuit<pallas::Base> for LeadContract {
             LEAD_COIN_PK_Y_OFFSET,
         )?;
 
-
         // =================
         // nonce constraints derived from previous coin's nonce
         // =================
@@ -522,6 +512,7 @@ impl Circuit<pallas::Base> for LeadContract {
         //
         let sn_commit = com.add(layouter.namespace(|| "nonce commit"), &blind)?;
         // constrain coin's pub key x value
+
         layouter.constrain_instance(
             sn_commit.inner().x().cell(),
             config.primary,
@@ -533,8 +524,6 @@ impl Circuit<pallas::Base> for LeadContract {
             config.primary,
             LEAD_COIN_SERIAL_NUMBER_Y_OFFSET,
         )?;
-
-
         // ==========================
         // commitment of coins c1,c2
         // ==========================
@@ -601,7 +590,6 @@ impl Circuit<pallas::Base> for LeadContract {
             LEAD_COIN_COMMIT_Y_OFFSET,
         )?;
 
-
         //
         let coin2_hash = {
             let poseidon_message = [coin_pk_commit.inner().x(),
@@ -638,6 +626,8 @@ impl Circuit<pallas::Base> for LeadContract {
         let coin2_commit_y : AssignedCell<Fp, Fp> = coin2_commit.inner().y();
         let cm2_zero_out_x = ar_chip.sub(layouter.namespace(|| "sub to zero"), coin2_commit_x, cm_c2_x)?;
         let cm2_zero_out_y = ar_chip.sub(layouter.namespace(|| "sub to zero"), coin2_commit_y, cm_c2_y)?;
+
+
         layouter.constrain_instance(
             cm2_zero_out_x.cell(),
             config.primary,
@@ -649,7 +639,7 @@ impl Circuit<pallas::Base> for LeadContract {
             config.primary,
             LEAD_COIN_COMMIT2_X_OFFSET,
         )?;
-        //let coin1_commit_pos : u32 = 0;
+
         // ===========================
         let path: Option<[pallas::Base; MERKLE_DEPTH_ORCHARD]> =
             self.path.map(|typed_path| gen_const_array(|i| typed_path[i].inner()));
@@ -685,34 +675,6 @@ impl Circuit<pallas::Base> for LeadContract {
             LEAD_COIN_COMMIT_PATH_OFFSET,
         )?;
 
-        // =============================
-        /*
-        let path: Option<[pallas::Base; MERKLE_DEPTH_ORCHARD]> =
-            self.path_sk.map(|typed_path| gen_const_array(|i| typed_path[i].inner()));
-
-        let merkle_inputs = MerklePath::construct(
-            config.merkle_chip_1(),
-            config.merkle_chip_2(),
-            OrchardHashDomains::MerkleCrh,
-            self.slot - self.coin_timestamp,
-            path,
-        );
-
-        //TODO fix this is a path to a leaf, i have no clue of that leaf
-        let computed_final_root =
-            merkle_inputs.calculate_root(layouter.namespace(|| "calculate root"), cm_c1)?;
-
-        layouter.constrain_instance(
-            computed_final_root.cell(),
-            config.primary,
-            LEAD_COIN_COMMIT_PATH_OFFSET,
-        )?;
-         */
-
-
-        // ============================
-        // constrain y
-        // ============================
 
         let message = {
             let (com, _ )  = {
@@ -745,9 +707,18 @@ impl Circuit<pallas::Base> for LeadContract {
             let y_commit_r = FixedPoint::from_inner(ecc_chip.clone(), y_commit_r);
             y_commit_r.mul(layouter.namespace(|| "coin serial number commit R"), self.mau_y)?
         };
-        let y_commit = com.add(layouter.namespace(|| "nonce commit"), &blind)?;
+        let mut y_commit = com.add(layouter.namespace(|| "nonce commit"), &blind)?;
         // ============================
-        let y_commit_x = y_commit.inner().x();
+        //let y_commit_base  : AssignedCell<Fp,Fp> = pallas::Base::from_repr(y_commit.inner().to_bytes()).unwrap();
+        //let y_commit_x  : AssignedCell<Fp,Fp> = y_commit.inner().x();
+        //let y_commit_x_base   = y_commit.inner().x().value().unwrap();
+        let y_commit_base_temp   =  pallas::Base::from_repr(y_commit.inner().point().unwrap().to_bytes()).unwrap();
+        let y_commit_base  = self.load_private(
+            layouter.namespace(|| "load coin y commit as pallas::base"),
+            config.advices[0],
+            Some(y_commit_base_temp),
+        )?;
+
         // ============================
         // constraint rho
         // ============================
@@ -773,19 +744,16 @@ impl Circuit<pallas::Base> for LeadContract {
             Some(pallas::Base::from(1024))
         )?;
         let c = pallas::Scalar::from(3); // leadership coefficient
-        let target = ar_chip.mul(layouter.namespace(|| "calculate target"), scalar, coin_value)?;
+        let target : AssignedCell<Fp,Fp> = ar_chip.mul(layouter.namespace(|| "calculate target"), scalar, coin_value)?;
 
-        let greater_than_chip = config.greaterthan_chip();
 
-        eb_chip.decompose(layouter.namespace(|| "y range check"), target.clone())?;
-        eb_chip.decompose(layouter.namespace(|| "t range check"), y_commit_x.clone())?;
+        eb_chip.decompose(layouter.namespace(|| "target range check"), target.clone())?;
+        eb_chip.decompose(layouter.namespace(|| "y_commit  range check"), y_commit_base.clone())?;
+
 
-        let (helper, is_gt) = greater_than_chip.greater_than(layouter.namespace(||"t>y"), target.into() , y_commit_x.into())?; //note assuming x,y coordinates are true random each?
+        let (helper, is_gt) = greater_than_chip.greater_than(layouter.namespace(||"t>y"), target.into() , y_commit_base.into())?; //note assuming x,y coordinates are true random each?
         eb_chip.decompose(layouter.namespace(|| "helper range check"), helper.0)?;
-        layouter.constrain_instance(is_gt.0.cell(),
-                                    config.primary,
-                                    LEAD_THRESHOLD_OFFSET
-        )?;
+        layouter.constrain_instance(is_gt.0.cell(), config.primary, LEAD_THRESHOLD_OFFSET)?;
         Ok(())
     }
 }

+ 1 - 0
src/zk/even_bits.rs

@@ -260,3 +260,4 @@ mod tests {
         assert_eq!(o.get_lower_128(), 0);
     }
 }
+//