Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions src/backends/plonky2/basetypes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,87 @@ 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()
});

/// 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)
}
}
2 changes: 1 addition & 1 deletion src/backends/plonky2/circuits/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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],
}
Expand Down
53 changes: 41 additions & 12 deletions src/backends/plonky2/circuits/mainpod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1220,9 +1220,28 @@ 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);

// 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 {
Expand All @@ -1247,11 +1266,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()
Expand Down Expand Up @@ -1310,6 +1329,7 @@ impl MainPodVerifyGadget {
Ok(MainPodVerifyTarget {
params: params.clone(),
vds_root,
vd_mt_proofs,
id,
signed_pods,
input_pods_self_statements,
Expand All @@ -1325,6 +1345,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>>,
Expand All @@ -1345,6 +1366,7 @@ pub struct CustomPredicateVerification {

pub struct MainPodVerifyInput {
pub vds_root: Hash,
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>,
Expand Down Expand Up @@ -1386,6 +1408,13 @@ impl MainPodVerifyTarget {
) -> Result<()> {
pw.set_target_arr(&self.vds_root.elements, &input.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)?;
}
for i in input.vd_mt_proofs.len()..self.vd_mt_proofs.len() {
self.vd_mt_proofs[i].set_targets(pw, false, &input.vd_mt_proofs[i])?;
}

assert!(input.signed_pods.len() <= self.params.max_input_signed_pods);
for (i, signed_pod) in input.signed_pods.iter().enumerate() {
self.signed_pods[i].set_targets(pw, signed_pod)?;
Expand Down Expand Up @@ -1434,13 +1463,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)?;
}

Expand Down Expand Up @@ -1567,7 +1596,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();
Expand All @@ -1581,7 +1610,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()
Expand Down Expand Up @@ -2360,7 +2389,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"));
Expand Down Expand Up @@ -2400,7 +2429,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"));
Expand Down
2 changes: 1 addition & 1 deletion src/backends/plonky2/circuits/signedpod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
7 changes: 4 additions & 3 deletions src/backends/plonky2/emptypod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down Expand Up @@ -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)> {
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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() {
Expand Down
Loading
Loading