Skip to content

Commit 69eff42

Browse files
add support for BLAKE2bp and BLAKE2sp
On an Intel i9-9880H with AVX2 support, both BLAKE2bp and BLAKE2sp are about 1.75x faster than BLAKE2b. Note that while these algorithms can be implemented with multi-threading, these implementations from blake2b_simd and blake2s_simd are single-threaded, using only SIMD parallelism. The blake2b_simd and blake2s_simd crates don't support salting or personalization for BLAKE2bp and BLAKE2sp, so the `with_params` methods are moved out into blake2b.rs and blake2s.rs.
1 parent 5b06106 commit 69eff42

File tree

8 files changed

+113
-30
lines changed

8 files changed

+113
-30
lines changed

blake2/benches/blake2bp.rs

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#![no_std]
2+
#![feature(test)]
3+
4+
digest::bench!(blake2::Blake2bp);

blake2/benches/blake2sp.rs

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#![no_std]
2+
#![feature(test)]
3+
4+
digest::bench!(blake2::Blake2sp);

blake2/src/blake2.rs

+13-30
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,10 @@ macro_rules! blake2_impl {
2828
/// make sure to compare codes in constant time! It can be done
2929
/// for example by using `subtle` crate.
3030
pub fn new_keyed(key: &[u8], output_size: usize) -> Self {
31-
Self::with_params(key, &[], &[], output_size)
32-
}
33-
34-
/// Creates a new hashing context with the full set of sequential-mode parameters.
35-
pub fn with_params(key: &[u8], salt: &[u8], persona: &[u8], output_size: usize) -> Self {
3631
let mut upstream_params = <$upstream_params>::new();
37-
upstream_params
38-
.key(key)
39-
.salt(salt)
40-
.personal(persona)
41-
.hash_length(output_size);
42-
32+
upstream_params.key(key);
33+
upstream_params.hash_length(output_size);
4334
let upstream_state = upstream_params.to_state();
44-
4535
Self { upstream_params, upstream_state, output_size }
4636
}
4737

@@ -98,24 +88,11 @@ macro_rules! blake2_impl {
9888
upstream_state: $upstream_state,
9989
}
10090

101-
impl $fix_state {
102-
/// Creates a new hashing context with the full set of sequential-mode parameters.
103-
pub fn with_params(key: &[u8], salt: &[u8], persona: &[u8]) -> Self {
104-
let mut upstream_params = <$upstream_params>::new();
105-
upstream_params
106-
.key(key)
107-
.salt(salt)
108-
.personal(persona);
109-
110-
let upstream_state = upstream_params.to_state();
111-
112-
Self { upstream_params, upstream_state }
113-
}
114-
}
115-
11691
impl Default for $fix_state {
11792
fn default() -> Self {
118-
Self::with_params(&[], &[], &[])
93+
let upstream_params = <$upstream_params>::new();
94+
let upstream_state = upstream_params.to_state();
95+
Self { upstream_params, upstream_state }
11996
}
12097
}
12198

@@ -147,14 +124,20 @@ macro_rules! blake2_impl {
147124
type KeySize = $key_bytes_typenum;
148125

149126
fn new(key: &GenericArray<u8, $key_bytes_typenum>) -> Self {
150-
Self::with_params(&key[..], &[], &[])
127+
let mut upstream_params = <$upstream_params>::new();
128+
upstream_params.key(&key[..]);
129+
let upstream_state = upstream_params.to_state();
130+
Self { upstream_params, upstream_state }
151131
}
152132

153133
fn new_varkey(key: &[u8]) -> Result<Self, InvalidKeyLength> {
154134
if key.len() > <$key_bytes_typenum>::to_usize() {
155135
Err(InvalidKeyLength)
156136
} else {
157-
Ok(Self::with_params(key, &[], &[]))
137+
let mut upstream_params = <$upstream_params>::new();
138+
upstream_params.key(key);
139+
let upstream_state = upstream_params.to_state();
140+
Ok(Self { upstream_params, upstream_state })
158141
}
159142
}
160143
}

blake2/src/blake2b.rs

+31
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,34 @@ blake2_impl!(
1111
"Blake2b instance with a variable output.",
1212
"Blake2b instance with a fixed output.",
1313
);
14+
15+
impl VarBlake2b {
16+
/// Creates a new hashing context with the full set of sequential-mode parameters.
17+
pub fn with_params(key: &[u8], salt: &[u8], persona: &[u8], output_size: usize) -> Self {
18+
let mut upstream_params = blake2b_simd::Params::new();
19+
upstream_params
20+
.key(key)
21+
.salt(salt)
22+
.personal(persona)
23+
.hash_length(output_size);
24+
let upstream_state = upstream_params.to_state();
25+
Self {
26+
upstream_params,
27+
upstream_state,
28+
output_size,
29+
}
30+
}
31+
}
32+
33+
impl Blake2b {
34+
/// Creates a new hashing context with the full set of sequential-mode parameters.
35+
pub fn with_params(key: &[u8], salt: &[u8], persona: &[u8]) -> Self {
36+
let mut upstream_params = blake2b_simd::Params::new();
37+
upstream_params.key(key).salt(salt).personal(persona);
38+
let upstream_state = upstream_params.to_state();
39+
Self {
40+
upstream_params,
41+
upstream_state,
42+
}
43+
}
44+
}

blake2/src/blake2bp.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use digest::generic_array::typenum::{U128, U64};
2+
3+
blake2_impl!(
4+
VarBlake2bp,
5+
Blake2bp,
6+
blake2b_simd::blake2bp::State,
7+
blake2b_simd::blake2bp::Params,
8+
U128,
9+
U64,
10+
U64,
11+
"Blake2bp instance with a variable output.",
12+
"Blake2bp instance with a fixed output.",
13+
);

blake2/src/blake2s.rs

+31
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,34 @@ blake2_impl!(
1111
"Blake2s instance with a variable output.",
1212
"Blake2s instance with a fixed output.",
1313
);
14+
15+
impl VarBlake2s {
16+
/// Creates a new hashing context with the full set of sequential-mode parameters.
17+
pub fn with_params(key: &[u8], salt: &[u8], persona: &[u8], output_size: usize) -> Self {
18+
let mut upstream_params = blake2s_simd::Params::new();
19+
upstream_params
20+
.key(key)
21+
.salt(salt)
22+
.personal(persona)
23+
.hash_length(output_size);
24+
let upstream_state = upstream_params.to_state();
25+
Self {
26+
upstream_params,
27+
upstream_state,
28+
output_size,
29+
}
30+
}
31+
}
32+
33+
impl Blake2s {
34+
/// Creates a new hashing context with the full set of sequential-mode parameters.
35+
pub fn with_params(key: &[u8], salt: &[u8], persona: &[u8]) -> Self {
36+
let mut upstream_params = blake2s_simd::Params::new();
37+
upstream_params.key(key).salt(salt).personal(persona);
38+
let upstream_state = upstream_params.to_state();
39+
Self {
40+
upstream_params,
41+
upstream_state,
42+
}
43+
}
44+
}

blake2/src/blake2sp.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use digest::generic_array::typenum::{U32, U64};
2+
3+
blake2_impl!(
4+
VarBlake2sp,
5+
Blake2sp,
6+
blake2s_simd::blake2sp::State,
7+
blake2s_simd::blake2sp::Params,
8+
U64,
9+
U32,
10+
U32,
11+
"Blake2sp instance with a variable output.",
12+
"Blake2sp instance with a fixed output.",
13+
);

blake2/src/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,14 @@ extern crate std;
9494
mod blake2;
9595

9696
mod blake2b;
97+
mod blake2bp;
9798
mod blake2s;
99+
mod blake2sp;
98100

99101
pub use crypto_mac;
100102
pub use digest::{self, Digest};
101103

102104
pub use crate::blake2b::{Blake2b, VarBlake2b};
105+
pub use crate::blake2bp::{Blake2bp, VarBlake2bp};
103106
pub use crate::blake2s::{Blake2s, VarBlake2s};
107+
pub use crate::blake2sp::{Blake2sp, VarBlake2sp};

0 commit comments

Comments
 (0)