Explorar el Código

merge conflicts

mohab hace 4 años
padre
commit
9d3ee2e926
Se han modificado 7 ficheros con 339 adiciones y 128 borrados
  1. 12 0
      Cargo.toml
  2. 1 1
      example/gt.rs
  3. 9 0
      src/zk/arith_chip.rs
  4. 241 122
      src/zk/circuit/lead_contract.rs
  5. 9 0
      src/zk/circuit/mod.rs
  6. 64 4
      src/zk/greater_than.rs
  7. 3 1
      src/zk/vm.rs

+ 12 - 0
Cargo.toml

@@ -318,6 +318,18 @@ path = "example/tx.rs"
 required-features = ["node"]
 required-features = ["node"]
 
 
 [[example]]
 [[example]]
+<<<<<<< HEAD
 name = "zk"
 name = "zk"
 path = "example/zk.rs"
 path = "example/zk.rs"
 required-features = ["crypto"]
 required-features = ["crypto"]
+=======
+name = "gt"
+path = "example/gt.rs"
+required-features = ["node"]
+
+[[example]]
+name = "lead"
+path = "example/lead.rs"
+required-features = ["node"]
+
+>>>>>>> miscellaneous changes to lead circuit, major change replace point by coordinate, or sum of coordinate, fix typos...

+ 1 - 1
example/gt.rs

@@ -12,7 +12,7 @@ use halo2_proofs::{
 };
 };
 use pasta_curves::{pallas, Fp, vesta, Fq};
 use pasta_curves::{pallas, Fp, vesta, Fq};
 
 
-const WORD_BITS: u32 = 64;
+const WORD_BITS: u32 = 24;
 
 
 #[derive(Clone)]
 #[derive(Clone)]
 struct ZkConfig {
 struct ZkConfig {

+ 9 - 0
src/zk/arith_chip.rs

@@ -76,6 +76,15 @@ impl ArithmeticChip {
             vec![s_sub * (lhs - rhs - out)]
             vec![s_sub * (lhs - rhs - out)]
         });
         });
 
 
+        cs.create_gate("pow", |cs| {
+            let lhs = cs.query_advice(a_col, Rotation::cur());
+            let rhs = cs.query_advice(b_col, Rotation::cur());
+            let out = cs.query_advice(a_col, Rotation::next());
+            let s_sub = cs.query_selector(s_sub);
+
+            vec![s_sub * (lhs - rhs - out)]
+        });
+
         ArithmeticChipConfig { a_col, b_col, s_add, s_mul, s_sub }
         ArithmeticChipConfig { a_col, b_col, s_add, s_mul, s_sub }
     }
     }
 
 

+ 241 - 122
src/zk/circuit/lead_contract.rs

@@ -5,34 +5,47 @@ use halo2_gadgets::{
     },
     },
     poseidon::{Hash as PoseidonHash, Pow5Chip as PoseidonChip, Pow5Config as PoseidonConfig},
     poseidon::{Hash as PoseidonHash, Pow5Chip as PoseidonChip, Pow5Config as PoseidonConfig},
     primitives::poseidon::{ConstantLength, P128Pow5T3},
     primitives::poseidon::{ConstantLength, P128Pow5T3},
+    sinsemilla::{
+        chip::{SinsemillaChip, SinsemillaConfig},
+        merkle::{
+            chip::{MerkleChip, MerkleConfig},
+            MerklePath,
+        },
+    },
     utilities::{lookup_range_check::LookupRangeCheckConfig, UtilitiesInstructions},
     utilities::{lookup_range_check::LookupRangeCheckConfig, UtilitiesInstructions},
 };
 };
 
 
 use halo2_proofs::{
 use halo2_proofs::{
     circuit::{AssignedCell, Layouter, SimpleFloorPlanner},
     circuit::{AssignedCell, Layouter, SimpleFloorPlanner},
     plonk,
     plonk,
-    plonk::{Advice, Circuit, Column, ConstraintSystem, Instance as InstanceColumn},
+    plonk::{Advice, Circuit, Column, ConstraintSystem, Instance as InstanceColumn, Error},
 };
 };
 
 
 use pasta_curves::{pallas, Fp};
 use pasta_curves::{pallas, Fp};
 
 
-use crate::crypto::constants::{
+use crate::crypto::{
     constants::{
     constants::{
+        sinsemilla::{OrchardCommitDomains, OrchardHashDomains},
         util::gen_const_array,
         util::gen_const_array,
+        NullifierK, OrchardFixedBases, OrchardFixedBasesFull, ValueCommitV, MERKLE_DEPTH_ORCHARD,
     },
     },
-    OrchardFixedBases, OrchardFixedBasesFull, ValueCommitV,
+    merkle_node::MerkleNode,
 };
 };
 
 
-use create::zk::{
+
+use crate::zk::{
     arith_chip::{ArithmeticChipConfig, ArithmeticChip},
     arith_chip::{ArithmeticChipConfig, ArithmeticChip},
-    GreaterThanChip, GreatherThanConfig,
+    greater_than::{GreaterThanChip, GreaterThanConfig, GreaterThanInstruction},
+    even_bits::{EvenBitsChip, EvenBitsConfig, EvenBitsLookup},
 };
 };
 
 
+const WORD_BITS : u32 = 24;
+
 #[derive(Clone,Debug)]
 #[derive(Clone,Debug)]
 pub struct LeadConfig
 pub struct LeadConfig
 {
 {
     primary: Column<InstanceColumn>,
     primary: Column<InstanceColumn>,
-    advices: [Column<Advice>;19],
+    advices: [Column<Advice>;12],
     ecc_config: EccConfig<OrchardFixedBases>,
     ecc_config: EccConfig<OrchardFixedBases>,
     poseidon_config: PoseidonConfig<pallas::Base,3,2>,
     poseidon_config: PoseidonConfig<pallas::Base,3,2>,
     merkle_config_1: MerkleConfig<OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases>,
     merkle_config_1: MerkleConfig<OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases>,
@@ -40,12 +53,13 @@ pub struct LeadConfig
     sinsemilla_config_1: SinsemillaConfig<OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases>,
     sinsemilla_config_1: SinsemillaConfig<OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases>,
     sinsemilla_config_2: SinsemillaConfig<OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases>,
     sinsemilla_config_2: SinsemillaConfig<OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases>,
     greaterthan_config: GreaterThanConfig,
     greaterthan_config: GreaterThanConfig,
+    evenbits_config: EvenBitsConfig,
     arith_config: ArithmeticChipConfig,
     arith_config: ArithmeticChipConfig,
 }
 }
 
 
 impl LeadConfig
 impl LeadConfig
 {
 {
-    fn ecc_chip(&self) -> EccChip<OrchardFixedBass>
+    fn ecc_chip(&self) -> EccChip<OrchardFixedBases>
     {
     {
         EccChip::construct(self.ecc_config.clone())
         EccChip::construct(self.ecc_config.clone())
     }
     }
@@ -71,6 +85,11 @@ impl LeadConfig
         GreaterThanChip::construct(self.greaterthan_config.clone())
         GreaterThanChip::construct(self.greaterthan_config.clone())
     }
     }
 
 
