1 //! [![GitHub](https://img.shields.io/github/tag/oconnor663/blake2_simd.svg?label=GitHub)](https://github.com/oconnor663/blake2_simd) [![crates.io](https://img.shields.io/crates/v/blake2b_simd.svg)](https://crates.io/crates/blake2b_simd) [![Actions Status](https://github.com/oconnor663/blake2_simd/workflows/tests/badge.svg)](https://github.com/oconnor663/blake2_simd/actions)
2 //!
3 //! An implementation of the BLAKE2b and BLAKE2bp hash functions. See also
4 //! [`blake2s_simd`](https://docs.rs/blake2s_simd).
5 //!
6 //! This crate includes:
7 //!
8 //! - 100% stable Rust.
9 //! - SIMD implementations based on Samuel Neves' [`blake2-avx2`](https://github.com/sneves/blake2-avx2).
10 //!   These are very fast. For benchmarks, see [the Performance section of the
11 //!   README](https://github.com/oconnor663/blake2_simd#performance).
12 //! - Portable, safe implementations for other platforms.
13 //! - Dynamic CPU feature detection. Binaries include multiple implementations by default and
14 //!   choose the fastest one the processor supports at runtime.
15 //! - All the features from the [the BLAKE2 spec](https://blake2.net/blake2.pdf), like adjustable
16 //!   length, keying, and associated data for tree hashing.
17 //! - `no_std` support. The `std` Cargo feature is on by default, for CPU feature detection and
18 //!   for implementing `std::io::Write`.
19 //! - Support for computing multiple BLAKE2b hashes in parallel, matching the efficiency of
20 //!   BLAKE2bp. See the [`many`](many/index.html) module.
21 //!
22 //! # Example
23 //!
24 //! ```
25 //! use blake2b_simd::{blake2b, Params};
26 //!
27 //! let expected = "ca002330e69d3e6b84a46a56a6533fd79d51d97a3bb7cad6c2ff43b354185d6d\
28 //!                 c1e723fb3db4ae0737e120378424c714bb982d9dc5bbd7a0ab318240ddd18f8d";
29 //! let hash = blake2b(b"foo");
30 //! assert_eq!(expected, &hash.to_hex());
31 //!
32 //! let hash = Params::new()
33 //!     .hash_length(16)
34 //!     .key(b"The Magic Words are Squeamish Ossifrage")
35 //!     .personal(b"L. P. Waterhouse")
36 //!     .to_state()
37 //!     .update(b"foo")
38 //!     .update(b"bar")
39 //!     .update(b"baz")
40 //!     .finalize();
41 //! assert_eq!("ee8ff4e9be887297cf79348dc35dab56", &hash.to_hex());
42 //! ```
43 
44 #![cfg_attr(not(feature = "std"), no_std)]
45 
46 use arrayref::{array_refs, mut_array_refs};
47 use core::cmp;
48 use core::fmt;
49 use core::mem::size_of;
50 
51 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
52 mod avx2;
53 mod portable;
54 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
55 mod sse41;
56 
57 pub mod blake2bp;
58 mod guts;
59 pub mod many;
60 
61 #[cfg(test)]
62 mod test;
63 
64 type Word = u64;
65 type Count = u128;
66 
67 /// The max hash length.
68 pub const OUTBYTES: usize = 8 * size_of::<Word>();
69 /// The max key length.
70 pub const KEYBYTES: usize = 8 * size_of::<Word>();
71 /// The max salt length.
72 pub const SALTBYTES: usize = 2 * size_of::<Word>();
73 /// The max personalization length.
74 pub const PERSONALBYTES: usize = 2 * size_of::<Word>();
75 /// The number input bytes passed to each call to the compression function. Small benchmarks need
76 /// to use an even multiple of `BLOCKBYTES`, or else their apparent throughput will be low.
77 pub const BLOCKBYTES: usize = 16 * size_of::<Word>();
78 
79 const IV: [Word; 8] = [
80     0x6A09E667F3BCC908,
81     0xBB67AE8584CAA73B,
82     0x3C6EF372FE94F82B,
83     0xA54FF53A5F1D36F1,
84     0x510E527FADE682D1,
85     0x9B05688C2B3E6C1F,
86     0x1F83D9ABFB41BD6B,
87     0x5BE0CD19137E2179,
88 ];
89 
90 const SIGMA: [[u8; 16]; 12] = [
91     [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
92     [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3],
93     [11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4],
94     [7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8],
95     [9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13],
96     [2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9],
97     [12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11],
98     [13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10],
99     [6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5],
100     [10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0],
101     [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
102     [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3],
103 ];
104 
105 /// Compute the BLAKE2b hash of a slice of bytes all at once, using default
106 /// parameters.
107 ///
108 /// # Example
109 ///
110 /// ```
111 /// # use blake2b_simd::{blake2b, Params};
112 /// let expected = "ca002330e69d3e6b84a46a56a6533fd79d51d97a3bb7cad6c2ff43b354185d6d\
113 ///                 c1e723fb3db4ae0737e120378424c714bb982d9dc5bbd7a0ab318240ddd18f8d";
114 /// let hash = blake2b(b"foo");
115 /// assert_eq!(expected, &hash.to_hex());
116 /// ```
blake2b(input: &[u8]) -> Hash117 pub fn blake2b(input: &[u8]) -> Hash {
118     Params::new().hash(input)
119 }
120 
121 /// A parameter builder that exposes all the non-default BLAKE2 features.
122 ///
123 /// Apart from `hash_length`, which controls the length of the final `Hash`,
124 /// all of these parameters are just associated data that gets mixed with the
125 /// input. For more details, see [the BLAKE2 spec](https://blake2.net/blake2.pdf).
126 ///
127 /// Several of the parameters have a valid range defined in the spec and
128 /// documented below. Trying to set an invalid parameter will panic.
129 ///
130 /// # Example
131 ///
132 /// ```
133 /// # use blake2b_simd::Params;
134 /// // Create a Params object with a secret key and a non-default length.
135 /// let mut params = Params::new();
136 /// params.key(b"my secret key");
137 /// params.hash_length(16);
138 ///
139 /// // Use those params to hash an input all at once.
140 /// let hash = params.hash(b"my input");
141 ///
142 /// // Or use those params to build an incremental State.
143 /// let mut state = params.to_state();
144 /// ```
145 #[derive(Clone)]
146 pub struct Params {
147     hash_length: u8,
148     key_length: u8,
149     key_block: [u8; BLOCKBYTES],
150     salt: [u8; SALTBYTES],
151     personal: [u8; PERSONALBYTES],
152     fanout: u8,
153     max_depth: u8,
154     max_leaf_length: u32,
155     node_offset: u64,
156     node_depth: u8,
157     inner_hash_length: u8,
158     last_node: guts::LastNode,
159     implementation: guts::Implementation,
160 }
161 
162 impl Params {
163     /// Equivalent to `Params::default()`.
164     #[inline]
new() -> Self165     pub fn new() -> Self {
166         Self {
167             hash_length: OUTBYTES as u8,
168             key_length: 0,
169             key_block: [0; BLOCKBYTES],
170             salt: [0; SALTBYTES],
171             personal: [0; PERSONALBYTES],
172             // NOTE: fanout and max_depth don't default to zero!
173             fanout: 1,
174             max_depth: 1,
175             max_leaf_length: 0,
176             node_offset: 0,
177             node_depth: 0,
178             inner_hash_length: 0,
179             last_node: guts::LastNode::No,
180             implementation: guts::Implementation::detect(),
181         }
182     }
183 
184     #[inline(always)]
to_words(&self) -> [Word; 8]185     fn to_words(&self) -> [Word; 8] {
186         let (salt_left, salt_right) = array_refs!(&self.salt, SALTBYTES / 2, SALTBYTES / 2);
187         let (personal_left, personal_right) =
188             array_refs!(&self.personal, PERSONALBYTES / 2, PERSONALBYTES / 2);
189         [
190             IV[0]
191                 ^ self.hash_length as u64
192                 ^ (self.key_length as u64) << 8
193                 ^ (self.fanout as u64) << 16
194                 ^ (self.max_depth as u64) << 24
195                 ^ (self.max_leaf_length as u64) << 32,
196             IV[1] ^ self.node_offset,
197             IV[2] ^ self.node_depth as u64 ^ (self.inner_hash_length as u64) << 8,
198             IV[3],
199             IV[4] ^ Word::from_le_bytes(*salt_left),
200             IV[5] ^ Word::from_le_bytes(*salt_right),
201             IV[6] ^ Word::from_le_bytes(*personal_left),
202             IV[7] ^ Word::from_le_bytes(*personal_right),
203         ]
204     }
205 
206     /// Hash an input all at once with these parameters.
207     #[inline]
hash(&self, input: &[u8]) -> Hash208     pub fn hash(&self, input: &[u8]) -> Hash {
209         // If there's a key, just fall back to using the State.
210         if self.key_length > 0 {
211             return self.to_state().update(input).finalize();
212         }
213         let mut words = self.to_words();
214         self.implementation.compress1_loop(
215             input,
216             &mut words,
217             0,
218             self.last_node,
219             guts::Finalize::Yes,
220             guts::Stride::Serial,
221         );
222         Hash {
223             bytes: state_words_to_bytes(&words),
224             len: self.hash_length,
225         }
226     }
227 
228     /// Construct a `State` object based on these parameters, for hashing input
229     /// incrementally.
to_state(&self) -> State230     pub fn to_state(&self) -> State {
231         State::with_params(self)
232     }
233 
234     /// Set the length of the final hash in bytes, from 1 to `OUTBYTES` (64). Apart from
235     /// controlling the length of the final `Hash`, this is also associated data, and changing it
236     /// will result in a totally different hash.
237     #[inline]
hash_length(&mut self, length: usize) -> &mut Self238     pub fn hash_length(&mut self, length: usize) -> &mut Self {
239         assert!(
240             1 <= length && length <= OUTBYTES,
241             "Bad hash length: {}",
242             length
243         );
244         self.hash_length = length as u8;
245         self
246     }
247 
248     /// Use a secret key, so that BLAKE2 acts as a MAC. The maximum key length is `KEYBYTES` (64).
249     /// An empty key is equivalent to having no key at all.
250     #[inline]
key(&mut self, key: &[u8]) -> &mut Self251     pub fn key(&mut self, key: &[u8]) -> &mut Self {
252         assert!(key.len() <= KEYBYTES, "Bad key length: {}", key.len());
253         self.key_length = key.len() as u8;
254         self.key_block = [0; BLOCKBYTES];
255         self.key_block[..key.len()].copy_from_slice(key);
256         self
257     }
258 
259     /// At most `SALTBYTES` (16). Shorter salts are padded with null bytes. An empty salt is
260     /// equivalent to having no salt at all.
261     #[inline]
salt(&mut self, salt: &[u8]) -> &mut Self262     pub fn salt(&mut self, salt: &[u8]) -> &mut Self {
263         assert!(salt.len() <= SALTBYTES, "Bad salt length: {}", salt.len());
264         self.salt = [0; SALTBYTES];
265         self.salt[..salt.len()].copy_from_slice(salt);
266         self
267     }
268 
269     /// At most `PERSONALBYTES` (16). Shorter personalizations are padded with null bytes. An empty
270     /// personalization is equivalent to having no personalization at all.
271     #[inline]
personal(&mut self, personalization: &[u8]) -> &mut Self272     pub fn personal(&mut self, personalization: &[u8]) -> &mut Self {
273         assert!(
274             personalization.len() <= PERSONALBYTES,
275             "Bad personalization length: {}",
276             personalization.len()
277         );
278         self.personal = [0; PERSONALBYTES];
279         self.personal[..personalization.len()].copy_from_slice(personalization);
280         self
281     }
282 
283     /// From 0 (meaning unlimited) to 255. The default is 1 (meaning sequential).
284     #[inline]
fanout(&mut self, fanout: u8) -> &mut Self285     pub fn fanout(&mut self, fanout: u8) -> &mut Self {
286         self.fanout = fanout;
287         self
288     }
289 
290     /// From 0 (meaning BLAKE2X B2 hashes), through 1 (the default, meaning sequential) to 255 (meaning unlimited).
291     #[inline]
max_depth(&mut self, depth: u8) -> &mut Self292     pub fn max_depth(&mut self, depth: u8) -> &mut Self {
293         self.max_depth = depth;
294         self
295     }
296 
297     /// From 0 (the default, meaning unlimited or sequential) to `2^32 - 1`.
298     #[inline]
max_leaf_length(&mut self, length: u32) -> &mut Self299     pub fn max_leaf_length(&mut self, length: u32) -> &mut Self {
300         self.max_leaf_length = length;
301         self
302     }
303 
304     /// From 0 (the default, meaning first, leftmost, leaf, or sequential) to `2^64 - 1`.
305     #[inline]
node_offset(&mut self, offset: u64) -> &mut Self306     pub fn node_offset(&mut self, offset: u64) -> &mut Self {
307         self.node_offset = offset;
308         self
309     }
310 
311     /// From 0 (the default, meaning leaf or sequential) to 255.
312     #[inline]
node_depth(&mut self, depth: u8) -> &mut Self313     pub fn node_depth(&mut self, depth: u8) -> &mut Self {
314         self.node_depth = depth;
315         self
316     }
317 
318     /// From 0 (the default, meaning sequential) to `OUTBYTES` (64).
319     #[inline]
inner_hash_length(&mut self, length: usize) -> &mut Self320     pub fn inner_hash_length(&mut self, length: usize) -> &mut Self {
321         assert!(length <= OUTBYTES, "Bad inner hash length: {}", length);
322         self.inner_hash_length = length as u8;
323         self
324     }
325 
326     /// Indicates the rightmost node in a row. This can also be changed on the
327     /// `State` object, potentially after hashing has begun. See
328     /// [`State::set_last_node`].
329     ///
330     /// [`State::set_last_node`]: struct.State.html#method.set_last_node
331     #[inline]
last_node(&mut self, last_node: bool) -> &mut Self332     pub fn last_node(&mut self, last_node: bool) -> &mut Self {
333         self.last_node = if last_node {
334             guts::LastNode::Yes
335         } else {
336             guts::LastNode::No
337         };
338         self
339     }
340 }
341 
342 impl Default for Params {
default() -> Self343     fn default() -> Self {
344         Self::new()
345     }
346 }
347 
348 impl fmt::Debug for Params {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result349     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
350         write!(
351             f,
352             "Params {{ hash_length: {}, key_length: {}, salt: {:?}, personal: {:?}, fanout: {}, \
353              max_depth: {}, max_leaf_length: {}, node_offset: {}, node_depth: {}, \
354              inner_hash_length: {}, last_node: {} }}",
355             self.hash_length,
356             // NB: Don't print the key itself. Debug shouldn't leak secrets.
357             self.key_length,
358             &self.salt,
359             &self.personal,
360             self.fanout,
361             self.max_depth,
362             self.max_leaf_length,
363             self.node_offset,
364             self.node_depth,
365             self.inner_hash_length,
366             self.last_node.yes(),
367         )
368     }
369 }
370 
371 /// An incremental hasher for BLAKE2b.
372 ///
373 /// To construct a `State` with non-default parameters, see `Params::to_state`.
374 ///
375 /// # Example
376 ///
377 /// ```
378 /// use blake2b_simd::{State, blake2b};
379 ///
380 /// let mut state = blake2b_simd::State::new();
381 ///
382 /// state.update(b"foo");
383 /// assert_eq!(blake2b(b"foo"), state.finalize());
384 ///
385 /// state.update(b"bar");
386 /// assert_eq!(blake2b(b"foobar"), state.finalize());
387 /// ```
388 #[derive(Clone)]
389 pub struct State {
390     words: [Word; 8],
391     count: Count,
392     buf: [u8; BLOCKBYTES],
393     buflen: u8,
394     last_node: guts::LastNode,
395     hash_length: u8,
396     implementation: guts::Implementation,
397     is_keyed: bool,
398 }
399 
400 impl State {
401     /// Equivalent to `State::default()` or `Params::default().to_state()`.
new() -> Self402     pub fn new() -> Self {
403         Self::with_params(&Params::default())
404     }
405 
with_params(params: &Params) -> Self406     fn with_params(params: &Params) -> Self {
407         let mut state = Self {
408             words: params.to_words(),
409             count: 0,
410             buf: [0; BLOCKBYTES],
411             buflen: 0,
412             last_node: params.last_node,
413             hash_length: params.hash_length,
414             implementation: params.implementation,
415             is_keyed: params.key_length > 0,
416         };
417         if state.is_keyed {
418             state.buf = params.key_block;
419             state.buflen = state.buf.len() as u8;
420         }
421         state
422     }
423 
fill_buf(&mut self, input: &mut &[u8])424     fn fill_buf(&mut self, input: &mut &[u8]) {
425         let take = cmp::min(BLOCKBYTES - self.buflen as usize, input.len());
426         self.buf[self.buflen as usize..self.buflen as usize + take].copy_from_slice(&input[..take]);
427         self.buflen += take as u8;
428         *input = &input[take..];
429     }
430 
431     // If the state already has some input in its buffer, try to fill the buffer and perform a
432     // compression. However, only do the compression if there's more input coming, otherwise it
433     // will give the wrong hash it the caller finalizes immediately after.
compress_buffer_if_possible(&mut self, input: &mut &[u8])434     fn compress_buffer_if_possible(&mut self, input: &mut &[u8]) {
435         if self.buflen > 0 {
436             self.fill_buf(input);
437             if !input.is_empty() {
438                 self.implementation.compress1_loop(
439                     &self.buf,
440                     &mut self.words,
441                     self.count,
442                     self.last_node,
443                     guts::Finalize::No,
444                     guts::Stride::Serial,
445                 );
446                 self.count = self.count.wrapping_add(BLOCKBYTES as Count);
447                 self.buflen = 0;
448             }
449         }
450     }
451 
452     /// Add input to the hash. You can call `update` any number of times.
update(&mut self, mut input: &[u8]) -> &mut Self453     pub fn update(&mut self, mut input: &[u8]) -> &mut Self {
454         // If we have a partial buffer, try to complete it.
455         self.compress_buffer_if_possible(&mut input);
456         // While there's more than a block of input left (which also means we cleared the buffer
457         // above), compress blocks directly without copying.
458         let mut end = input.len().saturating_sub(1);
459         end -= end % BLOCKBYTES;
460         if end > 0 {
461             self.implementation.compress1_loop(
462                 &input[..end],
463                 &mut self.words,
464                 self.count,
465                 self.last_node,
466                 guts::Finalize::No,
467                 guts::Stride::Serial,
468             );
469             self.count = self.count.wrapping_add(end as Count);
470             input = &input[end..];
471         }
472         // Buffer any remaining input, to be either compressed or finalized in a subsequent call.
473         // Note that this represents some copying overhead, which in theory we could avoid in
474         // all-at-once setting. A function hardcoded for exactly BLOCKSIZE input bytes is about 10%
475         // faster than using this implementation for the same input.
476         self.fill_buf(&mut input);
477         self
478     }
479 
480     /// Finalize the state and return a `Hash`. This method is idempotent, and calling it multiple
481     /// times will give the same result. It's also possible to `update` with more input in between.
finalize(&self) -> Hash482     pub fn finalize(&self) -> Hash {
483         let mut words_copy = self.words;
484         self.implementation.compress1_loop(
485             &self.buf[..self.buflen as usize],
486             &mut words_copy,
487             self.count,
488             self.last_node,
489             guts::Finalize::Yes,
490             guts::Stride::Serial,
491         );
492         Hash {
493             bytes: state_words_to_bytes(&words_copy),
494             len: self.hash_length,
495         }
496     }
497 
498     /// Set a flag indicating that this is the last node of its level in a tree hash. This is
499     /// equivalent to [`Params::last_node`], except that it can be set at any time before calling
500     /// `finalize`. That allows callers to begin hashing a node without knowing ahead of time
501     /// whether it's the last in its level. For more details about the intended use of this flag
502     /// [the BLAKE2 spec].
503     ///
504     /// [`Params::last_node`]: struct.Params.html#method.last_node
505     /// [the BLAKE2 spec]: https://blake2.net/blake2.pdf
set_last_node(&mut self, last_node: bool) -> &mut Self506     pub fn set_last_node(&mut self, last_node: bool) -> &mut Self {
507         self.last_node = if last_node {
508             guts::LastNode::Yes
509         } else {
510             guts::LastNode::No
511         };
512         self
513     }
514 
515     /// Return the total number of bytes input so far.
516     ///
517     /// Note that `count` doesn't include the bytes of the key block, if any.
518     /// It's exactly the total number of input bytes fed to `update`.
count(&self) -> Count519     pub fn count(&self) -> Count {
520         let mut ret = self.count.wrapping_add(self.buflen as Count);
521         if self.is_keyed {
522             ret -= BLOCKBYTES as Count;
523         }
524         ret
525     }
526 }
527 
528 #[inline(always)]
state_words_to_bytes(state_words: &[Word; 8]) -> [u8; OUTBYTES]529 fn state_words_to_bytes(state_words: &[Word; 8]) -> [u8; OUTBYTES] {
530     let mut bytes = [0; OUTBYTES];
531     {
532         const W: usize = size_of::<Word>();
533         let refs = mut_array_refs!(&mut bytes, W, W, W, W, W, W, W, W);
534         *refs.0 = state_words[0].to_le_bytes();
535         *refs.1 = state_words[1].to_le_bytes();
536         *refs.2 = state_words[2].to_le_bytes();
537         *refs.3 = state_words[3].to_le_bytes();
538         *refs.4 = state_words[4].to_le_bytes();
539         *refs.5 = state_words[5].to_le_bytes();
540         *refs.6 = state_words[6].to_le_bytes();
541         *refs.7 = state_words[7].to_le_bytes();
542     }
543     bytes
544 }
545 
546 #[cfg(feature = "std")]
547 impl std::io::Write for State {
write(&mut self, buf: &[u8]) -> std::io::Result<usize>548     fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
549         self.update(buf);
550         Ok(buf.len())
551     }
552 
flush(&mut self) -> std::io::Result<()>553     fn flush(&mut self) -> std::io::Result<()> {
554         Ok(())
555     }
556 }
557 
558 impl fmt::Debug for State {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result559     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
560         // NB: Don't print the words. Leaking them would allow length extension.
561         write!(
562             f,
563             "State {{ count: {}, hash_length: {}, last_node: {} }}",
564             self.count(),
565             self.hash_length,
566             self.last_node.yes(),
567         )
568     }
569 }
570 
571 impl Default for State {
default() -> Self572     fn default() -> Self {
573         Self::with_params(&Params::default())
574     }
575 }
576 
577 type HexString = arrayvec::ArrayString<[u8; 2 * OUTBYTES]>;
578 
579 /// A finalized BLAKE2 hash, with constant-time equality.
580 #[derive(Clone, Copy)]
581 pub struct Hash {
582     bytes: [u8; OUTBYTES],
583     len: u8,
584 }
585 
586 impl Hash {
587     /// Convert the hash to a byte slice. Note that if you're using BLAKE2 as a MAC, you need
588     /// constant time equality, which `&[u8]` doesn't provide.
as_bytes(&self) -> &[u8]589     pub fn as_bytes(&self) -> &[u8] {
590         &self.bytes[..self.len as usize]
591     }
592 
593     /// Convert the hash to a byte array. Note that if you're using BLAKE2 as a
594     /// MAC, you need constant time equality, which arrays don't provide. This
595     /// panics in debug mode if the length of the hash isn't `OUTBYTES`.
596     #[inline]
as_array(&self) -> &[u8; OUTBYTES]597     pub fn as_array(&self) -> &[u8; OUTBYTES] {
598         debug_assert_eq!(self.len as usize, OUTBYTES);
599         &self.bytes
600     }
601 
602     /// Convert the hash to a lowercase hexadecimal
603     /// [`ArrayString`](https://docs.rs/arrayvec/0.4/arrayvec/struct.ArrayString.html).
to_hex(&self) -> HexString604     pub fn to_hex(&self) -> HexString {
605         bytes_to_hex(self.as_bytes())
606     }
607 }
608 
bytes_to_hex(bytes: &[u8]) -> HexString609 fn bytes_to_hex(bytes: &[u8]) -> HexString {
610     let mut s = arrayvec::ArrayString::new();
611     let table = b"0123456789abcdef";
612     for &b in bytes {
613         s.push(table[(b >> 4) as usize] as char);
614         s.push(table[(b & 0xf) as usize] as char);
615     }
616     s
617 }
618 
619 /// This implementation is constant time, if the two hashes are the same length.
620 impl PartialEq for Hash {
eq(&self, other: &Hash) -> bool621     fn eq(&self, other: &Hash) -> bool {
622         constant_time_eq::constant_time_eq(&self.as_bytes(), &other.as_bytes())
623     }
624 }
625 
626 /// This implementation is constant time, if the slice is the same length as the hash.
627 impl PartialEq<[u8]> for Hash {
eq(&self, other: &[u8]) -> bool628     fn eq(&self, other: &[u8]) -> bool {
629         constant_time_eq::constant_time_eq(&self.as_bytes(), other)
630     }
631 }
632 
633 impl Eq for Hash {}
634 
635 impl AsRef<[u8]> for Hash {
as_ref(&self) -> &[u8]636     fn as_ref(&self) -> &[u8] {
637         self.as_bytes()
638     }
639 }
640 
641 impl fmt::Debug for Hash {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result642     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
643         write!(f, "Hash(0x{})", self.to_hex())
644     }
645 }
646 
647 // Paint a byte pattern that won't repeat, so that we don't accidentally miss
648 // buffer offset bugs. This is the same as what Bao uses in its tests.
649 #[cfg(test)]
paint_test_input(buf: &mut [u8])650 fn paint_test_input(buf: &mut [u8]) {
651     let mut offset = 0;
652     let mut counter: u32 = 1;
653     while offset < buf.len() {
654         let bytes = counter.to_le_bytes();
655         let take = cmp::min(bytes.len(), buf.len() - offset);
656         buf[offset..][..take].copy_from_slice(&bytes[..take]);
657         counter += 1;
658         offset += take;
659     }
660 }
661 
662 // This module is pub for internal benchmarks only. Please don't use it.
663 #[doc(hidden)]
664 pub mod benchmarks {
665     use super::*;
666 
force_portable(params: &mut Params)667     pub fn force_portable(params: &mut Params) {
668         params.implementation = guts::Implementation::portable();
669     }
670 
force_portable_blake2bp(params: &mut blake2bp::Params)671     pub fn force_portable_blake2bp(params: &mut blake2bp::Params) {
672         blake2bp::force_portable(params);
673     }
674 }
675