Эх сурвалжийг харах

zk: Port code to latest Halo2 API.

greater_than and crypsinous lead proof are temporarily disabled.
parazyd 4 жил өмнө
parent
commit
6215fc7bd6

+ 2 - 4
Cargo.lock

@@ -2054,8 +2054,7 @@ dependencies = [
 [[package]]
 name = "halo2_gadgets"
 version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13f3914f58cc4af5e4fe83d48b02d582be18976bc7e96c3151aa2bf1c98e9f60"
+source = "git+https://github.com/zcash/halo2.git?rev=a898d65ae3ad3d41987666f6a03cfc15edae01c4#a898d65ae3ad3d41987666f6a03cfc15edae01c4"
 dependencies = [
  "arrayvec 0.7.2",
  "bitvec",
@@ -2074,8 +2073,7 @@ dependencies = [
 [[package]]
 name = "halo2_proofs"
 version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e925780549adee8364c7f2b685c753f6f3df23bde520c67416e93bf615933760"
+source = "git+https://github.com/zcash/halo2.git?rev=a898d65ae3ad3d41987666f6a03cfc15edae01c4#a898d65ae3ad3d41987666f6a03cfc15edae01c4"
 dependencies = [
  "backtrace",
  "blake2b_simd 1.0.0",

+ 13 - 15
Cargo.toml

@@ -112,10 +112,10 @@ blake2b_simd = {version = "1.0.0", optional = true}
 pasta_curves = {version = "0.4.0", optional = true}
 crypto_api_chachapoly = {version = "0.5.0", optional = true}
 incrementalmerkletree = {version = "0.3.0", optional = true}
-#halo2_proofs = {version = "0.1.0", features = ["dev-graph", "gadget-traces", "sanity-checks"], optional = true}
-halo2_proofs = {version = "0.1.0", optional = true}
-halo2_gadgets = {version = "0.1.0", optional = true}
-#halo2_gadgets = {version = "0.1.0", features = ["dev-graph", "test-dependencies"], optional = true}
+#halo2_proofs = {version = "0.1.0", optional = true}
+#halo2_gadgets = {version = "0.1.0", optional = true}
+halo2_proofs = {git = "https://github.com/zcash/halo2.git", rev = "a898d65ae3ad3d41987666f6a03cfc15edae01c4", optional = true}
+halo2_gadgets = {git = "https://github.com/zcash/halo2.git", rev = "a898d65ae3ad3d41987666f6a03cfc15edae01c4", optional = true}
 
 # Smart contract runtime
 drk-sdk = {path = "src/sdk", optional = true}
@@ -132,8 +132,11 @@ sled = {version = "0.34.7", optional = true}
 
 [dev-dependencies]
 clap = {version = "3.1.18", features = ["derive"]}
-halo2_proofs = {version = "0.1.0", features = ["dev-graph", "gadget-traces", "sanity-checks"]}
-halo2_gadgets = {version = "0.1.0", features = ["dev-graph", "test-dependencies"]}
+#halo2_proofs = {version = "0.1.0", features = ["dev-graph", "gadget-traces", "sanity-checks"]}
+#halo2_gadgets = {version = "0.1.0", features = ["dev-graph", "test-dependencies"]}
+halo2_proofs = {git = "https://github.com/zcash/halo2.git", rev = "a898d65ae3ad3d41987666f6a03cfc15edae01c4", features = ["dev-graph", "gadget-traces", "sanity-checks"]}
+halo2_gadgets = {git = "https://github.com/zcash/halo2.git", rev = "a898d65ae3ad3d41987666f6a03cfc15edae01c4", features = ["dev-graph", "test-dependencies"]}
+
 plotters = "0.3.1"
 
 [features]
@@ -311,12 +314,7 @@ name = "zk"
 path = "example/zk.rs"
 required-features = ["crypto"]
 
-[[example]]
-name = "gt"
-path = "example/gt.rs"
-required-features = ["node"]
-
-[[example]]
-name = "lead"
-path = "example/lead.rs"
-required-features = ["node"]
+#[[example]]
+#name = "lead"
+#path = "example/lead.rs"
+#required-features = ["node"]

+ 0 - 124
example/gt.rs

@@ -1,124 +0,0 @@
-use darkfi::zk::gadget::{
-    arith_chip::{ArithChip, ArithConfig, ArithInstruction},
-    even_bits::{EvenBitsChip, EvenBitsConfig, EvenBitsLookup},
-    greater_than::{GreaterThanChip, GreaterThanConfig, GreaterThanInstruction},
-};
-use halo2_gadgets::utilities::UtilitiesInstructions;
-use halo2_proofs::{
-    circuit::{AssignedCell, Layouter, SimpleFloorPlanner},
-    dev::MockProver,
-    plonk,
-    plonk::{Advice, Circuit, Column, ConstraintSystem, Instance as InstanceColumn},
-};
-use pasta_curves::{pallas, Fp};
-
-const WORD_BITS: u32 = 24;
-
-#[derive(Clone)]
-struct ZkConfig {
-    primary: Column<InstanceColumn>,
-    advices: [Column<Advice>; 3],
-    evenbits_config: EvenBitsConfig,
-    greaterthan_config: GreaterThanConfig,
-    arith_config: ArithConfig,
-}
-
-impl ZkConfig {
-    fn evenbits_chip(&self) -> EvenBitsChip<pallas::Base, WORD_BITS> {
-        EvenBitsChip::construct(self.evenbits_config.clone())
-    }
-
-    fn greaterthan_chip(&self) -> GreaterThanChip<pallas::Base, WORD_BITS> {
-        GreaterThanChip::construct(self.greaterthan_config.clone())
-    }
-
-    fn arith_chip(&self) -> ArithChip {
-        ArithChip::construct(self.arith_config.clone())
-    }
-}
-
-struct ZkCircuit {
-    y: Option<pallas::Base>,
-    v: Option<pallas::Base>,
-    f: Option<pallas::Base>,
-}
-
-impl UtilitiesInstructions<pallas::Base> for ZkCircuit {
-    type Var = AssignedCell<Fp, Fp>;
-}
-
-impl Circuit<pallas::Base> for ZkCircuit {
-    type Config = ZkConfig;
-    type FloorPlanner = SimpleFloorPlanner;
-
-    fn without_witnesses(&self) -> Self {
-        Self { y: None, v: None, f: None }
-    }
-
-    fn configure(meta: &mut ConstraintSystem<pallas::Base>) -> Self::Config {
-        let advices = [meta.advice_column(), meta.advice_column(), meta.advice_column()];
-
-        // Instance column used for public inputs
-        let primary = meta.instance_column();
-        meta.enable_equality(primary);
-
-        for advice in advices.iter() {
-            meta.enable_equality(*advice);
-        }
-
-        let evenbits_config = EvenBitsChip::<pallas::Base, WORD_BITS>::configure(meta);
-        let greaterthan_config = GreaterThanChip::<pallas::Base, WORD_BITS>::configure(
-            meta,
-            [advices[1], advices[2]],
-            primary,
-        );
-        let arith_config = ArithChip::configure(meta, advices[1], advices[2], advices[0]);
-
-        ZkConfig { primary, advices, evenbits_config, greaterthan_config, arith_config }
-    }
-
-    fn synthesize(
-        &self,
-        config: Self::Config,
-        mut layouter: impl Layouter<pallas::Base>,
-    ) -> Result<(), plonk::Error> {
-        let eb_chip = config.evenbits_chip();
-        eb_chip.alloc_table(&mut layouter.namespace(|| "alloc table"))?;
-
-        let gt_chip = config.greaterthan_chip();
-
-        let ar_chip = config.arith_chip();
-
-        let y = self.load_private(layouter.namespace(|| "Witness y"), config.advices[0], self.y)?;
-        let v = self.load_private(layouter.namespace(|| "Witness v"), config.advices[0], self.v)?;
-        let f = self.load_private(layouter.namespace(|| "Witness t"), config.advices[0], self.f)?;
-
-        let t = ar_chip.mul(layouter.namespace(|| "target value"), &v, &f)?;
-
-        eb_chip.decompose(layouter.namespace(|| "y range check"), y.clone())?;
-        eb_chip.decompose(layouter.namespace(|| "t range check"), t.clone())?;
-
-        let (helper, greater_than) =
-            gt_chip.greater_than(layouter.namespace(|| "y > t"), y.into(), t.into())?;
-
-        eb_chip.decompose(layouter.namespace(|| "helper range check"), helper.0)?;
-
-        layouter.constrain_instance(greater_than.0.cell(), config.primary, 0)?;
-        Ok(())
-    }
-}
-
-fn main() {
-    let k = 13;
-    let y = pallas::Base::from(2);
-    let v = pallas::Base::from(3);
-    let f = pallas::Base::from(1);
-    //
-    let c = pallas::Base::from(0);
-    let circuit = ZkCircuit { y: Some(y), v: Some(v), f: Some(f) };
-
-    let public_inputs: Vec<pallas::Base> = vec![c];
-
-    let prover = MockProver::run(k, &circuit, vec![public_inputs]).unwrap();
-    assert_eq!(prover.verify(), Ok(()));
-}

+ 5 - 2
example/zk.rs

@@ -13,6 +13,7 @@ use darkfi::{
     zkas::decoder::ZkBinary,
     Result,
 };
+use halo2_proofs::circuit::Value;
 use pasta_curves::{
     arithmetic::CurveAffine,
     group::{ff::Field, Curve},
@@ -35,8 +36,10 @@ fn main() -> Result<()> {
     let value = 42;
     let value_blind = pallas::Scalar::random(&mut OsRng);
 
-    let prover_witnesses =
-        vec![Witness::Base(Some(pallas::Base::from(value))), Witness::Scalar(Some(value_blind))];
+    let prover_witnesses = vec![
+        Witness::Base(Value::known(pallas::Base::from(value))),
+        Witness::Scalar(Value::known(value_blind)),
+    ];
 
     // Create the public inputs
     let value_commit = pedersen_commitment_u64(value, value_blind);

+ 4 - 4
proof/arithmetic.zk

@@ -15,9 +15,9 @@ circuit "Arith" {
     difference = base_sub(a, b);
     constrain_instance(difference);
 
-    a_gt_b = greater_than(a, b);
-    constrain_instance(a_gt_b);
+    #a_gt_b = greater_than(a, b);
+    #constrain_instance(a_gt_b);
 
-    b_gt_a = greater_than(b, a);
-    constrain_instance(b_gt_a);
+    #b_gt_a = greater_than(b, a);
+    #constrain_instance(b_gt_a);
 }

+ 11 - 10
src/crypto/burn_proof.rs

@@ -1,6 +1,7 @@
 use std::time::Instant;
 
 use halo2_gadgets::poseidon::primitives as poseidon;
+use halo2_proofs::circuit::Value;
 use incrementalmerkletree::Hashable;
 use log::debug;
 use pasta_curves::{arithmetic::CurveAffine, group::Curve};
@@ -137,16 +138,16 @@ pub fn create_burn_proof(
     let leaf_position: u64 = leaf_position.into();
 
     let c = BurnContract {
-        secret_key: Some(secret.0),
-        serial: Some(serial),
-        value: Some(DrkValue::from(value)),
-        token: Some(token_id),
-        coin_blind: Some(coin_blind),
-        value_blind: Some(value_blind),
-        token_blind: Some(token_blind),
-        leaf_pos: Some(leaf_position as u32),
-        merkle_path: Some(merkle_path.try_into().unwrap()),
-        sig_secret: Some(signature_secret.0),
+        secret_key: Value::known(secret.0),
+        serial: Value::known(serial),
+        value: Value::known(DrkValue::from(value)),
+        token: Value::known(token_id),
+        coin_blind: Value::known(coin_blind),
+        value_blind: Value::known(value_blind),
+        token_blind: Value::known(token_blind),
+        leaf_pos: Value::known(leaf_position as u32),
+        merkle_path: Value::known(merkle_path.try_into().unwrap()),
+        sig_secret: Value::known(signature_secret.0),
     };
 
     let start = Instant::now();

+ 18 - 17
src/crypto/lead_proof.rs

@@ -1,5 +1,6 @@
 use std::time::Instant;
 
+use halo2_proofs::circuit::Value;
 use log::debug;
 use pasta_curves::pallas;
 use rand::rngs::OsRng;
@@ -25,23 +26,23 @@ pub fn create_lead_proof(pk: ProvingKey, coin: LeadCoin) -> Result<Proof> {
     let mau_y: pallas::Base = pallas::Base::from(yu64);
     let mau_rho: pallas::Base = pallas::Base::from(rhou64);
     let contract = LeadContract {
-        path: coin.path,
-        coin_pk_x: coin.pk_x,
-        coin_pk_y: coin.pk_y,
-        root_sk: coin.root_sk,
-        sf_root_sk: Some(mod_r_p(coin.root_sk.unwrap())),
-        path_sk: coin.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_pos: Some(coin.idx),
-        //sn_c1: Some(coin.sn.unwrap()),
-        slot: Some(coin.sl.unwrap()),
-        mau_rho: Some(mod_r_p(mau_rho)),
-        mau_y: Some(mod_r_p(mau_y)),
-        root_cm: Some(coin.root_cm.unwrap()),
+        path: Value::known(coin.path.unwrap()),
+        coin_pk_x: Value::known(coin.pk_x.unwrap()),
+        coin_pk_y: Value::known(coin.pk_y.unwrap()),
+        root_sk: Value::known(coin.root_sk.unwrap()),
+        sf_root_sk: Value::known(mod_r_p(coin.root_sk.unwrap())),
+        path_sk: Value::known(coin.path_sk.unwrap()),
+        coin_timestamp: Value::known(coin.tau.unwrap()),
+        coin_nonce: Value::known(coin.nonce.unwrap()),
+        coin_opening_1: Value::known(mod_r_p(coin.opening1.unwrap())),
+        value: Value::known(coin.value.unwrap()),
+        coin_opening_2: Value::known(mod_r_p(coin.opening2.unwrap())),
+        cm_pos: Value::known(coin.idx),
+        //sn_c1: Value::known(coin.sn.unwrap()),
+        slot: Value::known(coin.sl.unwrap()),
+        mau_rho: Value::known(mod_r_p(mau_rho)),
+        mau_y: Value::known(mod_r_p(mau_y)),
+        root_cm: Value::known(coin.root_cm.unwrap()),
     };
 
     let start = Instant::now();

+ 1 - 0
src/crypto/leadcoin.rs

@@ -1,3 +1,4 @@
+// FIXME: This needs a cleanup and halo2 0.2 port
 use pasta_curves::pallas;
 
 use crate::crypto::{

+ 9 - 8
src/crypto/mint_proof.rs

@@ -1,6 +1,7 @@
 use std::time::Instant;
 
 use halo2_gadgets::poseidon::primitives as poseidon;
+use halo2_proofs::circuit::Value;
 use log::debug;
 use pasta_curves::{arithmetic::CurveAffine, group::Curve, pallas};
 use rand::rngs::OsRng;
@@ -89,14 +90,14 @@ pub fn create_mint_proof(
     let coords = public_key.0.to_affine().coordinates().unwrap();
 
     let c = MintContract {
-        pub_x: Some(*coords.x()),
-        pub_y: Some(*coords.y()),
-        value: Some(DrkValue::from(value)),
-        token: Some(token_id),
-        serial: Some(serial),
-        coin_blind: Some(coin_blind),
-        value_blind: Some(value_blind),
-        token_blind: Some(token_blind),
+        pub_x: Value::known(*coords.x()),
+        pub_y: Value::known(*coords.y()),
+        value: Value::known(DrkValue::from(value)),
+        token: Value::known(token_id),
+        serial: Value::known(serial),
+        coin_blind: Value::known(coin_blind),
+        value_blind: Value::known(value_blind),
+        token_blind: Value::known(token_blind),
     };
 
     let start = Instant::now();

+ 2 - 2
src/crypto/mod.rs

@@ -21,8 +21,8 @@ pub use burn_proof::BurnRevealedValues;
 pub use mint_proof::MintRevealedValues;
 pub use proof::Proof;
 
-pub mod lead_proof;
-pub mod leadcoin;
+//pub mod lead_proof;
+//pub mod leadcoin;
 
 use keypair::SecretKey;
 

+ 13 - 14
src/zk/circuit/burn_contract.rs

@@ -17,7 +17,7 @@ use halo2_gadgets::{
     utilities::{lookup_range_check::LookupRangeCheckConfig, UtilitiesInstructions},
 };
 use halo2_proofs::{
-    circuit::{AssignedCell, Layouter, SimpleFloorPlanner},
+    circuit::{AssignedCell, Layouter, SimpleFloorPlanner, Value},
     plonk::{Advice, Circuit, Column, ConstraintSystem, Error, Instance as InstanceColumn},
 };
 use pasta_curves::{pallas, Fp};
@@ -94,17 +94,16 @@ const BURN_SIGKEYY_OFFSET: usize = 7;
 
 #[derive(Default, Debug)]
 pub struct BurnContract {
-    pub secret_key: Option<pallas::Base>,
-    pub serial: Option<pallas::Base>,
-    pub value: Option<pallas::Base>,
-    pub token: Option<pallas::Base>,
-    pub coin_blind: Option<pallas::Base>,
-    pub value_blind: Option<pallas::Scalar>,
-    pub token_blind: Option<pallas::Scalar>,
-    pub leaf_pos: Option<u32>,
-    pub merkle_path: Option<[MerkleNode; MERKLE_DEPTH_ORCHARD]>,
-    //pub sig_secret: Option<pallas::Scalar>,
-    pub sig_secret: Option<pallas::Base>,
+    pub secret_key: Value<pallas::Base>,
+    pub serial: Value<pallas::Base>,
+    pub value: Value<pallas::Base>,
+    pub token: Value<pallas::Base>,
+    pub coin_blind: Value<pallas::Base>,
+    pub value_blind: Value<pallas::Scalar>,
+    pub token_blind: Value<pallas::Scalar>,
+    pub leaf_pos: Value<u32>,
+    pub merkle_path: Value<[MerkleNode; MERKLE_DEPTH_ORCHARD]>,
+    pub sig_secret: Value<pallas::Base>,
 }
 
 impl UtilitiesInstructions<pallas::Base> for BurnContract {
@@ -335,7 +334,7 @@ impl Circuit<pallas::Base> for BurnContract {
         // Merkle root
         // ===========
 
-        let path: Option<[pallas::Base; MERKLE_DEPTH_ORCHARD]> =
+        let path: Value<[pallas::Base; MERKLE_DEPTH_ORCHARD]> =
             self.merkle_path.map(|typed_path| gen_const_array(|i| typed_path[i].inner()));
 
         let merkle_inputs = MerklePath::construct(
@@ -362,7 +361,7 @@ impl Circuit<pallas::Base> for BurnContract {
         let one = self.load_private(
             layouter.namespace(|| "load constant one"),
             config.advices[0],
-            Some(pallas::Base::one()),
+            Value::known(pallas::Base::one()),
         )?;
 
         let value =

+ 39 - 41
src/zk/circuit/lead_contract.rs

@@ -13,9 +13,8 @@ use halo2_gadgets::{
     },
     utilities::{lookup_range_check::LookupRangeCheckConfig, UtilitiesInstructions},
 };
-
 use halo2_proofs::{
-    circuit::{AssignedCell, Layouter, SimpleFloorPlanner},
+    circuit::{AssignedCell, Layouter, SimpleFloorPlanner, Value},
     plonk::{Advice, Circuit, Column, ConstraintSystem, Error, Instance as InstanceColumn},
 };
 
@@ -33,7 +32,6 @@ use crate::crypto::{
 use crate::zk::gadget::{
     arithmetic::{ArithChip, ArithConfig, ArithInstruction},
     even_bits::{EvenBitsChip, EvenBitsConfig, EvenBitsLookup},
-    greater_than::{GreaterThanChip, GreaterThanConfig, GreaterThanInstruction},
 };
 
 use pasta_curves::group::{ff::PrimeField, GroupEncoding};
@@ -52,7 +50,7 @@ pub struct LeadConfig {
         SinsemillaConfig<OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases>,
     _sinsemilla_config_2:
         SinsemillaConfig<OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases>,
-    greaterthan_config: GreaterThanConfig,
+    //greaterthan_config: GreaterThanConfig,
     evenbits_config: EvenBitsConfig,
     arith_config: ArithConfig,
 }
@@ -78,9 +76,9 @@ impl LeadConfig {
         MerkleChip::construct(self.merkle_config_2.clone())
     }
 
-    fn greaterthan_chip(&self) -> GreaterThanChip<pallas::Base, WORD_BITS> {
-        GreaterThanChip::construct(self.greaterthan_config.clone())
-    }
+    // fn greaterthan_chip(&self) -> GreaterThanChip<pallas::Base, WORD_BITS> {
+    // GreaterThanChip::construct(self.greaterthan_config.clone())
+    // }
 
     fn evenbits_chip(&self) -> EvenBitsChip<pallas::Base, WORD_BITS> {
         EvenBitsChip::construct(self.evenbits_config.clone())
@@ -110,25 +108,25 @@ pub fn concat_u8(lhs: &[u8], rhs: &[u8]) -> Vec<u8> {
 #[derive(Default, Debug)]
 pub struct LeadContract {
     // witness
-    pub path: Option<[MerkleNode; MERKLE_DEPTH_ORCHARD]>,
-    pub coin_pk_x: Option<pallas::Base>,
-    pub coin_pk_y: Option<pallas::Base>,
-    pub root_sk: Option<pallas::Base>, // coins merkle tree secret key of coin1
-    pub sf_root_sk: Option<pallas::Scalar>, // root_sk as pallas::Scalar
-    pub path_sk: Option<[MerkleNode; MERKLE_DEPTH_ORCHARD]>, // path to the secret key root_sk
-    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>,
+    pub path: Value<[MerkleNode; MERKLE_DEPTH_ORCHARD]>,
+    pub coin_pk_x: Value<pallas::Base>,
+    pub coin_pk_y: Value<pallas::Base>,
+    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 path_sk: Value<[MerkleNode; MERKLE_DEPTH_ORCHARD]>, // path to the secret key root_sk
+    pub coin_timestamp: Value<pallas::Base>,
+    pub coin_nonce: Value<pallas::Base>,
+    pub coin_opening_1: Value<pallas::Scalar>,
+    pub value: Value<pallas::Base>,
+    pub coin_opening_2: Value<pallas::Scalar>,
     // public advices
-    pub cm_pos: Option<u32>,
+    pub cm_pos: Value<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 slot: Value<pallas::Base>,
+    pub mau_rho: Value<pallas::Scalar>,
+    pub mau_y: Value<pallas::Scalar>,
+    pub root_cm: Value<pallas::Scalar>,
     //pub eta : Option<u32>,
     //pub rho : Option<u32>,
     //pub h : Option<u32>, // hash of this data
@@ -232,11 +230,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..12].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 = ArithChip::configure(meta, advices[7], advices[8], advices[6]);
 
@@ -249,7 +247,7 @@ impl Circuit<pallas::Base> for LeadContract {
             merkle_config_2,
             sinsemilla_config_1,
             _sinsemilla_config_2: sinsemilla_config_2,
-            greaterthan_config,
+            //greaterthan_config,
             evenbits_config,
             arith_config,
         }
@@ -265,7 +263,7 @@ 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();
+        //let greater_than_chip = config.greaterthan_chip();
 
         eb_chip.alloc_table(&mut layouter.namespace(|| "alloc table"))?;
 
@@ -276,7 +274,7 @@ impl Circuit<pallas::Base> for LeadContract {
         let one = self.load_private(
             layouter.namespace(|| "one"),
             config.advices[0],
-            Some(pallas::Base::one()),
+            Value::known(pallas::Base::one()),
         )?;
 
         // coin_timestamp tau
@@ -671,7 +669,7 @@ impl Circuit<pallas::Base> for LeadContract {
         let y_commit_base = self.load_private(
             layouter.namespace(|| "load coin y commit as pallas::base"),
             config.advices[0],
-            Some(y_commit_base_temp),
+            Value::known(y_commit_base_temp),
         )?;
 
         // ============================
@@ -701,13 +699,13 @@ impl Circuit<pallas::Base> for LeadContract {
         let scalar = self.load_private(
             layouter.namespace(|| "load scalar "),
             config.advices[0],
-            Some(pallas::Base::from(1024)),
+            Value::known(pallas::Base::from(1024)),
         )?;
         //leadership coefficient
         let c = self.load_private(
             layouter.namespace(|| ""),
             config.advices[0],
-            Some(pallas::Base::one()), // note! this parameter to be tuned.
+            Value::known(pallas::Base::one()), // note! this parameter to be tuned.
         )?;
         let ord = ar_chip.mul(layouter.namespace(|| ""), &scalar, &c)?;
         let target = ar_chip.mul(layouter.namespace(|| "calculate target"), &ord, &coin_value)?;
@@ -715,14 +713,14 @@ impl Circuit<pallas::Base> for LeadContract {
         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_base.into(),
-        )?;
-        eb_chip.decompose(layouter.namespace(|| "helper range check"), helper.0)?;
+        //let (helper, is_gt) = greater_than_chip.greater_than(
+        //  layouter.namespace(|| "t>y"),
+        //target.into(),
+        //            y_commit_base.into(),
+        //      )?;
+        //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(())
     }

+ 94 - 18
src/zk/circuit/mint_contract.rs

@@ -10,7 +10,7 @@ use halo2_gadgets::{
     utilities::{lookup_range_check::LookupRangeCheckConfig, UtilitiesInstructions},
 };
 use halo2_proofs::{
-    circuit::{AssignedCell, Layouter, SimpleFloorPlanner},
+    circuit::{floor_planner, AssignedCell, Layouter, Value},
     plonk,
     plonk::{Advice, Circuit, Column, ConstraintSystem, Instance as InstanceColumn},
 };
@@ -45,14 +45,22 @@ const MINT_TOKCOMY_OFFSET: usize = 4;
 
 #[derive(Default, Debug)]
 pub struct MintContract {
-    pub pub_x: Option<pallas::Base>,         // x coordinate for pubkey
-    pub pub_y: Option<pallas::Base>,         // y coordinate for pubkey
-    pub value: Option<pallas::Base>,         // The value of this coin
-    pub token: Option<pallas::Base>,         // The token ID
-    pub serial: Option<pallas::Base>,        // Unique serial number corresponding to this coin
-    pub coin_blind: Option<pallas::Base>,    // Random blinding factor for coin
-    pub value_blind: Option<pallas::Scalar>, // Random blinding factor for value commitment
-    pub token_blind: Option<pallas::Scalar>, // Random blinding factor for the token ID
+    /// X coordinate for public key
+    pub pub_x: Value<pallas::Base>,
+    /// Y coordinate for public key
+    pub pub_y: Value<pallas::Base>,
+    /// The value of this coin
+    pub value: Value<pallas::Base>,
+    /// The token ID
+    pub token: Value<pallas::Base>,
+    /// Unique serial number corresponding to this coin
+    pub serial: Value<pallas::Base>,
+    /// Random blinding factor for coin
+    pub coin_blind: Value<pallas::Base>,
+    /// Random blinding factor for value commitment
+    pub value_blind: Value<pallas::Scalar>,
+    /// Random blinding factor for the token ID
+    pub token_blind: Value<pallas::Scalar>,
 }
 
 impl UtilitiesInstructions<pallas::Base> for MintContract {
@@ -61,7 +69,7 @@ impl UtilitiesInstructions<pallas::Base> for MintContract {
 
 impl Circuit<pallas::Base> for MintContract {
     type Config = MintConfig;
-    type FloorPlanner = SimpleFloorPlanner;
+    type FloorPlanner = floor_planner::V1;
 
     fn without_witnesses(&self) -> Self {
         Self::default()
@@ -141,31 +149,31 @@ impl Circuit<pallas::Base> for MintContract {
     ) -> Result<(), plonk::Error> {
         let ecc_chip = config.ecc_chip();
 
-        let pub_x = self.load_private(
+        let pub_x = assign_free_advice(
             layouter.namespace(|| "load pubkey x"),
             config.advices[0],
             self.pub_x,
         )?;
 
-        let pub_y = self.load_private(
+        let pub_y = assign_free_advice(
             layouter.namespace(|| "load pubkey y"),
             config.advices[0],
             self.pub_y,
         )?;
 
         let value =
-            self.load_private(layouter.namespace(|| "load value"), config.advices[0], self.value)?;
+            assign_free_advice(layouter.namespace(|| "load value"), config.advices[0], self.value)?;
 
         let token =
-            self.load_private(layouter.namespace(|| "load token"), config.advices[0], self.token)?;
+            assign_free_advice(layouter.namespace(|| "load token"), config.advices[0], self.token)?;
 
-        let serial = self.load_private(
+        let serial = assign_free_advice(
             layouter.namespace(|| "load serial"),
             config.advices[0],
             self.serial,
         )?;
 
-        let coin_blind = self.load_private(
+        let coin_blind = assign_free_advice(
             layouter.namespace(|| "load coin_blind"),
             config.advices[0],
             self.coin_blind,
@@ -203,10 +211,10 @@ impl Circuit<pallas::Base> for MintContract {
         // ================
 
         // This constant one is used for short multiplication
-        let one = self.load_private(
+        let one = assign_free_advice(
             layouter.namespace(|| "load constant one"),
             config.advices[0],
-            Some(pallas::Base::one()),
+            Value::known(pallas::Base::one()),
         )?;
 
         // v * G_1
@@ -294,3 +302,71 @@ impl Circuit<pallas::Base> for MintContract {
         Ok(())
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::{
+        crypto::{
+            keypair::PublicKey,
+            util::{mod_r_p, pedersen_commitment_scalar},
+        },
+        Result,
+    };
+    use group::{ff::Field, Curve};
+    use halo2_gadgets::poseidon::{
+        primitives as poseidon,
+        primitives::{ConstantLength, P128Pow5T3},
+    };
+    use halo2_proofs::{
+        circuit::Value,
+        dev::{CircuitLayout, MockProver},
+    };
+    use pasta_curves::arithmetic::CurveAffine;
+    use rand::rngs::OsRng;
+
+    #[test]
+    fn circuit_assert() -> Result<()> {
+        let value = pallas::Base::from(42);
+        let token_id = pallas::Base::from(22);
+        let value_blind = pallas::Scalar::random(&mut OsRng);
+        let token_blind = pallas::Scalar::random(&mut OsRng);
+        let serial = pallas::Base::random(&mut OsRng);
+        let coin_blind = pallas::Base::random(&mut OsRng);
+        let public_key = PublicKey::random(&mut OsRng);
+        let coords = public_key.0.to_affine().coordinates().unwrap();
+
+        let msg = [*coords.x(), *coords.y(), value, token_id, serial, coin_blind];
+        let coin = poseidon::Hash::<_, P128Pow5T3, ConstantLength<6>, 3, 2>::init().hash(msg);
+
+        let value_commit = pedersen_commitment_scalar(mod_r_p(value), value_blind);
+        let value_coords = value_commit.to_affine().coordinates().unwrap();
+
+        let token_commit = pedersen_commitment_scalar(mod_r_p(token_id), token_blind);
+        let token_coords = token_commit.to_affine().coordinates().unwrap();
+
+        let public_inputs =
+            vec![coin, *value_coords.x(), *value_coords.y(), *token_coords.x(), *token_coords.y()];
+
+        let circuit = MintContract {
+            pub_x: Value::known(*coords.x()),
+            pub_y: Value::known(*coords.y()),
+            value: Value::known(value),
+            token: Value::known(token_id),
+            serial: Value::known(serial),
+            coin_blind: Value::known(coin_blind),
+            value_blind: Value::known(value_blind),
+            token_blind: Value::known(token_blind),
+        };
+
+        use plotters::prelude::*;
+        let root = BitMapBackend::new("mint_circuit_layout.png", (3840, 2160)).into_drawing_area();
+        root.fill(&WHITE).unwrap();
+        let root = root.titled("Mint Circuit Layout", ("sans-serif", 60)).unwrap();
+        CircuitLayout::default().render(9, &circuit, &root).unwrap();
+
+        let prover = MockProver::run(9, &circuit, vec![public_inputs])?;
+        prover.assert_satisfied();
+        Ok(())
+    }
+}

+ 2 - 2
src/zk/circuit/mod.rs

@@ -4,5 +4,5 @@ pub use burn_contract::BurnContract;
 pub mod mint_contract;
 pub use mint_contract::MintContract;
 
-pub mod lead_contract;
-pub use lead_contract::LeadContract;
+//pub mod lead_contract;
+//pub use lead_contract::LeadContract;

+ 3 - 18
src/zk/gadget/arithmetic.rs

@@ -119,12 +119,7 @@ impl ArithInstruction<pallas::Base> for ArithChip {
                 b.copy_advice(|| "copy b", &mut region, self.config.b, 0)?;
 
                 let scalar_val = a.value().zip(b.value()).map(|(a, b)| a + b);
-                region.assign_advice(
-                    || "c",
-                    self.config.c,
-                    0,
-                    || scalar_val.ok_or(plonk::Error::Synthesis),
-                )
+                region.assign_advice(|| "c", self.config.c, 0, || scalar_val)
             },
         )
     }
@@ -144,12 +139,7 @@ impl ArithInstruction<pallas::Base> for ArithChip {
                 b.copy_advice(|| "copy b", &mut region, self.config.b, 0)?;
 
                 let scalar_val = a.value().zip(b.value()).map(|(a, b)| a - b);
-                region.assign_advice(
-                    || "c",
-                    self.config.c,
-                    0,
-                    || scalar_val.ok_or(plonk::Error::Synthesis),
-                )
+                region.assign_advice(|| "c", self.config.c, 0, || scalar_val)
             },
         )
     }
@@ -169,12 +159,7 @@ impl ArithInstruction<pallas::Base> for ArithChip {
                 b.copy_advice(|| "copy b", &mut region, self.config.b, 0)?;
 
                 let scalar_val = a.value().zip(b.value()).map(|(a, b)| a * b);
-                region.assign_advice(
-                    || "c",
-                    self.config.c,
-                    0,
-                    || scalar_val.ok_or(plonk::Error::Synthesis),
-                )
+                region.assign_advice(|| "c", self.config.c, 0, || scalar_val)
             },
         )
     }

+ 6 - 23
src/zk/gadget/even_bits.rs

@@ -2,7 +2,7 @@ use std::{marker::PhantomData, ops::Deref};
 
 use halo2_proofs::{
     arithmetic::FieldExt,
-    circuit::{AssignedCell, Chip, Layouter, Region},
+    circuit::{AssignedCell, Chip, Layouter, Region, Value},
     plonk::{Advice, Column, ConstraintSystem, Error, Expression, Selector, TableColumn},
     poly::Rotation,
 };
@@ -21,18 +21,11 @@ impl EvenBitsConfig {
     pub fn load_private<F: FieldExt>(
         &self,
         mut layouter: impl Layouter<F>,
-        value: Option<F>,
+        value: Value<F>,
     ) -> Result<AssignedCell<F, F>, Error> {
         layouter.assign_region(
             || "load private",
-            |mut region| {
-                region.assign_advice(
-                    || "private input",
-                    self.advice[0],
-                    0,
-                    || value.ok_or(Error::Synthesis),
-                )
-            },
+            |mut region| region.assign_advice(|| "private input", self.advice[0], 0, || value),
         )
     }
 }
@@ -112,7 +105,7 @@ impl<F: FieldExt, const WORD_BITS: u32> EvenBitsChip<F, WORD_BITS> {
                         || format!("even_bits row {}", i),
                         self.config.even_bits,
                         i,
-                        || Ok(F::from(even_bits_at(i) as u64)),
+                        || Value::known(F::from(even_bits_at(i) as u64)),
                     )?;
                 }
                 Ok(())
@@ -192,21 +185,11 @@ impl<F: FieldExt, const WORD_BITS: u32> EvenBitsLookup<F> for EvenBitsChip<F, WO
 
                 let o_eo = c.value().cloned().map(decompose);
                 let e_cell = region
-                    .assign_advice(
-                        || "even bits",
-                        config.advice[0],
-                        0,
-                        || o_eo.map(|eo| *eo.0).ok_or(Error::Synthesis),
-                    )
+                    .assign_advice(|| "even bits", config.advice[0], 0, || o_eo.map(|eo| *eo.0))
                     .map(EvenBits)?;
 
                 let o_cell = region
-                    .assign_advice(
-                        || "odd bits",
-                        config.advice[1],
-                        0,
-                        || o_eo.map(|eo| *eo.1).ok_or(Error::Synthesis),
-                    )
+                    .assign_advice(|| "odd bits", config.advice[1], 0, || o_eo.map(|eo| *eo.1))
                     .map(OddBits)?;
 
                 c.copy_advice(|| "out", &mut region, config.advice[0], 1)?;

+ 20 - 18
src/zk/gadget/greater_than.rs

@@ -2,7 +2,7 @@ use std::marker::PhantomData;
 
 use halo2_proofs::{
     arithmetic::FieldExt,
-    circuit::{AssignedCell, Chip, Layouter, Region},
+    circuit::{AssignedCell, Chip, Layouter, Region, Value},
     plonk::{Advice, Column, ConstraintSystem, Error, Expression, Instance, Selector},
     poly::Rotation,
 };
@@ -174,21 +174,19 @@ impl<const WORD_BITS: u32> GreaterThanInstruction<pallas::Base>
                         config.advice[0],
                         1,
                         || {
-                            let is_greater = a.0.value().unwrap().get_lower_128() >
-                                b.0.value().unwrap().get_lower_128();
-                            a.0.value()
-                                .and_then(|a| {
-                                    b.0.value().map(|b| {
-                                        let x = *a - *b;
-
-                                        (if is_greater {
-                                            pallas::Base::from(2_u64.pow(WORD_BITS))
-                                        } else {
-                                            pallas::Base::zero()
-                                        }) - x
-                                    })
+                            let is_greater = a.0.value().inner().unwrap().get_lower_128() >
+                                b.0.value().get_lower_128();
+                            a.0.value().and_then(|a| {
+                                b.0.value().map(|b| {
+                                    let x = *a - *b;
+
+                                    (if is_greater {
+                                        pallas::Base::from(2_u64.pow(WORD_BITS))
+                                    } else {
+                                        pallas::Base::zero()
+                                    }) - x
                                 })
-                                .ok_or(Error::Synthesis)
+                            })
                         },
                     )
                     .map(Word)?;
@@ -199,9 +197,13 @@ impl<const WORD_BITS: u32> GreaterThanInstruction<pallas::Base>
                         config.advice[1],
                         1,
                         || {
-                            let is_greater = a.0.value().unwrap().get_lower_128() >
-                                b.0.value().unwrap().get_lower_128();
-                            Ok(if is_greater { pallas::Base::one() } else { pallas::Base::zero() })
+                            let is_greater = a.0.value().inner().unwrap().get_lower_128() >
+                                b.0.value().get_lower_128();
+                            Value::known(if is_greater {
+                                pallas::Base::one()
+                            } else {
+                                pallas::Base::zero()
+                            })
                         },
                     )
                     .map(Word)?;

+ 5 - 2
src/zk/gadget/mod.rs

@@ -4,5 +4,8 @@ pub mod arithmetic;
 /// Even-bits lookup table
 pub mod even_bits;
 
-/// Greater than comparison gadget;
-pub mod greater_than;
+// Greater than comparison gadget;
+//pub mod greater_than;
+
+/// Comparison gadget
+pub mod cmp;

+ 6 - 13
src/zk/mod.rs

@@ -1,6 +1,3 @@
-/// ZK gadget implementations
-pub mod gadget;
-
 /// Halo2 zkas virtual machine
 pub mod vm;
 pub mod vm_stack;
@@ -8,9 +5,12 @@ pub mod vm_stack;
 /// ZK circuits
 pub mod circuit;
 
+/// ZK gadget implementations
+pub mod gadget;
+
 use halo2_proofs::{
     arithmetic::Field,
-    circuit::{AssignedCell, Layouter},
+    circuit::{AssignedCell, Layouter, Value},
     plonk,
     plonk::{Advice, Assigned, Column},
 };
@@ -18,20 +18,13 @@ use halo2_proofs::{
 pub(in crate::zk) fn assign_free_advice<F: Field, V: Copy>(
     mut layouter: impl Layouter<F>,
     column: Column<Advice>,
-    value: Option<V>,
+    value: Value<V>,
 ) -> Result<AssignedCell<V, F>, plonk::Error>
 where
     for<'v> Assigned<F>: From<&'v V>,
 {
     layouter.assign_region(
         || "load private",
-        |mut region| {
-            region.assign_advice(
-                || "load private",
-                column,
-                0,
-                || value.ok_or(plonk::Error::Synthesis),
-            )
-        },
+        |mut region| region.assign_advice(|| "load private", column, 0, || value),
     )
 }

+ 13 - 13
src/zk/vm.rs

@@ -17,7 +17,7 @@ use halo2_gadgets::{
     utilities::{lookup_range_check::LookupRangeCheckConfig, UtilitiesInstructions},
 };
 use halo2_proofs::{
-    circuit::{AssignedCell, Layouter, SimpleFloorPlanner},
+    circuit::{AssignedCell, Layouter, SimpleFloorPlanner, Value},
     plonk,
     plonk::{Advice, Circuit, Column, ConstraintSystem, Instance as InstanceColumn},
 };
@@ -27,7 +27,6 @@ use pasta_curves::{group::Curve, pallas, Fp};
 use super::gadget::{
     arithmetic::{ArithChip, ArithConfig, ArithInstruction},
     even_bits::{EvenBitsChip, EvenBitsConfig, EvenBitsLookup},
-    greater_than::{GreaterThanChip, GreaterThanConfig, GreaterThanInstruction},
 };
 
 pub use super::vm_stack::{StackVar, Witness};
@@ -52,7 +51,7 @@ pub struct VmConfig {
     poseidon_config: PoseidonConfig<pallas::Base, 3, 2>,
     arith_config: ArithConfig,
     evenbits_config: EvenBitsConfig,
-    greaterthan_config: GreaterThanConfig,
+    //greaterthan_config: GreaterThanConfig,
 }
 
 impl VmConfig {
@@ -98,9 +97,9 @@ impl VmConfig {
         EvenBitsChip::construct(self.evenbits_config.clone())
     }
 
-    fn greaterthan_chip(&self) -> GreaterThanChip<pallas::Base, 24> {
-        GreaterThanChip::construct(self.greaterthan_config.clone())
-    }
+    //fn greaterthan_chip(&self) -> GreaterThanChip<pallas::Base, 24> {
+    //  GreaterThanChip::construct(self.greaterthan_config.clone())
+    //    }
 }
 
 #[derive(Clone, Default)]
@@ -208,8 +207,8 @@ impl Circuit<pallas::Base> for ZkCircuit {
         let evenbits_config = EvenBitsChip::<pallas::Base, 24>::configure(meta);
 
         // Configuration for the GreaterThan chip
-        let greaterthan_config =
-            GreaterThanChip::<pallas::Base, 24>::configure(meta, [advices[8], advices[9]], primary);
+        //let greaterthan_config =
+        //            GreaterThanChip::<pallas::Base, 24>::configure(meta, [advices[8], advices[9]], primary);
 
         // Configuration for a Sinsemilla hash instantiation and a
         // Merkle hash instantiation using this Sinsemilla instance.
@@ -252,7 +251,7 @@ impl Circuit<pallas::Base> for ZkCircuit {
             poseidon_config,
             arith_config,
             evenbits_config,
-            greaterthan_config,
+            //greaterthan_config,
         }
     }
 
@@ -283,13 +282,13 @@ impl Circuit<pallas::Base> for ZkCircuit {
         eb_chip.alloc_table(&mut layouter.namespace(|| "alloc table"))?;
 
         // Construct the GreaterThan chip.
-        let gt_chip = config.greaterthan_chip();
+        //let gt_chip = config.greaterthan_chip();
 
         // This constant one is used for short multiplication
         let one = self.load_private(
             layouter.namespace(|| "Load constant one"),
             config.advices[0],
-            Some(pallas::Base::one()),
+            Value::known(pallas::Base::one()),
         )?;
 
         // Lookup and push the constants onto the stack
@@ -355,7 +354,7 @@ impl Circuit<pallas::Base> for ZkCircuit {
 
                 Witness::MerklePath(w) => {
                     debug!("Witnessing MerklePath into circuit");
-                    let path: Option<[pallas::Base; MERKLE_DEPTH_ORCHARD]> =
+                    let path: Value<[pallas::Base; MERKLE_DEPTH_ORCHARD]> =
                         w.map(|typed_path| gen_const_array(|i| typed_path[i].inner()));
 
                     debug!("Pushing MerklePath to stack index {}", stack.len());
@@ -584,6 +583,7 @@ impl Circuit<pallas::Base> for ZkCircuit {
                     stack.push(StackVar::Base(difference));
                 }
 
+                /*
                 Opcode::GreaterThan => {
                     debug!("Executing `GreaterThan{:?}` opcode", opcode.1);
                     let args = &opcode.1;
@@ -605,7 +605,7 @@ impl Circuit<pallas::Base> for ZkCircuit {
                     debug!("Pushing comparison result to stack index {}", stack.len());
                     stack.push(StackVar::Base(greater_than.0));
                 }
-
+                */
                 Opcode::ConstrainInstance => {
                     debug!("Executing `ConstrainInstance{:?}` opcode", opcode.1);
                     let args = &opcode.1;

+ 22 - 22
src/zk/vm_stack.rs

@@ -1,6 +1,6 @@
 //! VM stack type abstractions
 use halo2_gadgets::ecc::{chip::EccChip, FixedPoint, FixedPointBaseField, FixedPointShort, Point};
-use halo2_proofs::circuit::AssignedCell;
+use halo2_proofs::circuit::{AssignedCell, Value};
 use pasta_curves::{pallas, EpAffine};
 
 use crate::{
@@ -12,13 +12,13 @@ use crate::{
 #[allow(clippy::large_enum_variant)]
 #[derive(Clone)]
 pub enum Witness {
-    EcPoint(Option<pallas::Point>),
-    EcFixedPoint(Option<pallas::Point>),
-    Base(Option<pallas::Base>),
-    Scalar(Option<pallas::Scalar>),
-    MerklePath(Option<[MerkleNode; 32]>),
-    Uint32(Option<u32>),
-    Uint64(Option<u64>),
+    EcPoint(Value<pallas::Point>),
+    EcFixedPoint(Value<pallas::Point>),
+    Base(Value<pallas::Base>),
+    Scalar(Value<pallas::Scalar>),
+    MerklePath(Value<[MerkleNode; 32]>),
+    Uint32(Value<u32>),
+    Uint64(Value<u64>),
 }
 
 /// Helper function for verifiers to generate empty witnesses for
@@ -28,13 +28,13 @@ pub fn empty_witnesses(zkbin: &ZkBinary) -> Vec<Witness> {
 
     for witness in &zkbin.witnesses {
         match witness {
-            Type::EcPoint => ret.push(Witness::EcPoint(None)),
-            Type::EcFixedPoint => ret.push(Witness::EcFixedPoint(None)),
-            Type::Base => ret.push(Witness::Base(None)),
-            Type::Scalar => ret.push(Witness::Scalar(None)),
-            Type::MerklePath => ret.push(Witness::MerklePath(None)),
-            Type::Uint32 => ret.push(Witness::Uint32(None)),
-            Type::Uint64 => ret.push(Witness::Uint64(None)),
+            Type::EcPoint => ret.push(Witness::EcPoint(Value::unknown())),
+            Type::EcFixedPoint => ret.push(Witness::EcFixedPoint(Value::unknown())),
+            Type::Base => ret.push(Witness::Base(Value::unknown())),
+            Type::Scalar => ret.push(Witness::Scalar(Value::unknown())),
+            Type::MerklePath => ret.push(Witness::MerklePath(Value::unknown())),
+            Type::Uint32 => ret.push(Witness::Uint32(Value::unknown())),
+            Type::Uint64 => ret.push(Witness::Uint64(Value::unknown())),
             _ => todo!("Handle this gracefully"),
         }
     }
@@ -51,10 +51,10 @@ pub enum StackVar {
     EcFixedPointShort(FixedPointShort<pallas::Affine, EccChip<OrchardFixedBases>>),
     EcFixedPointBase(FixedPointBaseField<pallas::Affine, EccChip<OrchardFixedBases>>),
     Base(AssignedCell<pallas::Base, pallas::Base>),
-    Scalar(Option<pallas::Scalar>),
-    MerklePath(Option<[pallas::Base; 32]>),
-    Uint32(Option<u32>),
-    Uint64(Option<u64>),
+    Scalar(Value<pallas::Scalar>),
+    MerklePath(Value<[pallas::Base; 32]>),
+    Uint32(Value<u32>),
+    Uint64(Value<u64>),
 }
 
 impl From<StackVar> for Point<pallas::Affine, EccChip<OrchardFixedBases>> {
@@ -75,7 +75,7 @@ impl From<StackVar> for FixedPoint<pallas::Affine, EccChip<OrchardFixedBases>> {
     }
 }
 
-impl From<StackVar> for std::option::Option<pallas::Scalar> {
+impl From<StackVar> for Value<pallas::Scalar> {
     fn from(value: StackVar) -> Self {
         match value {
             StackVar::Scalar(v) => v,
@@ -93,7 +93,7 @@ impl From<StackVar> for AssignedCell<pallas::Base, pallas::Base> {
     }
 }
 
-impl From<StackVar> for std::option::Option<u32> {
+impl From<StackVar> for Value<u32> {
     fn from(value: StackVar) -> Self {
         match value {
             StackVar::Uint32(v) => v,
@@ -102,7 +102,7 @@ impl From<StackVar> for std::option::Option<u32> {
     }
 }
 
-impl From<StackVar> for std::option::Option<[pallas::Base; 32]> {
+impl From<StackVar> for Value<[pallas::Base; 32]> {
     fn from(value: StackVar) -> Self {
         match value {
             StackVar::MerklePath(v) => v,

+ 2 - 1
tests/arithmetic_proof.rs

@@ -10,6 +10,7 @@ use darkfi::{
     zkas::decoder::ZkBinary,
     Result,
 };
+use halo2_proofs::circuit::Value;
 use pasta_curves::pallas;
 use rand::rngs::OsRng;
 
@@ -34,7 +35,7 @@ fn arithmetic_proof() -> Result<()> {
     let y_0 = pallas::Base::from(0); // Here we will compare a > b, which is false (0)
     let y_1 = pallas::Base::from(1); // Here we will compare b > a, which is true (1)
 
-    let prover_witnesses = vec![Witness::Base(Some(a)), Witness::Base(Some(b))];
+    let prover_witnesses = vec![Witness::Base(Value::known(a)), Witness::Base(Value::known(b))];
 
     // Create the public inputs
     let sum = a + b;

+ 11 - 10
tests/burn_proof.rs

@@ -14,6 +14,7 @@ use darkfi::{
     Result,
 };
 use halo2_gadgets::poseidon::primitives as poseidon;
+use halo2_proofs::circuit::Value;
 use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
 use pasta_curves::{
     arithmetic::CurveAffine,
@@ -72,16 +73,16 @@ fn burn_proof() -> Result<()> {
     let leaf_pos: u64 = leaf_pos.into();
 
     let prover_witnesses = vec![
-        Witness::Base(Some(secret.0)),
-        Witness::Base(Some(serial)),
-        Witness::Base(Some(pallas::Base::from(value))),
-        Witness::Base(Some(token_id)),
-        Witness::Base(Some(coin_blind)),
-        Witness::Scalar(Some(value_blind)),
-        Witness::Scalar(Some(token_blind)),
-        Witness::Uint32(Some(leaf_pos.try_into().unwrap())),
-        Witness::MerklePath(Some(merkle_path.try_into().unwrap())),
-        Witness::Base(Some(sig_secret.0)),
+        Witness::Base(Value::known(secret.0)),
+        Witness::Base(Value::known(serial)),
+        Witness::Base(Value::known(pallas::Base::from(value))),
+        Witness::Base(Value::known(token_id)),
+        Witness::Base(Value::known(coin_blind)),
+        Witness::Scalar(Value::known(value_blind)),
+        Witness::Scalar(Value::known(token_blind)),
+        Witness::Uint32(Value::known(leaf_pos.try_into().unwrap())),
+        Witness::MerklePath(Value::known(merkle_path.try_into().unwrap())),
+        Witness::Base(Value::known(sig_secret.0)),
     ];
 
     // Create the public inputs

+ 9 - 8
tests/mint_proof.rs

@@ -13,6 +13,7 @@ use darkfi::{
     Result,
 };
 use halo2_gadgets::poseidon::primitives as poseidon;
+use halo2_proofs::circuit::Value;
 use pasta_curves::{
     arithmetic::CurveAffine,
     group::{ff::Field, Curve},
@@ -41,14 +42,14 @@ fn mint_proof() -> Result<()> {
     let coords = public_key.0.to_affine().coordinates().unwrap();
 
     let prover_witnesses = vec![
-        Witness::Base(Some(*coords.x())),
-        Witness::Base(Some(*coords.y())),
-        Witness::Base(Some(pallas::Base::from(value))),
-        Witness::Base(Some(token_id)),
-        Witness::Base(Some(serial)),
-        Witness::Base(Some(coin_blind)),
-        Witness::Scalar(Some(value_blind)),
-        Witness::Scalar(Some(token_blind)),
+        Witness::Base(Value::known(*coords.x())),
+        Witness::Base(Value::known(*coords.y())),
+        Witness::Base(Value::known(pallas::Base::from(value))),
+        Witness::Base(Value::known(token_id)),
+        Witness::Base(Value::known(serial)),
+        Witness::Base(Value::known(coin_blind)),
+        Witness::Scalar(Value::known(value_blind)),
+        Witness::Scalar(Value::known(token_blind)),
     ];
 
     // Create the public inputs