+    fn evenbits_chip(&self) -> EvenBitsChip<pallas::Base, WORD_BITS> {
+        EvenBitsChip::construct(self.evenbits_config.clone())
+    }
+
+
     fn arith_chip(&self) -> ArithmeticChip {
     fn arith_chip(&self) -> ArithmeticChip {
         ArithmeticChip::construct(self.arith_config.clone())
         ArithmeticChip::construct(self.arith_config.clone())
     }
     }
@@ -79,10 +98,10 @@ impl LeadConfig
 
 
 //
 //
 const LEAD_COIN_PK_X_OFFSET: usize = 0;
 const LEAD_COIN_PK_X_OFFSET: usize = 0;
-const LEAD_COIN_PK_y_OFFSET: usize = 1;
+const LEAD_COIN_PK_Y_OFFSET: usize = 1;
 //
 //
 const LEAD_COIN_NONCE2_X_OFFSET: usize = 2;
 const LEAD_COIN_NONCE2_X_OFFSET: usize = 2;
-const LEAD_COIN_NONCE2_y_OFFSET: usize = 3;
+const LEAD_COIN_NONCE2_Y_OFFSET: usize = 3;
 
 
 const LEAD_COIN_SERIAL_NUMBER_X_OFFSET: usize = 4;
 const LEAD_COIN_SERIAL_NUMBER_X_OFFSET: usize = 4;
 const LEAD_COIN_SERIAL_NUMBER_Y_OFFSET: usize = 5;
 const LEAD_COIN_SERIAL_NUMBER_Y_OFFSET: usize = 5;
@@ -93,43 +112,58 @@ const LEAD_COIN2_SERIAL_NUMBER_Y_OFFSET: usize = 9;
 //
 //
 const LEAD_COIN_COMMIT_PATH_OFFSET: usize = 6;
 const LEAD_COIN_COMMIT_PATH_OFFSET: usize = 6;
 
 
-const LEAD_LEAD_THRESHOLD_OFFSET: usize = 7;
+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;
 
 
 #[derive(Debug,Default)]
 #[derive(Debug,Default)]
 pub struct LeadContract
 pub struct LeadContract
 {
 {
     // witness
     // witness
     pub path : Option<[MerkleNode;MERKLE_DEPTH_ORCHARD]>,
     pub path : Option<[MerkleNode;MERKLE_DEPTH_ORCHARD]>,
-    pub root_sk : Option<u32>, // coins merkle tree secret key of coin1
+    pub root_sk : Option<pallas::Scalar>, // coins merkle tree secret key of coin1
     pub path_sk : Option<[MerkleNode; MERKLE_DEPTH_ORCHARD]>, // path to the secret key root_sk
     pub path_sk : Option<[MerkleNode; MERKLE_DEPTH_ORCHARD]>, // path to the secret key root_sk
-    pub coin_timestamp: Option<u32>,
-    pub coin_nonce : Option<u32>,
-    pub coin_opening_1 :Option<pallas::Base>,
-    pub value: Option<u32>,
-    pub coin_opening_2 :Option<pallas::Base>,
+    pub coin_timestamp: Option<pallas::Base>,
+    pub coin_nonce : Option<pallas::Base>,
+    pub coin_opening_1 :Option<pallas::Scalar>,
+    pub value: Option<pallas::Base>,
+    pub coin_opening_2 :Option<pallas::Scalar>,
     // public advices
     // public advices
-    pub cm_c1 : Option<NonIdentityPoint>,
-    pub cm_c2 : Option<NonIdentityPoint>,
-    pub sn_c1 : Option<u32>,
-    //pub eta : Option<u32>, //TODO name, type
-    pub slot : Option<u32>,
-    //pub rho : Option<u32>, //TODO name, type
+    //
+    //TODO implement two version of load_private one or point, other for base
+    // or templated load_private. then you would be able to read (x,y) from cm_c1
+    pub cm_c1 : Option<pallas::Base>, //TODO can't you read the x, y from the cell?
+    pub cm_c1_x : Option<pallas::Base>,
+    pub cm_c1_y : Option<pallas::Base>,
+    pub cm_c2_x : Option<pallas::Base>,
+    pub cm_c2_y : Option<pallas::Base>,
+    //
+    pub cm_pos : Option<u32>,
+    //
+    pub sn_c1 : Option<pallas::Base>,
+    pub slot : Option<pallas::Base>,
+    pub mau_rho: Option<pallas::Scalar>,
+    pub mau_y: Option<pallas::Scalar>,
+    pub root_cm : Option<pallas::Scalar>,
+    //pub eta : Option<u32>,
+    //pub rho : Option<u32>,
     //pub h : Option<u32>, // hash of this data
     //pub h : Option<u32>, // hash of this data
     //pub ptr: Option<u32>, //hash of the previous block
     //pub ptr: Option<u32>, //hash of the previous block
-    pub mau_rho: Option<u32>, //TODO name, type
-    pub mau_y: Option<u32>, //TODO name, type
-    pub root : Option<u32>, //TODO name, type
 }
 }
 
 
-impl UtilitiesInstruction<pallas::Base> for LeadContract {
-    type var = AssignedCell<Fp, Fp>;
+impl UtilitiesInstructions<pallas::Base> for LeadContract {
+    type Var = AssignedCell<Fp, Fp>;
 }
 }
 
 
