Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
17 changes: 10 additions & 7 deletions src/backends/plonky2/circuits/mainpod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,10 +492,14 @@ impl MainPodVerifyTarget {
self.statements[i].set_targets(pw, &self.params, st)?;
self.operations[i].set_targets(pw, &self.params, op)?;
}
assert_eq!(input.merkle_proofs.len(), self.params.max_merkle_proofs);
assert!(input.merkle_proofs.len() <= self.params.max_merkle_proofs);
for (i, mp) in input.merkle_proofs.iter().enumerate() {
assert_eq!(mp.proof.siblings.len(), self.params.max_depth_mt_gadget);
self.merkle_proofs[i].set_targets(pw, mp)?;
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 {
self.merkle_proofs[i].set_targets(pw, false, &pad_mp)?;
}
Ok(())
}
Expand Down Expand Up @@ -579,7 +583,7 @@ mod tests {
for (merkle_proof_target, merkle_proof) in
merkle_proofs_target.iter().zip(merkle_proofs.iter())
{
merkle_proof_target.set_targets(&mut pw, &merkle_proof)?
merkle_proof_target.set_targets(&mut pw, true, &merkle_proof)?
}

// generate & verify proof
Expand Down Expand Up @@ -707,12 +711,11 @@ mod tests {
);

let merkle_proofs = vec![MerkleClaimAndProof::new(
params.max_depth_mt_gadget,
Hash::from(root.raw()),
key,
None,
&no_key_pf,
)?];
no_key_pf,
)];
let prev_statements = vec![root_st, key_st];
operation_verify(st, op, prev_statements, merkle_proofs.clone())?;

Expand Down
22 changes: 6 additions & 16 deletions src/backends/plonky2/circuits/signedpod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,8 @@ impl SignedPodVerifyTarget {
let (v, proof) = pod.dict.prove(k)?;
self.mt_proofs[i].set_targets(
pw,
&MerkleClaimAndProof::new(
self.params.max_depth_mt_gadget,
pod.dict.commitment(),
k.raw(),
Some(v.raw()),
&proof,
)?,
true,
&MerkleClaimAndProof::new(pod.dict.commitment(), k.raw(), Some(v.raw()), proof),
)?;
Ok(v)
})
Expand All @@ -160,24 +155,19 @@ impl SignedPodVerifyTarget {

self.mt_proofs[curr].set_targets(
pw,
&MerkleClaimAndProof::new(
self.params.max_depth_mt_gadget,
pod.dict.commitment(),
k.raw(),
Some(v.raw()),
&proof,
)?,
true,
&MerkleClaimAndProof::new(pod.dict.commitment(), k.raw(), Some(v.raw()), proof),
)?;
curr += 1;
}
// sanity check
assert!(curr <= self.params.max_signed_pod_values);

// add the proofs of empty leaves (if needed), till the max_signed_pod_values
let mut mp = MerkleClaimAndProof::empty(self.params.max_depth_mt_gadget);
let mut mp = MerkleClaimAndProof::empty();
mp.root = pod.dict.commitment();
for i in curr..self.params.max_signed_pod_values {
self.mt_proofs[i].set_targets(pw, &mp)?;
self.mt_proofs[i].set_targets(pw, false, &mp)?;
}

