mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-04 06:43:07 +00:00
Tweak Merkle proof API and make it public (#588)
- Add `_to_cap` to existing methods for clarity - Add variants which deal with Merkle roots instead of caps - Simplify `verify_merkle_proof_to_cap` - it can call `verify_merkle_proof_to_cap_with_cap_index` - Make them all public except `verify_merkle_proof_to_cap_with_cap_index`, which is pretty niche
This commit is contained in:
parent
e3834a5335
commit
dec0765fb5
@ -208,7 +208,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
|||||||
with_context!(
|
with_context!(
|
||||||
self,
|
self,
|
||||||
&format!("verify {}'th initial Merkle proof", i),
|
&format!("verify {}'th initial Merkle proof", i),
|
||||||
self.verify_merkle_proof_with_cap_index::<H>(
|
self.verify_merkle_proof_to_cap_with_cap_index::<H>(
|
||||||
evals.clone(),
|
evals.clone(),
|
||||||
x_index_bits,
|
x_index_bits,
|
||||||
cap_index,
|
cap_index,
|
||||||
@ -351,7 +351,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
|||||||
with_context!(
|
with_context!(
|
||||||
self,
|
self,
|
||||||
"verify FRI round Merkle proof.",
|
"verify FRI round Merkle proof.",
|
||||||
self.verify_merkle_proof_with_cap_index::<C::Hasher>(
|
self.verify_merkle_proof_to_cap_with_cap_index::<C::Hasher>(
|
||||||
flatten_target(evals),
|
flatten_target(evals),
|
||||||
&coset_index_bits,
|
&coset_index_bits,
|
||||||
cap_index,
|
cap_index,
|
||||||
|
|||||||
@ -8,7 +8,7 @@ use crate::fri::proof::{FriChallenges, FriInitialTreeProof, FriProof, FriQueryRo
|
|||||||
use crate::fri::structure::{FriBatchInfo, FriInstanceInfo, FriOpenings};
|
use crate::fri::structure::{FriBatchInfo, FriInstanceInfo, FriOpenings};
|
||||||
use crate::fri::{FriConfig, FriParams};
|
use crate::fri::{FriConfig, FriParams};
|
||||||
use crate::hash::hash_types::RichField;
|
use crate::hash::hash_types::RichField;
|
||||||
use crate::hash::merkle_proofs::verify_merkle_proof;
|
use crate::hash::merkle_proofs::verify_merkle_proof_to_cap;
|
||||||
use crate::hash::merkle_tree::MerkleCap;
|
use crate::hash::merkle_tree::MerkleCap;
|
||||||
use crate::plonk::config::{GenericConfig, Hasher};
|
use crate::plonk::config::{GenericConfig, Hasher};
|
||||||
use crate::util::reducing::ReducingFactor;
|
use crate::util::reducing::ReducingFactor;
|
||||||
@ -116,7 +116,7 @@ where
|
|||||||
[(); H::HASH_SIZE]:,
|
[(); H::HASH_SIZE]:,
|
||||||
{
|
{
|
||||||
for ((evals, merkle_proof), cap) in proof.evals_proofs.iter().zip(initial_merkle_caps) {
|
for ((evals, merkle_proof), cap) in proof.evals_proofs.iter().zip(initial_merkle_caps) {
|
||||||
verify_merkle_proof::<F, H>(evals.clone(), x_index, cap, merkle_proof)?;
|
verify_merkle_proof_to_cap::<F, H>(evals.clone(), x_index, cap, merkle_proof)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -224,7 +224,7 @@ where
|
|||||||
challenges.fri_betas[i],
|
challenges.fri_betas[i],
|
||||||
);
|
);
|
||||||
|
|
||||||
verify_merkle_proof::<F, C::Hasher>(
|
verify_merkle_proof_to_cap::<F, C::Hasher>(
|
||||||
flatten(evals),
|
flatten(evals),
|
||||||
coset_index,
|
coset_index,
|
||||||
&proof.commit_phase_merkle_caps[i],
|
&proof.commit_phase_merkle_caps[i],
|
||||||
|
|||||||
@ -13,7 +13,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
|||||||
/// bit of the integer, with little-endian ordering.
|
/// bit of the integer, with little-endian ordering.
|
||||||
/// Verifies that the decomposition is correct by using `k` `BaseSum<2>` gates
|
/// Verifies that the decomposition is correct by using `k` `BaseSum<2>` gates
|
||||||
/// with `k` such that `k * num_routed_wires >= num_bits`.
|
/// with `k` such that `k * num_routed_wires >= num_bits`.
|
||||||
pub(crate) fn split_le(&mut self, integer: Target, num_bits: usize) -> Vec<BoolTarget> {
|
pub fn split_le(&mut self, integer: Target, num_bits: usize) -> Vec<BoolTarget> {
|
||||||
if num_bits == 0 {
|
if num_bits == 0 {
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,9 +23,24 @@ pub struct MerkleProofTarget {
|
|||||||
pub siblings: Vec<HashOutTarget>,
|
pub siblings: Vec<HashOutTarget>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Verifies that the given leaf data is present at the given index in the Merkle tree with the
|
||||||
|
/// given root.
|
||||||
|
pub fn verify_merkle_proof<F: RichField, H: Hasher<F>>(
|
||||||
|
leaf_data: Vec<F>,
|
||||||
|
leaf_index: usize,
|
||||||
|
merkle_root: H::Hash,
|
||||||
|
proof: &MerkleProof<F, H>,
|
||||||
|
) -> Result<()>
|
||||||
|
where
|
||||||
|
[(); H::HASH_SIZE]:,
|
||||||
|
{
|
||||||
|
let merkle_cap = MerkleCap(vec![merkle_root]);
|
||||||
|
verify_merkle_proof_to_cap(leaf_data, leaf_index, &merkle_cap, proof)
|
||||||
|
}
|
||||||
|
|
||||||
/// Verifies that the given leaf data is present at the given index in the Merkle tree with the
|
/// Verifies that the given leaf data is present at the given index in the Merkle tree with the
|
||||||
/// given cap.
|
/// given cap.
|
||||||
pub(crate) fn verify_merkle_proof<F: RichField, H: Hasher<F>>(
|
pub fn verify_merkle_proof_to_cap<F: RichField, H: Hasher<F>>(
|
||||||
leaf_data: Vec<F>,
|
leaf_data: Vec<F>,
|
||||||
leaf_index: usize,
|
leaf_index: usize,
|
||||||
merkle_cap: &MerkleCap<F, H>,
|
merkle_cap: &MerkleCap<F, H>,
|
||||||
@ -55,37 +70,40 @@ where
|
|||||||
|
|
||||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||||
/// Verifies that the given leaf data is present at the given index in the Merkle tree with the
|
/// Verifies that the given leaf data is present at the given index in the Merkle tree with the
|
||||||
/// given cap. The index is given by it's little-endian bits.
|
/// given root. The index is given by its little-endian bits.
|
||||||
#[cfg(test)]
|
pub fn verify_merkle_proof<H: AlgebraicHasher<F>>(
|
||||||
pub(crate) fn verify_merkle_proof<H: AlgebraicHasher<F>>(
|
&mut self,
|
||||||
|
leaf_data: Vec<Target>,
|
||||||
|
leaf_index_bits: &[BoolTarget],
|
||||||
|
merkle_root: HashOutTarget,
|
||||||
|
proof: &MerkleProofTarget,
|
||||||
|
) {
|
||||||
|
let merkle_cap = MerkleCapTarget(vec![merkle_root]);
|
||||||
|
self.verify_merkle_proof_to_cap::<H>(leaf_data, leaf_index_bits, &merkle_cap, proof);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Verifies that the given leaf data is present at the given index in the Merkle tree with the
|
||||||
|
/// given cap. The index is given by its little-endian bits.
|
||||||
|
pub fn verify_merkle_proof_to_cap<H: AlgebraicHasher<F>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
leaf_data: Vec<Target>,
|
leaf_data: Vec<Target>,
|
||||||
leaf_index_bits: &[BoolTarget],
|
leaf_index_bits: &[BoolTarget],
|
||||||
merkle_cap: &MerkleCapTarget,
|
merkle_cap: &MerkleCapTarget,
|
||||||
proof: &MerkleProofTarget,
|
proof: &MerkleProofTarget,
|
||||||
) {
|
) {
|
||||||
let zero = self.zero();
|
let cap_index = self.le_sum(leaf_index_bits[proof.siblings.len()..].iter().copied());
|
||||||
let mut state: HashOutTarget = self.hash_or_noop::<H>(leaf_data);
|
self.verify_merkle_proof_to_cap_with_cap_index::<H>(
|
||||||
|
leaf_data,
|
||||||
for (&bit, &sibling) in leaf_index_bits.iter().zip(&proof.siblings) {
|
leaf_index_bits,
|
||||||
let mut perm_inputs = [zero; SPONGE_WIDTH];
|
cap_index,
|
||||||
perm_inputs[..4].copy_from_slice(&state.elements);
|
merkle_cap,
|
||||||
perm_inputs[4..8].copy_from_slice(&sibling.elements);
|
proof,
|
||||||
let outputs = self.permute_swapped::<H>(perm_inputs, bit);
|
);
|
||||||
state = HashOutTarget::from_vec(outputs[0..4].to_vec());
|
|
||||||
}
|
|
||||||
|
|
||||||
let index = self.le_sum(leaf_index_bits[proof.siblings.len()..].iter().copied());
|
|
||||||
|
|
||||||
for i in 0..4 {
|
|
||||||
let result =
|
|
||||||
self.random_access(index, merkle_cap.0.iter().map(|h| h.elements[i]).collect());
|
|
||||||
self.connect(result, state.elements[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Same as `verify_merkle_proof` but with the final "cap index" as extra parameter.
|
/// Same as `verify_merkle_proof_to_cap`, except with the final "cap index" as separate parameter,
|
||||||
pub(crate) fn verify_merkle_proof_with_cap_index<H: AlgebraicHasher<F>>(
|
/// rather than being contained in `leaf_index_bits`.
|
||||||
|
pub(crate) fn verify_merkle_proof_to_cap_with_cap_index<H: AlgebraicHasher<F>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
leaf_data: Vec<Target>,
|
leaf_data: Vec<Target>,
|
||||||
leaf_index_bits: &[BoolTarget],
|
leaf_index_bits: &[BoolTarget],
|
||||||
@ -176,7 +194,7 @@ mod tests {
|
|||||||
pw.set_target(data[j], tree.leaves[i][j]);
|
pw.set_target(data[j], tree.leaves[i][j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.verify_merkle_proof::<<C as GenericConfig<D>>::InnerHasher>(
|
builder.verify_merkle_proof_to_cap::<<C as GenericConfig<D>>::InnerHasher>(
|
||||||
data, &i_bits, &cap_t, &proof_t,
|
data, &i_bits, &cap_t, &proof_t,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -209,7 +209,7 @@ mod tests {
|
|||||||
use plonky2_field::extension::Extendable;
|
use plonky2_field::extension::Extendable;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::hash::merkle_proofs::verify_merkle_proof;
|
use crate::hash::merkle_proofs::verify_merkle_proof_to_cap;
|
||||||
use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig};
|
use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig};
|
||||||
|
|
||||||
fn random_data<F: RichField>(n: usize, k: usize) -> Vec<Vec<F>> {
|
fn random_data<F: RichField>(n: usize, k: usize) -> Vec<Vec<F>> {
|
||||||
@ -226,7 +226,7 @@ mod tests {
|
|||||||
let tree = MerkleTree::<F, C::Hasher>::new(leaves.clone(), cap_height);
|
let tree = MerkleTree::<F, C::Hasher>::new(leaves.clone(), cap_height);
|
||||||
for (i, leaf) in leaves.into_iter().enumerate() {
|
for (i, leaf) in leaves.into_iter().enumerate() {
|
||||||
let proof = tree.prove(i);
|
let proof = tree.prove(i);
|
||||||
verify_merkle_proof(leaf, i, &tree.cap, &proof)?;
|
verify_merkle_proof_to_cap(leaf, i, &tree.cap, &proof)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user