From 8d7d33b8124c946590063bb025a2e8cf8440bb6e Mon Sep 17 00:00:00 2001 From: oars Date: Sat, 3 Jan 2026 15:24:40 +0300 Subject: [PATCH] script/research/zkvm-metering: organize --- script/research/zkvm-metering/README.md | 4 +- .../research/zkvm-metering/generator/Makefile | 4 +- .../zkvm-metering/generator/src/main.rs | 318 +++--------------- .../generator/src/opcodes/mod.rs | 280 +++++++++++++++ .../{ => src/opcodes}/proof/base_add.zk | 0 .../{ => src/opcodes}/proof/base_mul.zk | 0 .../{ => src/opcodes}/proof/base_sub.zk | 0 .../{ => src/opcodes}/proof/bool_check.zk | 0 .../{ => src/opcodes}/proof/cond_select.zk | 0 .../opcodes}/proof/constrain_equal_base.zk | 0 .../opcodes}/proof/constrain_equal_point.zk | 0 .../opcodes}/proof/constrain_instance.zk | 0 .../{ => src/opcodes}/proof/debug.zk | 0 .../{ => src/opcodes}/proof/ec_add.zk | 0 .../{ => src/opcodes}/proof/ec_get_x.zk | 0 .../{ => src/opcodes}/proof/ec_get_y.zk | 0 .../{ => src/opcodes}/proof/ec_mul.zk | 0 .../{ => src/opcodes}/proof/ec_mul_base.zk | 0 .../{ => src/opcodes}/proof/ec_mul_short.zk | 0 .../opcodes}/proof/ec_mul_var_base.zk | 0 .../opcodes}/proof/less_than_loose.zk | 0 .../opcodes}/proof/less_than_strict.zk | 0 .../{ => src/opcodes}/proof/merkle_root.zk | 0 .../{ => src/opcodes}/proof/poseidon_hash.zk | 0 .../{ => src/opcodes}/proof/range_check.zk | 0 .../opcodes}/proof/sparse_merkle_root.zk | 0 .../{ => src/opcodes}/proof/witness_base.zk | 0 .../{ => src/opcodes}/proof/zero_cond.zk | 0 .../zkvm-metering/verifier/run_heaptrack.sh | 8 +- .../zkvm-metering/verifier/src/main.rs | 22 +- 30 files changed, 359 insertions(+), 277 deletions(-) create mode 100644 script/research/zkvm-metering/generator/src/opcodes/mod.rs rename script/research/zkvm-metering/generator/{ => src/opcodes}/proof/base_add.zk (100%) rename script/research/zkvm-metering/generator/{ => src/opcodes}/proof/base_mul.zk (100%) rename script/research/zkvm-metering/generator/{ => src/opcodes}/proof/base_sub.zk (100%) rename script/research/zkvm-metering/generator/{ => src/opcodes}/proof/bool_check.zk (100%) rename script/research/zkvm-metering/generator/{ => src/opcodes}/proof/cond_select.zk (100%) rename script/research/zkvm-metering/generator/{ => src/opcodes}/proof/constrain_equal_base.zk (100%) rename script/research/zkvm-metering/generator/{ => src/opcodes}/proof/constrain_equal_point.zk (100%) rename script/research/zkvm-metering/generator/{ => src/opcodes}/proof/constrain_instance.zk (100%) rename script/research/zkvm-metering/generator/{ => src/opcodes}/proof/debug.zk (100%) rename script/research/zkvm-metering/generator/{ => src/opcodes}/proof/ec_add.zk (100%) rename script/research/zkvm-metering/generator/{ => src/opcodes}/proof/ec_get_x.zk (100%) rename script/research/zkvm-metering/generator/{ => src/opcodes}/proof/ec_get_y.zk (100%) rename script/research/zkvm-metering/generator/{ => src/opcodes}/proof/ec_mul.zk (100%) rename script/research/zkvm-metering/generator/{ => src/opcodes}/proof/ec_mul_base.zk (100%) rename script/research/zkvm-metering/generator/{ => src/opcodes}/proof/ec_mul_short.zk (100%) rename script/research/zkvm-metering/generator/{ => src/opcodes}/proof/ec_mul_var_base.zk (100%) rename script/research/zkvm-metering/generator/{ => src/opcodes}/proof/less_than_loose.zk (100%) rename script/research/zkvm-metering/generator/{ => src/opcodes}/proof/less_than_strict.zk (100%) rename script/research/zkvm-metering/generator/{ => src/opcodes}/proof/merkle_root.zk (100%) rename script/research/zkvm-metering/generator/{ => src/opcodes}/proof/poseidon_hash.zk (100%) rename script/research/zkvm-metering/generator/{ => src/opcodes}/proof/range_check.zk (100%) rename script/research/zkvm-metering/generator/{ => src/opcodes}/proof/sparse_merkle_root.zk (100%) rename script/research/zkvm-metering/generator/{ => src/opcodes}/proof/witness_base.zk (100%) rename script/research/zkvm-metering/generator/{ => src/opcodes}/proof/zero_cond.zk (100%) diff --git a/script/research/zkvm-metering/README.md b/script/research/zkvm-metering/README.md index 9fcfa65af..6c96a21ac 100644 --- a/script/research/zkvm-metering/README.md +++ b/script/research/zkvm-metering/README.md @@ -27,13 +27,15 @@ second command. % ./run_heaptrack.sh ``` `run_heaptrack.sh` will generate `heaptrack` report for all the opcodes -in `output` directory. If you prover to analyze a single opcode run +in `output` directory. If you want to analyze a single opcode, run the following. ``` % heaptrack ./verifer [OPCODE_NAME] ``` Once the `heaptrack` report is generated you can view it using `heaptrack_gui`. +**Note:** This tool can also be used to generate and verify any ZkVM proof. + #### Analysis Results | # | Opcode | RAM Usage | Verifying Key Size | Proof Size | diff --git a/script/research/zkvm-metering/generator/Makefile b/script/research/zkvm-metering/generator/Makefile index 34d70e240..d5e7aae55 100644 --- a/script/research/zkvm-metering/generator/Makefile +++ b/script/research/zkvm-metering/generator/Makefile @@ -15,7 +15,7 @@ RUST_TARGET = $(shell rustc -Vv | grep '^host: ' | cut -d' ' -f2) ZKAS = ../../../../zkas # zkas circuits -PROOFS_SRC = $(shell find proof -type f -name '*.zk') +PROOFS_SRC = $(shell find -L src/*/proof -type f -name '*.zk') PROOFS_BIN = $(PROOFS_SRC:=.bin) SRC = \ @@ -43,6 +43,6 @@ clippy: clean: RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) clean --target=$(RUST_TARGET) --release --package $(BIN) rm -f $(BIN) - rm -f proof/*.bin + rm -f src/*/proof/*.bin .PHONY: all fmt clippy clean diff --git a/script/research/zkvm-metering/generator/src/main.rs b/script/research/zkvm-metering/generator/src/main.rs index 7778e5f7e..80f8b2f9b 100644 --- a/script/research/zkvm-metering/generator/src/main.rs +++ b/script/research/zkvm-metering/generator/src/main.rs @@ -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, Vec) { 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"), } } diff --git a/script/research/zkvm-metering/generator/src/opcodes/mod.rs b/script/research/zkvm-metering/generator/src/opcodes/mod.rs new file mode 100644 index 000000000..b4d3a5adf --- /dev/null +++ b/script/research/zkvm-metering/generator/src/opcodes/mod.rs @@ -0,0 +1,280 @@ +/* This file is part of DarkFi (https://dark.fi) + * + * Copyright (C) 2020-2026 Dyne.org foundation + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +use darkfi::zk::{Witness, halo2::Field}; +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 halo2_gadgets::ecc::chip::FixedPoint; +use halo2_proofs::circuit::Value; +use rand::rngs::OsRng; + +pub fn sparse_merkle_root() -> (Vec, Vec) { + let mut smt = SmtMemoryFp::new(MemoryStorageFp::new(), PoseidonFp::new(), &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) +} + +pub fn merkle_root() -> (Vec, Vec) { + 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) +} + +pub fn base_add() -> (Vec, Vec) { + 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) +} + +pub fn base_mul() -> (Vec, Vec) { + 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) +} + +pub fn base_sub() -> (Vec, Vec) { + 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) +} + +pub fn ec_add() -> (Vec, Vec) { + 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) +} + +pub fn ec_mul() -> (Vec, Vec) { + 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) +} + +pub fn ec_mul_base() -> (Vec, Vec) { + 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) +} + +pub fn ec_mul_short() -> (Vec, Vec) { + // 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) +} + +pub fn ec_mul_var_base() -> (Vec, Vec) { + 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) +} + +pub fn ec_get_x() -> (Vec, Vec) { + 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) +} + +pub fn ec_get_y() -> (Vec, Vec) { + 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) +} + +pub fn poseidon_hash_opcode() -> (Vec, Vec) { + 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) +} + +pub fn constrain_instance() -> (Vec, Vec) { + let a = Fp::random(&mut OsRng); + let prover_witnesses = vec![Witness::Base(Value::known(a))]; + let public_inputs = vec![a]; + + (prover_witnesses, public_inputs) +} + +pub fn constrain_equal_base() -> (Vec, Vec) { + let a = Fp::from(23); + let prover_witnesses = vec![Witness::Base(Value::known(a)), Witness::Base(Value::known(a))]; + + (prover_witnesses, vec![]) +} + +pub fn constrain_equal_point() -> (Vec, Vec) { + let a = Ep::random(&mut OsRng); + let prover_witnesses = + vec![Witness::EcPoint(Value::known(a)), Witness::EcPoint(Value::known(a))]; + + (prover_witnesses, vec![]) +} + +pub fn less_than_strict() -> (Vec, Vec) { + 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![]) +} + +pub fn less_than_loose() -> (Vec, Vec) { + let a = Fp::from(23); + let prover_witnesses = vec![Witness::Base(Value::known(a)), Witness::Base(Value::known(a))]; + + (prover_witnesses, vec![]) +} + +pub fn bool_check() -> (Vec, Vec) { + let a = Fp::from(1); + let prover_witnesses = vec![Witness::Base(Value::known(a))]; + + (prover_witnesses, vec![]) +} + +pub fn cond_select() -> (Vec, Vec) { + 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) +} + +pub fn zero_cond() -> (Vec, Vec) { + 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) +} + +pub fn range_check() -> (Vec, Vec) { + let a = Fp::from(23); + let prover_witnesses = vec![Witness::Base(Value::known(a))]; + + (prover_witnesses, vec![]) +} + +pub fn debug() -> (Vec, Vec) { + let a = Fp::from(23); + let prover_witnesses = vec![Witness::Base(Value::known(a))]; + + (prover_witnesses, vec![]) +} diff --git a/script/research/zkvm-metering/generator/proof/base_add.zk b/script/research/zkvm-metering/generator/src/opcodes/proof/base_add.zk similarity index 100% rename from script/research/zkvm-metering/generator/proof/base_add.zk rename to script/research/zkvm-metering/generator/src/opcodes/proof/base_add.zk diff --git a/script/research/zkvm-metering/generator/proof/base_mul.zk b/script/research/zkvm-metering/generator/src/opcodes/proof/base_mul.zk similarity index 100% rename from script/research/zkvm-metering/generator/proof/base_mul.zk rename to script/research/zkvm-metering/generator/src/opcodes/proof/base_mul.zk diff --git a/script/research/zkvm-metering/generator/proof/base_sub.zk b/script/research/zkvm-metering/generator/src/opcodes/proof/base_sub.zk similarity index 100% rename from script/research/zkvm-metering/generator/proof/base_sub.zk rename to script/research/zkvm-metering/generator/src/opcodes/proof/base_sub.zk diff --git a/script/research/zkvm-metering/generator/proof/bool_check.zk b/script/research/zkvm-metering/generator/src/opcodes/proof/bool_check.zk similarity index 100% rename from script/research/zkvm-metering/generator/proof/bool_check.zk rename to script/research/zkvm-metering/generator/src/opcodes/proof/bool_check.zk diff --git a/script/research/zkvm-metering/generator/proof/cond_select.zk b/script/research/zkvm-metering/generator/src/opcodes/proof/cond_select.zk similarity index 100% rename from script/research/zkvm-metering/generator/proof/cond_select.zk rename to script/research/zkvm-metering/generator/src/opcodes/proof/cond_select.zk diff --git a/script/research/zkvm-metering/generator/proof/constrain_equal_base.zk b/script/research/zkvm-metering/generator/src/opcodes/proof/constrain_equal_base.zk similarity index 100% rename from script/research/zkvm-metering/generator/proof/constrain_equal_base.zk rename to script/research/zkvm-metering/generator/src/opcodes/proof/constrain_equal_base.zk diff --git a/script/research/zkvm-metering/generator/proof/constrain_equal_point.zk b/script/research/zkvm-metering/generator/src/opcodes/proof/constrain_equal_point.zk similarity index 100% rename from script/research/zkvm-metering/generator/proof/constrain_equal_point.zk rename to script/research/zkvm-metering/generator/src/opcodes/proof/constrain_equal_point.zk diff --git a/script/research/zkvm-metering/generator/proof/constrain_instance.zk b/script/research/zkvm-metering/generator/src/opcodes/proof/constrain_instance.zk similarity index 100% rename from script/research/zkvm-metering/generator/proof/constrain_instance.zk rename to script/research/zkvm-metering/generator/src/opcodes/proof/constrain_instance.zk diff --git a/script/research/zkvm-metering/generator/proof/debug.zk b/script/research/zkvm-metering/generator/src/opcodes/proof/debug.zk similarity index 100% rename from script/research/zkvm-metering/generator/proof/debug.zk rename to script/research/zkvm-metering/generator/src/opcodes/proof/debug.zk diff --git a/script/research/zkvm-metering/generator/proof/ec_add.zk b/script/research/zkvm-metering/generator/src/opcodes/proof/ec_add.zk similarity index 100% rename from script/research/zkvm-metering/generator/proof/ec_add.zk rename to script/research/zkvm-metering/generator/src/opcodes/proof/ec_add.zk diff --git a/script/research/zkvm-metering/generator/proof/ec_get_x.zk b/script/research/zkvm-metering/generator/src/opcodes/proof/ec_get_x.zk similarity index 100% rename from script/research/zkvm-metering/generator/proof/ec_get_x.zk rename to script/research/zkvm-metering/generator/src/opcodes/proof/ec_get_x.zk diff --git a/script/research/zkvm-metering/generator/proof/ec_get_y.zk b/script/research/zkvm-metering/generator/src/opcodes/proof/ec_get_y.zk similarity index 100% rename from script/research/zkvm-metering/generator/proof/ec_get_y.zk rename to script/research/zkvm-metering/generator/src/opcodes/proof/ec_get_y.zk diff --git a/script/research/zkvm-metering/generator/proof/ec_mul.zk b/script/research/zkvm-metering/generator/src/opcodes/proof/ec_mul.zk similarity index 100% rename from script/research/zkvm-metering/generator/proof/ec_mul.zk rename to script/research/zkvm-metering/generator/src/opcodes/proof/ec_mul.zk diff --git a/script/research/zkvm-metering/generator/proof/ec_mul_base.zk b/script/research/zkvm-metering/generator/src/opcodes/proof/ec_mul_base.zk similarity index 100% rename from script/research/zkvm-metering/generator/proof/ec_mul_base.zk rename to script/research/zkvm-metering/generator/src/opcodes/proof/ec_mul_base.zk diff --git a/script/research/zkvm-metering/generator/proof/ec_mul_short.zk b/script/research/zkvm-metering/generator/src/opcodes/proof/ec_mul_short.zk similarity index 100% rename from script/research/zkvm-metering/generator/proof/ec_mul_short.zk rename to script/research/zkvm-metering/generator/src/opcodes/proof/ec_mul_short.zk diff --git a/script/research/zkvm-metering/generator/proof/ec_mul_var_base.zk b/script/research/zkvm-metering/generator/src/opcodes/proof/ec_mul_var_base.zk similarity index 100% rename from script/research/zkvm-metering/generator/proof/ec_mul_var_base.zk rename to script/research/zkvm-metering/generator/src/opcodes/proof/ec_mul_var_base.zk diff --git a/script/research/zkvm-metering/generator/proof/less_than_loose.zk b/script/research/zkvm-metering/generator/src/opcodes/proof/less_than_loose.zk similarity index 100% rename from script/research/zkvm-metering/generator/proof/less_than_loose.zk rename to script/research/zkvm-metering/generator/src/opcodes/proof/less_than_loose.zk diff --git a/script/research/zkvm-metering/generator/proof/less_than_strict.zk b/script/research/zkvm-metering/generator/src/opcodes/proof/less_than_strict.zk similarity index 100% rename from script/research/zkvm-metering/generator/proof/less_than_strict.zk rename to script/research/zkvm-metering/generator/src/opcodes/proof/less_than_strict.zk diff --git a/script/research/zkvm-metering/generator/proof/merkle_root.zk b/script/research/zkvm-metering/generator/src/opcodes/proof/merkle_root.zk similarity index 100% rename from script/research/zkvm-metering/generator/proof/merkle_root.zk rename to script/research/zkvm-metering/generator/src/opcodes/proof/merkle_root.zk diff --git a/script/research/zkvm-metering/generator/proof/poseidon_hash.zk b/script/research/zkvm-metering/generator/src/opcodes/proof/poseidon_hash.zk similarity index 100% rename from script/research/zkvm-metering/generator/proof/poseidon_hash.zk rename to script/research/zkvm-metering/generator/src/opcodes/proof/poseidon_hash.zk diff --git a/script/research/zkvm-metering/generator/proof/range_check.zk b/script/research/zkvm-metering/generator/src/opcodes/proof/range_check.zk similarity index 100% rename from script/research/zkvm-metering/generator/proof/range_check.zk rename to script/research/zkvm-metering/generator/src/opcodes/proof/range_check.zk diff --git a/script/research/zkvm-metering/generator/proof/sparse_merkle_root.zk b/script/research/zkvm-metering/generator/src/opcodes/proof/sparse_merkle_root.zk similarity index 100% rename from script/research/zkvm-metering/generator/proof/sparse_merkle_root.zk rename to script/research/zkvm-metering/generator/src/opcodes/proof/sparse_merkle_root.zk diff --git a/script/research/zkvm-metering/generator/proof/witness_base.zk b/script/research/zkvm-metering/generator/src/opcodes/proof/witness_base.zk similarity index 100% rename from script/research/zkvm-metering/generator/proof/witness_base.zk rename to script/research/zkvm-metering/generator/src/opcodes/proof/witness_base.zk diff --git a/script/research/zkvm-metering/generator/proof/zero_cond.zk b/script/research/zkvm-metering/generator/src/opcodes/proof/zero_cond.zk similarity index 100% rename from script/research/zkvm-metering/generator/proof/zero_cond.zk rename to script/research/zkvm-metering/generator/src/opcodes/proof/zero_cond.zk diff --git a/script/research/zkvm-metering/verifier/run_heaptrack.sh b/script/research/zkvm-metering/verifier/run_heaptrack.sh index a7bc2903a..cfe8deb6c 100755 --- a/script/research/zkvm-metering/verifier/run_heaptrack.sh +++ b/script/research/zkvm-metering/verifier/run_heaptrack.sh @@ -1,10 +1,10 @@ #!/bin/bash -SRC_DIR="../generator/proof" +SRC_DIR="../generator/src" -for file in "$SRC_DIR"/*.zk; do +for file in "$SRC_DIR"/*/proof/*.zk.bin; do filename=$(basename "$file") - name="${filename%.zk}" + name="${filename%.zk.bin}" - heaptrack --output "output/${name}" ./verifier "$name" + heaptrack --output "output/${name}" ./verifier "$file" done diff --git a/script/research/zkvm-metering/verifier/src/main.rs b/script/research/zkvm-metering/verifier/src/main.rs index edc75c464..156344e46 100644 --- a/script/research/zkvm-metering/verifier/src/main.rs +++ b/script/research/zkvm-metering/verifier/src/main.rs @@ -20,6 +20,7 @@ use std::{ env, fs::File, io::{Cursor, Read}, + path::Path, }; use darkfi::{ @@ -33,27 +34,34 @@ use darkfi_serial::deserialize; fn main() -> Result<()> { let args: Vec = env::args().collect(); if args.len() != 2 { - println!("Usage: ./verifier opcode_name"); + println!("Usage: ./verifier [ZK_BIN_FILE_PATH]"); return Ok(()) } - let file_name = &args[1]; + let zk_bin_path = Path::new(&args[1]); + + if !zk_bin_path.is_file() || !zk_bin_path.exists() || !&args[1].ends_with(".zk.bin") { + println!("Zk bin file path does not exist or is invalid"); + return Ok(()) + } - let name = file_name.split(".").next().unwrap(); //Load zkbin, proof, verifying key, public inputs from file - let mut file = File::open(format!("../generator/proof/{name}.zk.bin"))?; + let mut file = File::open(zk_bin_path)?; let mut bincode = vec![]; file.read_to_end(&mut bincode)?; - let mut file = File::open(format!("../generator/proof/{name}.proof.bin"))?; + let proof_path = zk_bin_path.to_str().unwrap().replace(".zk.bin", ".proof.bin"); + let mut file = File::open(proof_path)?; let mut proof_bin = vec![]; file.read_to_end(&mut proof_bin)?; - let mut file = File::open(format!("../generator/proof/{name}.vks.bin"))?; + let vks_path = zk_bin_path.to_str().unwrap().replace(".zk.bin", ".vks.bin"); + let mut file = File::open(vks_path)?; let mut vkbin = vec![]; file.read_to_end(&mut vkbin)?; - let mut file = File::open(format!("../generator/proof/{name}.pi.bin"))?; + let pi_path = zk_bin_path.to_str().unwrap().replace(".zk.bin", ".pi.bin"); + let mut file = File::open(pi_path)?; let mut public_inputs_bin = vec![]; file.read_to_end(&mut public_inputs_bin)?;