@@ -150,7 +150,12 @@ fn blake2sp_vectors() {
150
150
assert_eq ! ( 512 , test_num) ;
151
151
}
152
152
153
- fn blake2x_test < F : Fn ( & [ u8 ] , & [ u8 ] , u64 ) -> Vec < u8 > , F2 : Fn ( & [ u8 ] , u64 , usize ) -> Vec < u8 > > ( h0_hasher : F , b2_hasher : F2 , variant_hash_length : usize , variant_name : & str ) {
153
+ fn blake2x_test < F : Fn ( & [ u8 ] , & [ u8 ] , u64 ) -> Vec < u8 > , F2 : Fn ( & [ u8 ] , u64 , usize ) -> Vec < u8 > > (
154
+ h0_hasher : F ,
155
+ b2_hasher : F2 ,
156
+ variant_hash_length : usize ,
157
+ variant_name : & str ,
158
+ ) {
154
159
let mut test_num = 0u64 ;
155
160
for case in TEST_CASES . iter ( ) {
156
161
if & case. hash == variant_name {
@@ -163,23 +168,36 @@ fn blake2x_test<F: Fn(&[u8], &[u8], u64) -> Vec<u8>, F2: Fn(&[u8], u64, usize) -
163
168
vec ! [ ]
164
169
} ;
165
170
166
- let output_length = case. out . len ( ) /2 ;
167
- let encoded_output_length = ( ( ( output_length & ( ( 1 << 8 ) - 1 ) ) << 32 ) | ( ( output_length >> 8 ) << 40 ) ) as u64 ;
168
- let h0 = h0_hasher ( & input_bytes, & key, encoded_output_length) ;
171
+ let output_length = case. out . len ( ) / 2 ;
172
+
173
+ // BLAKE2X divides the underlying hash node_offset into two parts - node_offset
174
+ // and xof_digest_length. This is the encoding of xof_digest_length in the
175
+ // correct position in the node_offset.
176
+ let combined_node_offset_xof_length = ( output_length as u64 ) << 32 ;
177
+ let h0 = h0_hasher ( & input_bytes, & key, combined_node_offset_xof_length) ;
169
178
170
- let num_hashes = ( output_length + variant_hash_length - 1 ) /variant_hash_length;
171
179
let mut buf = vec ! [ ] ;
172
- for i in 0 ..num_hashes {
180
+ let mut b2_hash_index = 0 ;
181
+ while buf. len ( ) < output_length {
173
182
let hash_length = {
174
- if i == ( num_hashes - 1 ) && ( output_length % variant_hash_length) != 0 {
183
+ // Is this the last hash and the digest length doesn't divide the output
184
+ // length?
185
+ if output_length - buf. len ( ) < variant_hash_length
186
+ && ( output_length % variant_hash_length) != 0
187
+ {
175
188
output_length % variant_hash_length
176
189
} else {
177
190
variant_hash_length
178
191
}
179
192
} ;
180
193
181
- let b2_out = b2_hasher ( & h0, ( i as u64 ) | encoded_output_length, hash_length) ;
194
+ let b2_out = b2_hasher (
195
+ & h0,
196
+ ( b2_hash_index as u64 ) | combined_node_offset_xof_length,
197
+ hash_length,
198
+ ) ;
182
199
buf. extend_from_slice ( & b2_out) ;
200
+ b2_hash_index += 1 ;
183
201
}
184
202
assert_eq ! ( case. out, hex:: encode( & buf[ ..output_length] ) ) ;
185
203
}
@@ -193,66 +211,66 @@ fn blake2x_test<F: Fn(&[u8], &[u8], u64) -> Vec<u8>, F2: Fn(&[u8], u64, usize) -
193
211
194
212
#[ test]
195
213
fn blake2xs_vectors ( ) {
196
- let blake2xs_h0_hasher = | input_bytes : & [ u8 ] , key : & [ u8 ] , encoded_output_length : u64 | -> Vec < u8 > {
197
- let mut params = blake2s_simd :: Params :: new ( ) ;
198
- if key . len ( ) > 0 {
199
- params. key ( key ) ;
200
- }
201
- params
202
- . hash_length ( 32 )
203
- . node_offset ( encoded_output_length ) ;
204
- let mut state = params . to_state ( ) ;
205
- state . update ( & input_bytes ) ;
206
- let h0 = state . finalize ( ) . as_ref ( ) . to_vec ( ) ;
207
- h0
208
- } ;
209
- let blake2xs_b2_hasher = |input_bytes : & [ u8 ] , encoded_output_length : u64 , hash_length : usize | -> Vec < u8 > {
210
- let mut params = blake2s_simd:: Params :: new ( ) ;
211
- params
212
- . hash_length ( hash_length)
213
- . max_leaf_length ( 32 )
214
- . inner_hash_length ( 32 )
215
- . fanout ( 0 )
216
- . max_depth ( 0 )
217
- . node_offset ( encoded_output_length ) ;
218
- let mut state = params . to_state ( ) ;
219
- state . update ( & input_bytes ) ;
220
- let b2_out = state . finalize ( ) . as_ref ( ) . to_vec ( ) ;
221
- b2_out
222
- } ;
214
+ let blake2xs_h0_hasher =
215
+ | input_bytes : & [ u8 ] , key : & [ u8 ] , combined_node_offset_xof_length : u64 | -> Vec < u8 > {
216
+ let mut params = blake2s_simd :: Params :: new ( ) ;
217
+ let h0 = params
218
+ . key ( key )
219
+ . hash_length ( 32 )
220
+ . node_offset ( combined_node_offset_xof_length )
221
+ . hash ( & input_bytes )
222
+ . as_bytes ( )
223
+ . to_vec ( ) ;
224
+ h0
225
+ } ;
226
+ let blake2xs_b2_hasher =
227
+ |input_bytes : & [ u8 ] , combined_node_offset_xof_length : u64 , hash_length : usize | -> Vec < u8 > {
228
+ let mut params = blake2s_simd:: Params :: new ( ) ;
229
+ let b2_out = params
230
+ . hash_length ( hash_length)
231
+ . max_leaf_length ( 32 )
232
+ . inner_hash_length ( 32 )
233
+ . fanout ( 0 )
234
+ . max_depth ( 0 )
235
+ . node_offset ( combined_node_offset_xof_length )
236
+ . hash ( & input_bytes )
237
+ . as_bytes ( )
238
+ . to_vec ( ) ;
239
+ b2_out
240
+ } ;
223
241
224
242
blake2x_test ( blake2xs_h0_hasher, blake2xs_b2_hasher, 32 , "blake2xs" ) ;
225
243
}
226
244
227
245
#[ test]
228
246
fn blake2xb_vectors ( ) {
229
- let blake2xb_h0_hasher = | input_bytes : & [ u8 ] , key : & [ u8 ] , encoded_output_length : u64 | -> Vec < u8 > {
230
- let mut params = blake2b_simd :: Params :: new ( ) ;
231
- if key . len ( ) > 0 {
232
- params. key ( key ) ;
233
- }
234
- params
235
- . hash_length ( 64 )
236
- . node_offset ( encoded_output_length ) ;
237
- let mut state = params . to_state ( ) ;
238
- state . update ( & input_bytes ) ;
239
- let h0 = state . finalize ( ) . as_ref ( ) . to_vec ( ) ;
240
- h0
241
- } ;
242
- let blake2xb_b2_hasher = |input_bytes : & [ u8 ] , encoded_output_length : u64 , hash_length : usize | -> Vec < u8 > {
243
- let mut params = blake2b_simd:: Params :: new ( ) ;
244
- params
245
- . hash_length ( hash_length)
246
- . max_leaf_length ( 64 )
247
- . inner_hash_length ( 64 )
248
- . fanout ( 0 )
249
- . max_depth ( 0 )
250
- . node_offset ( encoded_output_length ) ;
251
- let mut state = params . to_state ( ) ;
252
- state . update ( & input_bytes ) ;
253
- let b2_out = state . finalize ( ) . as_ref ( ) . to_vec ( ) ;
254
- b2_out
255
- } ;
247
+ let blake2xb_h0_hasher =
248
+ | input_bytes : & [ u8 ] , key : & [ u8 ] , combined_node_offset_xof_length : u64 | -> Vec < u8 > {
249
+ let mut params = blake2b_simd :: Params :: new ( ) ;
250
+ let h0 = params
251
+ . key ( key )
252
+ . hash_length ( 64 )
253
+ . node_offset ( combined_node_offset_xof_length )
254
+ . hash ( & input_bytes )
255
+ . as_bytes ( )
256
+ . to_vec ( ) ;
257
+ h0
258
+ } ;
259
+ let blake2xb_b2_hasher =
260
+ |input_bytes : & [ u8 ] , combined_node_offset_xof_length : u64 , hash_length : usize | -> Vec < u8 > {
261
+ let mut params = blake2b_simd:: Params :: new ( ) ;
262
+ let b2_out = params
263
+ . hash_length ( hash_length)
264
+ . max_leaf_length ( 64 )
265
+ . inner_hash_length ( 64 )
266
+ . fanout ( 0 )
267
+ . max_depth ( 0 )
268
+ . node_offset ( combined_node_offset_xof_length )
269
+ . hash ( & input_bytes )
270
+ . as_bytes ( )
271
+ . to_vec ( ) ;
272
+ b2_out
273
+ } ;
256
274
257
275
blake2x_test ( blake2xb_h0_hasher, blake2xb_b2_hasher, 64 , "blake2xb" ) ;
258
276
}
0 commit comments