Skip to content

Commit dfe4f0e

Browse files
authored
feat(merkle): Pad single tree leaves to next power of two (#876)
* pad single elements to next power of two * fix starknet version * address pelitos cmts * fmt
1 parent e465d7c commit dfe4f0e

File tree

4 files changed

+26
-15
lines changed

4 files changed

+26
-15
lines changed

benches/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ ark-test-curves = { git = "https://github.com/arkworks-rs/algebra", rev = "ef8f7
99
ark-std = "0.4.0"
1010
rand = "0.8.5"
1111
rand_chacha = "0.3.1"
12-
starknet-curve = { git = "https://github.com/xJonathanLEI/starknet-rs" }
13-
starknet-ff = { git = "https://github.com/xJonathanLEI/starknet-rs" }
14-
starknet-crypto = { git = "https://github.com/xJonathanLEI/starknet-rs" }
12+
starknet-curve = { git = "https://github.com/xJonathanLEI/starknet-rs", tag = "starknet-curve/v0.4.2" }
13+
starknet-ff = { git = "https://github.com/xJonathanLEI/starknet-rs", tag = "starknet-ff/v0.3.7" }
14+
starknet-crypto = { git = "https://github.com/xJonathanLEI/starknet-rs", tag = "starknet-crypto/v0.6.2" }
1515
pathfinder-crypto = { git = "https://github.com/eqlabs/pathfinder.git" }
1616

1717
[dependencies.lambdaworks-math]

benches/benches/poseidon.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ fn poseidon_benchmarks(c: &mut Criterion) {
3131
mont_x.reverse();
3232
mont_y.reverse();
3333

34-
let sn_ff_x = starknet_ff::FieldElement::from_mont(mont_x);
35-
let sn_ff_y = starknet_ff::FieldElement::from_mont(mont_y);
34+
let sn_ff_x = starknet_crypto::FieldElement::from_mont(mont_x);
35+
let sn_ff_y = starknet_crypto::FieldElement::from_mont(mont_y);
3636
group.bench_function("starknet-rs", |bench| {
3737
bench.iter(|| black_box(starknet_crypto::poseidon_hash(sn_ff_x, sn_ff_y)))
3838
});

crypto/src/merkle_tree/merkle.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,6 @@ where
3333
pub fn build(unhashed_leaves: &[B::Data]) -> Self {
3434
let mut hashed_leaves: Vec<B::Node> = B::hash_leaves(unhashed_leaves);
3535

36-
// If there is only one node, handle it specially
37-
if hashed_leaves.len() == 1 {
38-
hashed_leaves.push(hashed_leaves[0].clone());
39-
}
40-
4136
//The leaf must be a power of 2 set
4237
hashed_leaves = complete_until_power_of_two(&mut hashed_leaves);
4338
let leaves_len = hashed_leaves.len();

crypto/src/merkle_tree/utils.rs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,20 @@ pub fn parent_index(node_index: usize) -> usize {
2222

2323
// The list of values is completed repeating the last value to a power of two length
2424
pub fn complete_until_power_of_two<T: Clone>(values: &mut Vec<T>) -> Vec<T> {
25-
if values.len() == 1 {
26-
return values.clone(); // Return immediately if there is only one element.
27-
}
2825
while !is_power_of_two(values.len()) {
2926
values.push(values[values.len() - 1].clone());
3027
}
3128
values.to_vec()
3229
}
3330

34-
pub fn is_power_of_two(x: usize) -> bool {
35-
(x != 0) && ((x & (x - 1)) == 0)
31+
// ! NOTE !
32+
// We in this function we say 2^0 = 1 is not a power of two when it is infact true. We
33+
// need this to maintain that the smallest tree at two leaves counts and we could not find
34+
// a name that wasn't overly verbose. In the case of a single value being present in a leaf node
35+
// this indicates we pad to next power of two (i.e. 2). The function is private and is only used
36+
// to ensure the tree has a power of 2 number of leaves.
37+
fn is_power_of_two(x: usize) -> bool {
38+
(x > 1) && ((x & (x - 1)) == 0)
3639
}
3740

3841
// ! CAUTION !
@@ -109,6 +112,19 @@ mod tests {
109112
}
110113
}
111114

115+
#[test]
116+
// expected |2|2|
117+
fn complete_the_length_of_one_field_element_to_be_a_power_of_two() {
118+
let mut values: Vec<FE> = vec![FE::new(2)];
119+
let hashed_leaves = complete_until_power_of_two(&mut values);
120+
121+
let mut expected_leaves = vec![FE::new(2)];
122+
expected_leaves.extend([FE::new(2)]);
123+
assert_eq!(hashed_leaves.len(), 2);
124+
assert_eq!(hashed_leaves[0], expected_leaves[0]);
125+
assert_eq!(hashed_leaves[1], expected_leaves[1]);
126+
}
127+
112128
const ROOT: usize = 0;
113129

114130
#[test]

0 commit comments

Comments
 (0)