mirror of
https://github.com/arnaucube/ark-r1cs-std.git
synced 2026-01-11 08:21:30 +01:00
Merkle Tree name refactors
This commit is contained in:
@@ -6,7 +6,7 @@ extern crate derivative;
|
|||||||
|
|
||||||
pub mod commitment;
|
pub mod commitment;
|
||||||
pub mod crh;
|
pub mod crh;
|
||||||
pub mod mht;
|
pub mod merkle_tree;
|
||||||
pub mod nizk;
|
pub mod nizk;
|
||||||
pub mod prf;
|
pub mod prf;
|
||||||
pub mod signature;
|
pub mod signature;
|
||||||
@@ -14,7 +14,7 @@ pub mod signature;
|
|||||||
pub use self::{
|
pub use self::{
|
||||||
commitment::CommitmentScheme,
|
commitment::CommitmentScheme,
|
||||||
crh::FixedLengthCRH,
|
crh::FixedLengthCRH,
|
||||||
mht::{HashMembershipProof, MerkleHashTree},
|
merkle_tree::{MerkleTreePath, MerkleHashTree},
|
||||||
nizk::NIZK,
|
nizk::NIZK,
|
||||||
prf::PRF,
|
prf::PRF,
|
||||||
signature::SignatureScheme,
|
signature::SignatureScheme,
|
||||||
@@ -24,7 +24,7 @@ pub use self::{
|
|||||||
pub use self::{
|
pub use self::{
|
||||||
commitment::CommitmentGadget,
|
commitment::CommitmentGadget,
|
||||||
crh::FixedLengthCRHGadget,
|
crh::FixedLengthCRHGadget,
|
||||||
mht::constraints::{MerklePath, MerklePathVerifierGadget},
|
merkle_tree::constraints::MerkleTreePathGadget,
|
||||||
nizk::NIZKVerifierGadget,
|
nizk::NIZKVerifierGadget,
|
||||||
prf::PRFGadget,
|
prf::PRFGadget,
|
||||||
signature::SigRandomizePkGadget,
|
signature::SigRandomizePkGadget,
|
||||||
|
|||||||
@@ -3,63 +3,51 @@ use r1cs_core::{ConstraintSystem, SynthesisError};
|
|||||||
use r1cs_std::prelude::*;
|
use r1cs_std::prelude::*;
|
||||||
use r1cs_std::boolean::AllocatedBit;
|
use r1cs_std::boolean::AllocatedBit;
|
||||||
|
|
||||||
use crate::mht::*;
|
use crate::merkle_tree::*;
|
||||||
use crate::crh::{FixedLengthCRH, FixedLengthCRHGadget};
|
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
|
where
|
||||||
P: MHTParameters,
|
P: MerkleTreeConfig,
|
||||||
HGadget: FixedLengthCRHGadget<P::H, ConstraintF>,
|
HGadget: FixedLengthCRHGadget<P::H, ConstraintF>,
|
||||||
ConstraintF: Field,
|
ConstraintF: Field,
|
||||||
{
|
{
|
||||||
path: Vec<(HGadget::OutputGadget, HGadget::OutputGadget)>,
|
path: Vec<(HGadget::OutputGadget, HGadget::OutputGadget)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MerklePathVerifierGadget<P, CRHGadget, ConstraintF>
|
impl<P, CRHGadget, ConstraintF> MerkleTreePathGadget<P, CRHGadget, ConstraintF>
|
||||||
where
|
where
|
||||||
P: MHTParameters,
|
P: MerkleTreeConfig,
|
||||||
ConstraintF: Field,
|
|
||||||
CRHGadget: FixedLengthCRHGadget<P::H, ConstraintF>,
|
|
||||||
{
|
|
||||||
_p: PhantomData<CRHGadget>,
|
|
||||||
_p2: PhantomData<P>,
|
|
||||||
_f: PhantomData<ConstraintF>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<P, CRHGadget, ConstraintF> MerklePathVerifierGadget<P, CRHGadget, ConstraintF>
|
|
||||||
where
|
|
||||||
P: MHTParameters,
|
|
||||||
ConstraintF: Field,
|
ConstraintF: Field,
|
||||||
CRHGadget: FixedLengthCRHGadget<P::H, ConstraintF>,
|
CRHGadget: FixedLengthCRHGadget<P::H, ConstraintF>,
|
||||||
{
|
{
|
||||||
pub fn check_membership<CS: ConstraintSystem<ConstraintF>>(
|
pub fn check_membership<CS: ConstraintSystem<ConstraintF>>(
|
||||||
|
&self,
|
||||||
cs: CS,
|
cs: CS,
|
||||||
parameters: &CRHGadget::ParametersGadget,
|
parameters: &CRHGadget::ParametersGadget,
|
||||||
root: &CRHGadget::OutputGadget,
|
root: &CRHGadget::OutputGadget,
|
||||||
leaf: impl ToBytesGadget<ConstraintF>,
|
leaf: impl ToBytesGadget<ConstraintF>,
|
||||||
witness: &MerklePath<P, CRHGadget, ConstraintF>,
|
|
||||||
) -> Result<(), SynthesisError> {
|
) -> Result<(), SynthesisError> {
|
||||||
Self::conditionally_check_membership(
|
self.conditionally_check_membership(
|
||||||
cs,
|
cs,
|
||||||
parameters,
|
parameters,
|
||||||
root,
|
root,
|
||||||
leaf,
|
leaf,
|
||||||
witness,
|
|
||||||
&Boolean::Constant(true),
|
&Boolean::Constant(true),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn conditionally_check_membership<CS: ConstraintSystem<ConstraintF>>(
|
pub fn conditionally_check_membership<CS: ConstraintSystem<ConstraintF>>(
|
||||||
|
&self,
|
||||||
mut cs: CS,
|
mut cs: CS,
|
||||||
parameters: &CRHGadget::ParametersGadget,
|
parameters: &CRHGadget::ParametersGadget,
|
||||||
root: &CRHGadget::OutputGadget,
|
root: &CRHGadget::OutputGadget,
|
||||||
leaf: impl ToBytesGadget<ConstraintF>,
|
leaf: impl ToBytesGadget<ConstraintF>,
|
||||||
witness: &MerklePath<P, CRHGadget, ConstraintF>,
|
|
||||||
should_enforce: &Boolean,
|
should_enforce: &Boolean,
|
||||||
) -> Result<(), SynthesisError> {
|
) -> 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
|
// Check that the hash of the given leaf matches the leaf hash in the membership
|
||||||
// proof.
|
// proof.
|
||||||
let leaf_bits = leaf.to_bytes(&mut cs.ns(|| "leaf_to_bytes"))?;
|
let leaf_bits = leaf.to_bytes(&mut cs.ns(|| "leaf_to_bytes"))?;
|
||||||
@@ -71,21 +59,21 @@ where
|
|||||||
|
|
||||||
// Check if leaf is one of the bottom-most siblings.
|
// Check if leaf is one of the bottom-most siblings.
|
||||||
let leaf_is_left = AllocatedBit::alloc(&mut cs.ns(|| "leaf_is_left"), || {
|
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();
|
.into();
|
||||||
CRHGadget::OutputGadget::conditional_enforce_equal_or(
|
CRHGadget::OutputGadget::conditional_enforce_equal_or(
|
||||||
&mut cs.ns(|| "check_leaf_is_left"),
|
&mut cs.ns(|| "check_leaf_is_left"),
|
||||||
&leaf_is_left,
|
&leaf_is_left,
|
||||||
&leaf_hash,
|
&leaf_hash,
|
||||||
&witness.path[0].0,
|
&self.path[0].0,
|
||||||
&witness.path[0].1,
|
&self.path[0].1,
|
||||||
should_enforce,
|
should_enforce,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Check levels between leaf level and root.
|
// Check levels between leaf level and root.
|
||||||
let mut previous_hash = leaf_hash;
|
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.
|
// Check if the previous_hash matches the correct current hash.
|
||||||
let previous_is_left =
|
let previous_is_left =
|
||||||
AllocatedBit::alloc(&mut cs.ns(|| format!("previous_is_left_{}", i)), || {
|
AllocatedBit::alloc(&mut cs.ns(|| format!("previous_is_left_{}", i)), || {
|
||||||
@@ -138,10 +126,10 @@ where
|
|||||||
HG::check_evaluation_gadget(cs, parameters, &bytes)
|
HG::check_evaluation_gadget(cs, parameters, &bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P, HGadget, ConstraintF> AllocGadget<HashMembershipProof<P>, ConstraintF>
|
impl<P, HGadget, ConstraintF> AllocGadget<MerkleTreePath<P>, ConstraintF>
|
||||||
for MerklePath<P, HGadget, ConstraintF>
|
for MerkleTreePathGadget<P, HGadget, ConstraintF>
|
||||||
where
|
where
|
||||||
P: MHTParameters,
|
P: MerkleTreeConfig,
|
||||||
HGadget: FixedLengthCRHGadget<P::H, ConstraintF>,
|
HGadget: FixedLengthCRHGadget<P::H, ConstraintF>,
|
||||||
ConstraintF: Field,
|
ConstraintF: Field,
|
||||||
{
|
{
|
||||||
@@ -151,7 +139,7 @@ where
|
|||||||
) -> Result<Self, SynthesisError>
|
) -> Result<Self, SynthesisError>
|
||||||
where
|
where
|
||||||
F: FnOnce() -> Result<T, SynthesisError>,
|
F: FnOnce() -> Result<T, SynthesisError>,
|
||||||
T: Borrow<HashMembershipProof<P>>,
|
T: Borrow<MerkleTreePath<P>>,
|
||||||
{
|
{
|
||||||
let mut path = Vec::new();
|
let mut path = Vec::new();
|
||||||
for (i, &(ref l, ref r)) in value_gen()?.borrow().path.iter().enumerate() {
|
for (i, &(ref l, ref r)) in value_gen()?.borrow().path.iter().enumerate() {
|
||||||
@@ -165,7 +153,7 @@ where
|
|||||||
})?;
|
})?;
|
||||||
path.push((l_hash, r_hash));
|
path.push((l_hash, r_hash));
|
||||||
}
|
}
|
||||||
Ok(MerklePath {
|
Ok(MerkleTreePathGadget {
|
||||||
path,
|
path,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -176,7 +164,7 @@ where
|
|||||||
) -> Result<Self, SynthesisError>
|
) -> Result<Self, SynthesisError>
|
||||||
where
|
where
|
||||||
F: FnOnce() -> Result<T, SynthesisError>,
|
F: FnOnce() -> Result<T, SynthesisError>,
|
||||||
T: Borrow<HashMembershipProof<P>>,
|
T: Borrow<MerkleTreePath<P>>,
|
||||||
{
|
{
|
||||||
let mut path = Vec::new();
|
let mut path = Vec::new();
|
||||||
for (i, &(ref l, ref r)) in value_gen()?.borrow().path.iter().enumerate() {
|
for (i, &(ref l, ref r)) in value_gen()?.borrow().path.iter().enumerate() {
|
||||||
@@ -191,7 +179,7 @@ where
|
|||||||
path.push((l_hash, r_hash));
|
path.push((l_hash, r_hash));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(MerklePath {
|
Ok(MerkleTreePathGadget {
|
||||||
path,
|
path,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -208,7 +196,7 @@ mod test {
|
|||||||
FixedLengthCRH,
|
FixedLengthCRH,
|
||||||
FixedLengthCRHGadget,
|
FixedLengthCRHGadget,
|
||||||
},
|
},
|
||||||
mht::*,
|
merkle_tree::*,
|
||||||
};
|
};
|
||||||
use algebra::{
|
use algebra::{
|
||||||
curves::jubjub::JubJubAffine as JubJub,
|
curves::jubjub::JubJubAffine as JubJub,
|
||||||
@@ -234,20 +222,20 @@ mod test {
|
|||||||
type H = PedersenCRH<JubJub, Window4x256>;
|
type H = PedersenCRH<JubJub, Window4x256>;
|
||||||
type HG = PedersenCRHGadget<JubJub, Fq, JubJubGadget>;
|
type HG = PedersenCRHGadget<JubJub, Fq, JubJubGadget>;
|
||||||
|
|
||||||
struct JubJubMHTParams;
|
struct JubJubMerkleTreeParams;
|
||||||
|
|
||||||
impl MHTParameters for JubJubMHTParams {
|
impl MerkleTreeConfig for JubJubMerkleTreeParams {
|
||||||
const HEIGHT: usize = 32;
|
const HEIGHT: usize = 32;
|
||||||
type H = H;
|
type H = H;
|
||||||
}
|
}
|
||||||
|
|
||||||
type JubJubMHT = MerkleHashTree<JubJubMHTParams>;
|
type JubJubMerkleTree = MerkleHashTree<JubJubMerkleTreeParams>;
|
||||||
|
|
||||||
fn generate_merkle_tree(leaves: &[[u8; 30]], use_bad_root: bool) -> () {
|
fn generate_merkle_tree(leaves: &[[u8; 30]], use_bad_root: bool) -> () {
|
||||||
let mut rng = XorShiftRng::seed_from_u64(9174123u64);
|
let mut rng = XorShiftRng::seed_from_u64(9174123u64);
|
||||||
|
|
||||||
let crh_parameters = Rc::new(H::setup(&mut rng).unwrap());
|
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 root = tree.root();
|
||||||
let mut satisfied = true;
|
let mut satisfied = true;
|
||||||
for (i, leaf) in leaves.iter().enumerate() {
|
for (i, leaf) in leaves.iter().enumerate() {
|
||||||
@@ -290,7 +278,7 @@ mod test {
|
|||||||
println!("constraints from leaf: {}", constraints_from_leaf);
|
println!("constraints from leaf: {}", constraints_from_leaf);
|
||||||
|
|
||||||
// Allocate Merkle Tree Path
|
// 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)
|
Ok(proof)
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -301,12 +289,11 @@ mod test {
|
|||||||
- constraints_from_leaf;
|
- constraints_from_leaf;
|
||||||
println!("constraints from path: {}", constraints_from_path);
|
println!("constraints from path: {}", constraints_from_path);
|
||||||
let leaf_g: &[UInt8] = leaf_g.as_slice();
|
let leaf_g: &[UInt8] = leaf_g.as_slice();
|
||||||
MerklePathVerifierGadget::<_, HG, _>::check_membership(
|
cw.check_membership(
|
||||||
&mut cs.ns(|| format!("new_witness_check_{}", i)),
|
&mut cs.ns(|| format!("new_witness_check_{}", i)),
|
||||||
&crh_parameters,
|
&crh_parameters,
|
||||||
&root,
|
&root,
|
||||||
&leaf_g,
|
&leaf_g,
|
||||||
&cw,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
if !cs.is_satisfied() {
|
if !cs.is_satisfied() {
|
||||||
@@ -330,7 +317,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn mht_gadget_test() {
|
fn good_root_test() {
|
||||||
let mut leaves = Vec::new();
|
let mut leaves = Vec::new();
|
||||||
for i in 0..4u8 {
|
for i in 0..4u8 {
|
||||||
let input = [i ; 30];
|
let input = [i ; 30];
|
||||||
@@ -7,7 +7,7 @@ use std::{fmt, rc::Rc};
|
|||||||
#[cfg(feature = "r1cs")]
|
#[cfg(feature = "r1cs")]
|
||||||
pub mod constraints;
|
pub mod constraints;
|
||||||
|
|
||||||
pub trait MHTParameters {
|
pub trait MerkleTreeConfig {
|
||||||
const HEIGHT: usize;
|
const HEIGHT: usize;
|
||||||
type H: FixedLengthCRH;
|
type H: FixedLengthCRH;
|
||||||
}
|
}
|
||||||
@@ -16,14 +16,18 @@ pub trait MHTParameters {
|
|||||||
/// Our path `is_left_child()` if the boolean in `path` is true.
|
/// Our path `is_left_child()` if the boolean in `path` is true.
|
||||||
#[derive(Derivative)]
|
#[derive(Derivative)]
|
||||||
#[derivative(
|
#[derivative(
|
||||||
Clone(bound = "P: MHTParameters"),
|
Clone(bound = "P: MerkleTreeConfig"),
|
||||||
Debug(bound = "P: MHTParameters, <P::H as FixedLengthCRH>::Output: fmt::Debug")
|
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)>,
|
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 {
|
fn default() -> Self {
|
||||||
let mut path = Vec::with_capacity(P::HEIGHT as usize);
|
let mut path = Vec::with_capacity(P::HEIGHT as usize);
|
||||||
for _i in 1..P::HEIGHT as usize {
|
for _i in 1..P::HEIGHT as usize {
|
||||||
@@ -35,7 +39,7 @@ impl<P: MHTParameters> Default for HashMembershipProof<P> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: MHTParameters> HashMembershipProof<P> {
|
impl<P: MerkleTreeConfig> MerkleTreePath<P> {
|
||||||
pub fn verify<L: ToBytes>(
|
pub fn verify<L: ToBytes>(
|
||||||
&self,
|
&self,
|
||||||
parameters: &<P::H as FixedLengthCRH>::Parameters,
|
parameters: &<P::H as FixedLengthCRH>::Parameters,
|
||||||
@@ -76,14 +80,14 @@ impl<P: MHTParameters> HashMembershipProof<P> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MerkleHashTree<P: MHTParameters> {
|
pub struct MerkleHashTree<P: MerkleTreeConfig> {
|
||||||
tree: Vec<<P::H as FixedLengthCRH>::Output>,
|
tree: Vec<<P::H as FixedLengthCRH>::Output>,
|
||||||
padding_tree: Vec<(<P::H as FixedLengthCRH>::Output, <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>,
|
parameters: Rc<<P::H as FixedLengthCRH>::Parameters>,
|
||||||
root: Option<<P::H as FixedLengthCRH>::Output>,
|
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 const HEIGHT: u8 = P::HEIGHT as u8;
|
||||||
|
|
||||||
pub fn blank(parameters: Rc<<P::H as FixedLengthCRH>::Parameters>) -> Self {
|
pub fn blank(parameters: Rc<<P::H as FixedLengthCRH>::Parameters>) -> Self {
|
||||||
@@ -96,7 +100,7 @@ impl<P: MHTParameters> MerkleHashTree<P> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn new<L: ToBytes>(parameters: Rc<<P::H as FixedLengthCRH>::Parameters>, leaves: &[L]) -> Result<Self, Error> {
|
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 last_level_size = leaves.len().next_power_of_two();
|
||||||
let tree_size = 2 * last_level_size - 1;
|
let tree_size = 2 * last_level_size - 1;
|
||||||
@@ -177,8 +181,8 @@ impl<P: MHTParameters> MerkleHashTree<P> {
|
|||||||
&self,
|
&self,
|
||||||
index: usize,
|
index: usize,
|
||||||
leaf: &L,
|
leaf: &L,
|
||||||
) -> Result<HashMembershipProof<P>, Error> {
|
) -> Result<MerkleTreePath<P>, Error> {
|
||||||
let prove_time = start_timer!(|| "MHT::GenProof");
|
let prove_time = start_timer!(|| "MerkleTree::GenProof");
|
||||||
let mut path = Vec::new();
|
let mut path = Vec::new();
|
||||||
|
|
||||||
let mut buffer = [0u8; 128];
|
let mut buffer = [0u8; 128];
|
||||||
@@ -189,7 +193,7 @@ impl<P: MHTParameters> MerkleHashTree<P> {
|
|||||||
|
|
||||||
// Check that the given index corresponds to the correct leaf.
|
// Check that the given index corresponds to the correct leaf.
|
||||||
if leaf_hash != self.tree[tree_index] {
|
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.
|
// Iterate from the leaf up to the root, storing all intermediate hash values.
|
||||||
@@ -219,9 +223,9 @@ impl<P: MHTParameters> MerkleHashTree<P> {
|
|||||||
}
|
}
|
||||||
end_timer!(prove_time);
|
end_timer!(prove_time);
|
||||||
if path.len() != (Self::HEIGHT - 1) as usize {
|
if path.len() != (Self::HEIGHT - 1) as usize {
|
||||||
Err(MHTError::IncorrectPathLength(path.len()))?
|
Err(MerkleTreeError::IncorrectPathLength(path.len()))?
|
||||||
} else {
|
} else {
|
||||||
Ok(HashMembershipProof {
|
Ok(MerkleTreePath {
|
||||||
path,
|
path,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -229,22 +233,22 @@ impl<P: MHTParameters> MerkleHashTree<P> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum MHTError {
|
pub enum MerkleTreeError {
|
||||||
IncorrectLeafIndex(usize),
|
IncorrectLeafIndex(usize),
|
||||||
IncorrectPathLength(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 {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let msg = match self {
|
let msg = match self {
|
||||||
MHTError::IncorrectLeafIndex(index) => format!("incorrect leaf index: {}", index),
|
MerkleTreeError::IncorrectLeafIndex(index) => format!("incorrect leaf index: {}", index),
|
||||||
MHTError::IncorrectPathLength(len) => format!("incorrect path length: {}", len),
|
MerkleTreeError::IncorrectPathLength(len) => format!("incorrect path length: {}", len),
|
||||||
};
|
};
|
||||||
write!(f, "{}", msg)
|
write!(f, "{}", msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::error::Error for MHTError {
|
impl std::error::Error for MerkleTreeError {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
None
|
None
|
||||||
@@ -357,7 +361,7 @@ pub(crate) fn hash_empty<H: FixedLengthCRH>(
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::{crh::{pedersen::*, *}, mht::*};
|
use crate::{crh::{pedersen::*, *}, merkle_tree::*};
|
||||||
use algebra::curves::jubjub::JubJubAffine as JubJub;
|
use algebra::curves::jubjub::JubJubAffine as JubJub;
|
||||||
use rand::SeedableRng;
|
use rand::SeedableRng;
|
||||||
use rand_xorshift::XorShiftRng;
|
use rand_xorshift::XorShiftRng;
|
||||||
@@ -372,20 +376,20 @@ mod test {
|
|||||||
|
|
||||||
type H = PedersenCRH<JubJub, Window4x256>;
|
type H = PedersenCRH<JubJub, Window4x256>;
|
||||||
|
|
||||||
struct JubJubMHTParams;
|
struct JubJubMerkleTreeParams;
|
||||||
|
|
||||||
impl MHTParameters for JubJubMHTParams {
|
impl MerkleTreeConfig for JubJubMerkleTreeParams {
|
||||||
const HEIGHT: usize = 32;
|
const HEIGHT: usize = 32;
|
||||||
type H = H;
|
type H = H;
|
||||||
}
|
}
|
||||||
type JubJubMHT = MerkleHashTree<JubJubMHTParams>;
|
type JubJubMerkleTree = MerkleHashTree<JubJubMerkleTreeParams>;
|
||||||
|
|
||||||
|
|
||||||
fn generate_merkle_tree<L: ToBytes + Clone + Eq>(leaves: &[L]) -> () {
|
fn generate_merkle_tree<L: ToBytes + Clone + Eq>(leaves: &[L]) -> () {
|
||||||
let mut rng = XorShiftRng::seed_from_u64(9174123u64);
|
let mut rng = XorShiftRng::seed_from_u64(9174123u64);
|
||||||
|
|
||||||
let crh_parameters = Rc::new(H::setup(&mut rng).unwrap());
|
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 root = tree.root();
|
||||||
for (i, leaf) in leaves.iter().enumerate() {
|
for (i, leaf) in leaves.iter().enumerate() {
|
||||||
let proof = tree.generate_proof(i, &leaf).unwrap();
|
let proof = tree.generate_proof(i, &leaf).unwrap();
|
||||||
@@ -394,7 +398,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn mht_test() {
|
fn good_root_test() {
|
||||||
let mut leaves = Vec::new();
|
let mut leaves = Vec::new();
|
||||||
for i in 0..4u8 {
|
for i in 0..4u8 {
|
||||||
leaves.push([i, i, i, i, i, i, i, i]);
|
leaves.push([i, i, i, i, i, i, i, i]);
|
||||||
@@ -412,7 +416,7 @@ mod test {
|
|||||||
let mut rng = XorShiftRng::seed_from_u64(13423423u64);
|
let mut rng = XorShiftRng::seed_from_u64(13423423u64);
|
||||||
|
|
||||||
let crh_parameters = Rc::new(H::setup(&mut rng).unwrap());
|
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();
|
let root = JubJub::zero();
|
||||||
for (i, leaf) in leaves.iter().enumerate() {
|
for (i, leaf) in leaves.iter().enumerate() {
|
||||||
let proof = tree.generate_proof(i, &leaf).unwrap();
|
let proof = tree.generate_proof(i, &leaf).unwrap();
|
||||||
@@ -422,7 +426,7 @@ mod test {
|
|||||||
|
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
#[test]
|
#[test]
|
||||||
fn bad_root_mht_test() {
|
fn bad_root_test() {
|
||||||
let mut leaves = Vec::new();
|
let mut leaves = Vec::new();
|
||||||
for i in 0..4u8 {
|
for i in 0..4u8 {
|
||||||
leaves.push([i, i, i, i, i, i, i, i]);
|
leaves.push([i, i, i, i, i, i, i, i]);
|
||||||
Reference in New Issue
Block a user