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) [![Build Status](https://travis-ci.org/oconnor663/blake2_simd.svg?branch=master)](https://travis-ci.org/oconnor663/blake2_simd)
3 //! An implementation of the BLAKE2b and BLAKE2bp hash functions. See also
4 //! [`blake2s_simd`](https://docs.rs/blake2s_simd).
6 //! This crate includes:
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.
25 //! use blake2b_simd::{blake2b, Params};
27 //! let expected = "ca002330e69d3e6b84a46a56a6533fd79d51d97a3bb7cad6c2ff43b354185d6d\
28 //! c1e723fb3db4ae0737e120378424c714bb982d9dc5bbd7a0ab318240ddd18f8d";
29 //! let hash = blake2b(b"foo");
30 //! assert_eq!(expected, &hash.to_hex());
32 //! let hash = Params::new()
34 //! .key(b"The Magic Words are Squeamish Ossifrage")
35 //! .personal(b"L. P. Waterhouse")
41 //! assert_eq!("ee8ff4e9be887297cf79348dc35dab56", &hash.to_hex());
44 #![cfg_attr(not(feature = "std"), no_std)]
46 use arrayref
::{array_refs, mut_array_refs}
;
49 use core
::mem
::size_of
;
51 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
54 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
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
>();
79 const IV
: [Word
; 8] = [
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],
105 /// Compute the BLAKE2b hash of a slice of bytes all at once, using default
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());
117 pub fn blake2b(input
: &[u8]) -> Hash
{
118 Params
::new().hash(input
)
121 /// A parameter builder that exposes all the non-default BLAKE2 features.
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).
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.
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);
139 /// // Use those params to hash an input all at once.
140 /// let hash = params.hash(b"my input");
142 /// // Or use those params to build an incremental State.
143 /// let mut state = params.to_state();
149 key_block
: [u8; BLOCKBYTES
],
150 salt
: [u8; SALTBYTES
],
151 personal
: [u8; PERSONALBYTES
],
154 max_leaf_length
: u32,
157 inner_hash_length
: u8,
158 last_node
: guts
::LastNode
,
159 implementation
: guts
::Implementation
,
163 /// Equivalent to `Params::default()`.
165 pub fn new() -> Self {
167 hash_length
: OUTBYTES
as u8,
169 key_block
: [0; BLOCKBYTES
],
170 salt
: [0; SALTBYTES
],
171 personal
: [0; PERSONALBYTES
],
172 // NOTE: fanout and max_depth don't default to zero!
178 inner_hash_length
: 0,
179 last_node
: guts
::LastNode
::No
,
180 implementation
: guts
::Implementation
::detect(),
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);
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,
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
),
206 /// Hash an input all at once with these parameters.
208 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();
213 let mut words
= self.to_words();
214 self.implementation
.compress1_loop(
220 guts
::Stride
::Serial
,
223 bytes
: state_words_to_bytes(&words
),
224 len
: self.hash_length
,
228 /// Construct a `State` object based on these parameters, for hashing input
230 pub fn to_state(&self) -> State
{
231 State
::with_params(self)
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.
238 pub fn hash_length(&mut self, length
: usize) -> &mut Self {
240 1 <= length
&& length
<= OUTBYTES
,
241 "Bad hash length: {}",
244 self.hash_length
= length
as u8;
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.
251 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
);
259 /// At most `SALTBYTES` (16). Shorter salts are padded with null bytes. An empty salt is
260 /// equivalent to having no salt at all.
262 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
);
269 /// At most `PERSONALBYTES` (16). Shorter personalizations are padded with null bytes. An empty
270 /// personalization is equivalent to having no personalization at all.
272 pub fn personal(&mut self, personalization
: &[u8]) -> &mut Self {
274 personalization
.len() <= PERSONALBYTES
,
275 "Bad personalization length: {}",
276 personalization
.len()
278 self.personal
= [0; PERSONALBYTES
];
279 self.personal
[..personalization
.len()].copy_from_slice(personalization
);
283 /// From 0 (meaning unlimited) to 255. The default is 1 (meaning sequential).
285 pub fn fanout(&mut self, fanout
: u8) -> &mut Self {
286 self.fanout
= fanout
;
290 /// From 0 (meaning BLAKE2X B2 hashes), through 1 (the default, meaning sequential) to 255 (meaning unlimited).
292 pub fn max_depth(&mut self, depth
: u8) -> &mut Self {
293 self.max_depth
= depth
;
297 /// From 0 (the default, meaning unlimited or sequential) to `2^32 - 1`.
299 pub fn max_leaf_length(&mut self, length
: u32) -> &mut Self {
300 self.max_leaf_length
= length
;
304 /// From 0 (the default, meaning first, leftmost, leaf, or sequential) to `2^64 - 1`.
306 pub fn node_offset(&mut self, offset
: u64) -> &mut Self {
307 self.node_offset
= offset
;
311 /// From 0 (the default, meaning leaf or sequential) to 255.
313 pub fn node_depth(&mut self, depth
: u8) -> &mut Self {
314 self.node_depth
= depth
;
318 /// From 0 (the default, meaning sequential) to `OUTBYTES` (64).
320 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;
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`].
330 /// [`State::set_last_node`]: struct.State.html#method.set_last_node
332 pub fn last_node(&mut self, last_node
: bool
) -> &mut Self {
333 self.last_node
= if last_node
{
342 impl Default
for Params
{
343 fn default() -> Self {
348 impl fmt
::Debug
for Params
{
349 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
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: {} }}",
356 // NB: Don't print the key itself. Debug shouldn't leak secrets.
362 self.max_leaf_length
,
365 self.inner_hash_length
,
366 self.last_node
.yes(),
371 /// An incremental hasher for BLAKE2b.
373 /// To construct a `State` with non-default parameters, see `Params::to_state`.
378 /// use blake2b_simd::{State, blake2b};
380 /// let mut state = blake2b_simd::State::new();
382 /// state.update(b"foo");
383 /// assert_eq!(blake2b(b"foo"), state.finalize());
385 /// state.update(b"bar");
386 /// assert_eq!(blake2b(b"foobar"), state.finalize());
392 buf
: [u8; BLOCKBYTES
],
394 last_node
: guts
::LastNode
,
396 implementation
: guts
::Implementation
,
401 /// Equivalent to `State::default()` or `Params::default().to_state()`.
402 pub fn new() -> Self {
403 Self::with_params(&Params
::default())
406 fn with_params(params
: &Params
) -> Self {
407 let mut state
= Self {
408 words
: params
.to_words(),
410 buf
: [0; BLOCKBYTES
],
412 last_node
: params
.last_node
,
413 hash_length
: params
.hash_length
,
414 implementation
: params
.implementation
,
415 is_keyed
: params
.key_length
> 0,
418 state
.buf
= params
.key_block
;
419 state
.buflen
= state
.buf
.len() as 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
..];
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.
434 fn compress_buffer_if_possible(&mut self, input
: &mut &[u8]) {
436 self.fill_buf(input
);
437 if !input
.is_empty() {
438 self.implementation
.compress1_loop(
444 guts
::Stride
::Serial
,
446 self.count
= self.count
.wrapping_add(BLOCKBYTES
as Count
);
452 /// Add input to the hash. You can call `update` any number of times.
453 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
;
461 self.implementation
.compress1_loop(
467 guts
::Stride
::Serial
,
469 self.count
= self.count
.wrapping_add(end
as Count
);
470 input
= &input
[end
..];
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
);
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.
482 pub fn finalize(&self) -> Hash
{
483 let mut words_copy
= self.words
;
484 self.implementation
.compress1_loop(
485 &self.buf
[..self.buflen
as usize],
490 guts
::Stride
::Serial
,
493 bytes
: state_words_to_bytes(&words_copy
),
494 len
: self.hash_length
,
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].
504 /// [`Params::last_node`]: struct.Params.html#method.last_node
505 /// [the BLAKE2 spec]: https://blake2.net/blake2.pdf
506 pub fn set_last_node(&mut self, last_node
: bool
) -> &mut Self {
507 self.last_node
= if last_node
{
515 /// Return the total number of bytes input so far.
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`.
519 pub fn count(&self) -> Count
{
520 let mut ret
= self.count
.wrapping_add(self.buflen
as Count
);
522 ret
-= BLOCKBYTES
as Count
;
529 fn state_words_to_bytes(state_words
: &[Word
; 8]) -> [u8; OUTBYTES
] {
530 let mut bytes
= [0; OUTBYTES
];
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();
546 #[cfg(feature = "std")]
547 impl std
::io
::Write
for State
{
548 fn write(&mut self, buf
: &[u8]) -> std
::io
::Result
<usize> {
553 fn flush(&mut self) -> std
::io
::Result
<()> {
558 impl fmt
::Debug
for State
{
559 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
560 // NB: Don't print the words. Leaking them would allow length extension.
563 "State {{ count: {}, hash_length: {}, last_node: {} }}",
566 self.last_node
.yes(),
571 impl Default
for State
{
572 fn default() -> Self {
573 Self::with_params(&Params
::default())
577 type HexString
= arrayvec
::ArrayString
<[u8; 2 * OUTBYTES
]>;
579 /// A finalized BLAKE2 hash, with constant-time equality.
580 #[derive(Clone, Copy)]
582 bytes
: [u8; OUTBYTES
],
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.
589 pub fn as_bytes(&self) -> &[u8] {
590 &self.bytes
[..self.len
as usize]
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`.
597 pub fn as_array(&self) -> &[u8; OUTBYTES
] {
598 debug_assert_eq
!(self.len
as usize, OUTBYTES
);
602 /// Convert the hash to a lowercase hexadecimal
603 /// [`ArrayString`](https://docs.rs/arrayvec/0.4/arrayvec/struct.ArrayString.html).
604 pub fn to_hex(&self) -> HexString
{
605 bytes_to_hex(self.as_bytes())
609 fn bytes_to_hex(bytes
: &[u8]) -> HexString
{
610 let mut s
= arrayvec
::ArrayString
::new();
611 let table
= b
"0123456789abcdef";
613 s
.push(table
[(b
>> 4) as usize] as char);
614 s
.push(table
[(b
& 0xf) as usize] as char);
619 /// This implementation is constant time, if the two hashes are the same length.
620 impl PartialEq
for Hash
{
621 fn eq(&self, other
: &Hash
) -> bool
{
622 constant_time_eq
::constant_time_eq(&self.as_bytes(), &other
.as_bytes())
626 /// This implementation is constant time, if the slice is the same length as the hash.
627 impl PartialEq
<[u8]> for Hash
{
628 fn eq(&self, other
: &[u8]) -> bool
{
629 constant_time_eq
::constant_time_eq(&self.as_bytes(), other
)
635 impl AsRef
<[u8]> for Hash
{
636 fn as_ref(&self) -> &[u8] {
641 impl fmt
::Debug
for Hash
{
642 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
643 write
!(f
, "Hash(0x{})", self.to_hex())
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.
650 fn paint_test_input(buf
: &mut [u8]) {
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
]);
662 // This module is pub for internal benchmarks only. Please don't use it.
667 pub fn force_portable(params
: &mut Params
) {
668 params
.implementation
= guts
::Implementation
::portable();
671 pub fn force_portable_blake2bp(params
: &mut blake2bp
::Params
) {
672 blake2bp
::force_portable(params
);