Просмотр исходного кода

script/research/zkvm-metering: organize

oars 7 месяцев назад
Родитель
Сommit
8d7d33b812
30 измененных файлов с 359 добавлено и 277 удалено
  1. 3 1
      script/research/zkvm-metering/README.md
  2. 2 2
      script/research/zkvm-metering/generator/Makefile
  3. 55 263
      script/research/zkvm-metering/generator/src/main.rs
  4. 280 0
      script/research/zkvm-metering/generator/src/opcodes/mod.rs
  5. 0 0
      script/research/zkvm-metering/generator/src/opcodes/proof/base_add.zk
  6. 0 0
      script/research/zkvm-metering/generator/src/opcodes/proof/base_mul.zk
  7. 0 0
      script/research/zkvm-metering/generator/src/opcodes/proof/base_sub.zk
  8. 0 0
      script/research/zkvm-metering/generator/src/opcodes/proof/bool_check.zk
  9. 0 0
      script/research/zkvm-metering/generator/src/opcodes/proof/cond_select.zk
  10. 0 0
      script/research/zkvm-metering/generator/src/opcodes/proof/constrain_equal_base.zk
  11. 0 0
      script/research/zkvm-metering/generator/src/opcodes/proof/constrain_equal_point.zk
  12. 0 0
      script/research/zkvm-metering/generator/src/opcodes/proof/constrain_instance.zk
  13. 0 0
      script/research/zkvm-metering/generator/src/opcodes/proof/debug.zk
  14. 0 0
      script/research/zkvm-metering/generator/src/opcodes/proof/ec_add.zk
  15. 0 0
      script/research/zkvm-metering/generator/src/opcodes/proof/ec_get_x.zk
  16. 0 0
      script/research/zkvm-metering/generator/src/opcodes/proof/ec_get_y.zk
  17. 0 0
      script/research/zkvm-metering/generator/src/opcodes/proof/ec_mul.zk
  18. 0 0
      script/research/zkvm-metering/generator/src/opcodes/proof/ec_mul_base.zk
  19. 0 0
      script/research/zkvm-metering/generator/src/opcodes/proof/ec_mul_short.zk
  20. 0 0
      script/research/zkvm-metering/generator/src/opcodes/proof/ec_mul_var_base.zk
  21. 0 0
      script/research/zkvm-metering/generator/src/opcodes/proof/less_than_loose.zk
  22. 0 0
      script/research/zkvm-metering/generator/src/opcodes/proof/less_than_strict.zk
  23. 0 0
      script/research/zkvm-metering/generator/src/opcodes/proof/merkle_root.zk
  24. 0 0
      script/research/zkvm-metering/generator/src/opcodes/proof/poseidon_hash.zk
  25. 0 0
      script/research/zkvm-metering/generator/src/opcodes/proof/range_check.zk
  26. 0 0
      script/research/zkvm-metering/generator/src/opcodes/proof/sparse_merkle_root.zk
  27. 0 0
      script/research/zkvm-metering/generator/src/opcodes/proof/witness_base.zk
  28. 0 0
      script/research/zkvm-metering/generator/src/opcodes/proof/zero_cond.zk
  29. 4 4
      script/research/zkvm-metering/verifier/run_heaptrack.sh
  30. 15 7
      script/research/zkvm-metering/verifier/src/main.rs

+ 3 - 1
script/research/zkvm-metering/README.md

