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

WIP debugging failing less_than proof

mohab metwally 3 лет назад
Родитель
Сommit
d477eb3106
4 измененных файлов с 176 добавлено и 9 удалено
  1. 5 0
      Cargo.toml
  2. 154 0
      example/less_than.rs
  3. 4 1
      src/consensus/coins.rs
  4. 13 8
      src/zk/circuit/lead_contract.rs

+ 5 - 0
Cargo.toml

@@ -374,3 +374,8 @@ required-features = ["node"]
 name = "crypsinous"
 path = "example/crypsinous.rs"
 required-features = ["node"]
+
+[[example]]
+name = "lessthan"
+path = "example/less_than.rs"
+required_features = ["node"]

+ 154 - 0
example/less_than.rs

@@ -0,0 +1,154 @@
+use halo2_proofs::{
+    arithmetic::FieldExt,
+    circuit::{AssignedCell, Chip, Layouter, Region, Value},
+    pasta::pallas,
+    plonk::{Circuit, Advice, Column, ConstraintSystem, Error, Expression, Selector, TableColumn},
+    poly::Rotation,
+    circuit::{floor_planner},
+    dev::{CircuitLayout, MockProver},
+};
+
+
+use darkfi::{
+    consensus::{utils::{fbig2base}, types::Float10},
+    crypto::{Proof, proof::{ProvingKey, VerifyingKey}, },
+    zk::gadget::{native_range_check::{NativeRangeCheckChip},
+                 less_than::{LessThanChip, LessThanConfig}},
+    VerifyFailed
+};
+use log::{info, error};
+use rand::rngs::OsRng;
+
+const WINDOW_SIZE : usize= 3;
+const NUM_BITS : usize = 253;
+const NUM_WINDOWS : usize =85;
+
+#[derive(Default)]
+struct LessThanCircuit {
+    a: Value<pallas::Base>,
+    b: Value<pallas::Base>,
+}
+
+impl Circuit<pallas::Base> for LessThanCircuit {
+    type Config =
+        (LessThanConfig<WINDOW_SIZE, NUM_BITS, NUM_WINDOWS>, Column<Advice>);
+    type FloorPlanner = floor_planner::V1;
+
+    fn without_witnesses(&self) -> Self {
+        Self { a: Value::unknown(), b: Value::unknown() }
+    }
+
+    fn configure(meta: &mut ConstraintSystem<pallas::Base>) -> Self::Config {
+        let w = meta.advice_column();
+        meta.enable_equality(w);
+
+        let a = meta.advice_column();
+        let b = meta.advice_column();
+        let a_offset = meta.advice_column();
+        let z1 = meta.advice_column();
+        let z2 = meta.advice_column();
+
+        let k_values_table = meta.lookup_table_column();
+
+        let constants = meta.fixed_column();
+        meta.enable_constant(constants);
+
+        (
+            LessThanChip::<WINDOW_SIZE, NUM_BITS, NUM_WINDOWS>::configure(
+                meta,
+                a,
+                b,
+                a_offset,
+                z1,
+                z2,
+                k_values_table,
+            ),
+            w,
+        )
+    }
+
+    fn synthesize(
+        &self,
+        config: Self::Config,
+        mut layouter: impl Layouter<pallas::Base>,
+    ) -> Result<(), Error> {
+        let less_than_chip =
+            LessThanChip::<WINDOW_SIZE, NUM_BITS, NUM_WINDOWS>::construct(
+                config.0.clone(),
+            );
+
+        NativeRangeCheckChip::<WINDOW_SIZE, NUM_BITS, NUM_WINDOWS>::load_k_table(
+            &mut layouter,
+            config.0.k_values_table,
+        )?;
+
+        less_than_chip.witness_less_than(
+            layouter.namespace(|| "a < b"),
+            self.a,
+            self.b,
+            0,
+            true,
+        )?;
+        Ok(())
+    }
+}
+
+fn simple_lessthan (k: u32) -> Result<(), halo2_proofs::plonk::Error>{
+    let y : pallas::Base = pallas::Base::zero();
+    let t : pallas::Base = pallas::Base::one();
+    let circuit = LessThanCircuit { a: Value::known(y), b: Value::known(t) };
+
+    let prover = MockProver::run(k, &circuit, vec![]).unwrap();
+    prover.assert_satisfied();
+    assert!(prover.verify().is_ok());
+
+    let public_inputs : Vec<pallas::Base> = vec![];
+    let pk = ProvingKey::build(k, &LessThanCircuit::default());
+    let vk = VerifyingKey::build(k, &LessThanCircuit::default());
+    let proof = Proof::create(&pk, &[circuit], &public_inputs, &mut OsRng)?;
+    match proof.verify(&vk, &public_inputs) {
+        Ok(()) => {
+            info!("proof verified");
+            Ok(())
+        },
+        Err(e) => {
+            error!("verification failed: {}", e);
+            return Err(e)
+        }
+    }
+}
+
+fn fullrange_lessthan (k: u32) -> Result<(), halo2_proofs::plonk::Error> {
+    let y_str : &'static str = "0x057eaec1c805d808f70c4e2d2f173c72d091e9c9f78b11dddf52d072c30951ad";
+    let t_str : &'static str = "0x2cb8d8aec6766dc83595602e3050b0b908191bbe59dcc3d1e2b7020a37339a14";
+    let y : pallas::Base = fbig2base(Float10::from_str_native(y_str).unwrap().with_precision(74).value());
+    let t : pallas::Base = fbig2base(Float10::from_str_native(t_str).unwrap().with_precision(74).value());
+
+    let circuit = LessThanCircuit { a: Value::known(y), b: Value::known(t) };
+
+    let prover = MockProver::run(k, &circuit, vec![]).unwrap();
+    prover.assert_satisfied();
+    assert!(prover.verify().is_ok());
+
+    let public_inputs : Vec<pallas::Base> = vec![];
+    let pk = ProvingKey::build(k, &LessThanCircuit::default());
+    let vk = VerifyingKey::build(k, &LessThanCircuit::default());
+    let proof = Proof::create(&pk, &[circuit], &public_inputs, &mut OsRng)?;
+    match proof.verify(&vk, &public_inputs) {
+        Ok(()) => {
+            info!("proof verified");
+            Ok(())
+        },
+        Err(e) => {
+            error!("verification failed: {}", e);
+            return Err(e)
+        }
+    }
+}
+
+fn main ()  {
+    env_logger::init();
+    let k = 11;
+    let res_simple = simple_lessthan(k).unwrap();
+    let res_fullrange = fullrange_lessthan(k).unwrap();
+}