-impl circuit<pallas::Base> for LeadContract {
+impl Circuit<pallas::Base> for LeadContract {
     type Config = LeadConfig;
     type Config = LeadConfig;
     type FloorPlanner = SimpleFloorPlanner;
     type FloorPlanner = SimpleFloorPlanner;
 
 
-    fn without_witness(&self) -> Self {
+    fn without_witnesses(&self) -> Self {
         Self::default()
         Self::default()
     }
     }
 
 
@@ -168,21 +202,20 @@ impl circuit<pallas::Base> for LeadContract {
             meta.fixed_column(),
             meta.fixed_column(),
             meta.fixed_column(),
             meta.fixed_column(),
             meta.fixed_column(),
             meta.fixed_column(),
-            meta.fixed_column(),
         ];
         ];
 
 
         let rc_a = lagrange_coeffs[2..5].try_into().unwrap();
         let rc_a = lagrange_coeffs[2..5].try_into().unwrap();
         let rc_b = lagrange_coeffs[5..8].try_into().unwrap();
         let rc_b = lagrange_coeffs[5..8].try_into().unwrap();
 
 
-        meta.enable_constant(laggrange_coeffs[0]);
+        meta.enable_constant(lagrange_coeffs[0]);
         let range_check = LookupRangeCheckConfig::configure(meta, advices[8], table_idx);
         let range_check = LookupRangeCheckConfig::configure(meta, advices[8], table_idx);
 
 
 
 
         //TODO how many columns needed for the eccChip?
         //TODO how many columns needed for the eccChip?
         //i assumed 5 for constants/private_witnesses
         //i assumed 5 for constants/private_witnesses
-        let ecc_config = EccChip::<OrchardFixedBases>::configure(meta, advices, lagrange_coeffs, range_check);
+        let ecc_config = EccChip::<OrchardFixedBases>::configure(meta, advices[0..9].try_into().expect("wrong slice size"), lagrange_coeffs, range_check);
 
 
-        let poseidon_config = PoseidonChip::configure<P128Pow5T3>(
+        let poseidon_config = PoseidonChip::configure::<P128Pow5T3>(
             meta,
             meta,
             advices[6..9].try_into().unwrap(),
             advices[6..9].try_into().unwrap(),
             advices[5],
             advices[5],
@@ -206,7 +239,7 @@ impl circuit<pallas::Base> for LeadContract {
         let (sinsemilla_config_2, merkle_config_2) = {
         let (sinsemilla_config_2, merkle_config_2) = {
             let sinsemilla_config_2 = SinsemillaChip::configure(
             let sinsemilla_config_2 = SinsemillaChip::configure(
                 meta,
                 meta,
-                advices[5.9].try_into().unwrap(),
+                advices[5..9].try_into().unwrap(),
                 advices[7],
                 advices[7],
                 lagrange_coeffs[1],
                 lagrange_coeffs[1],
                 lookup,
                 lookup,
@@ -217,7 +250,8 @@ impl circuit<pallas::Base> for LeadContract {
             (sinsemilla_config_2, merkle_config_2)
             (sinsemilla_config_2, merkle_config_2)
         };
         };
 
 
-        let  greaterthan_config = GreaterThanChip::<pallas::Base>::configure(meta, advices[10..11]);
+        let  greaterthan_config = GreaterThanChip::<pallas::Base, WORD_BITS>::configure(meta, advices[10..11].try_into().unwrap(), primary);
+        let evenbits_config = EvenBitsChip::<pallas::Base, WORD_BITS>::configure(meta);
         let arith_config = ArithmeticChip::configure(meta);
         let arith_config = ArithmeticChip::configure(meta);
 
 
         LeadConfig {
         LeadConfig {
@@ -230,6 +264,7 @@ impl circuit<pallas::Base> for LeadContract {
             sinsemilla_config_1,
             sinsemilla_config_1,
             sinsemilla_config_2,
             sinsemilla_config_2,
             greaterthan_config,
             greaterthan_config,
+            evenbits_config,
             arith_config,
             arith_config,
         }
         }
     }
     }
@@ -237,54 +272,72 @@ impl circuit<pallas::Base> for LeadContract {
     fn synthesize(&self,
     fn synthesize(&self,
                   config: Self::Config,
                   config: Self::Config,
                   mut layouter: impl Layouter<pallas::Base>,
                   mut layouter: impl Layouter<pallas::Base>,
-    ) -> Result<(),Error> {
+    ) -> Result<(), Error> {
         SinsemillaChip::load(config.sinsemilla_config_1.clone(), &mut layouter)?;
         SinsemillaChip::load(config.sinsemilla_config_1.clone(), &mut layouter)?;
         let ecc_chip = config.ecc_chip();
         let ecc_chip = config.ecc_chip();
         let ar_chip = config.arith_chip();
         let ar_chip = config.arith_chip();
         let ps_chip = config.poseidon_chip();
         let ps_chip = config.poseidon_chip();
+        let eb_chip = config.evenbits_chip();
+        eb_chip.alloc_table(&mut layouter.namespace(|| "alloc table"))?;
 
 
         // ===============
         // ===============
         // load witnesses
         // load witnesses
         // ===============
         // ===============
 
 
         // coin_timestamp tau
         // coin_timestamp tau
+
         let coin_timestamp = self.load_private(
         let coin_timestamp = self.load_private(
             layouter.namespace(|| "load coin time stamp"),
             layouter.namespace(|| "load coin time stamp"),
             config.advices[0],
             config.advices[0],
             self.coin_timestamp,
             self.coin_timestamp,
         )?;
         )?;
 
 
+
+
         // root of coin
         // root of coin
-        let coin_root = self.load_private(
+
+
+        /*
+        let root_sk = self.load_private(
             layouter.namespace(|| "load root coin"),
             layouter.namespace(|| "load root coin"),
             config.advices[0],
             config.advices[0],
             self.root_sk,
             self.root_sk,
         )?;
         )?;
+         */
+
+
+
 
 
         // coin nonce
         // coin nonce
+
         let coin_nonce = self.load_private(
         let coin_nonce = self.load_private(
             layouter.namespace(|| "load coin nonce"),
             layouter.namespace(|| "load coin nonce"),
             config.advices[0],
             config.advices[0],
-            self.nonce,
+            self.coin_nonce,
         )?;
         )?;
 
 
-        let coin_opening_1 = self.load_private(
+        let coin_value = self.load_private(
             layouter.namespace(|| "load opening 1"),
             layouter.namespace(|| "load opening 1"),
             config.advices[0],
             config.advices[0],
-            self.coin_opening_1,
+            self.value,
         )?;
         )?;
 
 
-        let coin_value = self.load_private(
+        /*
+        let coin_opening_1 = self.load_private(
             layouter.namespace(|| "load opening 1"),
             layouter.namespace(|| "load opening 1"),
             config.advices[0],
             config.advices[0],
-            self.value,
+            self.coin_opening_1,
         )?;
         )?;
-
         let coin_opening_2 = self.load_private(
         let coin_opening_2 = self.load_private(
             layouter.namespace(|| "load opening 2"),
             layouter.namespace(|| "load opening 2"),
             config.advices[0],
             config.advices[0],
             self.coin_opening_2,
             self.coin_opening_2,
         )?;
         )?;
+         */
+
+
+        //let cm_c1_point : pallas::Point = pallas::Point::from(1);
+        //let cm_c1 : AssignedCell<pallas::Point, pallas::Point> = cm_c1_point;
 
 
         let cm_c1 = self.load_private(
         let cm_c1 = self.load_private(
             layouter.namespace(|| ""),
             layouter.namespace(|| ""),
@@ -292,12 +345,35 @@ impl circuit<pallas::Base> for LeadContract {
             self.cm_c1,
             self.cm_c1,
         )?;
         )?;
 
 
-        let cm_c2 = self.load_private(
+        let cm_c1_x = self.load_private(
+            layouter.namespace(|| ""),
+            config.advices[0],
+            self.cm_c1_x,
+        )?;
+        let cm_c1_y = self.load_private(
+            layouter.namespace(|| ""),
+            config.advices[0],
+            self.cm_c1_y,
+        )?;
+
+        let cm_c2_x = self.load_private(
+            layouter.namespace(|| ""),
+            config.advices[0],
+            self.cm_c2_x,
+        )?;
+        let cm_c2_y = self.load_private(
             layouter.namespace(|| ""),
             layouter.namespace(|| ""),
             config.advices[0],
             config.advices[0],
-            self.cm_c2,
+            self.cm_c2_y,
         )?;
         )?;
 
 
+        /*
+        let cm_pos = self.load_private(
+            layouter.namespace(|| ""),
+            config.advices[0],
+            self.cm_pos
+        )?;
+         */
         let sn_c1 = self.load_private(
         let sn_c1 = self.load_private(
             layouter.namespace(|| ""),
             layouter.namespace(|| ""),
             config.advices[0],
             config.advices[0],
@@ -338,6 +414,7 @@ impl circuit<pallas::Base> for LeadContract {
         )?;
         )?;
          */
          */
 
 
+        /*
         let mau_rho = self.load_private(
         let mau_rho = self.load_private(
             layouter.namespace(|| ""),
             layouter.namespace(|| ""),
             config.advices[0],
             config.advices[0],
@@ -349,13 +426,21 @@ impl circuit<pallas::Base> for LeadContract {
             config.advices[0],
             config.advices[0],
             self.mau_y,
             self.mau_y,
         )?;
         )?;
+        */
 
 
+        /*
         let root = self.load_private(
         let root = self.load_private(
             layouter.namespace(|| ""),
             layouter.namespace(|| ""),
             config.advices[0],
             config.advices[0],
             self.root,
             self.root,
         )?;
         )?;
+         */
 
 
+        let one = self.load_private(
+            layouter.namespace(|| "one"),
+            config.advices[0],
+            Some(pallas::Base::one()),
+        )?;
         //TODO read the second coin commitment as constant(public input)
         //TODO read the second coin commitment as constant(public input)
         // in this case
         // in this case
         //
         //
@@ -367,41 +452,42 @@ impl circuit<pallas::Base> for LeadContract {
         let (com, _ )  = {
         let (com, _ )  = {
             let nonce2_commit_v = ValueCommitV;
             let nonce2_commit_v = ValueCommitV;
             let nonce2_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), nonce2_commit_v);
             let nonce2_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), nonce2_commit_v);
-            nonce2_commit_v.mul(layouter.namespace(|| "coin_pk commit v"), (coin_nonce, one))?
+            nonce2_commit_v.mul(layouter.namespace(|| "coin_pk commit v"), (coin_nonce.clone(), one.clone()))?
         };
         };
         // r*G_2
         // r*G_2
         let (blind, _) = {
         let (blind, _) = {
             let nonce2_commit_r = OrchardFixedBasesFull::ValueCommitR;
             let nonce2_commit_r = OrchardFixedBasesFull::ValueCommitR;
             let nonce2_commit_r = FixedPoint::from_inner(ecc_chip.clone(), nonce2_commit_r);
             let nonce2_commit_r = FixedPoint::from_inner(ecc_chip.clone(), nonce2_commit_r);
-            nonce2_commit_r.mul(layouter.namespace(|| "nonce2 commit R"), (coin_root.clone(), one))?
+            nonce2_commit_r.mul(layouter.namespace(|| "nonce2 commit R"), self.root_sk)?
         };
         };
         let coin2_nonce = com.add(layouter.namespace(|| "nonce2 commit"), &blind)?;
         let coin2_nonce = com.add(layouter.namespace(|| "nonce2 commit"), &blind)?;
         layouter.constrain_instance(
         layouter.constrain_instance(
             coin2_nonce.inner().x().cell(),
             coin2_nonce.inner().x().cell(),
             config.primary,
             config.primary,
-            LEAD_COIN_PK_X_OFFSET,
+            LEAD_COIN_NONCE2_X_OFFSET,
         )?;
         )?;
         // constrain coin's pub key y value
         // constrain coin's pub key y value
         layouter.constrain_instance(
         layouter.constrain_instance(
             coin2_nonce.inner().y().cell(),
             coin2_nonce.inner().y().cell(),
-            coinfig.primary,
-            CLEAD_COIN_PK_Y_OFFSET,
+            config.primary,
+            LEAD_COIN_NONCE2_Y_OFFSET,
         )?;
         )?;
         // ================
         // ================
         // coin public key constraints derived from the coin timestamp
         // coin public key constraints derived from the coin timestamp
         // ================
         // ================
 
 
+
         // m*G_1
         // m*G_1
         let (com, _ )  = {
         let (com, _ )  = {
             let coin_pk_commit_v = ValueCommitV;
             let coin_pk_commit_v = ValueCommitV;
             let coin_pk_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), coin_pk_commit_v);
             let coin_pk_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), coin_pk_commit_v);
-            coin_timestamp_commit_v.mul(layouter.namespace(|| "coin_pk commit v"), (coin_timestamp, one))?
+            coin_pk_commit_v.mul(layouter.namespace(|| "coin_pk commit v"), (coin_timestamp, one.clone()))?
         };
         };
         // r*G_2
         // r*G_2
         let (blind, _) = {
         let (blind, _) = {
             let coin_pk_commit_r = OrchardFixedBasesFull::ValueCommitR;
             let coin_pk_commit_r = OrchardFixedBasesFull::ValueCommitR;
             let coin_pk_commit_r = FixedPoint::from_inner(ecc_chip.clone(), coin_pk_commit_r);
             let coin_pk_commit_r = FixedPoint::from_inner(ecc_chip.clone(), coin_pk_commit_r);
-            coin_timestamp_commit_r.mul(layouter.namespace(|| "coin_pk commit R"), (coin_root.clone(), one))?
+            coin_pk_commit_r.mul(layouter.namespace(|| "coin_pk commit R"), self.root_sk)?
         };
         };
         let coin_pk_commit = com.add(layouter.namespace(|| "coin timestamp commit"), &blind)?;
         let coin_pk_commit = com.add(layouter.namespace(|| "coin timestamp commit"), &blind)?;
         // constrain coin's pub key x value
         // constrain coin's pub key x value
@@ -413,10 +499,11 @@ impl circuit<pallas::Base> for LeadContract {
         // constrain coin's pub key y value
         // constrain coin's pub key y value
         layouter.constrain_instance(
         layouter.constrain_instance(
             coin_pk_commit.inner().y().cell(),
             coin_pk_commit.inner().y().cell(),
-            coinfig.primary,
-            CLEAD_COIN_PK_Y_OFFSET,
+            config.primary,
+            LEAD_COIN_PK_Y_OFFSET,
         )?;
         )?;
 
 
+
         // =================
         // =================
         // nonce constraints derived from previous coin's nonce
         // nonce constraints derived from previous coin's nonce
         // =================
         // =================
@@ -429,13 +516,13 @@ impl circuit<pallas::Base> for LeadContract {
         let (com, _ )  = {
         let (com, _ )  = {
             let sn_commit_v = ValueCommitV;
             let sn_commit_v = ValueCommitV;
             let sn_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), sn_commit_v);
             let sn_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), sn_commit_v);
-            sn_commit_v.mul(layouter.namespace(|| "coin serial number commit v"), (coin_nonce, one))?
+            sn_commit_v.mul(layouter.namespace(|| "coin serial number commit v"), (coin_nonce.clone(), one.clone()))?
         };
         };
         // r*G_2
         // r*G_2
         let (blind, _) = {
         let (blind, _) = {
             let sn_commit_r = OrchardFixedBasesFull::ValueCommitR;
             let sn_commit_r = OrchardFixedBasesFull::ValueCommitR;
             let sn_commit_r = FixedPoint::from_inner(ecc_chip.clone(), sn_commit_r);
             let sn_commit_r = FixedPoint::from_inner(ecc_chip.clone(), sn_commit_r);
-            sn_commit_r.mul(layouter.namespace(|| "coin serial number commit R"), (coin_root.clone(), one))?
+            sn_commit_r.mul(layouter.namespace(|| "coin serial number commit R"), self.root_sk)?
         };
         };
         //
         //
         let sn_commit = com.add(layouter.namespace(|| "nonce commit"), &blind)?;
         let sn_commit = com.add(layouter.namespace(|| "nonce commit"), &blind)?;
@@ -447,11 +534,12 @@ impl circuit<pallas::Base> for LeadContract {
         )?;
         )?;
         // constrain coin's pub key y value
         // constrain coin's pub key y value
         layouter.constrain_instance(
         layouter.constrain_instance(
-            nonce_commit.inner().y().cell(),
-            coinfig.primary,
-            LEAD_COIN_SERIAL_NUMBER_X_OFFSET,
+            sn_commit.inner().y().cell(),
+            config.primary,
+            LEAD_COIN_SERIAL_NUMBER_Y_OFFSET,
         )?;
         )?;
 
 
+
         // ==========================
         // ==========================
         // commitment of coins c1,c2
         // commitment of coins c1,c2
         // ==========================
         // ==========================
@@ -469,9 +557,13 @@ impl circuit<pallas::Base> for LeadContract {
         //but only single value is in witness.
         //but only single value is in witness.
 
 
         let coin_hash = {
         let coin_hash = {
-            let poseidon_message = [coin_pk_commit.clone(), coin_value.clone(), coin_nonce.clone()];
+            let poseidon_message = [coin_pk_commit.inner().x(),
+                                    coin_pk_commit.inner().y(),
+                                    coin_value.clone(),
+                                    coin_nonce.clone()
+            ];
 
 
-            let poseidon_hasher = PoseidonHash::<_, _, P128Pow5T3, ConstantLength<2>, 3, 2>::init(
+            let poseidon_hasher = PoseidonHash::<_, _, P128Pow5T3, ConstantLength<4>, 3, 2>::init(
                 config.poseidon_chip(),
                 config.poseidon_chip(),
                 layouter.namespace(|| "Poseidon init"),
                 layouter.namespace(|| "Poseidon init"),
             )?;
             )?;
@@ -485,34 +577,46 @@ impl circuit<pallas::Base> for LeadContract {
         let (com, _ )  = {
         let (com, _ )  = {
             let coin_commit_v = ValueCommitV;
             let coin_commit_v = ValueCommitV;
             let coin_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), coin_commit_v);
             let coin_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), coin_commit_v);
-            sn_commit_v.mul(layouter.namespace(|| "coin commit v"), (coin_hash, one))?
+            coin_commit_v.mul(layouter.namespace(|| "coin commit v"), (coin_hash, one.clone()))?
         };
         };
         // r*G_2
         // r*G_2
         let (blind, _) = {
         let (blind, _) = {
             let coin_commit_r = OrchardFixedBasesFull::ValueCommitR;
             let coin_commit_r = OrchardFixedBasesFull::ValueCommitR;
             let coin_commit_r = FixedPoint::from_inner(ecc_chip.clone(), coin_commit_r);
             let coin_commit_r = FixedPoint::from_inner(ecc_chip.clone(), coin_commit_r);
-            coin_commit_r.mul(layouter.namespace(|| "coin serial number commit R"), (coin_opening_1, one))?
+            coin_commit_r.mul(layouter.namespace(|| "coin serial number commit R"), self.coin_opening_1)?
         };
         };
-        let coin_commit = com.add(layouter.namespace(|| "nonce commit"), &blind)?;
-        let cm1_zero_out = ar_chip.sub(layouter.namespace(|| "sub to zero"), (coin2_commit, cm_c1));
+        let coin_commit  = com.add(layouter.namespace(|| "nonce commit"), &blind)?;
+
+        let coin_commit_x : AssignedCell<Fp, Fp> = coin_commit.inner().x();
+        let coin_commit_y : AssignedCell<Fp, Fp> = coin_commit.inner().y();
+
+        let cm1_zero_out_x = ar_chip.sub(layouter.namespace(|| "sub to zero"), coin_commit_x, cm_c1_x)?;
+        let cm1_zero_out_y = ar_chip.sub(layouter.namespace(|| "sub to zero"), coin_commit_y, cm_c1_y)?;
 
 
         // constrain coin's pub key x value
         // constrain coin's pub key x value
         layouter.constrain_instance(
         layouter.constrain_instance(
-            cm1_zero_out.inner().x().cell(),
+            cm1_zero_out_x.cell(),
             config.primary,
             config.primary,
-            LEAD_COIN_SERIAL_NUMBER_X_OFFSET,
+            LEAD_COIN_COMMIT_X_OFFSET,
         )?;
         )?;
         // constrain coin's pub key y value
         // constrain coin's pub key y value
         layouter.constrain_instance(
         layouter.constrain_instance(
-            cm1_zero_out.inner().y().cell(),
+            cm1_zero_out_y.cell(),
             config.primary,
             config.primary,
-            LEAD_COIN_SERIAL_NUMBER_X_OFFSET,
+            LEAD_COIN_COMMIT_Y_OFFSET,
         )?;
         )?;
 
 
-        let coin2_hash = {
-            let poseidon_message = [coin_pk_commit.clone(), coin_value.clone(), coin2_nonce.clone()];
 
 
-            let poseidon_hasher = PoseidonHash::<_, _, P128Pow5T3, ConstantLength<2>, 3, 2>::init(
+        //
+        let coin2_hash = {
+            let poseidon_message = [coin_pk_commit.inner().x(),
+                                    coin_pk_commit.inner().y(),
+                                    coin_value.clone(),
+                                    coin2_nonce.inner().x(),
+                                    coin2_nonce.inner().y(),
+            ];
+
+            let poseidon_hasher = PoseidonHash::<_, _, P128Pow5T3, ConstantLength<5>, 3, 2>::init(
                 config.poseidon_chip(),
                 config.poseidon_chip(),
                 layouter.namespace(|| "Poseidon init"),
                 layouter.namespace(|| "Poseidon init"),
             )?;
             )?;
@@ -526,31 +630,31 @@ impl circuit<pallas::Base> for LeadContract {
         let (com, _ )  = {
         let (com, _ )  = {
             let coin_commit_v = ValueCommitV;
             let coin_commit_v = ValueCommitV;
             let coin_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), coin_commit_v);
             let coin_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), coin_commit_v);
-            sn_commit_v.mul(layouter.namespace(|| "coin commit v"), (coin2_hash, one))?
+            coin_commit_v.mul(layouter.namespace(|| "coin commit v"), (coin2_hash, one.clone()))?
         };
         };
         // r*G_2
         // r*G_2
         let (blind, _) = {
         let (blind, _) = {
-            let r = self.root_sk;
-            let sn_commit_r = OrchardFixedBasesFull::ValueCommitR;
-            let sn_commit_r = FixedPoint::from_inner(ecc_chip.clone(), coin_opening_2);
-            sn_commit_r.mul(layouter.namespace(|| "coin serial number commit R"), r)?
+            let coin_commit_r = OrchardFixedBasesFull::ValueCommitR;
+            let coin_commit_r = FixedPoint::from_inner(ecc_chip.clone(), coin_commit_r);
+            coin_commit_r.mul(layouter.namespace(|| "coin serial number commit R"), self.coin_opening_2)?
         };
         };
-        let coin2_commit = com.add(layouter.namespace(|| "nonce commit"), &blind)?;
-        let cm2_zero_out = ar_chip.sub(layouter.namespace(|| "sub to zero"), (coin2_commit, cm_c2));
+        let coin2_commit  = com.add(layouter.namespace(|| "nonce commit"), &blind)?;
+        let coin2_commit_x : AssignedCell<Fp, Fp> = coin2_commit.inner().x();
+        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(
         layouter.constrain_instance(
-            cm2_zero_out.inner().x().cell(),
+            cm2_zero_out_x.cell(),
             config.primary,
             config.primary,
-            LEAD_COIN2_SERIAL_NUMBER_X_OFFSET,
+            LEAD_COIN_COMMIT2_X_OFFSET,
         )?;
         )?;
         // constrain coin's pub key y value
         // constrain coin's pub key y value
         layouter.constrain_instance(
         layouter.constrain_instance(
-            cm2_zero_out.inner().y().cell(),
+            cm2_zero_out_y.cell(),
             config.primary,
             config.primary,
-            LEAD_COIN2_SERIAL_NUMBER_X_OFFSET,
+            LEAD_COIN_COMMIT2_X_OFFSET,
         )?;
         )?;
-        //TODO you need to add this coin1_commit to the tree and return rooted by self.root,
-        // and return the position coin1_commit_pos
-        let coin1_commit_pos : u32 = 0;
+        //let coin1_commit_pos : u32 = 0;
         // ===========================
         // ===========================
         let path: Option<[pallas::Base; MERKLE_DEPTH_ORCHARD]> =
         let path: Option<[pallas::Base; MERKLE_DEPTH_ORCHARD]> =
             self.path.map(|typed_path| gen_const_array(|i| typed_path[i].inner()));
             self.path.map(|typed_path| gen_const_array(|i| typed_path[i].inner()));
@@ -559,18 +663,19 @@ impl circuit<pallas::Base> for LeadContract {
             config.merkle_chip_1(),
             config.merkle_chip_1(),
             config.merkle_chip_2(),
             config.merkle_chip_2(),
             OrchardHashDomains::MerkleCrh,
             OrchardHashDomains::MerkleCrh,
-            coin1_commit_pos,
+            self.cm_pos,
             path,
             path,
         );
         );
 
 
         let computed_final_root =
         let computed_final_root =
-            merkle_inputs.calculate_root(layouter.namespace(|| "calculate root"), coin1_commit)?;
+            merkle_inputs.calculate_root(layouter.namespace(|| "calculate root"), cm_c1)?;
 
 
         layouter.constrain_instance(
         layouter.constrain_instance(
             computed_final_root.cell(),
             computed_final_root.cell(),
             config.primary,
             config.primary,
             LEAD_COIN_COMMIT_PATH_OFFSET,
             LEAD_COIN_COMMIT_PATH_OFFSET,
         )?;
         )?;
+
         // =============================
         // =============================
         /*
         /*
         let path: Option<[pallas::Base; MERKLE_DEPTH_ORCHARD]> =
         let path: Option<[pallas::Base; MERKLE_DEPTH_ORCHARD]> =
@@ -586,7 +691,7 @@ impl circuit<pallas::Base> for LeadContract {
 
 
         //TODO fix this is a path to a leaf, i have no clue of that leaf
         //TODO fix this is a path to a leaf, i have no clue of that leaf
         let computed_final_root =
         let computed_final_root =
-            merkle_inputs.calculate_root(layouter.namespace(|| "calculate root"), coin1_commit)?;
+            merkle_inputs.calculate_root(layouter.namespace(|| "calculate root"), cm_c1)?;
 
 
         layouter.constrain_instance(
         layouter.constrain_instance(
             computed_final_root.cell(),
             computed_final_root.cell(),
@@ -594,70 +699,84 @@ impl circuit<pallas::Base> for LeadContract {
             LEAD_COIN_COMMIT_PATH_OFFSET,
             LEAD_COIN_COMMIT_PATH_OFFSET,
         )?;
         )?;
          */
          */
+
+
         // ============================
         // ============================
         // constrain y
         // constrain y
-        //
-        let message = {
-            let poseidon_message = [root_sk.clone(), coin_nonce.clone()];
-
-            let poseidon_hasher = PoseidonHash::<_, _, P128Pow5T3, ConstantLength<2>, 3, 2>::init(
-                config.poseidon_chip(),
-                layouter.namespace(|| "Poseidon init"),
-            )?;
+        // ============================
 
 
-            let poseidon_output =
-                poseidon_hasher.hash(layouter.namespace(|| "Poseidon hash"), poseidon_message)?;
+        let message = {
+            let (com, _ )  = {
+                let commit_v = ValueCommitV;
+                let commit_v = FixedPointShort::from_inner(ecc_chip.clone(), commit_v);
+                commit_v.mul(layouter.namespace(|| "coin commit v"), (coin_nonce.clone(), one.clone()))?
+            };
+            // r*G_2
+            let (blind, _) = {
+                let commit_r = OrchardFixedBasesFull::ValueCommitR;
+                let commit_r = FixedPoint::from_inner(ecc_chip.clone(), commit_r);
+                commit_r.mul(layouter.namespace(|| "coin serial number commit R"), self.root_sk)?
+            };
+            com.add(layouter.namespace(|| "nonce commit"), &blind)?
 
 
-            let poseidon_output: AssignedCell<Fp, Fp> = poseidon_output;
-            poseidon_output
         };
         };
+        let message_sum = ar_chip.add(layouter.namespace(|| "msg x + y"),
+                                      message.inner().x(),
+                                      message.inner().y(),
+        )?;
 
 
         let (com, _ )  = {
         let (com, _ )  = {
-            //TODO concatenate message
-            //TODO message need to be eccchip::var
-            //let message = [root_sk, coin_nonce];
             let y_commit_v = ValueCommitV;
             let y_commit_v = ValueCommitV;
             let y_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), y_commit_v);
             let y_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), y_commit_v);
