hashes: Add x86 SHA-NI 2-way dispatch
What changed, and why it matters
This commit adds a performance optimization for computing SHA-256 hashes on modern x86 processors that support Intel's SHA-NI instructions. It is a routine feature addition, not a security fix or vulnerability patch. There is no indication in the commit that it addresses a security issue.
No security action required. Review as a normal performance optimization; verify the unsafe call's preconditions are met by the slice length checks and feature detection.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch introduces a 2-way dispatch path in the SHA-256 double-hash engine for x86/x86_64. When the appropriate CPU features are detected (via std’s feature detection or the crate’s cpufeatures fallback), it processes two 64-byte input blocks at once using the existing x86_shani::sha256d_64_2way unsafe function. This is purely an optimization dispatch; no cryptographic logic changes, no bounds checks are removed, and no new trusted input paths are introduced beyond the existing slice indexing already guarded by the while condition.
Changed components
hashes/src/sha256/crypto/mod.rsInspect captured patch +31 / −1
diff --git a/hashes/src/sha256/crypto/mod.rs b/hashes/src/sha256/crypto/mod.rs
index 83e0b115..a4c239e6 100644
--- a/hashes/src/sha256/crypto/mod.rs
+++ b/hashes/src/sha256/crypto/mod.rs
@@ -339,7 +339,37 @@ impl HashEngine {
// TODO: 8-way AVX2
// TODO: 4-way SSE4.1
- // TODO: 2-way x86 SHA-NI
+
+ // 2-way x86 SHA-NI
+ #[cfg(feature = "std")]
+ #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+ {
+ if std::is_x86_feature_detected!("sse4.1")
+ && std::is_x86_feature_detected!("sha")
+ && std::is_x86_feature_detected!("sse2")
+ && std::is_x86_feature_detected!("ssse3")
+ {
+ while count - i >= 2 {
+ let out = <&mut [[u8; 32]; 2]>::try_from(&mut outputs[i..i + 2]).unwrap();
+ let inp = <&[[u8; 64]; 2]>::try_from(&inputs[i..i + 2]).unwrap();
+ unsafe { x86_shani::sha256d_64_2way(out, inp) };
+ i += 2;
+ }
+ }
+ }
+
+ #[cfg(feature = "cpufeatures")]
+ #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+ {
+ if cpuid_sha256_x86::get() {
+ while count - i >= 2 {
+ let out = <&mut [[u8; 32]; 2]>::try_from(&mut outputs[i..i + 2]).unwrap();
+ let inp = <&[[u8; 64]; 2]>::try_from(&inputs[i..i + 2]).unwrap();
+ unsafe { x86_shani::sha256d_64_2way(out, inp) };
+ i += 2;
+ }
+ }
+ }
// 2-way ARM SHA2
#[cfg(feature = "std")]
Why this scored 17/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.