Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

blake2: integrate blake2b_simd/blake2s_simd crates #228

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
blake2: fix clippy nits
tarcieri committed Jan 13, 2023
commit 974a482ff541a85e21e615ebf3b4e243dd7968a4
6 changes: 3 additions & 3 deletions blake2/src/blake2b.rs
Original file line number Diff line number Diff line change
@@ -598,7 +598,7 @@ impl Hash {

/// Convert the hash to a lowercase hexadecimal
/// [`ArrayString`](https://docs.rs/arrayvec/0.4/arrayvec/struct.ArrayString.html).
pub fn to_hex(&self) -> HexString {
pub fn to_hex(self) -> HexString {
bytes_to_hex(self.as_bytes())
}
}
@@ -616,14 +616,14 @@ fn bytes_to_hex(bytes: &[u8]) -> HexString {
/// This implementation is constant time, if the two hashes are the same length.
impl PartialEq for Hash {
fn eq(&self, other: &Hash) -> bool {
constant_time_eq::constant_time_eq(&self.as_bytes(), &other.as_bytes())
constant_time_eq::constant_time_eq(self.as_bytes(), other.as_bytes())
}
}

/// This implementation is constant time, if the slice is the same length as the hash.
impl PartialEq<[u8]> for Hash {
fn eq(&self, other: &[u8]) -> bool {
constant_time_eq::constant_time_eq(&self.as_bytes(), other)
constant_time_eq::constant_time_eq(self.as_bytes(), other)
}
}

4 changes: 2 additions & 2 deletions blake2/src/blake2b/avx2.rs
Original file line number Diff line number Diff line change
@@ -844,8 +844,8 @@ pub unsafe fn compress4_loop(jobs: &mut [Job<'_, '_>; DEGREE], finalize: Finaliz
jobs[2].input.as_ptr(),
jobs[3].input.as_ptr(),
];
let mut h_vecs = transpose_state_vecs(&jobs);
let (mut counts_lo, mut counts_hi) = load_counts(&jobs);
let mut h_vecs = transpose_state_vecs(jobs);
let (mut counts_lo, mut counts_hi) = load_counts(jobs);

// Prepare the final blocks (note, which could be empty if the input is
// empty). Do all this before entering the main loop.
44 changes: 22 additions & 22 deletions blake2/src/blake2b/guts.rs
Original file line number Diff line number Diff line change
@@ -8,17 +8,17 @@ pub const MAX_DEGREE: usize = 4;
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
pub const MAX_DEGREE: usize = 1;

// Variants other than Portable are unreachable in no_std, unless CPU features
// are explicitly enabled for the build with e.g. RUSTFLAGS="-C target-feature=avx2".
// This might change in the future if is_x86_feature_detected moves into libcore.
/// Variants other than Portable are unreachable in no_std, unless CPU features
/// are explicitly enabled for the build with e.g. RUSTFLAGS="-C target-feature=avx2".
/// This might change in the future if is_x86_feature_detected moves into libcore.
#[allow(dead_code)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
enum Platform {
Portable,
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
SSE41,
Sse41,
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
AVX2,
Avx2,
}

#[derive(Clone, Copy, Debug)]
@@ -53,13 +53,13 @@ impl Implementation {
// Check whether SSE4.1 support is assumed by the build.
#[cfg(target_feature = "sse4.1")]
{
return Some(Implementation(Platform::SSE41));
return Some(Implementation(Platform::Sse41));
}
// Otherwise dynamically check for support if we can.
#[cfg(feature = "std")]
{
if is_x86_feature_detected!("sse4.1") {
return Some(Implementation(Platform::SSE41));
return Some(Implementation(Platform::Sse41));
}
}
None
@@ -71,13 +71,13 @@ impl Implementation {
// Check whether AVX2 support is assumed by the build.
#[cfg(target_feature = "avx2")]
{
return Some(Implementation(Platform::AVX2));
return Some(Implementation(Platform::Avx2));
}
// Otherwise dynamically check for support if we can.
#[cfg(feature = "std")]
{
if is_x86_feature_detected!("avx2") {
return Some(Implementation(Platform::AVX2));
return Some(Implementation(Platform::Avx2));
}
}
None
@@ -86,9 +86,9 @@ impl Implementation {
pub fn degree(&self) -> usize {
match self.0 {
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
Platform::AVX2 => avx2::DEGREE,
Platform::Avx2 => avx2::DEGREE,
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
Platform::SSE41 => sse41::DEGREE,
Platform::Sse41 => sse41::DEGREE,
Platform::Portable => 1,
}
}
@@ -104,7 +104,7 @@ impl Implementation {
) {
match self.0 {
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
Platform::AVX2 => unsafe {
Platform::Avx2 => unsafe {
avx2::compress1_loop(input, words, count, last_node, finalize, stride);
},
// Note that there's an SSE version of compress1 in the official C
@@ -118,7 +118,7 @@ impl Implementation {
pub fn compress2_loop(&self, jobs: &mut [Job<'_, '_>; 2], finalize: Finalize, stride: Stride) {
match self.0 {
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
Platform::AVX2 | Platform::SSE41 => unsafe {
Platform::Avx2 | Platform::Sse41 => unsafe {
sse41::compress2_loop(jobs, finalize, stride)
},
_ => panic!("unsupported"),
Copy link
Member Author

@tarcieri tarcieri Feb 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@oconnor663 noticing compile failures (well, more like warnings) for this and the other cases below when testing on a thumbv7em-none-eabi target (which is SOP for us).

Is there some sort of fallback on these platforms that will avoid this panic? If not, these should probably be changed to compile_error! (and separately, we should address the issue before merging if so)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tarcieri are you sure you can trigger this panic in practice? If you look at how these functions are used in compress_many, imp.degree() is checked first, which should prevent this panic. In particular, I expect the Portable platform should get selected on thumbv7em-none-eabi, which should have a degree() of 1.

@@ -128,7 +128,7 @@ impl Implementation {
pub fn compress4_loop(&self, jobs: &mut [Job<'_, '_>; 4], finalize: Finalize, stride: Stride) {
match self.0 {
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
Platform::AVX2 => unsafe { avx2::compress4_loop(jobs, finalize, stride) },
Platform::Avx2 => unsafe { avx2::compress4_loop(jobs, finalize, stride) },
_ => panic!("unsupported"),
}
}
@@ -271,20 +271,20 @@ mod test {
#[cfg(feature = "std")]
{
if is_x86_feature_detected!("avx2") {
assert_eq!(Platform::AVX2, Implementation::detect().0);
assert_eq!(Platform::Avx2, Implementation::detect().0);
assert_eq!(
Platform::AVX2,
Platform::Avx2,
Implementation::avx2_if_supported().unwrap().0
);
assert_eq!(
Platform::SSE41,
Platform::Sse41,
Implementation::sse41_if_supported().unwrap().0
);
} else if is_x86_feature_detected!("sse4.1") {
assert_eq!(Platform::SSE41, Implementation::detect().0);
assert_eq!(Platform::Sse41, Implementation::detect().0);
assert!(Implementation::avx2_if_supported().is_none());
assert_eq!(
Platform::SSE41,
Platform::Sse41,
Implementation::sse41_if_supported().unwrap().0
);
} else {
@@ -302,9 +302,9 @@ mod test {
{
// Chose counts to hit the relevant overflow cases.
let counts = &[
(0 as Count),
((1 as Count) << (8 * size_of::<Word>())) - BLOCKBYTES as Count,
(0 as Count).wrapping_sub(BLOCKBYTES as Count),
0_u128,
(1_u128 << (8 * size_of::<Word>())) - BLOCKBYTES as Count,
0_u128.wrapping_sub(BLOCKBYTES as Count),
];
for &stride in &[Stride::Serial, Stride::Parallel] {
let lengths = [
4 changes: 2 additions & 2 deletions blake2/src/blake2b/sse41.rs
Original file line number Diff line number Diff line change
@@ -380,8 +380,8 @@ pub unsafe fn compress2_loop(jobs: &mut [Job<'_, '_>; DEGREE], finalize: Finaliz
}

let msg_ptrs = [jobs[0].input.as_ptr(), jobs[1].input.as_ptr()];
let mut h_vecs = transpose_state_vecs(&jobs);
let (mut counts_lo, mut counts_hi) = load_counts(&jobs);
let mut h_vecs = transpose_state_vecs(jobs);
let (mut counts_lo, mut counts_hi) = load_counts(jobs);

// Prepare the final blocks (note, which could be empty if the input is
// empty). Do all this before entering the main loop.
4 changes: 2 additions & 2 deletions blake2/src/blake2bp.rs
Original file line number Diff line number Diff line change
@@ -464,7 +464,7 @@ fn finalize_root_words(
Stride::Serial,
);
Hash {
bytes: crate::blake2b::state_words_to_bytes(&root_words),
bytes: crate::blake2b::state_words_to_bytes(root_words),
len: hash_length,
}
}
@@ -537,7 +537,7 @@ pub(crate) mod test {
force_portable(&mut params);
}
let input = &buf[..num_blocks * BLOCKBYTES + extra];
let expected = blake2bp_reference(&input);
let expected = blake2bp_reference(input);
let mut state = params.to_state();
let found = state.update(input).finalize();
assert_eq!(expected, found);
6 changes: 3 additions & 3 deletions blake2/src/blake2s.rs
Original file line number Diff line number Diff line change
@@ -589,7 +589,7 @@ impl Hash {

/// Convert the hash to a lowercase hexadecimal
/// [`ArrayString`](https://docs.rs/arrayvec/0.4/arrayvec/struct.ArrayString.html).
pub fn to_hex(&self) -> HexString {
pub fn to_hex(self) -> HexString {
bytes_to_hex(self.as_bytes())
}
}
@@ -607,14 +607,14 @@ fn bytes_to_hex(bytes: &[u8]) -> HexString {
/// This implementation is constant time, if the two hashes are the same length.
impl PartialEq for Hash {
fn eq(&self, other: &Hash) -> bool {
constant_time_eq::constant_time_eq(&self.as_bytes(), &other.as_bytes())
constant_time_eq::constant_time_eq(self.as_bytes(), other.as_bytes())
}
}

/// This implementation is constant time, if the slice is the same length as the hash.
impl PartialEq<[u8]> for Hash {
fn eq(&self, other: &[u8]) -> bool {
constant_time_eq::constant_time_eq(&self.as_bytes(), other)
constant_time_eq::constant_time_eq(self.as_bytes(), other)
}
}

4 changes: 2 additions & 2 deletions blake2/src/blake2s/avx2.rs
Original file line number Diff line number Diff line change
@@ -477,8 +477,8 @@ pub unsafe fn compress8_loop(jobs: &mut [Job<'_, '_>; DEGREE], finalize: Finaliz
jobs[6].input.as_ptr(),
jobs[7].input.as_ptr(),
];
let mut h_vecs = transpose_state_vecs(&jobs);
let (mut counts_lo, mut counts_hi) = load_counts(&jobs);
let mut h_vecs = transpose_state_vecs(jobs);
let (mut counts_lo, mut counts_hi) = load_counts(jobs);

// Prepare the final blocks (note, which could be empty if the input is
// empty). Do all this before entering the main loop.
44 changes: 22 additions & 22 deletions blake2/src/blake2s/guts.rs
Original file line number Diff line number Diff line change
@@ -8,17 +8,17 @@ pub const MAX_DEGREE: usize = 8;
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
pub const MAX_DEGREE: usize = 1;

// Variants other than Portable are unreachable in no_std, unless CPU features
// are explicitly enabled for the build with e.g. RUSTFLAGS="-C target-feature=avx2".
// This might change in the future if is_x86_feature_detected moves into libcore.
/// Variants other than Portable are unreachable in no_std, unless CPU features
/// are explicitly enabled for the build with e.g. RUSTFLAGS="-C target-feature=avx2".
/// This might change in the future if is_x86_feature_detected moves into libcore.
#[allow(dead_code)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
enum Platform {
Portable,
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
SSE41,
Sse41,
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
AVX2,
Avx2,
}

#[derive(Clone, Copy, Debug)]
@@ -53,13 +53,13 @@ impl Implementation {
// Check whether SSE4.1 support is assumed by the build.
#[cfg(target_feature = "sse4.1")]
{
return Some(Implementation(Platform::SSE41));
return Some(Implementation(Platform::Sse41));
}
// Otherwise dynamically check for support if we can.
#[cfg(feature = "std")]
{
if is_x86_feature_detected!("sse4.1") {
return Some(Implementation(Platform::SSE41));
return Some(Implementation(Platform::Sse41));
}
}
None
@@ -71,13 +71,13 @@ impl Implementation {
// Check whether AVX2 support is assumed by the build.
#[cfg(target_feature = "avx2")]
{
return Some(Implementation(Platform::AVX2));
return Some(Implementation(Platform::Avx2));
}
// Otherwise dynamically check for support if we can.
#[cfg(feature = "std")]
{
if is_x86_feature_detected!("avx2") {
return Some(Implementation(Platform::AVX2));
return Some(Implementation(Platform::Avx2));
}
}
None
@@ -86,9 +86,9 @@ impl Implementation {
pub fn degree(&self) -> usize {
match self.0 {
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
Platform::AVX2 => avx2::DEGREE,
Platform::Avx2 => avx2::DEGREE,
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
Platform::SSE41 => sse41::DEGREE,
Platform::Sse41 => sse41::DEGREE,
Platform::Portable => 1,
}
}
@@ -104,7 +104,7 @@ impl Implementation {
) {
match self.0 {
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
Platform::AVX2 | Platform::SSE41 => unsafe {
Platform::Avx2 | Platform::Sse41 => unsafe {
sse41::compress1_loop(input, words, count, last_node, finalize, stride);
},
Platform::Portable => {
@@ -116,7 +116,7 @@ impl Implementation {
pub fn compress4_loop(&self, jobs: &mut [Job<'_, '_>; 4], finalize: Finalize, stride: Stride) {
match self.0 {
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
Platform::AVX2 | Platform::SSE41 => unsafe {
Platform::Avx2 | Platform::Sse41 => unsafe {
sse41::compress4_loop(jobs, finalize, stride)
},
_ => panic!("unsupported"),
@@ -126,7 +126,7 @@ impl Implementation {
pub fn compress8_loop(&self, jobs: &mut [Job<'_, '_>; 8], finalize: Finalize, stride: Stride) {
match self.0 {
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
Platform::AVX2 => unsafe { avx2::compress8_loop(jobs, finalize, stride) },
Platform::Avx2 => unsafe { avx2::compress8_loop(jobs, finalize, stride) },
_ => panic!("unsupported"),
}
}
@@ -269,20 +269,20 @@ mod test {
#[cfg(feature = "std")]
{
if is_x86_feature_detected!("avx2") {
assert_eq!(Platform::AVX2, Implementation::detect().0);
assert_eq!(Platform::Avx2, Implementation::detect().0);
assert_eq!(
Platform::AVX2,
Platform::Avx2,
Implementation::avx2_if_supported().unwrap().0
);
assert_eq!(
Platform::SSE41,
Platform::Sse41,
Implementation::sse41_if_supported().unwrap().0
);
} else if is_x86_feature_detected!("sse4.1") {
assert_eq!(Platform::SSE41, Implementation::detect().0);
assert_eq!(Platform::Sse41, Implementation::detect().0);
assert!(Implementation::avx2_if_supported().is_none());
assert_eq!(
Platform::SSE41,
Platform::Sse41,
Implementation::sse41_if_supported().unwrap().0
);
} else {
@@ -299,9 +299,9 @@ mod test {
{
// Chose counts to hit the relevant overflow cases.
let counts = &[
(0 as Count),
((1 as Count) << (8 * size_of::<Word>())) - BLOCKBYTES as Count,
(0 as Count).wrapping_sub(BLOCKBYTES as Count),
0_u64,
(1_u64 << (8 * size_of::<Word>())) - BLOCKBYTES as Count,
0_u64.wrapping_sub(BLOCKBYTES as Count),
];
for &stride in &[Stride::Serial, Stride::Parallel] {
let lengths = [
4 changes: 2 additions & 2 deletions blake2/src/blake2s/sse41.rs
Original file line number Diff line number Diff line change
@@ -800,8 +800,8 @@ pub unsafe fn compress4_loop(jobs: &mut [Job<'_, '_>; DEGREE], finalize: Finaliz
jobs[2].input.as_ptr(),
jobs[3].input.as_ptr(),
];
let mut h_vecs = transpose_state_vecs(&jobs);
let (mut counts_lo, mut counts_hi) = load_counts(&jobs);
let mut h_vecs = transpose_state_vecs(jobs);
let (mut counts_lo, mut counts_hi) = load_counts(jobs);

// Prepare the final blocks (note, which could be empty if the input is
// empty). Do all this before entering the main loop.
4 changes: 2 additions & 2 deletions blake2/src/blake2sp.rs
Original file line number Diff line number Diff line change
@@ -471,7 +471,7 @@ fn finalize_root_words(
Stride::Serial,
);
Hash {
bytes: crate::blake2s::state_words_to_bytes(&root_words),
bytes: crate::blake2s::state_words_to_bytes(root_words),
len: hash_length,
}
}
@@ -544,7 +544,7 @@ pub(crate) mod test {
force_portable(&mut params);
}
let input = &buf[..num_blocks * BLOCKBYTES + extra];
let expected = blake2sp_reference(&input);
let expected = blake2sp_reference(input);
let mut state = params.to_state();
let found = state.update(input).finalize();
assert_eq!(expected, found);
8 changes: 4 additions & 4 deletions blake2/tests/vector_tests.rs
Original file line number Diff line number Diff line change
@@ -218,7 +218,7 @@ fn blake2xs_vectors() {
.key(key)
.hash_length(32)
.node_offset(combined_node_offset_xof_length)
.hash(&input_bytes)
.hash(input_bytes)
.as_bytes()
.to_vec();
h0
@@ -233,7 +233,7 @@ fn blake2xs_vectors() {
.fanout(0)
.max_depth(0)
.node_offset(combined_node_offset_xof_length)
.hash(&input_bytes)
.hash(input_bytes)
.as_bytes()
.to_vec();
b2_out
@@ -251,7 +251,7 @@ fn blake2xb_vectors() {
.key(key)
.hash_length(64)
.node_offset(combined_node_offset_xof_length)
.hash(&input_bytes)
.hash(input_bytes)
.as_bytes()
.to_vec();
h0
@@ -266,7 +266,7 @@ fn blake2xb_vectors() {
.fanout(0)
.max_depth(0)
.node_offset(combined_node_offset_xof_length)
.hash(&input_bytes)
.hash(input_bytes)
.as_bytes()
.to_vec();
b2_out