@@ -30,41 +30,44 @@ use crate::{common::hash_together, BalancedBinaryMerkleTree, Hash};
30
30
#[ derive( Debug ) ]
31
31
pub struct BalancedBinaryMerkleProof < D > {
32
32
pub path : Vec < Hash > ,
33
- pub leaf_index : usize ,
33
+ pub node_index : usize ,
34
34
_phantom : PhantomData < D > ,
35
35
}
36
36
37
+ // Since this is balanced tree, the index `2k+1` is always left child and `2k` is right child
38
+
37
39
impl < D > BalancedBinaryMerkleProof < D >
38
40
where D : Digest + DomainDigest
39
41
{
40
- pub fn verify_consume ( mut self , root : & Hash , leaf_hash : Hash ) -> bool {
42
+ pub fn verify ( & self , root : & Hash , leaf_hash : Hash ) -> bool {
41
43
let mut computed_root = leaf_hash;
44
+ let mut node_index = self . node_index ;
42
45
for sibling in self . path . iter ( ) {
43
- if self . leaf_index & 1 == 1 {
46
+ if node_index & 1 == 1 {
44
47
computed_root = hash_together :: < D > ( & computed_root, sibling) ;
45
48
} else {
46
49
computed_root = hash_together :: < D > ( sibling, & computed_root) ;
47
50
}
48
- self . leaf_index = ( self . leaf_index - 1 ) >> 1 ;
51
+ node_index = ( node_index - 1 ) >> 1 ;
49
52
}
50
53
& computed_root == root
51
54
}
52
55
53
56
pub fn generate_proof ( tree : & BalancedBinaryMerkleTree < D > , leaf_index : usize ) -> Self {
54
- let mut index = tree. get_leaf_index ( leaf_index) ;
57
+ let mut node_index = tree. get_node_index ( leaf_index) ;
55
58
let mut proof = Vec :: new ( ) ;
56
- while index > 0 {
59
+ while node_index > 0 {
57
60
// Sibling
58
- let parent = ( index - 1 ) >> 1 ;
61
+ let parent = ( node_index - 1 ) >> 1 ;
59
62
// The children are 2i+1 and 2i+2, so together are 4i+3, we substract one, we get the other.
60
- let sibling = 4 * parent + 3 - index ;
63
+ let sibling = 4 * parent + 3 - node_index ;
61
64
proof. push ( tree. get_hash ( sibling) . clone ( ) ) ;
62
- // Parent
63
- index = parent;
65
+ // Traverse to parent
66
+ node_index = parent;
64
67
}
65
68
Self {
66
69
path : proof,
67
- leaf_index : tree. get_leaf_index ( leaf_index) ,
70
+ node_index : tree. get_node_index ( leaf_index) ,
68
71
_phantom : PhantomData ,
69
72
}
70
73
}
@@ -78,11 +81,22 @@ mod test {
78
81
hash_domain ! ( TestDomain , "testing" , 0 ) ;
79
82
80
83
#[ test]
81
- fn test_generate_and_verify ( ) {
82
- let leaves = vec ! [ vec![ 0 ; 32 ] ; 3000 ] ;
83
- let bmt = BalancedBinaryMerkleTree :: < DomainSeparatedHasher < Blake256 , TestDomain > > :: create ( leaves) ;
84
- let root = bmt. get_merkle_root ( ) ;
85
- let proof = BalancedBinaryMerkleProof :: generate_proof ( & bmt, 0 ) ;
86
- assert ! ( proof. verify_consume( & root, vec![ 0 ; 32 ] ) ) ;
84
+ fn test_generate_and_verify_big_tree ( ) {
85
+ for n in [ 1usize , 100 , 1000 , 10000 ] {
86
+ let leaves = ( 0 ..n)
87
+ . map ( |i| [ i. to_le_bytes ( ) . to_vec ( ) , vec ! [ 0u8 ; 24 ] ] . concat ( ) )
88
+ . collect :: < Vec < _ > > ( ) ;
89
+ let hash_0 = leaves[ 0 ] . clone ( ) ;
90
+ let hash_n_half = leaves[ n / 2 ] . clone ( ) ;
91
+ let hash_last = leaves[ n - 1 ] . clone ( ) ;
92
+ let bmt = BalancedBinaryMerkleTree :: < DomainSeparatedHasher < Blake256 , TestDomain > > :: create ( leaves) ;
93
+ let root = bmt. get_merkle_root ( ) ;
94
+ let proof = BalancedBinaryMerkleProof :: generate_proof ( & bmt, 0 ) ;
95
+ assert ! ( proof. verify( & root, hash_0) ) ;
96
+ let proof = BalancedBinaryMerkleProof :: generate_proof ( & bmt, n / 2 ) ;
97
+ assert ! ( proof. verify( & root, hash_n_half) ) ;
98
+ let proof = BalancedBinaryMerkleProof :: generate_proof ( & bmt, n - 1 ) ;
99
+ assert ! ( proof. verify( & root, hash_last) ) ;
100
+ }
87
101
}
88
102
}
0 commit comments