-            y_commit_v.mul(layouter.namespace(|| "coin commit v"), (message.clone(), one))?
+            y_commit_v.mul(layouter.namespace(|| "coin commit v"), (message_sum.clone(), one.clone()))?
         };
         };
         // r*G_2
         // r*G_2
         let (blind, _) = {
         let (blind, _) = {
-            //let r = mau_y;
             let y_commit_r = OrchardFixedBasesFull::ValueCommitR;
             let y_commit_r = OrchardFixedBasesFull::ValueCommitR;
             let y_commit_r = FixedPoint::from_inner(ecc_chip.clone(), y_commit_r);
             let y_commit_r = FixedPoint::from_inner(ecc_chip.clone(), y_commit_r);
-            y_commit_r.mul(layouter.namespace(|| "coin serial number commit R"), (mau_y, one))?
+            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 y_commit = com.add(layouter.namespace(|| "nonce commit"), &blind)?;
         // ============================
         // ============================
+        let y_commit_x = y_commit.inner().x();
+        // ============================
         // constraint rho
         // constraint rho
         // ============================
         // ============================
         let (com, _ )  = {
         let (com, _ )  = {
-            let y_commit_v = ValueCommitV;
-            let y_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), y_commit_v);
-            y_commit_v.mul(layouter.namespace(|| "coin commit v"), (message.clone(), one))?
+            let rho_commit_v = ValueCommitV;
+            let rho_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), rho_commit_v);
+            rho_commit_v.mul(layouter.namespace(|| "coin commit v"), (message_sum, one.clone()))?
         };
         };
         // r*G_2
         // r*G_2
         let (blind, _) = {
         let (blind, _) = {
-            let r = mau_rho;
-            let y_commit_r = OrchardFixedBasesFull::ValueCommitR;
-            let y_commit_r = FixedPoint::from_inner(ecc_chip.clone(), y_commit_r);
-            y_commit_r.mul(layouter.namespace(|| "coin serial number commit R"), r)?
+            let rho_commit_r = OrchardFixedBasesFull::ValueCommitR;
+            let rho_commit_r = FixedPoint::from_inner(ecc_chip.clone(), rho_commit_r);
+            rho_commit_r.mul(layouter.namespace(|| "coin serial number commit R"), self.mau_rho)?
         };
         };
         let rho_commit = com.add(layouter.namespace(|| "nonce commit"), &blind)?;
         let rho_commit = com.add(layouter.namespace(|| "nonce commit"), &blind)?;
 
 
         //TODO in case of the v_max lead statement you need to provide a proof
         //TODO in case of the v_max lead statement you need to provide a proof
         // that the coin value never get past it.
         // that the coin value never get past it.
 
 