@@ -27,13 +27,15 @@ second command.
 % ./run_heaptrack.sh
 % ./run_heaptrack.sh
 ```
 ```
 `run_heaptrack.sh` will generate `heaptrack` report for all the opcodes
 `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.
 the following.
 ```
 ```
 % heaptrack ./verifer [OPCODE_NAME]
 % heaptrack ./verifer [OPCODE_NAME]
 ```
 ```
 Once the `heaptrack` report is generated you can view it using `heaptrack_gui`. 
 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
 #### Analysis Results
 
 
 | #  | Opcode                | RAM Usage | Verifying Key Size | Proof Size |
 | #  | Opcode                | RAM Usage | Verifying Key Size | Proof Size |

+ 2 - 2
script/research/zkvm-metering/generator/Makefile

@@ -15,7 +15,7 @@ RUST_TARGET = $(shell rustc -Vv | grep '^host: ' | cut -d' ' -f2)
 ZKAS = ../../../../zkas
 ZKAS = ../../../../zkas
 
 
 # zkas circuits
 # 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)
 PROOFS_BIN = $(PROOFS_SRC:=.bin)
 
 
 SRC = \
 SRC = \
@@ -43,6 +43,6 @@ clippy:
 clean:
 clean:
 	RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) clean --target=$(RUST_TARGET) --release --package $(BIN)
 	RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) clean --target=$(RUST_TARGET) --release --package $(BIN)
 	rm -f $(BIN)
 	rm -f $(BIN)
-	rm -f proof/*.bin
+	rm -f src/*/proof/*.bin
 
 
 .PHONY: all fmt clippy clean
 .PHONY: all fmt clippy clean

+ 55 - 263
script/research/zkvm-metering/generator/src/main.rs

@@ -23,40 +23,45 @@ use std::{
 };
 };
 
 
 use darkfi::{
 use darkfi::{
-    zk::{Proof, ProvingKey, VerifyingKey, Witness, ZkCircuit, empty_witnesses, halo2::Field},
+    zk::{Proof, ProvingKey, VerifyingKey, Witness, ZkCircuit, empty_witnesses},
     zkas::ZkBinary,
     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 darkfi_serial::serialize;
-use halo2_gadgets::ecc::chip::FixedPoint;
-use halo2_proofs::circuit::Value;
+use halo2_proofs::dev::CircuitCost;
 use rand::rngs::OsRng;
 use rand::rngs::OsRng;
 
 
+
+/// Opcode zk proofs witness and public input generator.
+mod opcodes;
+
 fn main() {
 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 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
         // Skip if already generated
         if Path::new(&proof_file).exists() &&
         if Path::new(&proof_file).exists() &&
@@ -67,7 +72,7 @@ fn main() {
             continue;
             continue;
         }
         }
 
 
-        println!("Generating {name} ...");
+        println!("Generating {name}....");
 
 
         // Open zk bin
         // Open zk bin
         let mut file = File::open(&path).unwrap();
         let mut file = File::open(&path).unwrap();
@@ -106,243 +111,30 @@ fn main() {
 
 
 fn retrieve_proof_inputs(name: &str) -> (Vec<Witness>, Vec<Base>) {
 fn retrieve_proof_inputs(name: &str) -> (Vec<Witness>, Vec<Base>) {
     match name {
     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)]),
         "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"),
         _ => panic!("unsupported Zk script"),
     }
     }
 }
 }

+ 280 - 0
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 <https://www.gnu.org/licenses/>.
+ */
+
+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<Witness>, Vec<Base>) {
+    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<Witness>, Vec<Base>) {
+    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<Witness>, Vec<Base>) {
+    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<Witness>, Vec<Base>) {
+    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<Witness>, Vec<Base>) {
+    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<Witness>, Vec<Base>) {
+    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<Witness>, Vec<Base>) {
+    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<Witness>, Vec<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)
+}
+
+pub fn ec_mul_short() -> (Vec<Witness>, Vec<Base>) {
+    // 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<Witness>, Vec<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)
+}
+
+pub fn ec_get_x() -> (Vec<Witness>, Vec<Base>) {
+    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<Witness>, Vec<Base>) {
+    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<Witness>, Vec<Base>) {
+    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<Witness>, Vec<Base>) {
+    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<Witness>, Vec<Base>) {
+    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<Witness>, Vec<Base>) {
+    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<Witness>, Vec<Base>) {
+    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<Witness>, Vec<Base>) {
+    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<Witness>, Vec<Base>) {
+    let a = Fp::from(1);
+    let prover_witnesses = vec![Witness::Base(Value::known(a))];
+
+    (prover_witnesses, vec![])
+}
+
+pub fn cond_select() -> (Vec<Witness>, Vec<Base>) {
+    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<Witness>, Vec<Base>) {
+    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<Witness>, Vec<Base>) {
+    let a = Fp::from(23);
+    let prover_witnesses = vec![Witness::Base(Value::known(a))];
+
+    (prover_witnesses, vec![])
+}
+
+pub fn debug() -> (Vec<Witness>, Vec<Base>) {
+    let a = Fp::from(23);
+    let prover_witnesses = vec![Witness::Base(Value::known(a))];
+
+    (prover_witnesses, vec![])
+}

+ 0 - 0
script/research/zkvm-metering/generator/proof/base_add.zk → script/research/zkvm-metering/generator/src/opcodes/proof/base_add.zk


+ 0 - 0
script/research/zkvm-metering/generator/proof/base_mul.zk → script/research/zkvm-metering/generator/src/opcodes/proof/base_mul.zk


+ 0 - 0
script/research/zkvm-metering/generator/proof/base_sub.zk → script/research/zkvm-metering/generator/src/opcodes/proof/base_sub.zk


+ 0 - 0
script/research/zkvm-metering/generator/proof/bool_check.zk → script/research/zkvm-metering/generator/src/opcodes/proof/bool_check.zk


+ 0 - 0
script/research/zkvm-metering/generator/proof/cond_select.zk → script/research/zkvm-metering/generator/src/opcodes/proof/cond_select.zk


+ 0 - 0
script/research/zkvm-metering/generator/proof/constrain_equal_base.zk → script/research/zkvm-metering/generator/src/opcodes/proof/constrain_equal_base.zk


+ 0 - 0
script/research/zkvm-metering/generator/proof/constrain_equal_point.zk → script/research/zkvm-metering/generator/src/opcodes/proof/constrain_equal_point.zk


+ 0 - 0
script/research/zkvm-metering/generator/proof/constrain_instance.zk → script/research/zkvm-metering/generator/src/opcodes/proof/constrain_instance.zk


+ 0 - 0
script/research/zkvm-metering/generator/proof/debug.zk → script/research/zkvm-metering/generator/src/opcodes/proof/debug.zk


+ 0 - 0
script/research/zkvm-metering/generator/proof/ec_add.zk → script/research/zkvm-metering/generator/src/opcodes/proof/ec_add.zk


+ 0 - 0
script/research/zkvm-metering/generator/proof/ec_get_x.zk → script/research/zkvm-metering/generator/src/opcodes/proof/ec_get_x.zk


+ 0 - 0
script/research/zkvm-metering/generator/proof/ec_get_y.zk → script/research/zkvm-metering/generator/src/opcodes/proof/ec_get_y.zk


+ 0 - 0
script/research/zkvm-metering/generator/proof/ec_mul.zk → script/research/zkvm-metering/generator/src/opcodes/proof/ec_mul.zk


+ 0 - 0
script/research/zkvm-metering/generator/proof/ec_mul_base.zk → script/research/zkvm-metering/generator/src/opcodes/proof/ec_mul_base.zk


+ 0 - 0
script/research/zkvm-metering/generator/proof/ec_mul_short.zk → script/research/zkvm-metering/generator/src/opcodes/proof/ec_mul_short.zk


+ 0 - 0
script/research/zkvm-metering/generator/proof/ec_mul_var_base.zk → script/research/zkvm-metering/generator/src/opcodes/proof/ec_mul_var_base.zk


+ 0 - 0
script/research/zkvm-metering/generator/proof/less_than_loose.zk → script/research/zkvm-metering/generator/src/opcodes/proof/less_than_loose.zk


+ 0 - 0
script/research/zkvm-metering/generator/proof/less_than_strict.zk → script/research/zkvm-metering/generator/src/opcodes/proof/less_than_strict.zk


+ 0 - 0
script/research/zkvm-metering/generator/proof/merkle_root.zk → script/research/zkvm-metering/generator/src/opcodes/proof/merkle_root.zk


+ 0 - 0
script/research/zkvm-metering/generator/proof/poseidon_hash.zk → script/research/zkvm-metering/generator/src/opcodes/proof/poseidon_hash.zk


+ 0 - 0
script/research/zkvm-metering/generator/proof/range_check.zk → script/research/zkvm-metering/generator/src/opcodes/proof/range_check.zk


+ 0 - 0
script/research/zkvm-metering/generator/proof/sparse_merkle_root.zk → script/research/zkvm-metering/generator/src/opcodes/proof/sparse_merkle_root.zk


+ 0 - 0
script/research/zkvm-metering/generator/proof/witness_base.zk → script/research/zkvm-metering/generator/src/opcodes/proof/witness_base.zk


+ 0 - 0
script/research/zkvm-metering/generator/proof/zero_cond.zk → script/research/zkvm-metering/generator/src/opcodes/proof/zero_cond.zk


+ 4 - 4
script/research/zkvm-metering/verifier/run_heaptrack.sh

@@ -1,10 +1,10 @@
 #!/bin/bash
 #!/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")
     filename=$(basename "$file")
-    name="${filename%.zk}"
+    name="${filename%.zk.bin}"
 
 
-    heaptrack --output "output/${name}" ./verifier "$name"
+    heaptrack --output "output/${name}" ./verifier "$file"
 done
 done

+ 15 - 7
script/research/zkvm-metering/verifier/src/main.rs

@@ -20,6 +20,7 @@ use std::{
     env,
     env,
     fs::File,
     fs::File,
     io::{Cursor, Read},
     io::{Cursor, Read},
+    path::Path,
 };
 };
 
 
 use darkfi::{
 use darkfi::{
@@ -33,27 +34,34 @@ use darkfi_serial::deserialize;
 fn main() -> Result<()> {
 fn main() -> Result<()> {
     let args: Vec<String> = env::args().collect();
     let args: Vec<String> = env::args().collect();
     if args.len() != 2 {
     if args.len() != 2 {
-        println!("Usage: ./verifier opcode_name");
+        println!("Usage: ./verifier [ZK_BIN_FILE_PATH]");
         return Ok(())
         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
     //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![];
     let mut bincode = vec![];
     file.read_to_end(&mut bincode)?;
     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![];
     let mut proof_bin = vec![];
     file.read_to_end(&mut proof_bin)?;
     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![];
     let mut vkbin = vec![];
     file.read_to_end(&mut vkbin)?;
     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![];
     let mut public_inputs_bin = vec![];
     file.read_to_end(&mut public_inputs_bin)?;
     file.read_to_end(&mut public_inputs_bin)?;