// get the signer pk
Expand Down
32 changes: 9 additions & 23 deletions src/backends/plonky2/mainpod/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use crate::{
backends::plonky2::{
basetypes::{C, D},
circuits::mainpod::{MainPodVerifyCircuit, MainPodVerifyInput},
primitives::{merkletree, merkletree::MerkleClaimAndProof},
primitives::merkletree::MerkleClaimAndProof,
signedpod::SignedPod,
},
middleware::{
Expand All @@ -42,7 +42,7 @@ pub(crate) fn extract_merkle_proofs(
params: &Params,
operations: &[middleware::Operation],
) -> Result<Vec<MerkleClaimAndProof>> {
let mut merkle_proofs = operations
let merkle_proofs: Vec<_> = operations
.iter()
.flat_map(|op| match op {
middleware::Operation::ContainsFromEntries(
Expand All @@ -51,40 +51,32 @@ pub(crate) fn extract_merkle_proofs(
middleware::Statement::ValueOf(_, value),
pf,
) => Some(MerkleClaimAndProof::new(
params.max_depth_mt_gadget,
Hash::from(root.raw()),
key.raw(),
Some(value.raw()),
pf,
pf.clone(),
)),
middleware::Operation::NotContainsFromEntries(
middleware::Statement::ValueOf(_, root),
middleware::Statement::ValueOf(_, key),
pf,
) => Some(MerkleClaimAndProof::new(
params.max_depth_mt_gadget,
Hash::from(root.raw()),
key.raw(),
None,
pf,
pf.clone(),
)),
_ => None,
})
.collect::<Result<Vec<_>>>()?;
.collect();
if merkle_proofs.len() > params.max_merkle_proofs {
Err(anyhow!(
return Err(anyhow!(
"The number of required Merkle proofs ({}) exceeds the maximum number ({}).",
merkle_proofs.len(),
params.max_merkle_proofs
))
} else {
fill_pad(
&mut merkle_proofs,
MerkleClaimAndProof::empty(params.max_depth_mt_gadget),
params.max_merkle_proofs,
);
Ok(merkle_proofs)
));
}
Ok(merkle_proofs)
}

/// Find the operation argument statement in the list of previous statements and return the index.
Expand Down Expand Up @@ -115,12 +107,7 @@ fn find_op_aux(
middleware::OperationAux::MerkleProof(pf_arg) => merkle_proofs
.iter()
.enumerate()
.find_map(|(i, pf)| {
pf.clone()
.try_into()
.ok()
.and_then(|mid_pf: merkletree::MerkleProof| (&mid_pf == pf_arg).then_some(i))
})
.find_map(|(i, pf)| (pf.proof == *pf_arg).then_some(i))
.map(OperationAux::MerkleProofIndex)
.ok_or(anyhow!(
"Merkle proof corresponding to op arg {} not found",
Expand Down Expand Up @@ -293,7 +280,6 @@ pub(crate) fn process_public_statements_operations(
pub struct Prover {}

impl PodProver for Prover {
// TODO: Be consistent on where we apply the padding, here, or in the set_targets?
fn prove(&mut self, params: &Params, inputs: MainPodInputs) -> Result<Box<dyn Pod>> {
let config = CircuitConfig::standard_recursion_config();
let mut builder = CircuitBuilder::<F, D>::new(config);
Expand Down
19 changes: 9 additions & 10 deletions src/backends/plonky2/mainpod/operation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,15 @@ impl Operation {
})
.collect::<Result<Vec<_>>>()?;
let deref_aux = match self.2 {
OperationAux::None => Ok(crate::middleware::OperationAux::None),
OperationAux::MerkleProofIndex(i) => merkle_proofs
.get(i)
.cloned()
.ok_or(anyhow!("Missing Merkle proof index {}", i))
.and_then(|mp| {
mp.try_into()
.map(crate::middleware::OperationAux::MerkleProof)
}),
}?;
OperationAux::None => crate::middleware::OperationAux::None,
OperationAux::MerkleProofIndex(i) => crate::middleware::OperationAux::MerkleProof(
merkle_proofs
.get(i)
.ok_or(anyhow!("Missing Merkle proof index {}", i))?
.proof
.clone(),
),
};
middleware::Operation::op(self.0.clone(), &deref_args, &deref_aux)
}
}
Expand Down
80 changes: 10 additions & 70 deletions src/backends/plonky2/primitives/merkletree.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
//! Module that implements the MerkleTree specified at
//! https://0xparc.github.io/pod2/merkletree.html .
use std::{
collections::HashMap,
fmt,
iter::{self, IntoIterator},
};
use std::{collections::HashMap, fmt, iter::IntoIterator};

use anyhow::{anyhow, Result};
use plonky2::field::types::Field;
Expand Down Expand Up @@ -266,94 +262,38 @@ impl MerkleProof {

#[derive(Clone, Debug, PartialEq)]
pub struct MerkleClaimAndProof {
/// `enabled` determines if the merkleproof verification is enabled
pub enabled: bool,
pub root: Hash,
pub key: RawValue,
pub value: RawValue,
/// The siblings in this proof are padded to max_depth
pub proof: MerkleProof,
}

impl MerkleClaimAndProof {
pub fn empty(max_depth: usize) -> Self {
pub fn empty() -> Self {
Self {
enabled: false,
root: EMPTY_HASH,
key: EMPTY_VALUE,
value: EMPTY_VALUE,
proof: MerkleProof {
existence: true,
siblings: iter::repeat(EMPTY_HASH).take(max_depth).collect(),
siblings: vec![],
other_leaf: None,
},
}
}
pub fn new(
max_depth: usize,
root: Hash,
key: RawValue,
value: Option<RawValue>,
proof: &MerkleProof,
) -> Result<Self> {
if proof.siblings.len() > max_depth {
Err(anyhow!(
"Number of siblings ({}) exceeds maximum depth ({})",
proof.siblings.len(),
max_depth
))
} else {
Ok(Self {
enabled: true,
root,
key,
value: value.unwrap_or(EMPTY_VALUE),
proof: MerkleProof {
existence: proof.existence,
siblings: proof
.siblings
.iter()
.cloned()
.chain(iter::repeat(EMPTY_HASH))
.take(max_depth)
.collect(),
other_leaf: proof.other_leaf,
},
})
}
}
}

impl TryFrom<MerkleClaimAndProof> for MerkleProof {
type Error = anyhow::Error;
fn try_from(mp: MerkleClaimAndProof) -> Result<Self> {
if !mp.enabled {
return Err(anyhow!("Not a valid Merkle proof."));
pub fn new(root: Hash, key: RawValue, value: Option<RawValue>, proof: MerkleProof) -> Self {
Self {
root,
key,
value: value.unwrap_or(EMPTY_VALUE),
proof,
}
Ok(MerkleProof {
existence: mp.proof.existence,
// Trim padding (if any).
siblings: mp
.proof
.siblings
.into_iter()
.rev()
.skip_while(|s| s == &EMPTY_HASH)
.collect::<Vec<_>>()
.into_iter()
.rev()
.collect(),
other_leaf: mp.proof.other_leaf,
})
}
}

impl fmt::Display for MerkleClaimAndProof {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match MerkleProof::try_from(self.clone()) {
Err(_) => write!(f, "∅"),
Ok(mp) => mp.fmt(f),
}
self.proof.fmt(f)
}
}

Expand Down
Loading
Loading