-        let scalar = pallas::Scalar::from(1024);
+        let scalar = self.load_private(
+            layouter.namespace(||"load scalar "),
+            config.advices[0],
+            Some(pallas::Base::from(1024))
+        )?;
         let c = pallas::Scalar::from(3); // leadership coefficient
         let c = pallas::Scalar::from(3); // leadership coefficient
-        let target = ar_chip.mul(layouter.namespace(|| "calculate target"), scalar, value)?;
+        let target = ar_chip.mul(layouter.namespace(|| "calculate target"), scalar, coin_value)?;
 
 
-        let greater_than_chip = config.greaterthan_config();
-        greater_than_chip.greater_than(layouter.namespace("t>y"), target , y_commit);
-        layouter.constrain_instance(
-            greater_than_chip.cell(),
-            config.primary,
-            LEAD_LEAD_THRESHOLD_OFFSET,
+        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())?;
+
+        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?
+        eb_chip.decompose(layouter.namespace(|| "helper range check"), helper.0)?;
+        layouter.constrain_instance(is_gt.0.cell(),
+                                    config.primary,
+                                    LEAD_THRESHOLD_OFFSET
         )?;
         )?;
+        Ok(())
     }
     }
 }
 }

+ 9 - 0
src/zk/circuit/mod.rs

