From e8eb658f8ec046dd840bce6e45aa54a598c1a165 Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Tue, 6 Apr 2021 19:11:21 -0700 Subject: [PATCH] Candidate API for Merkle proof data Does this make sense? I think other libraries tend to include the leaf's index (either as an integer, or a series of bits indicating left/right turns) as part of a "proof". In FRI, the leaf indices are chosen by the verifier, so I thought that approach might be sort of redundant. Let me know what you think though. --- src/gadgets/merkle_proofs.rs | 24 ++++++++++++++++++++++++ src/gadgets/mod.rs | 3 ++- src/proof.rs | 21 +++++++++++++-------- src/prover.rs | 3 +++ 4 files changed, 42 insertions(+), 9 deletions(-) create mode 100644 src/gadgets/merkle_proofs.rs diff --git a/src/gadgets/merkle_proofs.rs b/src/gadgets/merkle_proofs.rs new file mode 100644 index 00000000..97f2ba2b --- /dev/null +++ b/src/gadgets/merkle_proofs.rs @@ -0,0 +1,24 @@ +use crate::circuit_builder::CircuitBuilder; +use crate::field::field::Field; +use crate::target::Target; + +pub struct MerkleProof { + /// The Merkle digest of each sibling subtree, staying from the bottommost layer. + pub siblings: Vec, +} + +pub struct MerkleProofTarget { + /// The Merkle digest of each sibling subtree, staying from the bottommost layer. + pub siblings: Vec, +} + +impl CircuitBuilder { + pub(crate) fn verify_merkle_proof( + &mut self, + leaf_index: Target, + leaf_data: Vec, + proof: MerkleProofTarget, + ) { + todo!() + } +} diff --git a/src/gadgets/mod.rs b/src/gadgets/mod.rs index f2c22478..8407efe7 100644 --- a/src/gadgets/mod.rs +++ b/src/gadgets/mod.rs @@ -1,3 +1,4 @@ pub(crate) mod arithmetic; -pub(crate) mod split_join; pub(crate) mod hash; +pub(crate) mod merkle_proofs; +pub(crate) mod split_join; diff --git a/src/proof.rs b/src/proof.rs index e9e61888..9bfd5843 100644 --- a/src/proof.rs +++ b/src/proof.rs @@ -1,5 +1,6 @@ use crate::field::field::Field; use crate::target::Target; +use crate::gadgets::merkle_proofs::{MerkleProofTarget, MerkleProof}; /// Represents a ~256 bit hash output. #[derive(Copy, Clone, Debug)] @@ -32,7 +33,8 @@ pub struct Proof { /// Purported values of each polynomial at each challenge point. pub openings: Vec>, - // TODO: FRI Merkle proofs. + /// A FRI argument for each FRI query. + pub fri_proofs: Vec>, } pub struct ProofTarget { @@ -50,22 +52,25 @@ pub struct ProofTarget { pub fri_proofs: Vec, } +pub struct FriProof { + /// Merkle proofs for the original purported codewords, i.e. the subject of the LDT. + pub initial_merkle_proofs: Vec>, + /// Merkle proofs for the reduced polynomials that were sent in the commit phase. + pub intermediate_merkle_proofs: Vec>, + /// The final polynomial in coefficient form. + pub final_poly: Vec, +} + /// Represents a single FRI query, i.e. a path through the reduction tree. pub struct FriProofTarget { /// Merkle proofs for the original purported codewords, i.e. the subject of the LDT. pub initial_merkle_proofs: Vec, /// Merkle proofs for the reduced polynomials that were sent in the commit phase. pub intermediate_merkle_proofs: Vec, - /// The final polynomial in point-value form. + /// The final polynomial in coefficient form. pub final_poly: Vec, } -pub struct MerkleProofTarget { - pub leaf: Vec, - pub siblings: Vec, - // TODO: Also need left/right turn info. -} - /// The purported values of each polynomial at a single point. pub struct OpeningSet { pub constants: Vec, diff --git a/src/prover.rs b/src/prover.rs index fe60e697..d4de3f5d 100644 --- a/src/prover.rs +++ b/src/prover.rs @@ -111,6 +111,8 @@ pub(crate) fn prove( let openings = Vec::new(); // TODO + let fri_proofs = Vec::new(); // TODO + info!("{:.3}s for overall witness & proof generation", start_proof_gen.elapsed().as_secs_f32()); @@ -119,6 +121,7 @@ pub(crate) fn prove( plonk_zs_root, quotient_polys_root, openings, + fri_proofs, } }