Skip to content

Commit fe4cff9

Browse files
authored
Refactor Merkle tree (#30)
1 parent 1a71386 commit fe4cff9

File tree

14 files changed

+928
-481
lines changed

14 files changed

+928
-481
lines changed

src/commitment/pedersen/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use ark_std::UniformRand;
99
use super::CommitmentScheme;
1010

1111
pub use crate::crh::pedersen::Window;
12-
use crate::crh::{pedersen, FixedLengthCRH};
12+
use crate::crh::{pedersen, CRH};
1313

1414
#[cfg(feature = "r1cs")]
1515
pub mod constraints;

src/crh/bowe_hopwood/constraints.rs

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::{
44
crh::{
55
bowe_hopwood::{Parameters, CHUNK_SIZE, CRH},
66
pedersen::Window,
7-
FixedLengthCRHGadget,
7+
CRHGadget as CRGGadgetTrait,
88
},
99
Vec,
1010
};
@@ -37,7 +37,7 @@ where
3737
_base_field: PhantomData<F>,
3838
}
3939

40-
impl<P, F, W> FixedLengthCRHGadget<CRH<P, W>, ConstraintF<P>> for CRHGadget<P, F>
40+
impl<P, F, W> CRGGadgetTrait<CRH<P, W>, ConstraintF<P>> for CRHGadget<P, F>
4141
where
4242
for<'a> &'a F: FieldOpsBounds<'a, P::BaseField, F>,
4343
F: FieldVar<P::BaseField, ConstraintF<P>>,
@@ -108,24 +108,22 @@ where
108108
mod test {
109109
use ark_std::rand::Rng;
110110

111-
use crate::crh::{
112-
bowe_hopwood::{constraints::CRHGadget, CRH},
113-
pedersen::Window as PedersenWindow,
114-
FixedLengthCRH, FixedLengthCRHGadget,
115-
};
111+
use crate::crh::bowe_hopwood;
112+
use crate::crh::pedersen;
113+
use crate::{CRHGadget, CRH};
116114
use ark_ec::ProjectiveCurve;
117115
use ark_ed_on_bls12_381::{constraints::FqVar, EdwardsParameters, Fq as Fr};
118116
use ark_r1cs_std::{alloc::AllocVar, uint8::UInt8, R1CSVar};
119117
use ark_relations::r1cs::{ConstraintSystem, ConstraintSystemRef};
120118
use ark_std::test_rng;
121119

122-
type TestCRH = CRH<EdwardsParameters, Window>;
123-
type TestCRHGadget = CRHGadget<EdwardsParameters, FqVar>;
120+
type TestCRH = bowe_hopwood::CRH<EdwardsParameters, Window>;
121+
type TestCRHGadget = bowe_hopwood::constraints::CRHGadget<EdwardsParameters, FqVar>;
124122

125123
#[derive(Clone, PartialEq, Eq, Hash)]
126124
pub(super) struct Window;
127125

128-
impl PedersenWindow for Window {
126+
impl pedersen::Window for Window {
129127
const WINDOW_SIZE: usize = 63;
130128
const NUM_WINDOWS: usize = 8;
131129
}
@@ -155,12 +153,11 @@ mod test {
155153
let parameters = TestCRH::setup(rng).unwrap();
156154
let primitive_result = TestCRH::evaluate(&parameters, &input).unwrap();
157155

158-
let parameters_var =
159-
<TestCRHGadget as FixedLengthCRHGadget<TestCRH, Fr>>::ParametersVar::new_witness(
160-
ark_relations::ns!(cs, "parameters_var"),
161-
|| Ok(&parameters),
162-
)
163-
.unwrap();
156+
let parameters_var = <TestCRHGadget as CRHGadget<TestCRH, Fr>>::ParametersVar::new_witness(
157+
ark_relations::ns!(cs, "parameters_var"),
158+
|| Ok(&parameters),
159+
)
160+
.unwrap();
164161
println!(
165162
"number of constraints for input + params: {}",
166163
cs.num_constraints()

src/crh/bowe_hopwood/mod.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use ark_std::{
88
use rayon::prelude::*;
99

1010
use super::pedersen;
11-
use crate::crh::FixedLengthCRH;
11+
use crate::crh::CRH as CRHTrait;
1212
use ark_ec::{
1313
twisted_edwards_extended::GroupProjective as TEProjective, ProjectiveCurve, TEModelParameters,
1414
};
@@ -50,7 +50,7 @@ impl<P: TEModelParameters, W: pedersen::Window> CRH<P, W> {
5050
}
5151
}
5252

53-
impl<P: TEModelParameters, W: pedersen::Window> FixedLengthCRH for CRH<P, W> {
53+
impl<P: TEModelParameters, W: pedersen::Window> CRHTrait for CRH<P, W> {
5454
const INPUT_SIZE_BITS: usize = pedersen::CRH::<TEProjective<P>, W>::INPUT_SIZE_BITS;
5555
type Output = TEProjective<P>;
5656
type Parameters = Parameters<P>;
@@ -172,8 +172,8 @@ impl<P: TEModelParameters> Debug for Parameters<P> {
172172
#[cfg(test)]
173173
mod test {
174174
use crate::{
175-
crh::{bowe_hopwood::CRH, pedersen::Window},
176-
FixedLengthCRH,
175+
crh::{bowe_hopwood, pedersen::Window},
176+
CRH,
177177
};
178178
use ark_ed_on_bls12_381::EdwardsParameters;
179179
use ark_std::test_rng;
@@ -188,9 +188,11 @@ mod test {
188188
}
189189

190190
let rng = &mut test_rng();
191-
let params = <CRH<EdwardsParameters, TestWindow> as FixedLengthCRH>::setup(rng).unwrap();
192-
let _ =
193-
<CRH<EdwardsParameters, TestWindow> as FixedLengthCRH>::evaluate(&params, &[1, 2, 3])
194-
.unwrap();
191+
let params = <bowe_hopwood::CRH<EdwardsParameters, TestWindow> as CRH>::setup(rng).unwrap();
192+
let _ = <bowe_hopwood::CRH<EdwardsParameters, TestWindow> as CRH>::evaluate(
193+
&params,
194+
&[1, 2, 3],
195+
)
196+
.unwrap();
195197
}
196198
}

src/crh/constraints.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use ark_ff::Field;
22
use core::fmt::Debug;
33

4-
use crate::crh::FixedLengthCRH;
4+
use crate::crh::{TwoToOneCRH, CRH};
55
use ark_relations::r1cs::SynthesisError;
66

77
use ark_r1cs_std::prelude::*;
88

9-
pub trait FixedLengthCRHGadget<H: FixedLengthCRH, ConstraintF: Field>: Sized {
9+
pub trait CRHGadget<H: CRH, ConstraintF: Field>: Sized {
1010
type OutputVar: EqGadget<ConstraintF>
1111
+ ToBytesGadget<ConstraintF>
1212
+ CondSelectGadget<ConstraintF>
@@ -23,3 +23,22 @@ pub trait FixedLengthCRHGadget<H: FixedLengthCRH, ConstraintF: Field>: Sized {
2323
input: &[UInt8<ConstraintF>],
2424
) -> Result<Self::OutputVar, SynthesisError>;
2525
}
26+
27+
pub trait TwoToOneCRHGadget<H: TwoToOneCRH, ConstraintF: Field>: Sized {
28+
type OutputVar: EqGadget<ConstraintF>
29+
+ ToBytesGadget<ConstraintF>
30+
+ CondSelectGadget<ConstraintF>
31+
+ AllocVar<H::Output, ConstraintF>
32+
+ R1CSVar<ConstraintF>
33+
+ Debug
34+
+ Clone
35+
+ Sized;
36+
37+
type ParametersVar: AllocVar<H::Parameters, ConstraintF> + Clone;
38+
39+
fn evaluate(
40+
parameters: &Self::ParametersVar,
41+
left_input: &[UInt8<ConstraintF>],
42+
right_input: &[UInt8<ConstraintF>],
43+
) -> Result<Self::OutputVar, SynthesisError>;
44+
}

src/crh/injective_map/constraints.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use core::{fmt::Debug, marker::PhantomData};
33
use crate::crh::{
44
injective_map::{InjectiveMap, PedersenCRHCompressor, TECompressor},
55
pedersen::{constraints as ped_constraints, Window},
6-
FixedLengthCRHGadget,
6+
CRHGadget,
77
};
88

99
use ark_ec::{
@@ -72,7 +72,7 @@ where
7272
_crh: ped_constraints::CRHGadget<C, GG, W>,
7373
}
7474

75-
impl<C, I, GG, IG, W> FixedLengthCRHGadget<PedersenCRHCompressor<C, I, W>, ConstraintF<C>>
75+
impl<C, I, GG, IG, W> CRHGadget<PedersenCRHCompressor<C, I, W>, ConstraintF<C>>
7676
for PedersenCRHCompressorGadget<C, I, W, GG, IG>
7777
where
7878
C: ProjectiveCurve,

src/crh/injective_map/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use ark_ff::bytes::ToBytes;
33
use ark_std::rand::Rng;
44
use ark_std::{fmt::Debug, hash::Hash, marker::PhantomData};
55

6-
use super::{pedersen, FixedLengthCRH};
6+
use super::{pedersen, CRH};
77
use ark_ec::{
88
models::{ModelParameters, TEModelParameters},
99
twisted_edwards_extended::{GroupAffine as TEAffine, GroupProjective as TEProjective},
@@ -36,7 +36,7 @@ pub struct PedersenCRHCompressor<C: ProjectiveCurve, I: InjectiveMap<C>, W: pede
3636
_crh: pedersen::CRH<C, W>,
3737
}
3838

39-
impl<C: ProjectiveCurve, I: InjectiveMap<C>, W: pedersen::Window> FixedLengthCRH
39+
impl<C: ProjectiveCurve, I: InjectiveMap<C>, W: pedersen::Window> CRH
4040
for PedersenCRHCompressor<C, I, W>
4141
{
4242
const INPUT_SIZE_BITS: usize = pedersen::CRH::<C, W>::INPUT_SIZE_BITS;

src/crh/mod.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ pub mod constraints;
1414
#[cfg(feature = "r1cs")]
1515
pub use constraints::*;
1616

17-
pub trait FixedLengthCRH {
17+
/// Interface to CRH. Note that in this release, while all implementations of `CRH` have fixed length,
18+
/// variable length CRH may also implement this trait in future.
19+
pub trait CRH {
1820
const INPUT_SIZE_BITS: usize;
1921

2022
type Output: ToBytes + Clone + Eq + core::fmt::Debug + Hash + Default;
@@ -23,3 +25,26 @@ pub trait FixedLengthCRH {
2325
fn setup<R: Rng>(r: &mut R) -> Result<Self::Parameters, Error>;
2426
fn evaluate(parameters: &Self::Parameters, input: &[u8]) -> Result<Self::Output, Error>;
2527
}
28+
29+
pub trait TwoToOneCRH {
30+
/// The bit size of the left input.
31+
const LEFT_INPUT_SIZE_BITS: usize;
32+
/// The bit size of the right input.
33+
const RIGHT_INPUT_SIZE_BITS: usize;
34+
35+
type Output: ToBytes + Clone + Eq + core::fmt::Debug + Hash + Default;
36+
type Parameters: Clone + Default;
37+
38+
fn setup<R: Rng>(r: &mut R) -> Result<Self::Parameters, Error>;
39+
/// Evaluates this CRH on the left and right inputs.
40+
///
41+
/// # Panics
42+
///
43+
/// If `left_input.len() != Self::LEFT_INPUT_SIZE_BITS`, or if
44+
/// `right_input.len() != Self::RIGHT_INPUT_SIZE_BITS`, then this method panics.
45+
fn evaluate(
46+
parameters: &Self::Parameters,
47+
left_input: &[u8],
48+
right_input: &[u8],
49+
) -> Result<Self::Output, Error>;
50+
}

src/crh/pedersen/constraints.rs

Lines changed: 76 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{
22
crh::{
33
pedersen::{Parameters, Window, CRH},
4-
FixedLengthCRHGadget,
4+
CRHGadget as CRHGadgetTrait,
55
},
66
Vec,
77
};
@@ -10,6 +10,7 @@ use ark_ff::Field;
1010
use ark_r1cs_std::prelude::*;
1111
use ark_relations::r1cs::{Namespace, SynthesisError};
1212

13+
use crate::crh::TwoToOneCRHGadget;
1314
use core::{borrow::Borrow, marker::PhantomData};
1415

1516
#[derive(Derivative)]
@@ -36,7 +37,7 @@ where
3637
_window: PhantomData<*const W>,
3738
}
3839

39-
impl<C, GG, W> FixedLengthCRHGadget<CRH<C, W>, ConstraintF<C>> for CRHGadget<C, GG, W>
40+
impl<C, GG, W> CRHGadgetTrait<CRH<C, W>, ConstraintF<C>> for CRHGadget<C, GG, W>
4041
where
4142
C: ProjectiveCurve,
4243
GG: CurveVar<C, ConstraintF<C>>,
@@ -74,6 +75,33 @@ where
7475
}
7576
}
7677

78+
impl<C, GG, W> TwoToOneCRHGadget<CRH<C, W>, ConstraintF<C>> for CRHGadget<C, GG, W>
79+
where
80+
C: ProjectiveCurve,
81+
GG: CurveVar<C, ConstraintF<C>>,
82+
W: Window,
83+
for<'a> &'a GG: GroupOpsBounds<'a, C, GG>,
84+
{
85+
type OutputVar = GG;
86+
type ParametersVar = CRHParametersVar<C, GG>;
87+
88+
#[tracing::instrument(target = "r1cs", skip(parameters))]
89+
fn evaluate(
90+
parameters: &Self::ParametersVar,
91+
left_input: &[UInt8<ConstraintF<C>>],
92+
right_input: &[UInt8<ConstraintF<C>>],
93+
) -> Result<Self::OutputVar, SynthesisError> {
94+
// assume equality of left and right length
95+
assert_eq!(left_input.len(), right_input.len());
96+
let chained_input: Vec<_> = left_input
97+
.to_vec()
98+
.into_iter()
99+
.chain(right_input.to_vec().into_iter())
100+
.collect();
101+
<Self as CRHGadgetTrait<_, _>>::evaluate(parameters, &chained_input)
102+
}
103+
}
104+
77105
impl<C, GG> AllocVar<Parameters<C>, ConstraintF<C>> for CRHParametersVar<C, GG>
78106
where
79107
C: ProjectiveCurve,
@@ -96,14 +124,15 @@ where
96124

97125
#[cfg(test)]
98126
mod test {
99-
use crate::crh::{pedersen, pedersen::constraints::*, FixedLengthCRH, FixedLengthCRHGadget};
127+
use crate::crh::{pedersen, CRHGadget, TwoToOneCRH, TwoToOneCRHGadget, CRH};
100128
use ark_ed_on_bls12_381::{constraints::EdwardsVar, EdwardsProjective as JubJub, Fq as Fr};
129+
use ark_r1cs_std::prelude::*;
101130
use ark_relations::r1cs::{ConstraintSystem, ConstraintSystemRef};
102131
use ark_std::rand::Rng;
103132
use ark_std::test_rng;
104133

105134
type TestCRH = pedersen::CRH<JubJub, Window>;
106-
type TestCRHGadget = CRHGadget<JubJub, EdwardsVar, Window>;
135+
type TestCRHGadget = pedersen::constraints::CRHGadget<JubJub, EdwardsVar, Window>;
107136

108137
#[derive(Clone, PartialEq, Eq, Hash)]
109138
pub(super) struct Window;
@@ -113,11 +142,12 @@ mod test {
113142
const NUM_WINDOWS: usize = 8;
114143
}
115144

116-
fn generate_input<R: Rng>(
145+
fn generate_u8_input<R: Rng>(
117146
cs: ConstraintSystemRef<Fr>,
147+
size: usize,
118148
rng: &mut R,
119-
) -> ([u8; 128], Vec<UInt8<Fr>>) {
120-
let mut input = [1u8; 128];
149+
) -> (Vec<u8>, Vec<UInt8<Fr>>) {
150+
let mut input = vec![1u8; size];
121151
rng.fill_bytes(&mut input);
122152

123153
let mut input_bytes = vec![];
@@ -132,16 +162,48 @@ mod test {
132162
let rng = &mut test_rng();
133163
let cs = ConstraintSystem::<Fr>::new_ref();
134164

135-
let (input, input_var) = generate_input(cs.clone(), rng);
165+
let (input, input_var) = generate_u8_input(cs.clone(), 128, rng);
166+
167+
let parameters = <TestCRH as CRH>::setup(rng).unwrap();
168+
let primitive_result = <TestCRH as CRH>::evaluate(&parameters, &input).unwrap();
136169

137-
let parameters = TestCRH::setup(rng).unwrap();
138-
let primitive_result = TestCRH::evaluate(&parameters, &input).unwrap();
170+
let parameters_var = pedersen::constraints::CRHParametersVar::new_constant(
171+
ark_relations::ns!(cs, "CRH Parameters"),
172+
&parameters,
173+
)
174+
.unwrap();
139175

140-
let parameters_var =
141-
CRHParametersVar::new_constant(ark_relations::ns!(cs, "CRH Parameters"), &parameters)
142-
.unwrap();
176+
let result_var =
177+
<TestCRHGadget as CRHGadget<_, _>>::evaluate(&parameters_var, &input_var).unwrap();
178+
179+
let primitive_result = primitive_result;
180+
assert_eq!(primitive_result, result_var.value().unwrap());
181+
assert!(cs.is_satisfied().unwrap());
182+
}
183+
184+
#[test]
185+
fn test_naive_two_to_one_equality() {
186+
let rng = &mut test_rng();
187+
let cs = ConstraintSystem::<Fr>::new_ref();
143188

144-
let result_var = TestCRHGadget::evaluate(&parameters_var, &input_var).unwrap();
189+
let (left_input, left_input_var) = generate_u8_input(cs.clone(), 64, rng);
190+
let (right_input, right_input_var) = generate_u8_input(cs.clone(), 64, rng);
191+
let parameters = <TestCRH as TwoToOneCRH>::setup(rng).unwrap();
192+
let primitive_result =
193+
<TestCRH as TwoToOneCRH>::evaluate(&parameters, &left_input, &right_input).unwrap();
194+
195+
let parameters_var = pedersen::constraints::CRHParametersVar::new_constant(
196+
ark_relations::ns!(cs, "CRH Parameters"),
197+
&parameters,
198+
)
199+
.unwrap();
200+
201+
let result_var = <TestCRHGadget as TwoToOneCRHGadget<_, _>>::evaluate(
202+
&parameters_var,
203+
&left_input_var,
204+
&right_input_var,
205+
)
206+
.unwrap();
145207

146208
let primitive_result = primitive_result;
147209
assert_eq!(primitive_result, result_var.value().unwrap());

0 commit comments

Comments
 (0)