@@ -1,5 +1,14 @@
 pub mod burn_contract;
 pub mod burn_contract;
 pub use burn_contract::BurnContract;
 pub use burn_contract::BurnContract;
 
 
+
+pub mod spend_contract;
+pub mod lead_contract;
+
+
+
 pub mod mint_contract;
 pub mod mint_contract;
 pub use mint_contract::MintContract;
 pub use mint_contract::MintContract;
+
+pub use spend_contract::SpendContract;
+pub use lead_contract::LeadContract;

+ 64 - 4
src/zk/greater_than.rs

@@ -3,17 +3,21 @@ use std::marker::PhantomData;
 use halo2_proofs::{
 use halo2_proofs::{
     arithmetic::FieldExt,
     arithmetic::FieldExt,
     circuit::{AssignedCell, Chip, Layouter, Region},
     circuit::{AssignedCell, Chip, Layouter, Region},
-    plonk::{Advice, Column, ConstraintSystem, Error, Expression, Selector},
+    plonk::{Advice, Column, Instance, ConstraintSystem, Error, Expression, Selector},
     poly::Rotation,
     poly::Rotation,
 };
 };
+
 use pasta_curves::pallas;
 use pasta_curves::pallas;
 
 
+
 #[derive(Clone, Debug)]
 #[derive(Clone, Debug)]
 pub struct GreaterThanConfig {
 pub struct GreaterThanConfig {
-    advice: [Column<Advice>; 2],
+    pub advice: [Column<Advice>; 2],
+    pub instance: Column<Instance>,
     s_gt: Selector,
     s_gt: Selector,
 }
 }
 
 
