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

zk/vm: Implement function for making empty witnesses from ZkBinary.

This is useful for verifiers to enforce behaviour and avoid mismanaging
the witnesses that need to be input into the circuit when verifying
a proof.

Note that the prover still has to manage this by themself. There
might be some way to generalise this, but in practice, when creating
a ZK proof, the prover should always be aware of what witnesses they
should be inputting, so this can be represented procedurally in the
code without the need of an abstraction.
parazyd 4 лет назад
Родитель
Сommit
87b1cb49ad
5 измененных файлов с 41 добавлено и 28 удалено
  1. 1 1
      src/zk/mod.rs
  2. 25 1
      src/zk/vm_stack.rs
  3. 5 2
      tests/arithmetic_proof.rs
  4. 5 13
      tests/burn_proof.rs
  5. 5 11
      tests/mint_proof.rs

+ 1 - 1
src/zk/mod.rs

@@ -3,6 +3,6 @@ pub mod arith_chip;
 
 /// Halo2 zkas virtual machine
 pub mod vm;
-mod vm_stack;
+pub mod vm_stack;
 
 pub mod circuit;

+ 25 - 1
src/zk/vm_stack.rs

@@ -3,7 +3,10 @@ use halo2_gadgets::ecc::{chip::EccChip, FixedPoint, FixedPointBaseField, FixedPo
 use halo2_proofs::circuit::AssignedCell;
 use pasta_curves::{pallas, EpAffine};
 
-use crate::crypto::{constants::OrchardFixedBases, merkle_node::MerkleNode};
+use crate::{
+    crypto::{constants::OrchardFixedBases, merkle_node::MerkleNode},
+    zkas::{decoder::ZkBinary, types::Type},
+};
 
 /// These represent the witness types outside of the circuit
 #[allow(clippy::large_enum_variant)]
@@ -18,6 +21,27 @@ pub enum Witness {
     Uint64(Option<u64>),
 }
 
+/// Helper function for verifiers to generate empty witnesses for
+/// a given decoded zkas binary
+pub fn empty_witnesses(zkbin: &ZkBinary) -> Vec<Witness> {
+    let mut ret = Vec::with_capacity(zkbin.witnesses.len());
+
+    for witness in &zkbin.witnesses {
+        match witness {
+            Type::EcPoint => ret.push(Witness::EcPoint(None)),
+            Type::EcFixedPoint => ret.push(Witness::EcFixedPoint(None)),
+            Type::Base => ret.push(Witness::Base(None)),
+            Type::Scalar => ret.push(Witness::Scalar(None)),
+            Type::MerklePath => ret.push(Witness::MerklePath(None)),
+            Type::Uint32 => ret.push(Witness::Uint32(None)),
+            Type::Uint64 => ret.push(Witness::Uint64(None)),
+            _ => todo!("Handle this gracefully"),
+        }
+    }
+
+    ret
+}
+
 /// These represent the witness types inside the circuit
 #[allow(clippy::large_enum_variant)]
 #[derive(Clone)]

+ 5 - 2
tests/arithmetic_proof.rs

@@ -3,7 +3,10 @@ use darkfi::{
         proof::{ProvingKey, VerifyingKey},
         Proof,
     },
-    zk::vm::{Witness, ZkCircuit},
+    zk::{
+        vm::{Witness, ZkCircuit},
+        vm_stack::empty_witnesses,
+    },
     zkas::decoder::ZkBinary,
     Result,
 };
@@ -44,7 +47,7 @@ fn arithmetic_proof() -> Result<()> {
     // ========
 
     // Construct empty witnesses
-    let verifier_witnesses = vec![Witness::Base(None), Witness::Base(None)];
+    let verifier_witnesses = empty_witnesses(&zkbin);
 
     // Create the circuit
     let circuit = ZkCircuit::new(verifier_witnesses, zkbin);

+ 5 - 13
tests/burn_proof.rs

@@ -6,7 +6,10 @@ use darkfi::{
         util::{mod_r_p, pedersen_commitment_scalar, pedersen_commitment_u64},
         Proof,
     },
-    zk::vm::{Witness, ZkCircuit},
+    zk::{
+        vm::{Witness, ZkCircuit},
+        vm_stack::empty_witnesses,
+    },
     zkas::decoder::ZkBinary,
     Result,
 };
@@ -121,18 +124,7 @@ fn burn_proof() -> Result<()> {
     // ========
 
     // Construct empty witnesses
-    let verifier_witnesses = vec![
-        Witness::Base(None),
-        Witness::Base(None),
-        Witness::Base(None),
-        Witness::Base(None),
-        Witness::Base(None),
-        Witness::Scalar(None),
-        Witness::Scalar(None),
-        Witness::Uint32(None),
-        Witness::MerklePath(None),
-        Witness::Base(None),
-    ];
+    let verifier_witnesses = empty_witnesses(&zkbin);
 
     // Create the circuit
     let circuit = ZkCircuit::new(verifier_witnesses, zkbin);

+ 5 - 11
tests/mint_proof.rs

@@ -5,7 +5,10 @@ use darkfi::{
         util::{mod_r_p, pedersen_commitment_scalar, pedersen_commitment_u64},
         Proof,
     },
-    zk::vm::{Witness, ZkCircuit},
+    zk::{
+        vm::{Witness, ZkCircuit},
+        vm_stack::empty_witnesses,
+    },
     zkas::decoder::ZkBinary,
     Result,
 };
@@ -75,16 +78,7 @@ fn mint_proof() -> Result<()> {
     // ========
 
     // Construct empty witnesses
-    let verifier_witnesses = vec![
-        Witness::Base(None),
-        Witness::Base(None),
-        Witness::Base(None),
-        Witness::Base(None),
-        Witness::Base(None),
-        Witness::Base(None),
-        Witness::Scalar(None),
-        Witness::Scalar(None),
-    ];
+    let verifier_witnesses = empty_witnesses(&zkbin);
 
     // Create the circuit
     let circuit = ZkCircuit::new(verifier_witnesses, zkbin);