|
|
@@ -23,40 +23,45 @@ use std::{
|
|
|
};
|
|
|
|
|
|
use darkfi::{
|
|
|
- zk::{Proof, ProvingKey, VerifyingKey, Witness, ZkCircuit, empty_witnesses, halo2::Field},
|
|
|
+ zk::{Proof, ProvingKey, VerifyingKey, Witness, ZkCircuit, empty_witnesses},
|
|
|
zkas::ZkBinary,
|
|
|
};
|
|
|
-use darkfi_sdk::{
|
|
|
- crypto::{
|
|
|
- MerkleNode, MerkleTree,
|
|
|
- constants::{
|
|
|
- NullifierK,
|
|
|
- OrchardFixedBasesFull::ValueCommitR,
|
|
|
- fixed_bases::{VALUE_COMMITMENT_PERSONALIZATION, VALUE_COMMITMENT_V_BYTES},
|
|
|
- },
|
|
|
- pasta_prelude::{Curve, CurveAffine, CurveExt, Group},
|
|
|
- smt::{EMPTY_NODES_FP, MemoryStorageFp, PoseidonFp, SmtMemoryFp},
|
|
|
- util::{fp_mod_fv, poseidon_hash},
|
|
|
- },
|
|
|
- pasta::{Ep, Fp, Fq, pallas, pallas::Base},
|
|
|
-};
|
|
|
+use darkfi_sdk::pasta::{Eq, Fp, pallas::Base};
|
|
|
use darkfi_serial::serialize;
|
|
|
-use halo2_gadgets::ecc::chip::FixedPoint;
|
|
|
-use halo2_proofs::circuit::Value;
|
|
|
+use halo2_proofs::dev::CircuitCost;
|
|
|
use rand::rngs::OsRng;
|
|
|
|
|
|
+
|
|
|
+/// Opcode zk proofs witness and public input generator.
|
|
|
+mod opcodes;
|
|
|
+
|
|
|
fn main() {
|
|
|
- let entries = read_dir("proof").unwrap();
|
|
|
- // Read each compiled zk file bin
|
|
|
- for entry in entries.flatten() {
|
|
|
- let path = entry.path();
|
|
|
- if !(path.is_file() && path.to_str().unwrap().ends_with(".zk.bin")) {
|
|
|
- continue
|
|
|
+ // Read all src/*/proof directories contents
|
|
|
+ let mut zk_bin_files = vec![];
|
|
|
+
|
|
|
+ for entry in read_dir("src").unwrap() {
|
|
|
+ let path = entry.unwrap().path();
|
|
|
+ if !path.is_dir() {
|
|
|
+ continue;
|
|
|
}
|
|
|
+ let path = path.join("proof");
|
|
|
+ if path.exists() && path.is_dir() {
|
|
|
+ read_dir(path).unwrap().flatten().for_each(|e| {
|
|
|
+ let zk_path = e.path();
|
|
|
+ if zk_path.is_file() && zk_path.to_str().unwrap().ends_with(".zk.bin") {
|
|
|
+ zk_bin_files.push(zk_path)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Read each compiled zk file bin
|
|
|
+ for path in zk_bin_files {
|
|
|
+ let base_dir = path.parent().unwrap().to_str().unwrap();
|
|
|
let name = path.file_name().unwrap().to_str().unwrap().split(".").next().unwrap();
|
|
|
- let proof_file = format!("proof/{name}.proof.bin");
|
|
|
- let vk_file = format!("proof/{name}.vks.bin");
|
|
|
- let public_inputs_file = format!("proof/{name}.pi.bin");
|
|
|
+ let proof_file = format!("{base_dir}/{name}.proof.bin");
|
|
|
+ let vk_file = format!("{base_dir}/{name}.vks.bin");
|
|
|
+ let public_inputs_file = format!("{base_dir}/{name}.pi.bin");
|
|
|
|
|
|
// Skip if already generated
|
|
|
if Path::new(&proof_file).exists() &&
|
|
|
@@ -67,7 +72,7 @@ fn main() {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- println!("Generating {name} ...");
|
|
|
+ println!("Generating {name}....");
|
|
|
|
|
|
// Open zk bin
|
|
|
let mut file = File::open(&path).unwrap();
|
|
|
@@ -106,243 +111,30 @@ fn main() {
|
|
|
|
|
|
fn retrieve_proof_inputs(name: &str) -> (Vec<Witness>, Vec<Base>) {
|
|
|
match name {
|
|
|
- "sparse_merkle_root" => {
|
|
|
- let hasher = PoseidonFp::new();
|
|
|
- let store = MemoryStorageFp::new();
|
|
|
- let mut smt = SmtMemoryFp::new(store, hasher.clone(), &EMPTY_NODES_FP);
|
|
|
-
|
|
|
- let leaves =
|
|
|
- vec![Fp::random(&mut OsRng), Fp::random(&mut OsRng), Fp::random(&mut OsRng)];
|
|
|
- let leaves: Vec<_> = leaves.into_iter().map(|l| (l, l)).collect();
|
|
|
- smt.insert_batch(leaves.clone()).unwrap();
|
|
|
-
|
|
|
- let (pos, leaf) = leaves[2];
|
|
|
-
|
|
|
- let root = smt.root();
|
|
|
- let path = smt.prove_membership(&pos);
|
|
|
-
|
|
|
- let prover_witnesses = vec![
|
|
|
- Witness::SparseMerklePath(Value::known(path.path)),
|
|
|
- Witness::Base(Value::known(leaf)),
|
|
|
- ];
|
|
|
-
|
|
|
- let public_inputs = vec![root];
|
|
|
-
|
|
|
- (prover_witnesses, public_inputs)
|
|
|
- }
|
|
|
- "merkle_root" => {
|
|
|
- let mut tree = MerkleTree::new(u32::MAX as usize);
|
|
|
- let node1 = MerkleNode::from(Fp::random(&mut OsRng));
|
|
|
- let node2 = MerkleNode::from(Fp::random(&mut OsRng));
|
|
|
- let node3 = MerkleNode::from(Fp::random(&mut OsRng));
|
|
|
- tree.append(node1);
|
|
|
- tree.mark();
|
|
|
- tree.append(node2);
|
|
|
- let leaf_pos = tree.mark().unwrap();
|
|
|
- tree.append(node3);
|
|
|
-
|
|
|
- let root = tree.root(0).unwrap().inner();
|
|
|
- let path = tree.witness(leaf_pos, 0).unwrap();
|
|
|
-
|
|
|
- let prover_witnesses = vec![
|
|
|
- Witness::Base(Value::known(node2.inner())),
|
|
|
- Witness::Uint32(Value::known(u64::from(leaf_pos).try_into().unwrap())),
|
|
|
- Witness::MerklePath(Value::known(path.try_into().unwrap())),
|
|
|
- ];
|
|
|
- let public_inputs = vec![root];
|
|
|
-
|
|
|
- (prover_witnesses, public_inputs)
|
|
|
- }
|
|
|
- "base_add" => {
|
|
|
- let b1 = Fp::from(4u64);
|
|
|
- let b2 = Fp::from(110u64);
|
|
|
- let prover_witnesses =
|
|
|
- vec![Witness::Base(Value::known(b1)), Witness::Base(Value::known(b2))];
|
|
|
- let public_inputs = vec![b1 + b2];
|
|
|
-
|
|
|
- (prover_witnesses, public_inputs)
|
|
|
- }
|
|
|
- "base_mul" => {
|
|
|
- let b1 = Fp::from(4u64);
|
|
|
- let b2 = Fp::from(110u64);
|
|
|
- let prover_witnesses =
|
|
|
- vec![Witness::Base(Value::known(b1)), Witness::Base(Value::known(b2))];
|
|
|
- let public_inputs = vec![b1 * b2];
|
|
|
-
|
|
|
- (prover_witnesses, public_inputs)
|
|
|
- }
|
|
|
- "base_sub" => {
|
|
|
- let b1 = Fp::from(4u64);
|
|
|
- let b2 = Fp::from(110u64);
|
|
|
- let prover_witnesses =
|
|
|
- vec![Witness::Base(Value::known(b1)), Witness::Base(Value::known(b2))];
|
|
|
- let public_inputs = vec![b1 - b2];
|
|
|
-
|
|
|
- (prover_witnesses, public_inputs)
|
|
|
- }
|
|
|
- "ec_add" => {
|
|
|
- let p1 = Ep::random(&mut OsRng);
|
|
|
- let p2 = Ep::random(&mut OsRng);
|
|
|
- let sum = (p1 + p2).to_affine();
|
|
|
- let sum_x = *sum.coordinates().unwrap().x();
|
|
|
- let sum_y = *sum.coordinates().unwrap().y();
|
|
|
- let prover_witnesses =
|
|
|
- vec![Witness::EcPoint(Value::known(p1)), Witness::EcPoint(Value::known(p2))];
|
|
|
- let public_inputs = vec![sum_x, sum_y];
|
|
|
-
|
|
|
- (prover_witnesses, public_inputs)
|
|
|
- }
|
|
|
- "ec_mul" => {
|
|
|
- let scalar_blind = Fq::random(&mut OsRng);
|
|
|
- let vcr = (ValueCommitR.generator() * scalar_blind).to_affine();
|
|
|
- let vcr_x = *vcr.coordinates().unwrap().x();
|
|
|
- let vcr_y = *vcr.coordinates().unwrap().y();
|
|
|
- let prover_witnesses = vec![Witness::Scalar(Value::known(scalar_blind))];
|
|
|
- let public_inputs = vec![vcr_x, vcr_y];
|
|
|
-
|
|
|
- (prover_witnesses, public_inputs)
|
|
|
- }
|
|
|
- "ec_mul_base" => {
|
|
|
- let secret_key = Fp::random(&mut OsRng);
|
|
|
- let pubkey = (NullifierK.generator() * fp_mod_fv(secret_key)).to_affine();
|
|
|
- let pubkey_x = *pubkey.coordinates().unwrap().x();
|
|
|
- let pubkey_y = *pubkey.coordinates().unwrap().y();
|
|
|
- let prover_witnesses = vec![Witness::Base(Value::known(secret_key))];
|
|
|
- let public_inputs = vec![pubkey_x, pubkey_y];
|
|
|
-
|
|
|
- (prover_witnesses, public_inputs)
|
|
|
- }
|
|
|
- "ec_mul_short" => {
|
|
|
- // we can't use Fp::random() since it can be more than u64::MAX and we need value to be u64
|
|
|
- let value = Fp::from(42);
|
|
|
- let hasher = pallas::Point::hash_to_curve(VALUE_COMMITMENT_PERSONALIZATION);
|
|
|
- let val_commit = hasher(&VALUE_COMMITMENT_V_BYTES);
|
|
|
-
|
|
|
- let vcv = (val_commit * fp_mod_fv(value)).to_affine();
|
|
|
- let vcv_x = *vcv.coordinates().unwrap().x();
|
|
|
- let vcv_y = *vcv.coordinates().unwrap().y();
|
|
|
- let prover_witnesses = vec![Witness::Base(Value::known(value))];
|
|
|
- let public_inputs = vec![vcv_x, vcv_y];
|
|
|
-
|
|
|
- (prover_witnesses, public_inputs)
|
|
|
- }
|
|
|
- "ec_mul_var_base" => {
|
|
|
- let ephem_secret = Fp::random(&mut OsRng);
|
|
|
- let pubkey = NullifierK.generator() * fp_mod_fv(ephem_secret);
|
|
|
- let ephem_pub = (pubkey * fp_mod_fv(ephem_secret)).to_affine();
|
|
|
- let ephem_pub_x = *ephem_pub.coordinates().unwrap().x();
|
|
|
- let ephem_pub_y = *ephem_pub.coordinates().unwrap().y();
|
|
|
- let prover_witnesses = vec![
|
|
|
- Witness::Base(Value::known(ephem_secret)),
|
|
|
- Witness::EcNiPoint(Value::known(pubkey)),
|
|
|
- ];
|
|
|
- let public_inputs = vec![ephem_pub_x, ephem_pub_y];
|
|
|
-
|
|
|
- (prover_witnesses, public_inputs)
|
|
|
- }
|
|
|
- "ec_get_x" => {
|
|
|
- let p = Ep::random(&mut OsRng);
|
|
|
- let x = *p.to_affine().coordinates().unwrap().x();
|
|
|
- let prover_witnesses = vec![Witness::EcPoint(Value::known(p))];
|
|
|
- let public_inputs = vec![x];
|
|
|
-
|
|
|
- (prover_witnesses, public_inputs)
|
|
|
- }
|
|
|
- "ec_get_y" => {
|
|
|
- let p = Ep::random(&mut OsRng);
|
|
|
- let y = *p.to_affine().coordinates().unwrap().y();
|
|
|
- let prover_witnesses = vec![Witness::EcPoint(Value::known(p))];
|
|
|
- let public_inputs = vec![y];
|
|
|
-
|
|
|
- (prover_witnesses, public_inputs)
|
|
|
- }
|
|
|
- "poseidon_hash" => {
|
|
|
- let a = Fp::random(&mut OsRng);
|
|
|
- let b = Fp::random(&mut OsRng);
|
|
|
- let hash = poseidon_hash([a, b]);
|
|
|
- let prover_witnesses =
|
|
|
- vec![Witness::Base(Value::known(a)), Witness::Base(Value::known(b))];
|
|
|
- let public_inputs = vec![hash];
|
|
|
-
|
|
|
- (prover_witnesses, public_inputs)
|
|
|
- }
|
|
|
- "constrain_instance" => {
|
|
|
- let a = Fp::random(&mut OsRng);
|
|
|
- let prover_witnesses = vec![Witness::Base(Value::known(a))];
|
|
|
- let public_inputs = vec![a];
|
|
|
-
|
|
|
- (prover_witnesses, public_inputs)
|
|
|
- }
|
|
|
+ "sparse_merkle_root" => opcodes::sparse_merkle_root(),
|
|
|
+ "merkle_root" => opcodes::merkle_root(),
|
|
|
+ "base_add" => opcodes::base_add(),
|
|
|
+ "base_mul" => opcodes::base_mul(),
|
|
|
+ "base_sub" => opcodes::base_sub(),
|
|
|
+ "ec_add" => opcodes::ec_add(),
|
|
|
+ "ec_mul" => opcodes::ec_mul(),
|
|
|
+ "ec_mul_base" => opcodes::ec_mul_base(),
|
|
|
+ "ec_mul_short" => opcodes::ec_mul_short(),
|
|
|
+ "ec_mul_var_base" => opcodes::ec_mul_var_base(),
|
|
|
+ "ec_get_x" => opcodes::ec_get_x(),
|
|
|
+ "ec_get_y" => opcodes::ec_get_y(),
|
|
|
+ "poseidon_hash" => opcodes::poseidon_hash_opcode(),
|
|
|
+ "constrain_instance" => opcodes::constrain_instance(),
|
|
|
"witness_base" => (vec![], vec![Fp::from(2)]),
|
|
|
- "constrain_equal_base" => {
|
|
|
- let a = Fp::from(23);
|
|
|
- let prover_witnesses =
|
|
|
- vec![Witness::Base(Value::known(a)), Witness::Base(Value::known(a))];
|
|
|
-
|
|
|
- (prover_witnesses, vec![])
|
|
|
- }
|
|
|
- "constrain_equal_point" => {
|
|
|
- let a = Ep::random(&mut OsRng);
|
|
|
- let prover_witnesses =
|
|
|
- vec![Witness::EcPoint(Value::known(a)), Witness::EcPoint(Value::known(a))];
|
|
|
-
|
|
|
- (prover_witnesses, vec![])
|
|
|
- }
|
|
|
- "less_than_strict" => {
|
|
|
- let a = Fp::from(23);
|
|
|
- let b = Fp::from(42);
|
|
|
- let prover_witnesses =
|
|
|
- vec![Witness::Base(Value::known(a)), Witness::Base(Value::known(b))];
|
|
|
-
|
|
|
- (prover_witnesses, vec![])
|
|
|
- }
|
|
|
- "less_than_loose" => {
|
|
|
- let a = Fp::from(23);
|
|
|
- let prover_witnesses =
|
|
|
- vec![Witness::Base(Value::known(a)), Witness::Base(Value::known(a))];
|
|
|
-
|
|
|
- (prover_witnesses, vec![])
|
|
|
- }
|
|
|
- "bool_check" => {
|
|
|
- let a = Fp::from(1);
|
|
|
- let prover_witnesses = vec![Witness::Base(Value::known(a))];
|
|
|
-
|
|
|
- (prover_witnesses, vec![])
|
|
|
- }
|
|
|
- "cond_select" => {
|
|
|
- let a = Fp::from(23);
|
|
|
- let b = Fp::from(42);
|
|
|
- let cond = Fp::from(1);
|
|
|
- let prover_witnesses = vec![
|
|
|
- Witness::Base(Value::known(a)),
|
|
|
- Witness::Base(Value::known(b)),
|
|
|
- Witness::Base(Value::known(cond)),
|
|
|
- ];
|
|
|
- let public_inputs = vec![a];
|
|
|
-
|
|
|
- (prover_witnesses, public_inputs)
|
|
|
- }
|
|
|
- "zero_cond" => {
|
|
|
- let a = Fp::from(0);
|
|
|
- let b = Fp::from(23);
|
|
|
- let prover_witnesses =
|
|
|
- vec![Witness::Base(Value::known(a)), Witness::Base(Value::known(b))];
|
|
|
- let public_inputs = vec![a];
|
|
|
-
|
|
|
- (prover_witnesses, public_inputs)
|
|
|
- }
|
|
|
- "range_check" => {
|
|
|
- let a = Fp::from(23);
|
|
|
- let prover_witnesses = vec![Witness::Base(Value::known(a))];
|
|
|
-
|
|
|
- (prover_witnesses, vec![])
|
|
|
- }
|
|
|
- "debug" => {
|
|
|
- let a = Fp::from(23);
|
|
|
- let prover_witnesses = vec![Witness::Base(Value::known(a))];
|
|
|
-
|
|
|
- (prover_witnesses, vec![])
|
|
|
- }
|
|
|
+ "constrain_equal_base" => opcodes::constrain_equal_base(),
|
|
|
+ "constrain_equal_point" => opcodes::constrain_equal_point(),
|
|
|
+ "less_than_strict" => opcodes::less_than_strict(),
|
|
|
+ "less_than_loose" => opcodes::less_than_loose(),
|
|
|
+ "bool_check" => opcodes::bool_check(),
|
|
|
+ "cond_select" => opcodes::cond_select(),
|
|
|
+ "zero_cond" => opcodes::zero_cond(),
|
|
|
+ "range_check" => opcodes::range_check(),
|
|
|
+ "debug" => opcodes::debug(),
|
|
|
_ => panic!("unsupported Zk script"),
|
|
|
}
|
|
|
}
|