+
 pub struct GreaterThanChip<F: FieldExt, const WORD_BITS: u32> {
 pub struct GreaterThanChip<F: FieldExt, const WORD_BITS: u32> {
     config: GreaterThanConfig,
     config: GreaterThanConfig,
     _marker: PhantomData<F>,
     _marker: PhantomData<F>,
@@ -37,9 +41,10 @@ impl<F: FieldExt, const WORD_BITS: u32> GreaterThanChip<F, WORD_BITS> {
         Self { config, _marker: PhantomData }
         Self { config, _marker: PhantomData }
     }
     }
 
 
+    /*
     pub fn configure(meta: &mut ConstraintSystem<F>) -> <Self as Chip<F>>::Config {
     pub fn configure(meta: &mut ConstraintSystem<F>) -> <Self as Chip<F>>::Config {
-        let constant = meta.fixed_column();
-        meta.enable_constant(constant);
+        //let constant = meta.fixed_column();
+        //meta.enable_constant(constant);
 
 
         let advice = [meta.advice_column(), meta.advice_column()];
         let advice = [meta.advice_column(), meta.advice_column()];
 
 
@@ -67,6 +72,61 @@ impl<F: FieldExt, const WORD_BITS: u32> GreaterThanChip<F, WORD_BITS> {
 
 
         GreaterThanConfig { advice, s_gt }
         GreaterThanConfig { advice, s_gt }
     }
     }
+
+    pub fn configure(meta: &mut ConstraintSystem<F>) -> <Self as Chip<F>>::Config {
+        let advice = [meta.advice_column(), meta.advice_column()];
+
+
+        let s_gt = meta.selector();
+
+        meta.create_gate("greater than", |meta| {
+            let lhs = meta.query_advice(advice[0], Rotation::cur());
+            let rhs = meta.query_advice(advice[1], Rotation::cur());
+
+            // This value is `lhs - rhs` if `lhs !> rhs` and `2^W - (lhs - rhs)` if `lhs > rhs`
+            let helper = meta.query_advice(advice[0], Rotation::next());
+
+            let is_greater = meta.query_advice(advice[1], Rotation::next());
+            let s_gt = meta.query_selector(s_gt);
+
+            vec![
+                s_gt * (lhs - rhs + helper -
+                    Expression::Constant(F::from(2_u64.pow(WORD_BITS))) * is_greater),
+            ]
+        });
+
+        GreaterThanConfig { advice, s_gt }
+    }
+     */
+    pub fn configure(meta: &mut ConstraintSystem<F>,
+                     advice : [Column<Advice>; 2],
+                     instance: Column<Instance>) -> <Self as Chip<F>>::Config {
+
+
+        for column in &advice {
+            meta.enable_equality(*column);
+        }
+
+        let s_gt = meta.selector();
+
+        meta.create_gate("greater than", |meta| {
+            let lhs = meta.query_advice(advice[0], Rotation::cur());
+            let rhs = meta.query_advice(advice[1], Rotation::cur());
+
+            // This value is `lhs - rhs` if `lhs !> rhs` and `2^W - (lhs - rhs)` if `lhs > rhs`
+            let helper = meta.query_advice(advice[0], Rotation::next());
+
+            let is_greater = meta.query_advice(advice[1], Rotation::next());
+            let s_gt = meta.query_selector(s_gt);
+
+            vec![
+                s_gt * (lhs - rhs + helper -
+                    Expression::Constant(F::from(2_u64.pow(WORD_BITS))) * is_greater),
+            ]
+        });
+
+        GreaterThanConfig { advice, instance, s_gt }
+    }
 }
 }
 
 
 pub trait GreaterThanInstruction<F: FieldExt>: Chip<F> {
 pub trait GreaterThanInstruction<F: FieldExt>: Chip<F> {

+ 3 - 1
src/zk/vm.rs

@@ -144,6 +144,8 @@ impl Circuit<pallas::Base> for ZkCircuit {
             meta.advice_column(),
             meta.advice_column(),
             meta.advice_column(),
             meta.advice_column(),
             meta.advice_column(),
             meta.advice_column(),
+            //meta.advice_column(),
+            //meta.advice_column(),
         ];
         ];
 
 
         // Fixed columns for the Sinsemilla generator lookup table
         // Fixed columns for the Sinsemilla generator lookup table
@@ -204,7 +206,7 @@ impl Circuit<pallas::Base> for ZkCircuit {
         let evenbits_config = EvenBitsChip::<pallas::Base, 24>::configure(meta);
         let evenbits_config = EvenBitsChip::<pallas::Base, 24>::configure(meta);
 
 
         // Configuration for the GreaterThan chip
         // Configuration for the GreaterThan chip
-        let greaterthan_config = GreaterThanChip::<pallas::Base, 24>::configure(meta);
+        let greaterthan_config = GreaterThanChip::<pallas::Base, 24>::configure(meta, [advices[8], advices[9]], primary);
 
 
         // Configuration for a Sinsemilla hash instantiation and a
         // Configuration for a Sinsemilla hash instantiation and a
         // Merkle hash instantiation using this Sinsemilla instance.
         // Merkle hash instantiation using this Sinsemilla instance.