What changed, and why it matters
This commit simply moves existing code around in two files. It relocates the implementation blocks for SHA256 and SipHash24 hash types to appear earlier in their respective files, right after the hash type is declared. No code behavior was changed, no bugs were fixed, and no security issues were introduced.
No action needed. This is a non-functional style/consistency refactor.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff is a pure code reorganization (refactor) in hashes/src/sha256/mod.rs and hashes/src/siphash24/mod.rs. The impl Hash { ... } blocks are cut from their previous locations after the HashEngine implementation and pasted near the top of each file, immediately following the general_hash_type! macro invocation or macro definitions. The exact same methods, signatures, attributes, and bodies are preserved unchanged. No functional modifications are present.
Changed components
hashes/src/sha256/mod.rshashes/src/siphash24/mod.rsInspect captured patch +99 / −99
diff --git a/hashes/src/sha256/mod.rs b/hashes/src/sha256/mod.rs
index 02aa2fd7..66cd1661 100644
--- a/hashes/src/sha256/mod.rs
+++ b/hashes/src/sha256/mod.rs
@@ -20,6 +20,53 @@ crate::internal_macros::general_hash_type! {
"Output of the SHA256 hash function."
}
+impl Hash {
+ /// Finalize a hash engine to obtain a hash.
+ #[cfg(not(hashes_fuzz))]
+ pub fn from_engine(mut e: HashEngine) -> Self {
+ // pad buffer with a single 1-bit then all 0s, until there are exactly 8 bytes remaining
+ let n_bytes_hashed = e.bytes_hashed;
+
+ let buf_idx = incomplete_block_len(&e);
+
+ e.buffer[buf_idx] = 0x80;
+ e.buffer[buf_idx+1..].fill(0);
+
+ if buf_idx >= BLOCK_SIZE - 8 {
+ HashEngine::process_blocks(&mut e.h, &e.buffer);
+ e.buffer[..BLOCK_SIZE - 8].fill(0);
+ }
+
+ e.buffer[BLOCK_SIZE - 8..].copy_from_slice(&(8 * n_bytes_hashed).to_be_bytes());
+ HashEngine::process_blocks(&mut e.h, &e.buffer);
+
+ Self(e.midstate_unchecked().bytes)
+ }
+
+ /// Finalize a hash engine to obtain a hash.
+ #[cfg(hashes_fuzz)]
+ pub fn from_engine(e: HashEngine) -> Self {
+ let mut hash = e.midstate_unchecked().bytes;
+ if hash == [0; 32] {
+ // Assume sha256 is secure and never generate 0-hashes (which represent invalid
+ // secp256k1 secret keys, causing downstream application breakage).
+ hash[0] = 1;
+ }
+ Hash(hash)
+ }
+
+ /// Iterate the sha256 algorithm to turn a sha256 hash into a sha256d hash
+ #[must_use]
+ pub fn hash_again(&self) -> sha256d::Hash { sha256d::Hash::from_byte_array(hash(&self.0).0) }
+
+ /// Computes hash from `bytes` in `const` context.
+ ///
+ /// Warning: this function is inefficient. It should be only used in `const` context.
+ pub const fn hash_unoptimized(bytes: &[u8]) -> Self {
+ Self(Midstate::compute_midstate_unoptimized(bytes, true).bytes)
+ }
+}
+
const BLOCK_SIZE: usize = 64;
/// Engine to compute SHA256 hash function.
@@ -124,53 +171,6 @@ impl crate::HashEngine for HashEngine {
fn finalize(self) -> Self::Hash { Hash::from_engine(self) }
}
-impl Hash {
- /// Finalize a hash engine to obtain a hash.
- #[cfg(not(hashes_fuzz))]
- pub fn from_engine(mut e: HashEngine) -> Self {
- // pad buffer with a single 1-bit then all 0s, until there are exactly 8 bytes remaining
- let n_bytes_hashed = e.bytes_hashed;
-
- let buf_idx = incomplete_block_len(&e);
-
- e.buffer[buf_idx] = 0x80;
- e.buffer[buf_idx+1..].fill(0);
-
- if buf_idx >= BLOCK_SIZE - 8 {
- HashEngine::process_blocks(&mut e.h, &e.buffer);
- e.buffer[..BLOCK_SIZE - 8].fill(0);
- }
-
- e.buffer[BLOCK_SIZE - 8..].copy_from_slice(&(8 * n_bytes_hashed).to_be_bytes());
- HashEngine::process_blocks(&mut e.h, &e.buffer);
-
- Self(e.midstate_unchecked().bytes)
- }
-
- /// Finalize a hash engine to obtain a hash.
- #[cfg(hashes_fuzz)]
- pub fn from_engine(e: HashEngine) -> Self {
- let mut hash = e.midstate_unchecked().bytes;
- if hash == [0; 32] {
- // Assume sha256 is secure and never generate 0-hashes (which represent invalid
- // secp256k1 secret keys, causing downstream application breakage).
- hash[0] = 1;
- }
- Hash(hash)
- }
-
- /// Iterate the sha256 algorithm to turn a sha256 hash into a sha256d hash
- #[must_use]
- pub fn hash_again(&self) -> sha256d::Hash { sha256d::Hash::from_byte_array(hash(&self.0).0) }
-
- /// Computes hash from `bytes` in `const` context.
- ///
- /// Warning: this function is inefficient. It should be only used in `const` context.
- pub const fn hash_unoptimized(bytes: &[u8]) -> Self {
- Self(Midstate::compute_midstate_unoptimized(bytes, true).bytes)
- }
-}
-
/// Unfinalized output of the SHA256 hash function.
///
/// The `Midstate` type is obscure and specialized and should not be used unless you are sure of
diff --git a/hashes/src/siphash24/mod.rs b/hashes/src/siphash24/mod.rs
index d65585dd..b03362c1 100644
--- a/hashes/src/siphash24/mod.rs
+++ b/hashes/src/siphash24/mod.rs
@@ -50,6 +50,58 @@ macro_rules! load_int_le {
}};
}
+impl Hash {
+ /// Constructs a new SipHash24 engine with keys.
+ pub fn engine(k0: u64, k1: u64) -> HashEngine { HashEngine::with_keys(k0, k1) }
+
+ /// Produces a hash from the current state of a given engine.
+ #[cfg(not(hashes_fuzz))]
+ pub fn from_engine(e: HashEngine) -> Self { Self::from_u64(Self::from_engine_to_u64(e)) }
+
+ #[cfg(hashes_fuzz)]
+ pub fn from_engine(e: HashEngine) -> Self {
+ let state = e.state.clone();
+ Hash::from_u64(state.v0 ^ state.v1 ^ state.v2 ^ state.v3)
+ }
+
+ /// Hashes the given data with an engine with the provided keys.
+ pub fn hash_with_keys(k0: u64, k1: u64, data: &[u8]) -> Self {
+ let mut engine = HashEngine::with_keys(k0, k1);
+ engine.input(data);
+ Self::from_engine(engine)
+ }
+
+ /// Hashes the given data directly to u64 with an engine with the provided keys.
+ pub fn hash_to_u64_with_keys(k0: u64, k1: u64, data: &[u8]) -> u64 {
+ let mut engine = HashEngine::with_keys(k0, k1);
+ engine.input(data);
+ Self::from_engine_to_u64(engine)
+ }
+
+ /// Produces a hash as `u64` from the current state of a given engine.
+ #[inline]
+ pub fn from_engine_to_u64(e: HashEngine) -> u64 {
+ let mut state = e.state;
+
+ let b: u64 = ((e.bytes_hashed & 0xff) << 56) | e.tail;
+
+ state.v3 ^= b;
+ HashEngine::c_rounds(&mut state);
+ state.v0 ^= b;
+
+ state.v2 ^= 0xff;
+ HashEngine::d_rounds(&mut state);
+
+ state.v0 ^ state.v1 ^ state.v2 ^ state.v3
+ }
+
+ /// Returns the (little endian) 64-bit integer representation of the hash value.
+ pub fn to_u64(self) -> u64 { u64::from_le_bytes(self.0) }
+
+ /// Constructs a new hash from its (little endian) 64-bit integer representation.
+ pub fn from_u64(hash: u64) -> Self { Self(hash.to_le_bytes()) }
+}
+
/// Internal state of the [`HashEngine`].
#[derive(Debug, Clone)]
pub struct State {
@@ -162,58 +214,6 @@ impl crate::HashEngine for HashEngine {
fn finalize(self) -> Self::Hash { Hash::from_engine(self) }
}
-impl Hash {
- /// Constructs a new SipHash24 engine with keys.
- pub fn engine(k0: u64, k1: u64) -> HashEngine { HashEngine::with_keys(k0, k1) }
-
- /// Produces a hash from the current state of a given engine.
- #[cfg(not(hashes_fuzz))]
- pub fn from_engine(e: HashEngine) -> Self { Self::from_u64(Self::from_engine_to_u64(e)) }
-
- #[cfg(hashes_fuzz)]
- pub fn from_engine(e: HashEngine) -> Self {
- let state = e.state.clone();
- Hash::from_u64(state.v0 ^ state.v1 ^ state.v2 ^ state.v3)
- }
-
- /// Hashes the given data with an engine with the provided keys.
- pub fn hash_with_keys(k0: u64, k1: u64, data: &[u8]) -> Self {
- let mut engine = HashEngine::with_keys(k0, k1);
- engine.input(data);
- Self::from_engine(engine)
- }
-
- /// Hashes the given data directly to u64 with an engine with the provided keys.
- pub fn hash_to_u64_with_keys(k0: u64, k1: u64, data: &[u8]) -> u64 {
- let mut engine = HashEngine::with_keys(k0, k1);
- engine.input(data);
- Self::from_engine_to_u64(engine)
- }
-
- /// Produces a hash as `u64` from the current state of a given engine.
- #[inline]
- pub fn from_engine_to_u64(e: HashEngine) -> u64 {
- let mut state = e.state;
-
- let b: u64 = ((e.bytes_hashed & 0xff) << 56) | e.tail;
-
- state.v3 ^= b;
- HashEngine::c_rounds(&mut state);
- state.v0 ^= b;
-
- state.v2 ^= 0xff;
- HashEngine::d_rounds(&mut state);
-
- state.v0 ^ state.v1 ^ state.v2 ^ state.v3
- }
-
- /// Returns the (little endian) 64-bit integer representation of the hash value.
- pub fn to_u64(self) -> u64 { u64::from_le_bytes(self.0) }
-
- /// Constructs a new hash from its (little endian) 64-bit integer representation.
- pub fn from_u64(hash: u64) -> Self { Self(hash.to_le_bytes()) }
-}
-
/// Loads a u64 using up to 7 bytes of a byte slice.
///
/// Unsafe because: unchecked indexing at `start..start+len`.
Why this scored 15/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.