Procházet zdrojové kódy

zk/vm: Remove old VM code and move newest to "vm" module.

parazyd před 4 roky
rodič
revize
6cab96a28c
13 změnil soubory, kde provedl 137 přidání a 1090 odebrání
  1. 1 1
      .gitignore
  2. 1 11
      Cargo.toml
  3. 1 1
      Makefile
  4. 132 88
      example/vm.rs
  5. 0 158
      example/vm2.rs
  6. 0 177
      example/vm_burn.rs
  7. 1 1
      src/crypto/mod.rs
  8. 1 3
      src/zk/mod.rs
  9. 0 545
      src/zk/vm.rs
  10. 0 0
      src/zk/vm/mod.rs
  11. 0 0
      src/zk/vm/vm.rs
  12. 0 0
      src/zk/vm/vm_stack.rs
  13. 0 105
      src/zk/vm_serial.rs

+ 1 - 1
.gitignore

@@ -2,7 +2,7 @@
 *.sage.py
 target/*
 
-/proofs/*.bin
+/proof/*.bin
 
 /zkas
 /drk

+ 1 - 11
Cargo.toml

@@ -242,12 +242,7 @@ required-features = ["async-runtime", "tui"]
 [[example]]
 name = "vm"
 path = "example/vm.rs"
-required-features = ["crypto"]
-
-[[example]]
-name = "vm_burn"
-path = "example/vm_burn.rs"
-required-features = ["crypto"]
+required-features = ["cli", "zkvm"]
 
 [[example]]
 name = "tx"
@@ -258,8 +253,3 @@ required-features = ["node"]
 name = "tree"
 path = "example/tree.rs"
 required-features = ["crypto"]
-
-[[example]]
-name = "vm2"
-path = "example/vm2.rs"
-required-features = ["cli", "zkvm"]

+ 1 - 1
Makefile

@@ -42,7 +42,7 @@ test-tx:
 test-vm: zkas
 	./zkas proof/mint.zk
 	./zkas proof/burn.zk
-	$(CARGO) run --release --features=cli,zkvm --example vm2
+	$(CARGO) run --release --features=cli,zkvm --example vm
 
 clean:
 	rm -f $(BINS)

+ 132 - 88
example/vm.rs

@@ -1,114 +1,158 @@
-use halo2::dev::MockProver;
-use halo2_gadgets::{
-    primitives,
-    primitives::poseidon::{ConstantLength, P128Pow5T3},
-};
-use pasta_curves::{
+use halo2::{
     arithmetic::{CurveAffine, Field},
-    group::{Curve, Group},
-    pallas,
+    dev::MockProver,
+};
+use halo2_gadgets::primitives::{
+    poseidon,
+    poseidon::{ConstantLength, P128Pow5T3},
 };
+use incrementalmerkletree::{bridgetree::BridgeTree, Frontier, Tree};
+use log::info;
+use pasta_curves::{group::Curve, pallas};
 use rand::rngs::OsRng;
-use std::{collections::HashMap, fs::File, time::Instant};
+use simplelog::{ColorChoice, LevelFilter, TermLogger, TerminalMode};
 
 use darkfi::{
     crypto::{
-        constants::OrchardFixedBases,
-        proof::{Proof, ProvingKey, VerifyingKey},
-        util::pedersen_commitment_u64,
+        keypair::{PublicKey, SecretKey},
+        merkle_node::MerkleNode,
+        mint_proof::MintRevealedValues,
+        spend_proof::SpendRevealedValues,
     },
-    util::serial::Decodable,
-    zk::vm,
-    Error,
+    zk::vm::{Witness, ZkCircuit},
+    zkas::decoder::ZkBinary,
+    Result,
 };
 
-fn main() -> std::result::Result<(), Error> {
-    // The number of rows in our circuit cannot exceed 2^k
-    let k: u32 = 11;
-
-    let start = Instant::now();
-    let file = File::open("../proof/mint.zk.bin")?;
-    let zkbin = vm::ZkBinary::decode(file)?;
-    for contract_name in zkbin.contracts.keys() {
-        println!("Loaded '{}' contract.", contract_name);
-    }
-    println!("Load time: [{:?}]", start.elapsed());
-
-    let contract = &zkbin.contracts["Mint"];
-
-    //contract.witness_base(...);
-    //contract.witness_base(...);
-    //contract.witness_base(...);
-
-    let pubkey = pallas::Point::random(&mut OsRng);
-    let coords = pubkey.to_affine().coordinates().unwrap();
-
-    let value = 110;
-    let asset = 1;
+fn mint_proof() -> Result<()> {
+    let bincode = include_bytes!("../proof/mint.zk.bin");
+    let zkbin = ZkBinary::decode(bincode)?;
 
+    let value = 42;
+    let token_id = pallas::Base::from(22);
     let value_blind = pallas::Scalar::random(&mut OsRng);
-    let asset_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 mut coin = pallas::Base::zero();
-
-    let messages = [
-        [*coords.x(), *coords.y()],
-        [pallas::Base::from(value), pallas::Base::from(asset)],
-        [serial, coin_blind],
+    let public_key = PublicKey::random(&mut OsRng);
+
+    let revealed = MintRevealedValues::compute(
+        value,
+        token_id,
+        value_blind,
+        token_blind,
+        serial,
+        coin_blind,
+        public_key,
+    );
+
+    let pk_coords = public_key.0.to_affine().coordinates().unwrap();
+    let witnesses = vec![
+        Witness::Base(*pk_coords.x()),
+        Witness::Base(*pk_coords.y()),
+        Witness::Base(pallas::Base::from(value)),
+        Witness::Base(token_id),
+        Witness::Base(serial),
+        Witness::Base(coin_blind),
+        Witness::Scalar(value_blind),
+        Witness::Scalar(token_blind),
     ];
 
-    for msg in messages.iter() {
-        coin += primitives::poseidon::Hash::init(P128Pow5T3, ConstantLength::<2>).hash(*msg);
-    }
-
-    let _coin2 = primitives::poseidon::Hash::init(P128Pow5T3, ConstantLength::<2>)
-        .hash([*coords.x(), *coords.y()]);
-
-    let value_commit = pedersen_commitment_u64(value, value_blind);
-    let value_coords = value_commit.to_affine().coordinates().unwrap();
-
-    let asset_commit = pedersen_commitment_u64(asset, asset_blind);
-    let asset_coords = asset_commit.to_affine().coordinates().unwrap();
-
-    let public_inputs =
-        vec![coin, *value_coords.x(), *value_coords.y(), *asset_coords.x(), *asset_coords.y()];
+    let circuit = ZkCircuit::new(witnesses, zkbin);
+    let prover = MockProver::run(11, &circuit, vec![revealed.make_outputs().to_vec()]).unwrap();
+    assert_eq!(prover.verify(), Ok(()));
 
-    let mut const_fixed_points = HashMap::new();
-    const_fixed_points.insert("VALUE_COMMIT_VALUE".to_string(), OrchardFixedBases::ValueCommitV);
-    const_fixed_points.insert("VALUE_COMMIT_RANDOM".to_string(), OrchardFixedBases::ValueCommitR);
+    Ok(())
+}
 
-    let mut circuit = vm::ZkCircuit::new(const_fixed_points, &zkbin.constants, contract);
-    let empty_circuit = circuit.clone();
+fn burn_proof() -> Result<()> {
+    let bincode = include_bytes!("../proof/burn.zk.bin");
+    let zkbin = ZkBinary::decode(bincode)?;
 
-    circuit.witness_base("pub_x", *coords.x())?;
-    circuit.witness_base("pub_y", *coords.y())?;
-    circuit.witness_base("value", pallas::Base::from(value))?;
-    circuit.witness_base("asset", pallas::Base::from(asset))?;
-    circuit.witness_base("serial", serial)?;
-    circuit.witness_base("coin_blind", coin_blind)?;
-    circuit.witness_scalar("value_blind", value_blind)?;
-    circuit.witness_scalar("asset_blind", asset_blind)?;
+    let value = 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 secret = SecretKey::random(&mut OsRng);
+    let sig_secret = SecretKey::random(&mut OsRng);
+
+    let mut tree = BridgeTree::<MerkleNode, 32>::new(100);
+
+    let random_coin_1 = pallas::Base::random(&mut OsRng);
+    tree.append(&MerkleNode(random_coin_1));
+    tree.witness();
+    let random_coin_2 = pallas::Base::random(&mut OsRng);
+    tree.append(&MerkleNode(random_coin_2));
+
+    let coin = {
+        let coords = PublicKey::from_secret(secret).0.to_affine().coordinates().unwrap();
+        let messages =
+            [*coords.x(), *coords.y(), pallas::Base::from(value), token_id, serial, coin_blind];
+
+        poseidon::Hash::init(P128Pow5T3, ConstantLength::<6>).hash(messages)
+    };
+
+    tree.append(&MerkleNode(coin));
+    tree.witness();
+
+    let random_coin_3 = pallas::Base::random(&mut OsRng);
+    tree.append(&MerkleNode(random_coin_3));
+    tree.witness();
+
+    let (leaf_position, merkle_path) = tree.authentication_path(&MerkleNode(coin)).unwrap();
+
+    let revealed = SpendRevealedValues::compute(
+        value,
+        token_id,
+        value_blind,
+        token_blind,
+        serial,
+        coin_blind,
+        secret,
+        leaf_position,
+        merkle_path.clone(),
+        sig_secret,
+    );
+
+    // Why are these types not matched in halo2 gadgets?
+    let leaf_pos: u64 = leaf_position.into();
+    let leaf_pos = leaf_pos as u32;
+
+    let witnesses = vec![
+        Witness::Base(secret.0),
+        Witness::Base(serial),
+        Witness::Base(pallas::Base::from(value)),
+        Witness::Base(token_id),
+        Witness::Base(coin_blind),
+        Witness::Scalar(value_blind),
+        Witness::Scalar(token_blind),
+        Witness::Uint32(leaf_pos),
+        Witness::MerklePath(merkle_path),
+        Witness::Base(sig_secret.0),
+    ];
 
-    // Valid MockProver
-    let prover = MockProver::run(k, &circuit, vec![public_inputs.clone()]).unwrap();
+    let circuit = ZkCircuit::new(witnesses, zkbin);
+    let prover = MockProver::run(11, &circuit, vec![revealed.make_outputs().to_vec()])?;
     assert_eq!(prover.verify(), Ok(()));
 
-    // Actual ZK proof
-    let start = Instant::now();
-    let vk = VerifyingKey::build(k, empty_circuit.clone());
-    let pk = ProvingKey::build(k, empty_circuit.clone());
-    println!("\nSetup: [{:?}]", start.elapsed());
+    Ok(())
+}
+
+fn main() -> Result<()> {
+    TermLogger::init(
+        LevelFilter::Debug,
+        simplelog::Config::default(),
+        TerminalMode::Mixed,
+        ColorChoice::Auto,
+    )?;
 
-    let start = Instant::now();
-    let proof = Proof::create(&pk, &[circuit], &public_inputs).unwrap();
-    println!("Prove: [{:?}]", start.elapsed());
+    info!("Executing Mint proof");
+    mint_proof()?;
 
-    let start = Instant::now();
-    assert!(proof.verify(&vk, &public_inputs).is_ok());
-    println!("Verify: [{:?}]", start.elapsed());
+    info!("Executing Burn proof");
+    burn_proof()?;
 
     Ok(())
 }

+ 0 - 158
example/vm2.rs

@@ -1,158 +0,0 @@
-use halo2::{
-    arithmetic::{CurveAffine, Field},
-    dev::MockProver,
-};
-use halo2_gadgets::primitives::{
-    poseidon,
-    poseidon::{ConstantLength, P128Pow5T3},
-};
-use incrementalmerkletree::{bridgetree::BridgeTree, Frontier, Tree};
-use log::info;
-use pasta_curves::{group::Curve, pallas};
-use rand::rngs::OsRng;
-use simplelog::{ColorChoice, LevelFilter, TermLogger, TerminalMode};
-
-use darkfi::{
-    crypto::{
-        keypair::{PublicKey, SecretKey},
-        merkle_node::MerkleNode,
-        mint_proof::MintRevealedValues,
-        spend_proof::SpendRevealedValues,
-    },
-    zk::vm2::{Witness, ZkCircuit},
-    zkas::decoder::ZkBinary,
-    Result,
-};
-
-fn mint_proof() -> Result<()> {
-    let bincode = include_bytes!("../proofs/mint.zk.bin");
-    let zkbin = ZkBinary::decode(bincode)?;
-
-    let value = 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 revealed = MintRevealedValues::compute(
-        value,
-        token_id,
-        value_blind,
-        token_blind,
-        serial,
-        coin_blind,
-        public_key,
-    );
-
-    let pk_coords = public_key.0.to_affine().coordinates().unwrap();
-    let witnesses = vec![
-        Witness::Base(*pk_coords.x()),
-        Witness::Base(*pk_coords.y()),
-        Witness::Base(pallas::Base::from(value)),
-        Witness::Base(token_id),
-        Witness::Base(serial),
-        Witness::Base(coin_blind),
-        Witness::Scalar(value_blind),
-        Witness::Scalar(token_blind),
-    ];
-
-    let circuit = ZkCircuit::new(witnesses, zkbin);
-    let prover = MockProver::run(11, &circuit, vec![revealed.make_outputs().to_vec()]).unwrap();
-    assert_eq!(prover.verify(), Ok(()));
-
-    Ok(())
-}
-
-fn burn_proof() -> Result<()> {
-    let bincode = include_bytes!("../proofs/burn.zk.bin");
-    let zkbin = ZkBinary::decode(bincode)?;
-
-    let value = 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 secret = SecretKey::random(&mut OsRng);
-    let sig_secret = SecretKey::random(&mut OsRng);
-
-    let mut tree = BridgeTree::<MerkleNode, 32>::new(100);
-
-    let random_coin_1 = pallas::Base::random(&mut OsRng);
-    tree.append(&MerkleNode(random_coin_1));
-    tree.witness();
-    let random_coin_2 = pallas::Base::random(&mut OsRng);
-    tree.append(&MerkleNode(random_coin_2));
-
-    let coin = {
-        let coords = PublicKey::from_secret(secret).0.to_affine().coordinates().unwrap();
-        let messages =
-            [*coords.x(), *coords.y(), pallas::Base::from(value), token_id, serial, coin_blind];
-
-        poseidon::Hash::init(P128Pow5T3, ConstantLength::<6>).hash(messages)
-    };
-
-    tree.append(&MerkleNode(coin));
-    tree.witness();
-
-    let random_coin_3 = pallas::Base::random(&mut OsRng);
-    tree.append(&MerkleNode(random_coin_3));
-    tree.witness();
-
-    let (leaf_position, merkle_path) = tree.authentication_path(&MerkleNode(coin)).unwrap();
-
-    let revealed = SpendRevealedValues::compute(
-        value,
-        token_id,
-        value_blind,
-        token_blind,
-        serial,
-        coin_blind,
-        secret,
-        leaf_position,
-        merkle_path.clone(),
-        sig_secret,
-    );
-
-    // Why are these types not matched in halo2 gadgets?
-    let leaf_pos: u64 = leaf_position.into();
-    let leaf_pos = leaf_pos as u32;
-
-    let witnesses = vec![
-        Witness::Base(secret.0),
-        Witness::Base(serial),
-        Witness::Base(pallas::Base::from(value)),
-        Witness::Base(token_id),
-        Witness::Base(coin_blind),
-        Witness::Scalar(value_blind),
-        Witness::Scalar(token_blind),
-        Witness::Uint32(leaf_pos),
-        Witness::MerklePath(merkle_path),
-        Witness::Base(sig_secret.0),
-    ];
-
-    let circuit = ZkCircuit::new(witnesses, zkbin);
-    let prover = MockProver::run(11, &circuit, vec![revealed.make_outputs().to_vec()])?;
-    assert_eq!(prover.verify(), Ok(()));
-
-    Ok(())
-}
-
-fn main() -> Result<()> {
-    TermLogger::init(
-        LevelFilter::Debug,
-        simplelog::Config::default(),
-        TerminalMode::Mixed,
-        ColorChoice::Auto,
-    )?;
-
-    info!("Executing Mint proof");
-    mint_proof()?;
-
-    info!("Executing Burn proof");
-    burn_proof()?;
-
-    Ok(())
-}

+ 0 - 177
example/vm_burn.rs

@@ -1,177 +0,0 @@
-use std::iter;
-
-use halo2::dev::MockProver;
-use halo2_gadgets::{
-    ecc::FixedPoints,
-    primitives,
-    primitives::{
-        poseidon::{ConstantLength, P128Pow5T3},
-        sinsemilla::S_PERSONALIZATION,
-    },
-};
-use pasta_curves::{
-    arithmetic::{CurveAffine, Field},
-    group::{ff::PrimeFieldBits, Curve},
-    pallas,
-};
-use rand::rngs::OsRng;
-use std::{collections::HashMap, fs::File, time::Instant};
-
-use darkfi::{
-    crypto::{
-        constants::{
-            sinsemilla::{i2lebsp, MERKLE_CRH_PERSONALIZATION},
-            OrchardFixedBases,
-        },
-        proof::{Proof, ProvingKey, VerifyingKey},
-        util::pedersen_commitment_u64,
-    },
-    util::serial::Decodable,
-    zk::vm,
-    Error,
-};
-
-fn root(path: [pallas::Base; 32], leaf_pos: u32, leaf: pallas::Base) -> pallas::Base {
-    let domain = primitives::sinsemilla::HashDomain::new(MERKLE_CRH_PERSONALIZATION);
-
-    let pos_bool = i2lebsp::<32>(leaf_pos as u64);
-
-    let mut node = leaf;
-    for (l, (sibling, pos)) in path.iter().zip(pos_bool.iter()).enumerate() {
-        let (left, right) = if *pos { (*sibling, node) } else { (node, *sibling) };
-
-        let l_star = i2lebsp::<10>(l as u64);
-        let left: Vec<_> = left.to_le_bits().iter().by_val().take(255).collect();
-        let right: Vec<_> = right.to_le_bits().iter().by_val().take(255).collect();
-
-        let mut message = l_star.to_vec();
-        message.extend_from_slice(&left);
-        message.extend_from_slice(&right);
-
-        node = domain.hash(message.into_iter()).unwrap();
-    }
-    node
-}
-
-fn main() -> std::result::Result<(), Error> {
-    // The number of rows in our circuit cannot exceed 2^k
-    let k: u32 = 11;
-
-    let start = Instant::now();
-    let file = File::open("../proof/burn.zk.bin")?;
-    let zkbin = vm::ZkBinary::decode(file)?;
-    for contract_name in zkbin.contracts.keys() {
-        println!("Loaded '{}' contract.", contract_name);
-    }
-    println!("Load time: [{:?}]", start.elapsed());
-
-    let contract = &zkbin.contracts["Burn"];
-
-    //contract.witness_base(...);
-    //contract.witness_base(...);
-    //contract.witness_base(...);
-
-    let secret = pallas::Scalar::random(&mut OsRng);
-    let serial = pallas::Base::random(&mut OsRng);
-
-    let value = 110;
-    let asset = 1;
-
-    // Nullifier = poseidon(sinsemilla(secret_key), serial)
-    let domain = primitives::sinsemilla::HashDomain::new(S_PERSONALIZATION);
-    let bits_secretkey: Vec<bool> = secret.to_le_bits().iter().by_val().collect();
-    let hashed_secret_key = domain.hash(iter::empty().chain(bits_secretkey)).unwrap();
-
-    let nullifier = [hashed_secret_key, serial];
-    let nullifier =
-        primitives::poseidon::Hash::init(P128Pow5T3, ConstantLength::<2>).hash(nullifier);
-
-    // Public key derivation
-    let public_key = OrchardFixedBases::SpendAuthG.generator() * secret;
-    let coords = public_key.to_affine().coordinates().unwrap();
-
-    // Construct Coin
-    let mut coin = pallas::Base::zero();
-    let coin_blind = pallas::Base::random(&mut OsRng);
-    let messages = [
-        [*coords.x(), *coords.y()],
-        [pallas::Base::from(value), pallas::Base::from(asset)],
-        [serial, coin_blind],
-    ];
-
-    for msg in messages.iter() {
-        let hash = primitives::poseidon::Hash::init(P128Pow5T3, ConstantLength::<2>).hash(*msg);
-        coin += hash;
-    }
-
-    // Merkle root
-    let leaf = pallas::Base::random(&mut OsRng);
-    let leaf_pos = rand::random::<u32>();
-    let path: Vec<_> = (0..32).map(|_| pallas::Base::random(&mut OsRng)).collect();
-    let merkle_root = root(path.clone().try_into().unwrap(), leaf_pos, leaf);
-
-    // Value and asset commitments
-    let value_blind = pallas::Scalar::random(&mut OsRng);
-    let asset_blind = pallas::Scalar::random(&mut OsRng);
-    let value_commit = pedersen_commitment_u64(value, value_blind);
-    let asset_commit = pedersen_commitment_u64(asset, asset_blind);
-
-    let value_coords = value_commit.to_affine().coordinates().unwrap();
-    let asset_coords = asset_commit.to_affine().coordinates().unwrap();
-
-    // Derive signature public key from signature secret key
-    let sig_secret = pallas::Scalar::random(&mut OsRng);
-    let sig_pubkey = OrchardFixedBases::SpendAuthG.generator() * sig_secret;
-    let sig_coords = sig_pubkey.to_affine().coordinates().unwrap();
-
-    let public_inputs = vec![
-        nullifier,
-        merkle_root,
-        *value_coords.x(),
-        *value_coords.y(),
-        *asset_coords.x(),
-        *asset_coords.y(),
-        *sig_coords.x(),
-        *sig_coords.y(),
-    ];
-
-    //
-
-    let mut const_fixed_points = HashMap::new();
-    const_fixed_points.insert("VALUE_COMMIT_VALUE".to_string(), OrchardFixedBases::ValueCommitV);
-    const_fixed_points.insert("VALUE_COMMIT_RANDOM".to_string(), OrchardFixedBases::ValueCommitR);
-    const_fixed_points.insert("SPEND_AUTH_G".to_string(), OrchardFixedBases::SpendAuthG);
-
-    let mut circuit = vm::ZkCircuit::new(const_fixed_points, &zkbin.constants, contract);
-    let empty_circuit = circuit.clone();
-
-    circuit.witness_base("secret", hashed_secret_key)?;
-    circuit.witness_base("serial", serial)?;
-    circuit.witness_merkle_path("path", leaf_pos, path.try_into().unwrap())?;
-    circuit.witness_base("leaf", leaf)?;
-    circuit.witness_base("value", pallas::Base::from(value))?;
-    circuit.witness_base("asset", pallas::Base::from(asset))?;
-    circuit.witness_scalar("value_blind", value_blind)?;
-    circuit.witness_scalar("asset_blind", asset_blind)?;
-    circuit.witness_scalar("sig_secret", sig_secret)?;
-
-    // Valid MockProver
-    let prover = MockProver::run(k, &circuit, vec![public_inputs.clone()]).unwrap();
-    assert_eq!(prover.verify(), Ok(()));
-
-    // Actual ZK proof
-    let start = Instant::now();
-    let vk = VerifyingKey::build(k, empty_circuit.clone());
-    let pk = ProvingKey::build(k, empty_circuit.clone());
-    println!("\nSetup: [{:?}]", start.elapsed());
-
-    let start = Instant::now();
-    let proof = Proof::create(&pk, &[circuit], &public_inputs).unwrap();
-    println!("Prove: [{:?}]", start.elapsed());
-
-    let start = Instant::now();
-    assert!(proof.verify(&vk, &public_inputs).is_ok());
-    println!("Verify: [{:?}]", start.elapsed());
-
-    Ok(())
-}

+ 1 - 1
src/crypto/mod.rs

@@ -4,7 +4,7 @@ pub mod coin;
 pub mod constants;
 pub mod diffie_hellman;
 pub mod keypair;
-pub mod loader;
+//pub mod loader;
 pub mod merkle_node;
 pub mod mint_proof;
 pub mod note;

+ 1 - 3
src/zk/mod.rs

@@ -1,6 +1,4 @@
 pub mod circuit;
-pub mod vm;
-pub mod vm_serial;
 
 #[cfg(feature = "zkvm")]
-pub mod vm2;
+pub mod vm;

+ 0 - 545
src/zk/vm.rs

@@ -1,545 +0,0 @@
-use std::{collections::HashMap, convert::TryInto};
-
-use halo2::{
-    circuit::{Layouter, SimpleFloorPlanner},
-    plonk,
-    plonk::{Advice, Circuit, Column, ConstraintSystem, Instance as InstanceColumn, Selector},
-};
-use halo2_gadgets::{
-    ecc::{
-        chip::{EccChip, EccConfig},
-        FixedPoint,
-    },
-    poseidon::{Hash as PoseidonHash, Pow5T3Chip as PoseidonChip, Pow5T3Config as PoseidonConfig},
-    primitives::poseidon::{ConstantLength, P128Pow5T3},
-    sinsemilla::{
-        chip::{SinsemillaChip, SinsemillaConfig},
-        merkle::{
-            chip::{MerkleChip, MerkleConfig},
-            MerklePath,
-        },
-    },
-    utilities::{
-        lookup_range_check::LookupRangeCheckConfig, CellValue, UtilitiesInstructions, Var,
-    },
-};
-use pasta_curves::pallas;
-
-use crate::{
-    crypto::{
-        arith_chip::{ArithmeticChip, ArithmeticChipConfig},
-        constants::{
-            sinsemilla::{OrchardCommitDomains, OrchardHashDomains},
-            OrchardFixedBases,
-        },
-    },
-    error::{Error, Result},
-};
-
-#[derive(Clone, Debug, PartialEq)]
-pub enum ZkType {
-    Base,
-    Scalar,
-    EcPoint,
-    EcFixedPoint,
-    MerklePath,
-}
-
-type ArgIdx = usize;
-
-#[derive(Clone, Debug)]
-pub enum ZkFunctionCall {
-    PoseidonHash(ArgIdx, ArgIdx),
-    Add(ArgIdx, ArgIdx),
-    ConstrainInstance(ArgIdx),
-    EcMulShort(ArgIdx, ArgIdx),
-    EcMul(ArgIdx, ArgIdx),
-    EcAdd(ArgIdx, ArgIdx),
-    EcGetX(ArgIdx),
-    EcGetY(ArgIdx),
-    CalculateMerkleRoot(ArgIdx, ArgIdx),
-}
-
-pub struct ZkBinary {
-    pub constants: Vec<(String, ZkType)>,
-    pub contracts: HashMap<String, ZkContract>,
-}
-
-#[derive(Clone, Debug)]
-pub struct ZkContract {
-    pub witness: Vec<(String, ZkType)>,
-    pub code: Vec<ZkFunctionCall>,
-}
-
-// These is the actual structures below which interpret the structures
-// deserialized above.
-
-#[derive(Clone, Debug)]
-pub struct MintConfig {
-    pub primary: Column<InstanceColumn>,
-    pub q_add: Selector,
-    pub advices: [Column<Advice>; 10],
-    pub ecc_config: EccConfig,
-    pub merkle_config_1: MerkleConfig<OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases>,
-    pub merkle_config_2: MerkleConfig<OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases>,
-    pub sinsemilla_config_1:
-        SinsemillaConfig<OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases>,
-    pub sinsemilla_config_2:
-        SinsemillaConfig<OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases>,
-    pub poseidon_config: PoseidonConfig<pallas::Base>,
-    pub arith_config: ArithmeticChipConfig,
-}
-
-impl MintConfig {
-    pub fn ecc_chip(&self) -> EccChip<OrchardFixedBases> {
-        EccChip::construct(self.ecc_config.clone())
-    }
-
-    pub fn poseidon_chip(&self) -> PoseidonChip<pallas::Base> {
-        PoseidonChip::construct(self.poseidon_config.clone())
-    }
-
-    pub fn arithmetic_chip(&self) -> ArithmeticChip {
-        ArithmeticChip::construct(self.arith_config.clone())
-    }
-
-    fn merkle_chip_1(
-        &self,
-    ) -> MerkleChip<OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases> {
-        MerkleChip::construct(self.merkle_config_1.clone())
-    }
-
-    fn merkle_chip_2(
-        &self,
-    ) -> MerkleChip<OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases> {
-        MerkleChip::construct(self.merkle_config_2.clone())
-    }
-}
-
-#[derive(Clone, Debug)]
-pub struct ZkCircuit<'a> {
-    pub const_fixed_points: HashMap<String, OrchardFixedBases>,
-    pub constants: &'a [(String, ZkType)],
-    pub contract: &'a ZkContract,
-    // For each type create a separate stack
-    pub witness_base: HashMap<String, Option<pallas::Base>>,
-    pub witness_scalar: HashMap<String, Option<pallas::Scalar>>,
-    pub witness_merkle_path: HashMap<String, (Option<u32>, Option<[pallas::Base; 32]>)>,
-}
-
-impl<'a> ZkCircuit<'a> {
-    pub fn new(
-        const_fixed_points: HashMap<String, OrchardFixedBases>,
-        constants: &'a [(String, ZkType)],
-        contract: &'a ZkContract,
-    ) -> Self {
-        let mut witness_base = HashMap::new();
-        let mut witness_scalar = HashMap::new();
-        let mut witness_merkle_path = HashMap::new();
-        for (name, type_id) in contract.witness.iter() {
-            match type_id {
-                ZkType::Base => {
-                    witness_base.insert(name.clone(), None);
-                }
-                ZkType::Scalar => {
-                    witness_scalar.insert(name.clone(), None);
-                }
-                ZkType::MerklePath => {
-                    witness_merkle_path.insert(name.clone(), (None, None));
-                }
-                _ => {
-                    unimplemented!();
-                }
-            }
-        }
-
-        Self {
-            const_fixed_points,
-            constants,
-            contract,
-            witness_base,
-            witness_scalar,
-            witness_merkle_path,
-        }
-    }
-
-    pub fn witness_base(&mut self, name: &str, value: pallas::Base) -> Result<()> {
-        for (variable, type_id) in self.contract.witness.iter() {
-            if name != variable {
-                continue
-            }
-            if *type_id != ZkType::Base {
-                return Err(Error::InvalidParamType)
-            }
-            *self.witness_base.get_mut(name).unwrap() = Some(value);
-            return Ok(())
-        }
-        Err(Error::InvalidParamName)
-    }
-
-    pub fn witness_scalar(&mut self, name: &str, value: pallas::Scalar) -> Result<()> {
-        for (variable, type_id) in self.contract.witness.iter() {
-            if name != variable {
-                continue
-            }
-            if *type_id != ZkType::Scalar {
-                return Err(Error::InvalidParamType)
-            }
-            *self.witness_scalar.get_mut(name).unwrap() = Some(value);
-            return Ok(())
-        }
-        Err(Error::InvalidParamName)
-    }
-
-    pub fn witness_merkle_path(
-        &mut self,
-        name: &str,
-        leaf_pos: u32,
-        path: [pallas::Base; 32],
-    ) -> Result<()> {
-        for (variable, type_id) in self.contract.witness.iter() {
-            if name != variable {
-                continue
-            }
-            if *type_id != ZkType::MerklePath {
-                return Err(Error::InvalidParamType)
-            }
-            *self.witness_merkle_path.get_mut(name).unwrap() = (Some(leaf_pos), Some(path));
-            return Ok(())
-        }
-        Err(Error::InvalidParamName)
-    }
-}
-
-impl<'a> UtilitiesInstructions<pallas::Base> for ZkCircuit<'a> {
-    type Var = CellValue<pallas::Base>;
-}
-
-impl<'a> Circuit<pallas::Base> for ZkCircuit<'a> {
-    type Config = MintConfig;
-    type FloorPlanner = SimpleFloorPlanner;
-
-    fn without_witnesses(&self) -> Self {
-        Self {
-            const_fixed_points: self.const_fixed_points.clone(),
-            constants: self.constants,
-            contract: self.contract,
-            witness_base: self.witness_base.keys().map(|key| (key.clone(), None)).collect(),
-            witness_scalar: self.witness_scalar.keys().map(|key| (key.clone(), None)).collect(),
-            witness_merkle_path: self
-                .witness_scalar
-                .keys()
-                .map(|key| (key.clone(), (None, None)))
-                .collect(),
-        }
-    }
-
-    fn configure(meta: &mut ConstraintSystem<pallas::Base>) -> Self::Config {
-        let advices = [
-            meta.advice_column(),
-            meta.advice_column(),
-            meta.advice_column(),
-            meta.advice_column(),
-            meta.advice_column(),
-            meta.advice_column(),
-            meta.advice_column(),
-            meta.advice_column(),
-            meta.advice_column(),
-            meta.advice_column(),
-        ];
-
-        let q_add = meta.selector();
-
-        let table_idx = meta.lookup_table_column();
-        let lookup = (table_idx, meta.lookup_table_column(), meta.lookup_table_column());
-
-        let primary = meta.instance_column();
-
-        meta.enable_equality(primary.into());
-
-        for advice in advices.iter() {
-            meta.enable_equality((*advice).into());
-        }
-
-        let lagrange_coeffs = [
-            meta.fixed_column(),
-            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_b = lagrange_coeffs[5..8].try_into().unwrap();
-
-        meta.enable_constant(lagrange_coeffs[0]);
-
-        let range_check = LookupRangeCheckConfig::configure(meta, advices[9], table_idx);
-
-        let ecc_config = EccChip::<OrchardFixedBases>::configure(
-            meta,
-            advices,
-            lagrange_coeffs,
-            range_check.clone(),
-        );
-
-        let poseidon_config = PoseidonChip::configure(
-            meta,
-            P128Pow5T3,
-            advices[6..9].try_into().unwrap(),
-            advices[5],
-            rc_a,
-            rc_b,
-        );
-
-        let arith_config = ArithmeticChip::configure(meta);
-
-        // Configuration for a Sinsemilla hash instantiation and a
-        // Merkle hash instantiation using this Sinsemilla instance.
-        // Since the Sinsemilla config uses only 5 advice columns,
-        // we can fit two instances side-by-side.
-        let (sinsemilla_config_1, merkle_config_1) = {
-            let sinsemilla_config_1 = SinsemillaChip::configure(
-                meta,
-                advices[..5].try_into().unwrap(),
-                advices[6],
-                lagrange_coeffs[0],
-                lookup,
-                range_check.clone(),
-            );
-            let merkle_config_1 = MerkleChip::configure(meta, sinsemilla_config_1.clone());
-            (sinsemilla_config_1, merkle_config_1)
-        };
-
-        // Configuration for a Sinsemilla hash instantiation and a
-        // Merkle hash instantiation using this Sinsemilla instance.
-        // Since the Sinsemilla config uses only 5 advice columns,
-        // we can fit two instances side-by-side.
-        let (sinsemilla_config_2, merkle_config_2) = {
-            let sinsemilla_config_2 = SinsemillaChip::configure(
-                meta,
-                advices[5..].try_into().unwrap(),
-                advices[7],
-                lagrange_coeffs[1],
-                lookup,
-                range_check,
-            );
-            let merkle_config_2 = MerkleChip::configure(meta, sinsemilla_config_2.clone());
-
-            (sinsemilla_config_2, merkle_config_2)
-        };
-
-        MintConfig {
-            primary,
-            q_add,
-            advices,
-            ecc_config,
-            merkle_config_1,
-            merkle_config_2,
-            sinsemilla_config_1,
-            sinsemilla_config_2,
-            poseidon_config,
-            arith_config,
-        }
-    }
-
-    fn synthesize(
-        &self,
-        config: Self::Config,
-        mut layouter: impl Layouter<pallas::Base>,
-    ) -> std::result::Result<(), plonk::Error> {
-        // Load the Sinsemilla generator lookup table used by the whole circuit.
-        SinsemillaChip::load(config.sinsemilla_config_1.clone(), &mut layouter)?;
-
-        let arith_chip = config.arithmetic_chip();
-
-        // Construct the ECC chip.
-        let ecc_chip = config.ecc_chip();
-
-        let mut stack_base = Vec::new();
-        let mut stack_scalar = Vec::new();
-        let mut stack_ec_point = Vec::new();
-        let mut stack_ec_fixed_point = Vec::new();
-        let mut stack_merkle_path = Vec::new();
-
-        // Load constants first onto the stacks
-        for (variable, type_id) in self.constants.iter() {
-            match *type_id {
-                ZkType::Base => {
-                    unimplemented!();
-                }
-                ZkType::Scalar => {
-                    unimplemented!();
-                }
-                ZkType::EcPoint => {
-                    unimplemented!();
-                }
-                ZkType::EcFixedPoint => {
-                    let value = self.const_fixed_points[variable];
-                    stack_ec_fixed_point.push(value);
-                }
-                ZkType::MerklePath => {
-                    unimplemented!();
-                }
-            }
-        }
-
-        // Push the witnesses onto the stacks in order
-        for (variable, type_id) in self.contract.witness.iter() {
-            match *type_id {
-                ZkType::Base => {
-                    let value = self.witness_base.get(variable).expect("witness base set");
-                    let value = self.load_private(
-                        layouter.namespace(|| "load pubkey x"),
-                        config.advices[0],
-                        *value,
-                    )?;
-                    stack_base.push(value);
-                }
-                ZkType::Scalar => {
-                    let value = self.witness_scalar.get(variable).expect("witness base set");
-                    stack_scalar.push(*value);
-                }
-                ZkType::EcPoint => {
-                    unimplemented!();
-                }
-                ZkType::EcFixedPoint => {
-                    unimplemented!();
-                }
-                ZkType::MerklePath => {
-                    let value =
-                        self.witness_merkle_path.get(variable).expect("witness merkle path set");
-                    stack_merkle_path.push(*value);
-                }
-            }
-        }
-
-        let mut current_instance_offset = 0;
-
-        for func_call in self.contract.code.iter() {
-            match func_call {
-                ZkFunctionCall::PoseidonHash(lhs_idx, rhs_idx) => {
-                    assert!(*lhs_idx < stack_base.len());
-                    assert!(*rhs_idx < stack_base.len());
-                    let poseidon_message = [stack_base[*lhs_idx], stack_base[*rhs_idx]];
-
-                    let poseidon_hasher = PoseidonHash::<_, _, P128Pow5T3, _, 3, 2>::init(
-                        config.poseidon_chip(),
-                        layouter.namespace(|| "Poseidon init"),
-                        ConstantLength::<2>,
-                    )?;
-
-                    let poseidon_output = poseidon_hasher
-                        .hash(layouter.namespace(|| "poseidon hash"), poseidon_message)?;
-
-                    let poseidon_output: CellValue<pallas::Base> = poseidon_output.inner().into();
-                    stack_base.push(poseidon_output);
-                }
-                ZkFunctionCall::Add(lhs_idx, rhs_idx) => {
-                    assert!(*lhs_idx < stack_base.len());
-                    assert!(*rhs_idx < stack_base.len());
-                    let (lhs, rhs) = (stack_base[*lhs_idx], stack_base[*rhs_idx]);
-                    let output =
-                        arith_chip.add(layouter.namespace(|| "arithmetic add"), lhs, rhs)?;
-                    stack_base.push(output);
-                }
-                ZkFunctionCall::ConstrainInstance(arg_idx) => {
-                    assert!(*arg_idx < stack_base.len());
-                    let arg = stack_base[*arg_idx];
-                    layouter.constrain_instance(
-                        arg.cell(),
-                        config.primary,
-                        current_instance_offset,
-                    )?;
-                    current_instance_offset += 1;
-                }
-                ZkFunctionCall::EcMulShort(value_idx, point_idx) => {
-                    assert!(*value_idx < stack_base.len());
-                    let value = stack_base[*value_idx];
-
-                    assert!(*point_idx < stack_ec_fixed_point.len());
-                    let fixed_point = stack_ec_fixed_point[*point_idx];
-
-                    // This constant one is used for multiplication
-                    let one = self.load_private(
-                        layouter.namespace(|| "load constant one"),
-                        config.advices[0],
-                        Some(pallas::Base::one()),
-                    )?;
-
-                    // v * G_1
-                    let (result, _) = {
-                        let value_commit_v = FixedPoint::from_inner(ecc_chip.clone(), fixed_point);
-                        value_commit_v.mul_short(
-                            layouter.namespace(|| "[value] ValueCommitV"),
-                            (value, one),
-                        )?
-                    };
-
-                    stack_ec_point.push(result);
-                }
-                ZkFunctionCall::EcMul(value_idx, point_idx) => {
-                    assert!(*value_idx < stack_scalar.len());
-                    let value = stack_scalar[*value_idx];
-
-                    assert!(*point_idx < stack_ec_fixed_point.len());
-                    let fixed_point = stack_ec_fixed_point[*point_idx];
-
-                    let (result, _) = {
-                        let value_commit_r = FixedPoint::from_inner(ecc_chip.clone(), fixed_point);
-                        value_commit_r
-                            .mul(layouter.namespace(|| "[value_blind] ValueCommitR"), value)?
-                    };
-
-                    stack_ec_point.push(result);
-                }
-                ZkFunctionCall::EcAdd(lhs_idx, rhs_idx) => {
-                    assert!(*lhs_idx < stack_ec_point.len());
-                    assert!(*rhs_idx < stack_ec_point.len());
-                    let lhs = &stack_ec_point[*lhs_idx];
-                    let rhs = &stack_ec_point[*rhs_idx];
-
-                    let result = lhs.add(layouter.namespace(|| "valuecommit"), rhs)?;
-                    stack_ec_point.push(result);
-                }
-                ZkFunctionCall::EcGetX(arg_idx) => {
-                    assert!(*arg_idx < stack_ec_point.len());
-                    let arg = &stack_ec_point[*arg_idx];
-                    let x = arg.inner().x();
-                    stack_base.push(x);
-                }
-                ZkFunctionCall::EcGetY(arg_idx) => {
-                    assert!(*arg_idx < stack_ec_point.len());
-                    let arg = &stack_ec_point[*arg_idx];
-                    let y = arg.inner().y();
-                    stack_base.push(y);
-                }
-                ZkFunctionCall::CalculateMerkleRoot(path_idx, leaf_idx) => {
-                    assert!(*path_idx < stack_merkle_path.len());
-                    assert!(*leaf_idx < stack_base.len());
-
-                    let (leaf_pos, path) = &stack_merkle_path[*path_idx];
-                    let leaf = &stack_base[*leaf_idx];
-
-                    let path = MerklePath {
-                        chip_1: config.merkle_chip_1(),
-                        chip_2: config.merkle_chip_2(),
-                        domain: OrchardHashDomains::MerkleCrh,
-                        leaf_pos: *leaf_pos,
-                        path: *path,
-                    };
-
-                    let root =
-                        path.calculate_root(layouter.namespace(|| "calculate root"), *leaf)?;
-                    stack_base.push(root);
-                }
-            }
-        }
-
-        // At this point we've enforced all of our public inputs.
-        Ok(())
-    }
-}

+ 0 - 0
src/zk/vm2/mod.rs → src/zk/vm/mod.rs


+ 0 - 0
src/zk/vm2/vm.rs → src/zk/vm/vm.rs


+ 0 - 0
src/zk/vm2/vm_stack.rs → src/zk/vm/vm_stack.rs


+ 0 - 105
src/zk/vm_serial.rs

@@ -1,105 +0,0 @@
-use std::io;
-
-use super::vm::{ZkBinary, ZkContract, ZkFunctionCall, ZkType};
-use crate::{
-    error::{Error, Result},
-    impl_vec,
-    util::serial::{Decodable, Encodable, ReadExt, VarInt},
-};
-
-impl_vec!((String, ZkType));
-impl_vec!(ZkFunctionCall);
-impl_vec!((String, ZkContract));
-
-impl Encodable for ZkType {
-    fn encode<S: io::Write>(&self, _s: S) -> Result<usize> {
-        unimplemented!();
-        //Ok(0)
-    }
-}
-
-impl Decodable for ZkType {
-    fn decode<D: io::Read>(mut d: D) -> Result<Self> {
-        let op_type = ReadExt::read_u8(&mut d)?;
-        match op_type {
-            0 => Ok(Self::Base),
-            1 => Ok(Self::Scalar),
-            2 => Ok(Self::EcPoint),
-            3 => Ok(Self::EcFixedPoint),
-            4 => Ok(Self::MerklePath),
-            _i => Err(Error::BadOperationType),
-        }
-    }
-}
-
-impl Encodable for ZkFunctionCall {
-    fn encode<S: io::Write>(&self, _s: S) -> Result<usize> {
-        unimplemented!();
-        //Ok(0)
-    }
-}
-
-impl Decodable for ZkFunctionCall {
-    fn decode<D: io::Read>(mut d: D) -> Result<Self> {
-        let func_id = ReadExt::read_u8(&mut d)?;
-        match func_id {
-            0 => Ok(Self::PoseidonHash(
-                ReadExt::read_u32(&mut d)? as usize,
-                ReadExt::read_u32(&mut d)? as usize,
-            )),
-            1 => Ok(Self::Add(
-                ReadExt::read_u32(&mut d)? as usize,
-                ReadExt::read_u32(&mut d)? as usize,
-            )),
-            2 => Ok(Self::ConstrainInstance(ReadExt::read_u32(&mut d)? as usize)),
-            3 => Ok(Self::EcMulShort(
-                ReadExt::read_u32(&mut d)? as usize,
-                ReadExt::read_u32(&mut d)? as usize,
-            )),
-            4 => Ok(Self::EcMul(
-                ReadExt::read_u32(&mut d)? as usize,
-                ReadExt::read_u32(&mut d)? as usize,
-            )),
-            5 => Ok(Self::EcAdd(
-                ReadExt::read_u32(&mut d)? as usize,
-                ReadExt::read_u32(&mut d)? as usize,
-            )),
-            6 => Ok(Self::EcGetX(ReadExt::read_u32(&mut d)? as usize)),
-            7 => Ok(Self::EcGetY(ReadExt::read_u32(&mut d)? as usize)),
-            8 => Ok(Self::CalculateMerkleRoot(
-                ReadExt::read_u32(&mut d)? as usize,
-                ReadExt::read_u32(&mut d)? as usize,
-            )),
-            _i => Err(Error::BadOperationType),
-        }
-    }
-}
-
-impl Encodable for ZkBinary {
-    fn encode<S: io::Write>(&self, _s: S) -> Result<usize> {
-        unimplemented!();
-        //Ok(0)
-    }
-}
-
-impl Decodable for ZkBinary {
-    fn decode<D: io::Read>(mut d: D) -> Result<Self> {
-        Ok(Self {
-            constants: Decodable::decode(&mut d)?,
-            contracts: Vec::<(String, ZkContract)>::decode(&mut d)?.into_iter().collect(),
-        })
-    }
-}
-
-impl Encodable for ZkContract {
-    fn encode<S: io::Write>(&self, _s: S) -> Result<usize> {
-        unimplemented!();
-        //Ok(0)
-    }
-}
-
-impl Decodable for ZkContract {
-    fn decode<D: io::Read>(mut d: D) -> Result<Self> {
-        Ok(Self { witness: Decodable::decode(&mut d)?, code: Decodable::decode(&mut d)? })
-    }
-}