Procházet zdrojové kódy

migrate vm2 to src/

narodnik před 4 roky
rodič
revize
c58e6a55d3
12 změnil soubory, kde provedl 239 přidání a 19 odebrání
  1. 1 0
      Cargo.lock
  2. 1 0
      Cargo.toml
  3. 0 2
      run_burn_zk.sh
  4. 0 2
      run_mint_zk.sh
  5. 15 11
      src/bin/vm2.rs
  6. 211 0
      src/bin/vm2_burn.rs
  7. 0 0
      src/crypto/arith_chip.rs
  8. 1 0
      src/crypto/mod.rs
  9. 2 0
      src/error.rs
  10. 2 0
      src/lib.rs
  11. 6 4
      src/vm2.rs
  12. 0 0
      src/vm2_serial.rs

+ 1 - 0
Cargo.lock

@@ -1282,6 +1282,7 @@ dependencies = [
  "bytes 1.1.0",
  "crypto_api_chachapoly",
  "dirs",
+ "failure",
  "futures",
  "group",
  "halo2",

+ 1 - 0
Cargo.toml

@@ -66,6 +66,7 @@ smol = "1.2.5"
 # Utilities
 anyhow = "1.0.44"
 dirs = "4.0.0"
+failure = "0.1.8"
 lazy_static = "1.4.0"
 log = "0.4.14"
 num_cpus = "1.13.0"

+ 0 - 2
example/halo2/doit_burn.sh → run_burn_zk.sh

@@ -1,9 +1,7 @@
 #!/bin/bash -x
-cd ../..
 python script/zkas.py proof/burn.zk --bincode
 du -sh proof/burn.zk.bin
 python script/zkas.py proof/burn.zk
 #python script/zkas.py proof/mint.zk
-cd example/halo2/
 cargo run --release --bin vm2_burn
 

+ 0 - 2
example/halo2/doit.sh → run_mint_zk.sh

@@ -1,9 +1,7 @@
 #!/bin/bash -x
-cd ../..
 python script/zkas.py proof/mint.zk --bincode
 du -sh proof/mint.zk.bin
 python script/zkas.py proof/mint.zk
 #python script/zkas.py proof/mint.zk
-cd example/halo2/
 cargo run --release --bin vm2
 

+ 15 - 11
example/halo2/src/bin/vm2.rs → src/bin/vm2.rs

@@ -37,16 +37,20 @@ use pasta_curves::{
 use rand::rngs::OsRng;
 use std::{collections::HashMap, fs::File, time::Instant};
 
-use drk_halo2::{
-    constants::{
-        sinsemilla::{OrchardCommitDomains, OrchardHashDomains, MERKLE_CRH_PERSONALIZATION},
-        OrchardFixedBases,
+use drk::{
+    crypto::{
+        constants::{
+            sinsemilla::{OrchardCommitDomains, OrchardHashDomains, MERKLE_CRH_PERSONALIZATION},
+            OrchardFixedBases,
+        },
+        util::{
+            pedersen_commitment_u64,
+            pedersen_commitment_scalar
+        },
+        proof::{Proof, ProvingKey, VerifyingKey},
     },
-    crypto::pedersen_commitment,
-    proof::{Proof, ProvingKey, VerifyingKey},
     serial::Decodable,
-    spec::i2lebsp,
-    vm2,
+    vm2
 };
 
 fn main() -> std::result::Result<(), failure::Error> {
@@ -54,7 +58,7 @@ fn main() -> std::result::Result<(), failure::Error> {
     let k: u32 = 11;
 
     let start = Instant::now();
-    let file = File::open("../../proof/mint.zk.bin")?;
+    let file = File::open("proof/mint.zk.bin")?;
     let zkbin = vm2::ZkBinary::decode(file)?;
     for contract_name in zkbin.contracts.keys() {
         println!("Loaded '{}' contract.", contract_name);
@@ -94,10 +98,10 @@ fn main() -> std::result::Result<(), failure::Error> {
     let coin2 = primitives::poseidon::Hash::init(P128Pow5T3, ConstantLength::<2>)
         .hash([*coords.x(), *coords.y()]);
 
-    let value_commit = pedersen_commitment(value, value_blind);
+    let value_commit = pedersen_commitment_u64(value, value_blind);
     let value_coords = value_commit.to_affine().coordinates().unwrap();
 
-    let asset_commit = pedersen_commitment(asset, asset_blind);
+    let asset_commit = pedersen_commitment_u64(asset, asset_blind);
     let asset_coords = asset_commit.to_affine().coordinates().unwrap();
 
     let mut public_inputs = vec![

+ 211 - 0
src/bin/vm2_burn.rs

@@ -0,0 +1,211 @@
+use std::iter;
+
+use halo2::{
+    circuit::{Layouter, SimpleFloorPlanner},
+    dev::MockProver,
+    plonk::{
+        Advice, Circuit, Column, ConstraintSystem, Error, Instance as InstanceColumn, Selector,
+    },
+    poly::Rotation,
+};
+use halo2_gadgets::{
+    ecc::{
+        chip::{EccChip, EccConfig},
+        FixedPoint, FixedPoints,
+    },
+    poseidon::{
+        Hash as PoseidonHash, Pow5T3Chip as PoseidonChip, Pow5T3Config as PoseidonConfig,
+        StateWord, Word,
+    },
+    primitives,
+    primitives::{
+        poseidon::{ConstantLength, P128Pow5T3},
+        sinsemilla::S_PERSONALIZATION,
+    },
+    sinsemilla::{
+        chip::{SinsemillaChip, SinsemillaConfig},
+        merkle::chip::{MerkleChip, MerkleConfig},
+        merkle::MerklePath,
+    },
+    utilities::{
+        lookup_range_check::LookupRangeCheckConfig, CellValue, UtilitiesInstructions, Var,
+    },
+};
+use pasta_curves::{
+    arithmetic::{CurveAffine, Field},
+    group::{ff::PrimeFieldBits, Curve, Group},
+    pallas,
+};
+use rand::rngs::OsRng;
+use std::{collections::HashMap, fs::File, time::Instant};
+
+use drk::{
+    crypto::{
+        constants::{
+            sinsemilla::{OrchardCommitDomains, OrchardHashDomains, MERKLE_CRH_PERSONALIZATION, i2lebsp},
+            OrchardFixedBases,
+        },
+        util::{
+            pedersen_commitment_u64,
+            pedersen_commitment_scalar
+        },
+        proof::{Proof, ProvingKey, VerifyingKey},
+    },
+    serial::Decodable,
+    vm2
+};
+
+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<(), failure::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 = vm2::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 = vm2::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(())
+}

+ 0 - 0
example/halo2/src/arith_chip.rs → src/crypto/arith_chip.rs


+ 1 - 0
src/crypto/mod.rs

@@ -1,3 +1,4 @@
+pub mod arith_chip;
 pub mod coin;
 pub mod constants;
 pub mod diffie_hellman;

+ 2 - 0
src/error.rs

@@ -38,6 +38,7 @@ pub enum Error {
     BadOperationType,
     BadConstraintType,
     InvalidParamName,
+    InvalidParamType,
     MissingParams,
     VmError,
     BadContract,
@@ -113,6 +114,7 @@ impl fmt::Display for Error {
             Error::BadOperationType => f.write_str("Bad operation type byte"),
             Error::BadConstraintType => f.write_str("Bad constraint type byte"),
             Error::InvalidParamName => f.write_str("Invalid param name"),
+            Error::InvalidParamType => f.write_str("Invalid param type"),
             Error::MissingParams => f.write_str("Missing params"),
             Error::VmError => f.write_str("VM error"),
             Error::BadContract => f.write_str("Contract is poorly defined"),

+ 2 - 0
src/lib.rs

@@ -16,5 +16,7 @@ pub mod tx;
 pub mod types;
 pub mod util;
 pub mod wallet;
+pub mod vm2;
+pub mod vm2_serial;
 
 pub use crate::error::{Error, Result};

+ 6 - 4
example/halo2/src/vm2.rs → src/vm2.rs

@@ -28,10 +28,12 @@ use halo2_gadgets::{
 use pasta_curves::pallas;
 
 use crate::{
-    arith_chip::{ArithmeticChip, ArithmeticChipConfig},
-    constants::{
-        sinsemilla::{OrchardCommitDomains, OrchardHashDomains, MERKLE_CRH_PERSONALIZATION},
-        OrchardFixedBases,
+    crypto::{
+        arith_chip::{ArithmeticChip, ArithmeticChipConfig},
+        constants::{
+            sinsemilla::{OrchardCommitDomains, OrchardHashDomains, MERKLE_CRH_PERSONALIZATION},
+            OrchardFixedBases,
+        },
     },
     error::{Error, Result},
 };

+ 0 - 0
example/halo2/src/vm2_serial.rs → src/vm2_serial.rs