Add verifier-datas tree (set) & in-circuit verification (#274)

* containers: add method to create new {Dict,Set,Array} with custom max_depth

* add vds_tree computation, update tree circuit interface

* add VDTree struct, add DEFAULT_VD_TREE, integrate it with MainPod,EmptyPod,frontend,etc.

* adapt frontend/serialization tests to new containers field (max_depth)

* adapt interfaces to allow using custom vd_tree in frontend & backend constructors

* rename VDTree to VDSet (and derivate namings too)

* containers 'new' always with param 'max_depth', use params.max_depth_mt_containers instead of the global constant MAX_DEPTH

* adapt after rebasing the branch to main latest changes

* apply review suggestions from @ed255

* use emptypod vd_mt_proofs (using vd_set as circuit input), merge the two existing set_targets methods of MainPodVerifyTarget

* document VDSet & vds_root
This commit is contained in:
arnaucube 2025-06-11 13:08:39 +02:00 committed by GitHub
parent 6258e52e1a
commit 273d803ebd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 486 additions and 259 deletions

View file

@ -36,3 +36,91 @@ pub type VerifierCircuitData = circuit_data::VerifierCircuitData<F, C, D>;
pub type CircuitBuilder = circuit_builder::CircuitBuilder<F, D>;
pub type Proof = proof::Proof<F, C, D>;
pub type ProofWithPublicInputs = proof::ProofWithPublicInputs<F, C, D>;
use std::{collections::HashMap, sync::LazyLock};
use itertools::Itertools;
use plonky2::hash::hash_types::HashOut;
use crate::{
backends::plonky2::{
emptypod::STANDARD_EMPTY_POD_DATA, primitives::merkletree::MerkleClaimAndProof,
DEFAULT_PARAMS, STANDARD_REC_MAIN_POD_CIRCUIT_DATA,
},
middleware::{containers::Array, Hash, RawValue, Result, Value},
};
pub static DEFAULT_VD_SET: LazyLock<VDSet> = LazyLock::new(|| {
let params = &*DEFAULT_PARAMS;
let vds = vec![
STANDARD_REC_MAIN_POD_CIRCUIT_DATA.verifier_only.clone(),
STANDARD_EMPTY_POD_DATA.1.verifier_only.clone(),
];
VDSet::new(params.max_depth_mt_vds, &vds).unwrap()
});
/// VDSet is the set of the allowed verifier_data hashes. When proving a
/// MainPod, the circuit will enforce that all the used verifier_datas for
/// verifying the recursive proofs of previous PODs appears in the VDSet.
/// The VDSet struct that allows to get the specific merkle proofs for the given
/// verifier_data.
#[derive(Clone, Debug)]
pub struct VDSet {
root: Hash,
// (verifier_data, merkleproof)
proofs_map: HashMap<HashOut<F>, MerkleClaimAndProof>,
}
impl VDSet {
/// builds the verifier_datas tree, and returns the root and the proofs
pub fn new(tree_depth: usize, vds: &[VerifierOnlyCircuitData]) -> Result<Self> {
// first of all, sort the vds, so that each set of verifier_datas gets
// the same root
let vds: Vec<&VerifierOnlyCircuitData> = vds
.iter()
.sorted_by_key(|vd| RawValue(vd.circuit_digest.elements))
.collect::<Vec<_>>();
let array = Array::new(
tree_depth,
vds.iter()
.map(|vd| Value::from(RawValue(vd.circuit_digest.elements)))
.collect(),
)?;
let root = array.commitment();
let mut proofs_map = HashMap::<HashOut<F>, MerkleClaimAndProof>::new();
for (i, vd) in vds.iter().enumerate() {
let (value, proof) = array.prove(i)?;
let p = MerkleClaimAndProof {
root,
key: RawValue::from(i as i64),
value: value.raw(),
proof,
};
proofs_map.insert(vd.circuit_digest, p);
}
Ok(Self { root, proofs_map })
}
pub fn root(&self) -> Hash {
self.root
}
/// returns the vector of merkle proofs corresponding to the given verifier_datas
pub fn get_vds_proofs(
&self,
vds: &[VerifierOnlyCircuitData],
) -> Result<Vec<MerkleClaimAndProof>> {
let mut proofs: Vec<MerkleClaimAndProof> = vec![];
for vd in vds {
let p =
self.proofs_map
.get(&vd.circuit_digest)
.ok_or(crate::middleware::Error::custom(
"verifier_data not found in VDSet".to_string(),
))?;
proofs.push(p.clone());
}
Ok(proofs)
}
}

View file

@ -40,7 +40,7 @@ use crate::{
pub const CODE_SIZE: usize = HASH_SIZE + 2;
const NUM_BITS: usize = 32;
#[derive(Copy, Clone)]
#[derive(Copy, Clone, Debug)]
pub struct ValueTarget {
pub elements: [Target; VALUE_SIZE],
}

View file

@ -17,7 +17,7 @@ use plonky2::{
use crate::{
backends::plonky2::{
basetypes::CircuitBuilder,
basetypes::{CircuitBuilder, VDSet},
circuits::{
common::{
CircuitBuilderPod, CustomPredicateBatchTarget, CustomPredicateEntryTarget,
@ -28,7 +28,7 @@ use crate::{
},
signedpod::{SignedPodVerifyGadget, SignedPodVerifyTarget},
},
emptypod::EmptyPod,
emptypod::{EmptyPod, STANDARD_EMPTY_POD_DATA},
error::Result,
mainpod::{self, pad_statement},
primitives::merkletree::{
@ -39,10 +39,9 @@ use crate::{
},
measure_gates_begin, measure_gates_end,
middleware::{
AnchoredKey, CustomPredicate, CustomPredicateBatch, CustomPredicateRef, Hash,
NativeOperation, NativePredicate, Params, PodType, PredicatePrefix, Statement,
StatementArg, ToFields, Value, WildcardValue, EMPTY_VALUE, F, HASH_SIZE, KEY_TYPE, SELF,
VALUE_SIZE,
AnchoredKey, CustomPredicate, CustomPredicateBatch, CustomPredicateRef, NativeOperation,
NativePredicate, Params, PodType, PredicatePrefix, Statement, StatementArg, ToFields,
Value, WildcardValue, EMPTY_VALUE, F, HASH_SIZE, KEY_TYPE, SELF, VALUE_SIZE,
},
};
@ -1220,9 +1219,31 @@ impl MainPodVerifyGadget {
}
let vds_root = builder.add_virtual_hash();
// TODO: verify that all input pod proofs use verifier data from the public input VD array
// This requires merkle proofs
// https://github.com/0xPARC/pod2/issues/250
// verify that all input pod proofs use verifier data from the public input VD array This
// requires merkle proofs
let mut vd_mt_proofs: Vec<MerkleClaimAndProofTarget> = vec![];
for verified_proof in verified_proofs {
// add target for the vd_mt_proof
let vd_mt_proof = MerkleProofGadget {
max_depth: params.max_depth_mt_vds,
}
.eval(builder);
// ensure that mt_proof is enabled
let true_targ = builder._true();
builder.connect(vd_mt_proof.enabled.target, true_targ.target);
// connect the vd_mt_proof's root to the actual vds_root, to ensure that the mt proof
// verifies against the vds_root
builder.connect_hashes(vds_root, vd_mt_proof.root);
// connect vd_mt_proof's value with the verified_proof.verifier_data_hash
builder.connect_hashes(
verified_proof.verifier_data_hash,
HashOutTarget::from_vec(vd_mt_proof.value.elements.to_vec()),
);
vd_mt_proofs.push(vd_mt_proof);
}
// Verify that VD array that input pod uses is the same we use now.
for verified_proof in verified_proofs {
@ -1247,11 +1268,11 @@ impl MainPodVerifyGadget {
// Add Merkle claim/proof targets
let mp_gadget = MerkleProofGadget {
max_depth: params.max_depth_mt_gadget,
max_depth: params.max_depth_mt_containers,
};
let merkle_proofs: Vec<_> = (0..params.max_merkle_proofs)
let merkle_proofs: Vec<_> = (0..params.max_merkle_proofs_containers)
.map(|_| mp_gadget.eval(builder))
.collect::<Result<_>>()?;
.collect();
let merkle_claims: Vec<_> = merkle_proofs
.clone()
.into_iter()
@ -1310,6 +1331,7 @@ impl MainPodVerifyGadget {
Ok(MainPodVerifyTarget {
params: params.clone(),
vds_root,
vd_mt_proofs,
id,
signed_pods,
input_pods_self_statements,
@ -1325,6 +1347,7 @@ impl MainPodVerifyGadget {
pub struct MainPodVerifyTarget {
params: Params,
vds_root: HashOutTarget,
vd_mt_proofs: Vec<MerkleClaimAndProofTarget>,
id: HashOutTarget,
signed_pods: Vec<SignedPodVerifyTarget>,
input_pods_self_statements: Vec<Vec<StatementTarget>>,
@ -1344,7 +1367,11 @@ pub struct CustomPredicateVerification {
}
pub struct MainPodVerifyInput {
pub vds_root: Hash,
pub vds_set: VDSet,
// field containing the `vd_mt_proofs` aside from the `vds_set`, because
// inide the MainPodVerifyTarget circuit, since it is the InnerCircuit for
// the RecursiveCircuit, we don't have access to the used verifier_datas.
pub vd_mt_proofs: Vec<MerkleClaimAndProof>,
pub signed_pods: Vec<SignedPod>,
pub recursive_pods_pub_self_statements: Vec<Vec<Statement>>,
pub statements: Vec<mainpod::Statement>,
@ -1378,13 +1405,58 @@ fn set_targets_input_pods_self_statements(
Ok(())
}
impl MainPodVerifyTarget {
pub fn set_targets(
pub struct MainPodVerifyCircuit {
pub params: Params,
}
// TODO: Remove this type and implement it's logic directly in `impl InnerCircuit for MainPodVerifyTarget`
impl MainPodVerifyCircuit {
pub fn eval(
&self,
pw: &mut PartialWitness<F>,
input: &MainPodVerifyInput,
) -> Result<()> {
pw.set_target_arr(&self.vds_root.elements, &input.vds_root.0)?;
builder: &mut CircuitBuilder,
verified_proofs: &[VerifiedProofTarget],
) -> Result<MainPodVerifyTarget> {
let main_pod = MainPodVerifyGadget {
params: self.params.clone(),
}
.eval(builder, verified_proofs)?;
builder.register_public_inputs(&main_pod.id.elements);
builder.register_public_inputs(&main_pod.vds_root.elements);
Ok(main_pod)
}
}
impl InnerCircuit for MainPodVerifyTarget {
type Input = MainPodVerifyInput;
type Params = Params;
fn build(
builder: &mut CircuitBuilder,
params: &Self::Params,
verified_proofs: &[VerifiedProofTarget],
) -> Result<Self> {
MainPodVerifyCircuit {
params: params.clone(),
}
.eval(builder, verified_proofs)
}
/// assigns the values to the targets
fn set_targets(&self, pw: &mut PartialWitness<F>, input: &Self::Input) -> Result<()> {
let vds_root = input.vds_set.root();
pw.set_target_arr(&self.vds_root.elements, &vds_root.0)?;
for (i, vd_mt_proof) in input.vd_mt_proofs.iter().enumerate() {
self.vd_mt_proofs[i].set_targets(pw, true, vd_mt_proof)?;
}
// the rest of vd_mt_proofs set them to the empty_pod vd_mt_proof
let vd_emptypod_mt_proof = input
.vds_set
.get_vds_proofs(&[STANDARD_EMPTY_POD_DATA.1.verifier_only.clone()])?;
let vd_emptypod_mt_proof = vd_emptypod_mt_proof[0].clone();
for i in input.vd_mt_proofs.len()..self.vd_mt_proofs.len() {
self.vd_mt_proofs[i].set_targets(pw, true, &vd_emptypod_mt_proof)?;
}
assert!(input.signed_pods.len() <= self.params.max_input_signed_pods);
for (i, signed_pod) in input.signed_pods.iter().enumerate() {
@ -1414,7 +1486,7 @@ impl MainPodVerifyTarget {
}
// Padding
if input.recursive_pods_pub_self_statements.len() != self.params.max_input_recursive_pods {
let empty_pod = EmptyPod::new_boxed(&self.params, input.vds_root);
let empty_pod = EmptyPod::new_boxed(&self.params, input.vds_set.root());
let empty_pod_statements = empty_pod.pub_statements();
for i in
input.recursive_pods_pub_self_statements.len()..self.params.max_input_recursive_pods
@ -1434,13 +1506,13 @@ impl MainPodVerifyTarget {
self.operations[i].set_targets(pw, &self.params, op)?;
}
assert!(input.merkle_proofs.len() <= self.params.max_merkle_proofs);
assert!(input.merkle_proofs.len() <= self.params.max_merkle_proofs_containers);
for (i, mp) in input.merkle_proofs.iter().enumerate() {
self.merkle_proofs[i].set_targets(pw, true, mp)?;
}
// Padding
let pad_mp = MerkleClaimAndProof::empty();
for i in input.merkle_proofs.len()..self.params.max_merkle_proofs {
for i in input.merkle_proofs.len()..self.params.max_merkle_proofs_containers {
self.merkle_proofs[i].set_targets(pw, false, &pad_mp)?;
}
@ -1487,48 +1559,6 @@ impl MainPodVerifyTarget {
}
}
pub struct MainPodVerifyCircuit {
pub params: Params,
}
// TODO: Remove this type and implement it's logic directly in `impl InnerCircuit for MainPodVerifyTarget`
impl MainPodVerifyCircuit {
pub fn eval(
&self,
builder: &mut CircuitBuilder,
verified_proofs: &[VerifiedProofTarget],
) -> Result<MainPodVerifyTarget> {
let main_pod = MainPodVerifyGadget {
params: self.params.clone(),
}
.eval(builder, verified_proofs)?;
builder.register_public_inputs(&main_pod.id.elements);
builder.register_public_inputs(&main_pod.vds_root.elements);
Ok(main_pod)
}
}
impl InnerCircuit for MainPodVerifyTarget {
type Input = MainPodVerifyInput;
type Params = Params;
fn build(
builder: &mut CircuitBuilder,
params: &Self::Params,
verified_proofs: &[VerifiedProofTarget],
) -> Result<Self> {
MainPodVerifyCircuit {
params: params.clone(),
}
.eval(builder, verified_proofs)
}
/// assigns the values to the targets
fn set_targets(&self, pw: &mut PartialWitness<F>, input: &Self::Input) -> Result<()> {
self.set_targets(pw, input)
}
}
#[cfg(test)]
mod tests {
use std::{iter, ops::Not};
@ -1567,7 +1597,7 @@ mod tests {
..Default::default()
};
let mp_gadget = MerkleProofGadget {
max_depth: params.max_depth_mt_gadget,
max_depth: params.max_depth_mt_containers,
};
let config = CircuitConfig::standard_recursion_config();
@ -1581,7 +1611,7 @@ mod tests {
let merkle_proofs_target: Vec<_> = merkle_proofs
.iter()
.map(|_| mp_gadget.eval(&mut builder))
.collect::<Result<_>>()?;
.collect();
let merkle_claims_target: Vec<_> = merkle_proofs_target
.clone()
.into_iter()
@ -2360,7 +2390,7 @@ mod tests {
]
.into_iter()
.collect();
let mt = MerkleTree::new(params.max_depth_mt_gadget, &kvs)?;
let mt = MerkleTree::new(params.max_depth_mt_containers, &kvs)?;
let root = Value::from(mt.root());
let root_ak = AnchoredKey::from((PodId(RawValue::from(88).into()), "merkle root"));
@ -2400,7 +2430,7 @@ mod tests {
]
.into_iter()
.collect();
let mt = MerkleTree::new(params.max_depth_mt_gadget, &kvs)?;
let mt = MerkleTree::new(params.max_depth_mt_containers, &kvs)?;
let root = Value::from(mt.root());
let root_ak = AnchoredKey::from((PodId(RawValue::from(88).into()), "merkle root"));

View file

@ -41,7 +41,7 @@ impl SignedPodVerifyGadget {
let mut mt_proofs = Vec::new();
for _ in 0..self.params.max_signed_pod_values {
let mt_proof = MerkleProofExistenceGadget {
max_depth: self.params.max_depth_mt_gadget,
max_depth: self.params.max_depth_mt_containers,
}
.eval(builder)?;
builder.connect_hashes(id, mt_proof.root);

View file

@ -27,7 +27,7 @@ use crate::{
},
middleware::{
self, AnchoredKey, DynError, Hash, Params, Pod, PodId, PodType, RecursivePod, Statement,
ToFields, Value, VerifierOnlyCircuitData, EMPTY_HASH, F, HASH_SIZE, KEY_TYPE, SELF,
ToFields, Value, VerifierOnlyCircuitData, F, HASH_SIZE, KEY_TYPE, SELF,
},
timed,
};
@ -80,7 +80,7 @@ pub struct EmptyPod {
type CircuitData = circuit_data::CircuitData<F, C, D>;
static STANDARD_EMPTY_POD_DATA: LazyLock<(EmptyPodVerifyTarget, CircuitData)> =
pub static STANDARD_EMPTY_POD_DATA: LazyLock<(EmptyPodVerifyTarget, CircuitData)> =
LazyLock::new(|| build().expect("successful build"));
fn build() -> Result<(EmptyPodVerifyTarget, CircuitData)> {
@ -144,7 +144,7 @@ impl EmptyPod {
let public_inputs = id
.to_fields(&self.params)
.iter()
.chain(EMPTY_HASH.0.iter()) // slot for the unused vds root
.chain(self.vds_root.0.iter())
.cloned()
.collect_vec();
@ -222,6 +222,7 @@ impl RecursivePod for EmptyPod {
#[cfg(test)]
pub mod tests {
use super::*;
use crate::middleware::EMPTY_HASH;
#[test]
fn test_empty_pod() {

View file

@ -28,7 +28,7 @@ use crate::{
middleware::{
self, resolve_wildcard_values, AnchoredKey, CustomPredicateBatch, DynError, Hash,
MainPodInputs, NativeOperation, NonePod, OperationType, Params, Pod, PodId, PodProver,
PodType, RecursivePod, StatementArg, ToFields, F, KEY_TYPE, SELF,
PodType, RecursivePod, StatementArg, ToFields, VDSet, F, KEY_TYPE, SELF,
},
};
@ -153,11 +153,11 @@ pub(crate) fn extract_merkle_proofs(
_ => None,
})
.collect();
if merkle_proofs.len() > params.max_merkle_proofs {
if merkle_proofs.len() > params.max_merkle_proofs_containers {
return Err(Error::custom(format!(
"The number of required Merkle proofs ({}) exceeds the maximum number ({}).",
merkle_proofs.len(),
params.max_merkle_proofs
params.max_merkle_proofs_containers
)));
}
Ok(merkle_proofs)
@ -283,7 +283,7 @@ pub(crate) fn layout_statements(
// We mocking or we don't need padding so we skip creating an EmptyPod
MockEmptyPod::new_boxed(params)
} else {
EmptyPod::new_boxed(params, inputs.vds_root)
EmptyPod::new_boxed(params, inputs.vds_set.root())
};
let empty_pod = empty_pod_box.as_ref();
assert!(inputs.recursive_pods.len() <= params.max_input_recursive_pods);
@ -410,7 +410,7 @@ pub(crate) fn process_public_statements_operations(
pub struct Prover {}
impl Prover {
fn _prove(&self, params: &Params, inputs: MainPodInputs) -> Result<MainPod> {
fn _prove(&self, params: &Params, vd_set: &VDSet, inputs: MainPodInputs) -> Result<MainPod> {
let rec_circuit_data = &*STANDARD_REC_MAIN_POD_CIRCUIT_DATA;
let (main_pod_target, circuit_data) =
RecursiveCircuit::<MainPodVerifyTarget>::target_and_circuit_data_padded(
@ -445,7 +445,7 @@ impl Prover {
// We don't need padding so we skip creating an EmptyPod
MockEmptyPod::new_boxed(params)
} else {
EmptyPod::new_boxed(params, inputs.vds_root)
EmptyPod::new_boxed(params, inputs.vds_set.root())
};
let inputs = MainPodInputs {
recursive_pods: &inputs
@ -492,10 +492,10 @@ impl Prover {
.recursive_pods
.iter()
.map(|pod| {
assert_eq!(inputs.vds_root, pod.vds_root());
assert_eq!(inputs.vds_set.root(), pod.vds_root());
ProofWithPublicInputs {
proof: pod.proof(),
public_inputs: [pod.id().0 .0, inputs.vds_root.0].concat(),
public_inputs: [pod.id().0 .0, inputs.vds_set.root().0].concat(),
}
})
.collect_vec();
@ -504,8 +504,12 @@ impl Prover {
.iter()
.map(|pod| pod.verifier_data())
.collect_vec();
let vd_mt_proofs = vd_set.get_vds_proofs(&verifier_datas)?;
let input = MainPodVerifyInput {
vds_root: inputs.vds_root,
vds_set: inputs.vds_set.clone(),
vd_mt_proofs,
signed_pods: signed_pods_input,
recursive_pods_pub_self_statements,
statements: statements[statements.len() - params.max_statements..].to_vec(),
@ -519,7 +523,7 @@ impl Prover {
Ok(MainPod {
params: params.clone(),
id,
vds_root: inputs.vds_root,
vds_root: inputs.vds_set.root(),
public_statements,
proof: proof_with_pis.proof,
})
@ -530,9 +534,10 @@ impl PodProver for Prover {
fn prove(
&self,
params: &Params,
vd_set: &VDSet,
inputs: MainPodInputs,
) -> Result<Box<dyn RecursivePod>, Box<DynError>> {
Ok(self._prove(params, inputs).map(Box::new)?)
Ok(self._prove(params, vd_set, inputs).map(Box::new)?)
}
}
@ -540,6 +545,11 @@ impl PodProver for Prover {
pub struct MainPod {
params: Params,
id: PodId,
/// vds_root is the merkle-root of the `VDSet`, which contains the
/// verifier_data hashes of the allowed set of VerifierOnlyCircuitData, for
/// the succession of recursive MainPods, which when proving the POD, it is
/// proven that all the recursive proofs that are being verified in-circuit
/// use one of the verifier_data's contained in the VDSet.
vds_root: Hash,
public_statements: Vec<Statement>,
proof: Proof,
@ -696,7 +706,7 @@ pub mod tests {
{self},
},
middleware,
middleware::{CustomPredicateRef, NativePredicate as NP},
middleware::{CustomPredicateRef, NativePredicate as NP, DEFAULT_VD_SET},
op,
};
@ -711,6 +721,7 @@ pub mod tests {
..Default::default()
};
println!("{:#?}", params);
let vd_set = &*DEFAULT_VD_SET;
let (gov_id_builder, pay_stub_builder, sanction_list_builder) =
zu_kyc_sign_pod_builders(&params);
@ -720,8 +731,13 @@ pub mod tests {
let pay_stub_pod = pay_stub_builder.sign(&mut signer)?;
let mut signer = Signer(SecretKey(3u64.into()));
let sanction_list_pod = sanction_list_builder.sign(&mut signer)?;
let kyc_builder =
zu_kyc_pod_builder(&params, &gov_id_pod, &pay_stub_pod, &sanction_list_pod)?;
let kyc_builder = zu_kyc_pod_builder(
&params,
&vd_set,
&gov_id_pod,
&pay_stub_pod,
&sanction_list_pod,
)?;
let mut prover = Prover {};
let kyc_pod = kyc_builder.prove(&mut prover, &params)?;
@ -742,6 +758,7 @@ pub mod tests {
max_input_pods_public_statements: 10,
..Default::default()
};
let vd_set = &*DEFAULT_VD_SET;
let mut gov_id_builder = frontend::SignedPodBuilder::new(&params);
gov_id_builder.insert("idNumber", "4242424242");
@ -750,7 +767,7 @@ pub mod tests {
let mut signer = Signer(SecretKey(42u64.into()));
let gov_id = gov_id_builder.sign(&mut signer).unwrap();
let now_minus_18y: i64 = 1169909388;
let mut kyc_builder = frontend::MainPodBuilder::new(&params);
let mut kyc_builder = frontend::MainPodBuilder::new(&params, &vd_set);
kyc_builder.add_signed_pod(&gov_id);
kyc_builder
.pub_op(op!(lt, (&gov_id, "dateOfBirth"), now_minus_18y))
@ -792,11 +809,13 @@ pub mod tests {
max_custom_predicate_arity: 2,
max_custom_predicate_wildcards: 2,
max_custom_batch_size: 2,
max_merkle_proofs: 2,
max_depth_mt_gadget: 4,
max_merkle_proofs_containers: 2,
max_depth_mt_containers: 4,
max_depth_mt_vds: 6,
};
let vd_set = &*DEFAULT_VD_SET;
let pod_builder = frontend::MainPodBuilder::new(&params);
let pod_builder = frontend::MainPodBuilder::new(&params, &vd_set);
// Mock
let mut prover = MockProver {};
@ -828,6 +847,7 @@ pub mod tests {
..Default::default()
};
println!("{:#?}", params);
let vd_set = &*DEFAULT_VD_SET;
let mut alice = Signer(SecretKey(1u32.into()));
let bob = Signer(SecretKey(2u32.into()));
@ -842,6 +862,7 @@ pub mod tests {
let alice_bob_ethdos_builder = eth_dos_pod_builder(
&params,
&vd_set,
false,
&alice_attestation,
&charlie_attestation,
@ -878,6 +899,7 @@ pub mod tests {
..Default::default()
};
println!("{:#?}", params);
let vd_set = &*DEFAULT_VD_SET;
let mut cpb_builder = CustomPredicateBatchBuilder::new(params.clone(), "cpb".into());
let stb0 = STB::new(NP::ValueOf)
@ -898,7 +920,7 @@ pub mod tests {
let cpb_and = CustomPredicateRef::new(cpb.clone(), 0);
let _cpb_or = CustomPredicateRef::new(cpb.clone(), 1);
let mut pod_builder = MainPodBuilder::new(&params);
let mut pod_builder = MainPodBuilder::new(&params, &vd_set);
let st0 = pod_builder.priv_op(op!(new_entry, ("score", 42)))?;
let st1 = pod_builder.priv_op(op!(new_entry, ("foo", 42)))?;

View file

@ -19,7 +19,7 @@ use crate::{
},
middleware::{
self, hash_str, AnchoredKey, DynError, Hash, MainPodInputs, NativePredicate, Params, Pod,
PodId, PodProver, PodType, Predicate, RecursivePod, StatementArg, KEY_TYPE, SELF,
PodId, PodProver, PodType, Predicate, RecursivePod, StatementArg, VDSet, KEY_TYPE, SELF,
},
};
@ -29,6 +29,7 @@ impl PodProver for MockProver {
fn prove(
&self,
params: &Params,
_vd_set: &VDSet,
inputs: MainPodInputs,
) -> Result<Box<dyn RecursivePod>, Box<DynError>> {
Ok(Box::new(MockMainPod::new(params, inputs)?))
@ -176,7 +177,7 @@ impl MockMainPod {
Ok(Self {
params: params.clone(),
id,
vds_root: inputs.vds_root,
vds_root: inputs.vds_set.root(),
// input_signed_pods,
// input_main_pods,
// input_statements,
@ -356,12 +357,13 @@ pub mod tests {
zu_kyc_sign_pod_builders,
},
frontend,
middleware::{self},
middleware::{self, DEFAULT_VD_SET},
};
#[test]
fn test_mock_main_zu_kyc() -> frontend::Result<()> {
let params = middleware::Params::default();
let vd_set = &*DEFAULT_VD_SET;
let (gov_id_builder, pay_stub_builder, sanction_list_builder) =
zu_kyc_sign_pod_builders(&params);
let mut signer = MockSigner {
@ -376,8 +378,13 @@ pub mod tests {
pk: "ZooOFAC".into(),
};
let sanction_list_pod = sanction_list_builder.sign(&mut signer)?;
let kyc_builder =
zu_kyc_pod_builder(&params, &gov_id_pod, &pay_stub_pod, &sanction_list_pod)?;
let kyc_builder = zu_kyc_pod_builder(
&params,
&vd_set,
&gov_id_pod,
&pay_stub_pod,
&sanction_list_pod,
)?;
let mut prover = MockProver {};
let kyc_pod = kyc_builder.prove(&mut prover, &params)?;

View file

@ -27,13 +27,13 @@ impl MockSigner {
}
impl MockSigner {
fn _sign(&mut self, _params: &Params, kvs: &HashMap<Key, Value>) -> Result<MockSignedPod> {
fn _sign(&mut self, params: &Params, kvs: &HashMap<Key, Value>) -> Result<MockSignedPod> {
let mut kvs = kvs.clone();
let pubkey = self.public_key();
kvs.insert(Key::from(KEY_SIGNER), Value::from(pubkey));
kvs.insert(Key::from(KEY_TYPE), Value::from(PodType::MockSigned));
let dict = Dictionary::new(kvs.clone())?;
let dict = Dictionary::new(params.max_depth_mt_containers, kvs.clone())?;
let id = PodId(dict.commitment());
let signature = format!("{}_signed_by_{}", id, pubkey);
Ok(MockSignedPod { id, signature, kvs })

View file

@ -42,7 +42,7 @@ pub struct MerkleProofGadget {
pub max_depth: usize,
}
#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct MerkleClaimAndProofTarget {
pub(crate) max_depth: usize,
// `enabled` determines if the merkleproof verification is enabled
@ -59,7 +59,7 @@ pub struct MerkleClaimAndProofTarget {
impl MerkleProofGadget {
/// creates the targets and defines the logic of the circuit
pub fn eval(&self, builder: &mut CircuitBuilder<F, D>) -> Result<MerkleClaimAndProofTarget> {
pub fn eval(&self, builder: &mut CircuitBuilder<F, D>) -> MerkleClaimAndProofTarget {
let measure = measure_gates_begin!(builder, format!("MerkleProof_{}", self.max_depth));
let enabled = builder.add_virtual_bool_target_safe();
let root = builder.add_virtual_hash();
@ -128,7 +128,7 @@ impl MerkleProofGadget {
// (this is for the three cases (existence, non-existence case i, and
// non-existence case ii).
let obtained_root =
compute_root_from_leaf(self.max_depth, builder, &path, &leaf_hash, &siblings)?;
compute_root_from_leaf(self.max_depth, builder, &path, &leaf_hash, &siblings);
// check that obtained_root==root (from inputs), when enabled==true
let zero = builder.zero();
@ -143,7 +143,7 @@ impl MerkleProofGadget {
}
measure_gates_end!(builder, measure);
Ok(MerkleClaimAndProofTarget {
MerkleClaimAndProofTarget {
max_depth: self.max_depth,
enabled,
existence,
@ -154,7 +154,7 @@ impl MerkleProofGadget {
case_ii_selector,
other_key,
other_value,
})
}
}
}
@ -241,7 +241,7 @@ impl MerkleProofExistenceGadget {
// compute the root for the given siblings and the computed leaf_hash.
let obtained_root =
compute_root_from_leaf(self.max_depth, builder, &path, &leaf_hash, &siblings)?;
compute_root_from_leaf(self.max_depth, builder, &path, &leaf_hash, &siblings);
// check that obtained_root==root (from inputs), when enabled==true
let zero = builder.zero();
@ -305,7 +305,7 @@ fn compute_root_from_leaf(
path: &[BoolTarget],
leaf_hash: &HashOutTarget,
siblings: &[HashOutTarget],
) -> Result<HashOutTarget> {
) -> HashOutTarget {
assert_eq!(siblings.len(), max_depth);
// Convenience constants
let zero = builder.zero();
@ -356,7 +356,7 @@ fn compute_root_from_leaf(
.collect();
h = HashOutTarget::from_vec(h_targ);
}
Ok(h)
h
}
// Note: this logic is in its own method for easy of reusability but
@ -546,7 +546,7 @@ pub mod tests {
let mut builder = CircuitBuilder::<F, D>::new(config);
let mut pw = PartialWitness::<F>::new();
let targets = MerkleProofGadget { max_depth }.eval(&mut builder)?;
let targets = MerkleProofGadget { max_depth }.eval(&mut builder);
targets.set_targets(
&mut pw,
true,
@ -667,7 +667,7 @@ pub mod tests {
let mut builder = CircuitBuilder::<F, D>::new(config);
let mut pw = PartialWitness::<F>::new();
let targets = MerkleProofGadget { max_depth }.eval(&mut builder)?;
let targets = MerkleProofGadget { max_depth }.eval(&mut builder);
targets.set_targets(
&mut pw,
true,
@ -714,7 +714,7 @@ pub mod tests {
let mut builder = CircuitBuilder::<F, D>::new(config);
let mut pw = PartialWitness::<F>::new();
let targets = MerkleProofGadget { max_depth }.eval(&mut builder)?;
let targets = MerkleProofGadget { max_depth }.eval(&mut builder);
// verification enabled & proof of existence
let mp = MerkleClaimAndProof::new(tree2.root(), key, Some(value), proof);
targets.set_targets(&mut pw, true, &mp)?;
@ -730,7 +730,7 @@ pub mod tests {
let mut builder = CircuitBuilder::<F, D>::new(config);
let mut pw = PartialWitness::<F>::new();
let targets = MerkleProofGadget { max_depth }.eval(&mut builder)?;
let targets = MerkleProofGadget { max_depth }.eval(&mut builder);
// verification disabled & proof of existence
targets.set_targets(&mut pw, false, &mp)?;

View file

@ -28,13 +28,13 @@ use crate::{
pub struct Signer(pub SecretKey);
impl Signer {
fn _sign(&mut self, _params: &Params, kvs: &HashMap<Key, Value>) -> Result<SignedPod> {
fn _sign(&mut self, params: &Params, kvs: &HashMap<Key, Value>) -> Result<SignedPod> {
let mut kvs = kvs.clone();
let pubkey = self.0.public_key();
kvs.insert(Key::from(KEY_SIGNER), Value::from(pubkey));
kvs.insert(Key::from(KEY_TYPE), Value::from(PodType::Signed));
let dict = Dictionary::new(kvs)?;
let dict = Dictionary::new(params.max_depth_mt_containers, kvs)?;
let id = RawValue::from(dict.commitment()); // PodId as Value
let nonce = OsRng.gen_biguint_below(&GROUP_ORDER);
@ -232,7 +232,7 @@ pub mod tests {
.into_iter()
.chain(iter::once(bad_kv))
.collect::<HashMap<Key, Value>>();
bad_pod.dict = Dictionary::new(bad_kvs).unwrap();
bad_pod.dict = Dictionary::new(params.max_depth_mt_containers, bad_kvs).unwrap();
assert!(bad_pod.verify().is_err());
let mut bad_pod = pod.clone();
@ -244,7 +244,7 @@ pub mod tests {
.into_iter()
.chain(iter::once(bad_kv))
.collect::<HashMap<Key, Value>>();
bad_pod.dict = Dictionary::new(bad_kvs).unwrap();
bad_pod.dict = Dictionary::new(params.max_depth_mt_containers, bad_kvs).unwrap();
assert!(bad_pod.verify().is_err());
Ok(())