+ 4 - 1
src/consensus/coins.rs

@@ -239,10 +239,13 @@ fn create_leadcoin(
 
     //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: pallas::Point = keypair.public.0;
     let c_pk_coord = c_pk.to_affine().coordinates().unwrap();
     let c_pk_x = c_pk_coord.x();
     let c_pk_y = c_pk_coord.y();
+    info!("coin pk [{}] x: {:?}", i, c_pk_x);
+    info!("coin pk [{}] y: {:?}", i, c_pk_y);
 
     let c_seed = pallas::Base::from(seed);
     let sn_msg = [c_seed, c_root_sk.inner(), zero.clone(), one.clone()];
@@ -289,7 +292,7 @@ fn create_leadcoin(
     let c_seed2: pallas::Base =
         poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<4>, 3, 2>::init()
             .hash(coin_nonce2_msg);
-
+    info!("coin2 seed [{}] : {:?}", i, c_seed2);
     let coin2_commit_msg_input =
         [pallas::Base::from(*PRF_NULLIFIER_PREFIX), *c_pk_x, *c_pk_y, c_v, c_seed2, one];
     let coin2_commit_msg: pallas::Base =

+ 13 - 8
src/zk/circuit/lead_contract.rs

@@ -675,14 +675,7 @@ impl Circuit<pallas::Base> for LeadContract {
 
         info!("y: {:?}", y);
         info!("T: {:?}", T);
-        // Constrain y < target
-        lessthan_chip.copy_less_than(
-            layouter.namespace(|| "y < target"),
-            y_commit_base.clone(),
-            target,
-            0,
-            true,
-        )?;
+
         // Constrain derived `sn_commit` to be equal to witnessed `coin1_serial`.
         info!("coin1 cm root LHS: {:?}", coin1_cm_root.value());
         info!("coin1 cm root RHS: {:?}", coin1_commit_root.value());
@@ -712,6 +705,8 @@ impl Circuit<pallas::Base> for LeadContract {
         // Constrain derived rho_commit to witnessed rho
         rho_commit.constrain_equal(layouter.namespace(|| "rho equality"), &rho)?;
 
+        info!("coin pk: x {:?}", coin_pk.inner().x());
+        info!("coin pk: y {:?}", coin_pk.inner().y());
         // Constrain coin's public key coordinates with public inputs
         layouter.constrain_instance(
             coin_pk.inner().x().cell(),
@@ -723,6 +718,7 @@ impl Circuit<pallas::Base> for LeadContract {
             config.primary,
             LEADCOIN_PK_Y_OFFSET,
         )?;
+        info!("coin2 nonce: {:?}", coin2_nonce);
         // Constrain coin2_nonce with associated public input
         layouter.constrain_instance(
             coin2_nonce.cell(),
@@ -737,6 +733,15 @@ impl Circuit<pallas::Base> for LeadContract {
             LEADCOIN_Y_BASE_OFFSET,
         )?;
 
+        // Constrain y < target
+        lessthan_chip.copy_less_than(
+            layouter.namespace(|| "y < target"),
+            y_commit_base.clone(),
+            target,
+            0,
+            true,
+        )?;
+
         Ok(())
     }
 }