1
1
pub use blake2_rfc:: blake2b:: Blake2bResult ;
2
2
3
+ use crate :: storage:: Node ;
3
4
use blake2_rfc:: blake2b:: Blake2b ;
4
5
use byteorder:: { BigEndian , WriteBytesExt } ;
5
6
// use ed25519_dalek::PublicKey;
6
- use crate :: storage:: Node ;
7
7
use merkle_tree_stream:: Node as NodeTrait ;
8
8
use std:: convert:: AsRef ;
9
+ use std:: fmt;
9
10
use std:: mem;
10
11
use std:: ops:: { Deref , DerefMut } ;
11
12
@@ -14,53 +15,57 @@ const LEAF_TYPE: [u8; 1] = [0x00];
14
15
const PARENT_TYPE : [ u8 ; 1 ] = [ 0x01 ] ;
15
16
const ROOT_TYPE : [ u8 ; 1 ] = [ 0x02 ] ;
16
17
//const HYPERCORE: [u8; 9] = *b"hypercore";
18
+ const BLAKE_2_HASH_SIZE : usize = 32 ;
17
19
20
+ type StoredHash = [ u8 ; BLAKE_2_HASH_SIZE ] ;
18
21
/// `BLAKE2b` hash.
19
- #[ derive( Debug , Clone , PartialEq ) ]
22
+ /// uses [blake2_rfc::blake2b::Blake2bResult] to hash its inputs on initalisation, the calculated
23
+ /// hash is then constant and can not be changed.
24
+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
20
25
pub struct Hash {
21
- hash : Blake2bResult ,
26
+ hash : StoredHash ,
22
27
}
23
28
24
29
impl Hash {
25
30
/// Hash a `Leaf` node.
26
31
pub fn from_leaf ( data : & [ u8 ] ) -> Self {
27
32
let size = u64_as_be ( data. len ( ) as u64 ) ;
28
33
29
- let mut hasher = Blake2b :: new ( 32 ) ;
34
+ let mut hasher = Blake2b :: new ( BLAKE_2_HASH_SIZE ) ;
30
35
hasher. update ( & LEAF_TYPE ) ;
31
36
hasher. update ( & size) ;
32
37
hasher. update ( data) ;
33
38
34
39
Self {
35
- hash : hasher . finalize ( ) ,
40
+ hash : hasher_to_stored_hash ( hasher ) ,
36
41
}
37
42
}
38
43
39
44
/// Hash two `Leaf` nodes hashes together to form a `Parent` hash.
40
45
pub fn from_hashes ( left : & Node , right : & Node ) -> Self {
41
- let ( node1, node2) = if left. index <= right. index {
46
+ let ( node1, node2) = if left <= right {
42
47
( left, right)
43
48
} else {
44
49
( right, left)
45
50
} ;
46
51
47
52
let size = u64_as_be ( ( node1. length + node2. length ) as u64 ) ;
48
53
49
- let mut hasher = Blake2b :: new ( 32 ) ;
54
+ let mut hasher = Blake2b :: new ( BLAKE_2_HASH_SIZE ) ;
50
55
hasher. update ( & PARENT_TYPE ) ;
51
56
hasher. update ( & size) ;
52
57
hasher. update ( node1. hash ( ) ) ;
53
58
hasher. update ( node2. hash ( ) ) ;
54
59
55
60
Self {
56
- hash : hasher . finalize ( ) ,
61
+ hash : hasher_to_stored_hash ( hasher ) ,
57
62
}
58
63
}
59
64
60
65
// /// Hash a public key. Useful to find the key you're looking for on a public
61
66
// /// network without leaking the key itself.
62
67
// pub fn from_key(public_key: PublicKey) -> Self {
63
- // let mut hasher = Blake2b::new(32 );
68
+ // let mut hasher = Blake2b::new(BLAKE_2_HASH_SIZE );
64
69
// hasher.update(*HYPERCORE);
65
70
// hasher.update(public_key.as_bytes());
66
71
// Self {
@@ -71,7 +76,7 @@ impl Hash {
71
76
/// Hash a vector of `Root` nodes.
72
77
// Called `crypto.tree()` in the JS implementation.
73
78
pub fn from_roots ( roots : & [ impl AsRef < Node > ] ) -> Self {
74
- let mut hasher = Blake2b :: new ( 32 ) ;
79
+ let mut hasher = Blake2b :: new ( BLAKE_2_HASH_SIZE ) ;
75
80
hasher. update ( & ROOT_TYPE ) ;
76
81
77
82
for node in roots {
@@ -82,14 +87,37 @@ impl Hash {
82
87
}
83
88
84
89
Self {
85
- hash : hasher. finalize ( ) ,
90
+ hash : hasher_to_stored_hash ( hasher) ,
91
+ }
92
+ }
93
+
94
+ pub fn from_bytes ( bytes : & [ u8 ] ) -> Self {
95
+ Self {
96
+ hash : slice_to_stored_hash ( bytes) ,
86
97
}
87
98
}
88
99
89
100
/// Returns a byte slice of this `Hash`'s contents.
90
101
pub fn as_bytes ( & self ) -> & [ u8 ] {
91
- self . hash . as_bytes ( )
102
+ & self . hash [ ..]
103
+ }
104
+ }
105
+
106
+ fn slice_to_stored_hash ( slice : & [ u8 ] ) -> StoredHash {
107
+ assert ! ( slice. len( ) == BLAKE_2_HASH_SIZE ) ;
108
+
109
+ let mut stored_hash: StoredHash = [ 0 ; BLAKE_2_HASH_SIZE ] ;
110
+ let mut i = 0 ;
111
+ for byte in slice. iter ( ) {
112
+ stored_hash[ i] = * byte;
113
+ i = i + 1 ;
92
114
}
115
+
116
+ stored_hash
117
+ }
118
+
119
+ fn hasher_to_stored_hash ( hasher : Blake2b ) -> StoredHash {
120
+ slice_to_stored_hash ( hasher. finalize ( ) . as_bytes ( ) )
93
121
}
94
122
95
123
fn u64_as_be ( n : u64 ) -> [ u8 ; 8 ] {
@@ -99,7 +127,7 @@ fn u64_as_be(n: u64) -> [u8; 8] {
99
127
}
100
128
101
129
impl Deref for Hash {
102
- type Target = Blake2bResult ;
130
+ type Target = StoredHash ;
103
131
104
132
fn deref ( & self ) -> & Self :: Target {
105
133
& self . hash
@@ -112,6 +140,12 @@ impl DerefMut for Hash {
112
140
}
113
141
}
114
142
143
+ impl fmt:: Display for Hash {
144
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
145
+ write ! ( f, "{:x?}" , self . hash)
146
+ }
147
+ }
148
+
115
149
#[ cfg( test) ]
116
150
mod tests {
117
151
use super :: * ;
@@ -143,8 +177,8 @@ mod tests {
143
177
fn parent_hash ( ) {
144
178
let d1: & [ u8 ] = & [ 0 , 1 , 2 , 3 , 4 ] ;
145
179
let d2: & [ u8 ] = & [ 42 , 43 , 44 , 45 , 46 , 47 , 48 ] ;
146
- let node1 = Node :: new ( 0 , Hash :: from_leaf ( d1) . as_bytes ( ) . to_vec ( ) , d1. len ( ) ) ;
147
- let node2 = Node :: new ( 1 , Hash :: from_leaf ( d2) . as_bytes ( ) . to_vec ( ) , d2. len ( ) ) ;
180
+ let node1 = Node :: new ( 0 , Hash :: from_leaf ( d1) , d1. len ( ) ) ;
181
+ let node2 = Node :: new ( 1 , Hash :: from_leaf ( d2) , d2. len ( ) ) ;
148
182
check_hash (
149
183
Hash :: from_hashes ( & node1, & node2) ,
150
184
"6fac58578fa385f25a54c0637adaca71fdfddcea885d561f33d80c4487149a14" ,
@@ -159,8 +193,8 @@ mod tests {
159
193
fn root_hash ( ) {
160
194
let d1: & [ u8 ] = & [ 0 , 1 , 2 , 3 , 4 ] ;
161
195
let d2: & [ u8 ] = & [ 42 , 43 , 44 , 45 , 46 , 47 , 48 ] ;
162
- let node1 = Node :: new ( 0 , Hash :: from_leaf ( d1) . as_bytes ( ) . to_vec ( ) , d1. len ( ) ) ;
163
- let node2 = Node :: new ( 1 , Hash :: from_leaf ( d2) . as_bytes ( ) . to_vec ( ) , d2. len ( ) ) ;
196
+ let node1 = Node :: new ( 0 , Hash :: from_leaf ( d1) , d1. len ( ) ) ;
197
+ let node2 = Node :: new ( 1 , Hash :: from_leaf ( d2) , d2. len ( ) ) ;
164
198
check_hash (
165
199
Hash :: from_roots ( & [ & node1, & node2] ) ,
166
200
"2d117e0bb15c6e5236b6ce764649baed1c41890da901a015341503146cc20bcd" ,
0 commit comments