arnaucube
arnaucube/ark-r1cs-stdPublic Self-hosted repository
Merkle Tree name refactors
Pratyush Mishra pratyushmishra@berkeley.edu
Fri, 11 Oct 2019 19:24:21 -0700
commit

2a86b591387b17dda32d4de8a0df3dddebf34e7e

parent

25e35a25d06957f5fd782eb2570f89020d6f65ec

M crypto-primitives/src/lib.rs → crypto-primitives/src/lib.rs

@@ -6,7 +6,7 @@ extern crate derivative;

pub mod commitment; pub mod crh; -pub mod mht; +pub mod merkle_tree; pub mod nizk; pub mod prf; pub mod signature;

@@ -14,7 +14,7 @@

pub use self::{ commitment::CommitmentScheme, crh::FixedLengthCRH, - mht::{HashMembershipProof, MerkleHashTree}, + merkle_tree::{MerkleTreePath, MerkleHashTree}, nizk::NIZK, prf::PRF, signature::SignatureScheme,

@@ -24,7 +24,7 @@ #[cfg(feature = "r1cs")]

pub use self::{ commitment::CommitmentGadget, crh::FixedLengthCRHGadget, - mht::constraints::{MerklePath, MerklePathVerifierGadget}, + merkle_tree::constraints::MerkleTreePathGadget, nizk::NIZKVerifierGadget, prf::PRFGadget, signature::SigRandomizePkGadget,
M crypto-primitives/src/mht/constraints.rs → crypto-primitives/src/merkle_tree/constraints.rs

@@ -3,63 +3,51 @@ use r1cs_core::{ConstraintSystem, SynthesisError};

use r1cs_std::prelude::*; use r1cs_std::boolean::AllocatedBit; -use crate::mht::*; +use crate::merkle_tree::*; use crate::crh::{FixedLengthCRH, FixedLengthCRHGadget}; -use std::{borrow::Borrow, marker::PhantomData}; +use std::borrow::Borrow; -pub struct MerklePath<P, HGadget, ConstraintF> +pub struct MerkleTreePathGadget<P, HGadget, ConstraintF> where - P: MHTParameters, + P: MerkleTreeConfig, HGadget: FixedLengthCRHGadget<P::H, ConstraintF>, ConstraintF: Field, { path: Vec<(HGadget::OutputGadget, HGadget::OutputGadget)>, } -pub struct MerklePathVerifierGadget<P, CRHGadget, ConstraintF> -where - P: MHTParameters, - ConstraintF: Field, - CRHGadget: FixedLengthCRHGadget<P::H, ConstraintF>, -{ - _p: PhantomData<CRHGadget>, - _p2: PhantomData<P>, - _f: PhantomData<ConstraintF>, -} - -impl<P, CRHGadget, ConstraintF> MerklePathVerifierGadget<P, CRHGadget, ConstraintF> +impl<P, CRHGadget, ConstraintF> MerkleTreePathGadget<P, CRHGadget, ConstraintF> where - P: MHTParameters, + P: MerkleTreeConfig, ConstraintF: Field, CRHGadget: FixedLengthCRHGadget<P::H, ConstraintF>, { pub fn check_membership<CS: ConstraintSystem<ConstraintF>>( + &self, cs: CS, parameters: &CRHGadget::ParametersGadget, root: &CRHGadget::OutputGadget, leaf: impl ToBytesGadget<ConstraintF>, - witness: &MerklePath<P, CRHGadget, ConstraintF>, ) -> Result<(), SynthesisError> { - Self::conditionally_check_membership( + self.conditionally_check_membership( cs, parameters, root, leaf, - witness, &Boolean::Constant(true), ) } pub fn conditionally_check_membership<CS: ConstraintSystem<ConstraintF>>( + &self, mut cs: CS, parameters: &CRHGadget::ParametersGadget, root: &CRHGadget::OutputGadget, leaf: impl ToBytesGadget<ConstraintF>, - witness: &MerklePath<P, CRHGadget, ConstraintF>, should_enforce: &Boolean, ) -> Result<(), SynthesisError> { - assert_eq!(witness.path.len(), P::HEIGHT - 1); + assert_eq!(self.path.len(), P::HEIGHT - 1); // Check that the hash of the given leaf matches the leaf hash in the membership // proof. let leaf_bits = leaf.to_bytes(&mut cs.ns(|| "leaf_to_bytes"))?;

@@ -71,21 +59,21 @@ )?;

// Check if leaf is one of the bottom-most siblings. let leaf_is_left = AllocatedBit::alloc(&mut cs.ns(|| "leaf_is_left"), || { - Ok(leaf_hash == witness.path[0].0) + Ok(leaf_hash == self.path[0].0) })? .into(); CRHGadget::OutputGadget::conditional_enforce_equal_or( &mut cs.ns(|| "check_leaf_is_left"), &leaf_is_left, &leaf_hash, - &witness.path[0].0, - &witness.path[0].1, + &self.path[0].0, + &self.path[0].1, should_enforce, )?; // Check levels between leaf level and root. let mut previous_hash = leaf_hash; - for (i, &(ref left_hash, ref right_hash)) in witness.path.iter().enumerate() { + for (i, &(ref left_hash, ref right_hash)) in self.path.iter().enumerate() { // Check if the previous_hash matches the correct current hash. let previous_is_left = AllocatedBit::alloc(&mut cs.ns(|| format!("previous_is_left_{}", i)), || {

@@ -138,10 +126,10 @@

HG::check_evaluation_gadget(cs, parameters, &bytes) } -impl<P, HGadget, ConstraintF> AllocGadget<HashMembershipProof<P>, ConstraintF> - for MerklePath<P, HGadget, ConstraintF> +impl<P, HGadget, ConstraintF> AllocGadget<MerkleTreePath<P>, ConstraintF> + for MerkleTreePathGadget<P, HGadget, ConstraintF> where - P: MHTParameters, + P: MerkleTreeConfig, HGadget: FixedLengthCRHGadget<P::H, ConstraintF>, ConstraintF: Field, {

@@ -151,7 +139,7 @@ value_gen: F,

) -> Result<Self, SynthesisError> where F: FnOnce() -> Result<T, SynthesisError>, - T: Borrow<HashMembershipProof<P>>, + T: Borrow<MerkleTreePath<P>>, { let mut path = Vec::new(); for (i, &(ref l, ref r)) in value_gen()?.borrow().path.iter().enumerate() {

@@ -165,7 +153,7 @@ Ok(r.clone())

})?; path.push((l_hash, r_hash)); } - Ok(MerklePath { + Ok(MerkleTreePathGadget { path, }) }

@@ -176,7 +164,7 @@ value_gen: F,

) -> Result<Self, SynthesisError> where F: FnOnce() -> Result<T, SynthesisError>, - T: Borrow<HashMembershipProof<P>>, + T: Borrow<MerkleTreePath<P>>, { let mut path = Vec::new(); for (i, &(ref l, ref r)) in value_gen()?.borrow().path.iter().enumerate() {

@@ -191,7 +179,7 @@ )?;

path.push((l_hash, r_hash)); } - Ok(MerklePath { + Ok(MerkleTreePathGadget { path, }) }

@@ -208,7 +196,7 @@ pedersen::constraints::PedersenCRHGadget,

FixedLengthCRH, FixedLengthCRHGadget, }, - mht::*, + merkle_tree::*, }; use algebra::{ curves::jubjub::JubJubAffine as JubJub,

@@ -234,20 +222,20 @@

type H = PedersenCRH<JubJub, Window4x256>; type HG = PedersenCRHGadget<JubJub, Fq, JubJubGadget>; - struct JubJubMHTParams; + struct JubJubMerkleTreeParams; - impl MHTParameters for JubJubMHTParams { + impl MerkleTreeConfig for JubJubMerkleTreeParams { const HEIGHT: usize = 32; type H = H; } - type JubJubMHT = MerkleHashTree<JubJubMHTParams>; + type JubJubMerkleTree = MerkleHashTree<JubJubMerkleTreeParams>; fn generate_merkle_tree(leaves: &[[u8; 30]], use_bad_root: bool) -> () { let mut rng = XorShiftRng::seed_from_u64(9174123u64); let crh_parameters = Rc::new(H::setup(&mut rng).unwrap()); - let tree = JubJubMHT::new(crh_parameters.clone(), leaves).unwrap(); + let tree = JubJubMerkleTree::new(crh_parameters.clone(), leaves).unwrap(); let root = tree.root(); let mut satisfied = true; for (i, leaf) in leaves.iter().enumerate() {

@@ -290,7 +278,7 @@ cs.num_constraints() - constraints_from_parameters - constraints_from_digest;

println!("constraints from leaf: {}", constraints_from_leaf); // Allocate Merkle Tree Path - let cw = MerklePath::<_, HG, _>::alloc(&mut cs.ns(|| format!("new_witness_{}", i)), || { + let cw = MerkleTreePathGadget::<_, HG, _>::alloc(&mut cs.ns(|| format!("new_witness_{}", i)), || { Ok(proof) }) .unwrap();

@@ -301,12 +289,11 @@ - constraints_from_digest

- constraints_from_leaf; println!("constraints from path: {}", constraints_from_path); let leaf_g: &[UInt8] = leaf_g.as_slice(); - MerklePathVerifierGadget::<_, HG, _>::check_membership( + cw.check_membership( &mut cs.ns(|| format!("new_witness_check_{}", i)), &crh_parameters, &root, &leaf_g, - &cw, ) .unwrap(); if !cs.is_satisfied() {

@@ -330,7 +317,7 @@ assert!(satisfied);

} #[test] - fn mht_gadget_test() { + fn good_root_test() { let mut leaves = Vec::new(); for i in 0..4u8 { let input = [i ; 30];
M crypto-primitives/src/mht/mod.rs → crypto-primitives/src/merkle_tree/mod.rs

@@ -7,7 +7,7 @@

#[cfg(feature = "r1cs")] pub mod constraints; -pub trait MHTParameters { +pub trait MerkleTreeConfig { const HEIGHT: usize; type H: FixedLengthCRH; }

@@ -16,14 +16,18 @@ /// Stores the hashes of a particular path (in order) from leaf to root.

/// Our path `is_left_child()` if the boolean in `path` is true. #[derive(Derivative)] #[derivative( - Clone(bound = "P: MHTParameters"), - Debug(bound = "P: MHTParameters, <P::H as FixedLengthCRH>::Output: fmt::Debug") + Clone(bound = "P: MerkleTreeConfig"), + Debug(bound = "P: MerkleTreeConfig, <P::H as FixedLengthCRH>::Output: fmt::Debug") )] -pub struct HashMembershipProof<P: MHTParameters> { +pub struct MerkleTreePath<P: MerkleTreeConfig> { pub(crate) path: Vec<(<P::H as FixedLengthCRH>::Output, <P::H as FixedLengthCRH>::Output)>, } -impl<P: MHTParameters> Default for HashMembershipProof<P> { +pub type MerkleTreeParams<P> = <<P as MerkleTreeConfig>::H as FixedLengthCRH>::Parameters; +pub type MerkleTreeDigest<P> = <<P as MerkleTreeConfig>::H as FixedLengthCRH>::Output; + + +impl<P: MerkleTreeConfig> Default for MerkleTreePath<P> { fn default() -> Self { let mut path = Vec::with_capacity(P::HEIGHT as usize); for _i in 1..P::HEIGHT as usize {

@@ -35,7 +39,7 @@ }

} } -impl<P: MHTParameters> HashMembershipProof<P> { +impl<P: MerkleTreeConfig> MerkleTreePath<P> { pub fn verify<L: ToBytes>( &self, parameters: &<P::H as FixedLengthCRH>::Parameters,

@@ -76,14 +80,14 @@ }

} } -pub struct MerkleHashTree<P: MHTParameters> { +pub struct MerkleHashTree<P: MerkleTreeConfig> { tree: Vec<<P::H as FixedLengthCRH>::Output>, padding_tree: Vec<(<P::H as FixedLengthCRH>::Output, <P::H as FixedLengthCRH>::Output)>, parameters: Rc<<P::H as FixedLengthCRH>::Parameters>, root: Option<<P::H as FixedLengthCRH>::Output>, } -impl<P: MHTParameters> MerkleHashTree<P> { +impl<P: MerkleTreeConfig> MerkleHashTree<P> { pub const HEIGHT: u8 = P::HEIGHT as u8; pub fn blank(parameters: Rc<<P::H as FixedLengthCRH>::Parameters>) -> Self {

@@ -96,7 +100,7 @@ }

} pub fn new<L: ToBytes>(parameters: Rc<<P::H as FixedLengthCRH>::Parameters>, leaves: &[L]) -> Result<Self, Error> { - let new_time = start_timer!(|| "MHT::New"); + let new_time = start_timer!(|| "MerkleTree::New"); let last_level_size = leaves.len().next_power_of_two(); let tree_size = 2 * last_level_size - 1;

@@ -177,8 +181,8 @@ pub fn generate_proof<L: ToBytes>(

&self, index: usize, leaf: &L, - ) -> Result<HashMembershipProof<P>, Error> { - let prove_time = start_timer!(|| "MHT::GenProof"); + ) -> Result<MerkleTreePath<P>, Error> { + let prove_time = start_timer!(|| "MerkleTree::GenProof"); let mut path = Vec::new(); let mut buffer = [0u8; 128];

@@ -189,7 +193,7 @@ let empty_hash = hash_empty::<P::H>(&self.parameters)?;

// Check that the given index corresponds to the correct leaf. if leaf_hash != self.tree[tree_index] { - Err(MHTError::IncorrectLeafIndex(tree_index))? + Err(MerkleTreeError::IncorrectLeafIndex(tree_index))? } // Iterate from the leaf up to the root, storing all intermediate hash values.

@@ -219,9 +223,9 @@ }

} end_timer!(prove_time); if path.len() != (Self::HEIGHT - 1) as usize { - Err(MHTError::IncorrectPathLength(path.len()))? + Err(MerkleTreeError::IncorrectPathLength(path.len()))? } else { - Ok(HashMembershipProof { + Ok(MerkleTreePath { path, }) }

@@ -229,22 +233,22 @@ }

} #[derive(Debug)] -pub enum MHTError { +pub enum MerkleTreeError { IncorrectLeafIndex(usize), IncorrectPathLength(usize), } -impl std::fmt::Display for MHTError { +impl std::fmt::Display for MerkleTreeError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let msg = match self { - MHTError::IncorrectLeafIndex(index) => format!("incorrect leaf index: {}", index), - MHTError::IncorrectPathLength(len) => format!("incorrect path length: {}", len), + MerkleTreeError::IncorrectLeafIndex(index) => format!("incorrect leaf index: {}", index), + MerkleTreeError::IncorrectPathLength(len) => format!("incorrect path length: {}", len), }; write!(f, "{}", msg) } } -impl std::error::Error for MHTError { +impl std::error::Error for MerkleTreeError { #[inline] fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None

@@ -357,7 +361,7 @@

#[cfg(test)] mod test { - use crate::{crh::{pedersen::*, *}, mht::*}; + use crate::{crh::{pedersen::*, *}, merkle_tree::*}; use algebra::curves::jubjub::JubJubAffine as JubJub; use rand::SeedableRng; use rand_xorshift::XorShiftRng;

@@ -372,20 +376,20 @@

type H = PedersenCRH<JubJub, Window4x256>; - struct JubJubMHTParams; + struct JubJubMerkleTreeParams; - impl MHTParameters for JubJubMHTParams { + impl MerkleTreeConfig for JubJubMerkleTreeParams { const HEIGHT: usize = 32; type H = H; } - type JubJubMHT = MerkleHashTree<JubJubMHTParams>; + type JubJubMerkleTree = MerkleHashTree<JubJubMerkleTreeParams>; fn generate_merkle_tree<L: ToBytes + Clone + Eq>(leaves: &[L]) -> () { let mut rng = XorShiftRng::seed_from_u64(9174123u64); let crh_parameters = Rc::new(H::setup(&mut rng).unwrap()); - let tree = JubJubMHT::new(crh_parameters.clone(), &leaves).unwrap(); + let tree = JubJubMerkleTree::new(crh_parameters.clone(), &leaves).unwrap(); let root = tree.root(); for (i, leaf) in leaves.iter().enumerate() { let proof = tree.generate_proof(i, &leaf).unwrap();

@@ -394,7 +398,7 @@ }

} #[test] - fn mht_test() { + fn good_root_test() { let mut leaves = Vec::new(); for i in 0..4u8 { leaves.push([i, i, i, i, i, i, i, i]);

@@ -412,7 +416,7 @@ use algebra::groups::Group;

let mut rng = XorShiftRng::seed_from_u64(13423423u64); let crh_parameters = Rc::new(H::setup(&mut rng).unwrap()); - let tree = JubJubMHT::new(crh_parameters.clone(), &leaves).unwrap(); + let tree = JubJubMerkleTree::new(crh_parameters.clone(), &leaves).unwrap(); let root = JubJub::zero(); for (i, leaf) in leaves.iter().enumerate() { let proof = tree.generate_proof(i, &leaf).unwrap();

@@ -422,7 +426,7 @@ }

#[should_panic] #[test] - fn bad_root_mht_test() { + fn bad_root_test() { let mut leaves = Vec::new(); for i in 0..4u8 { leaves.push([i, i, i, i, i, i, i, i]);