From d3846895d790e4782795afc4b83130bc7d73de7d Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Thu, 20 Feb 2025 13:20:12 +1100 Subject: [PATCH] hashes: Add hash function to modules Add a standalone `hash` function that is a drop in replacement for `GeneralHash::hash`. Do not add it to `hmac` - this is in parity with the current code because `Hmac` does not implement `GeneralHash::hash`. Use the new function in `bitcoin` removing all occurrences of `GeneralHash` from `bitcoin`. In `hashes` replace usage of `GeneralHash::hash` with the new `hash` function. --- bitcoin/src/consensus/encode.rs | 4 ++-- bitcoin/src/psbt/macros.rs | 6 +++--- bitcoin/src/psbt/map/input.rs | 8 ++++---- hashes/src/internal_macros.rs | 11 ++++++++++- hashes/src/sha256/mod.rs | 4 +--- hashes/src/sha256t/mod.rs | 12 ++++++++++++ 6 files changed, 32 insertions(+), 13 deletions(-) diff --git a/bitcoin/src/consensus/encode.rs b/bitcoin/src/consensus/encode.rs index e2946b16b..a8637c2c6 100644 --- a/bitcoin/src/consensus/encode.rs +++ b/bitcoin/src/consensus/encode.rs @@ -16,7 +16,7 @@ use core::mem; -use hashes::{sha256, sha256d, GeneralHash, Hash}; +use hashes::{sha256, sha256d, Hash}; use hex::DisplayHex as _; use internals::{compact_size, ToU64}; use io::{BufRead, Cursor, Read, Write}; @@ -629,7 +629,7 @@ impl Decodable for Box<[u8]> { /// Does a double-SHA256 on `data` and returns the first 4 bytes. fn sha2_checksum(data: &[u8]) -> [u8; 4] { - let checksum = ::hash(data); + let checksum = sha256d::hash(data); let checksum = checksum.to_byte_array(); [checksum[0], checksum[1], checksum[2], checksum[3]] } diff --git a/bitcoin/src/psbt/macros.rs b/bitcoin/src/psbt/macros.rs index 089d705b4..4044a5e52 100644 --- a/bitcoin/src/psbt/macros.rs +++ b/bitcoin/src/psbt/macros.rs @@ -113,15 +113,15 @@ macro_rules! impl_psbt_insert_pair { #[rustfmt::skip] macro_rules! psbt_insert_hash_pair { - (&mut $slf:ident.$map:ident <= $raw_key:ident|$raw_value:ident|$hash:path|$hash_type_error:path) => { + (&mut $slf:ident.$map:ident <= $raw_key:ident|$raw_value:ident|$hash:ident|$hash_type_error:path) => { if $raw_key.key_data.is_empty() { return Err($crate::psbt::Error::InvalidKey($raw_key)); } - let key_val: $hash = Deserialize::deserialize(&$raw_key.key_data)?; + let key_val: $hash::Hash = Deserialize::deserialize(&$raw_key.key_data)?; match $slf.$map.entry(key_val) { btree_map::Entry::Vacant(empty_key) => { let val: Vec = Deserialize::deserialize(&$raw_value)?; - if <$hash as hashes::GeneralHash>::hash(&val) != key_val { + if $hash::hash(&val) != key_val { return Err($crate::psbt::Error::InvalidPreimageHashPair { preimage: val.into_boxed_slice(), hash: Box::from(key_val.borrow()), diff --git a/bitcoin/src/psbt/map/input.rs b/bitcoin/src/psbt/map/input.rs index 401bc34b4..66802623b 100644 --- a/bitcoin/src/psbt/map/input.rs +++ b/bitcoin/src/psbt/map/input.rs @@ -317,22 +317,22 @@ impl Input { } PSBT_IN_RIPEMD160 => { psbt_insert_hash_pair! { - &mut self.ripemd160_preimages <= raw_key|raw_value|ripemd160::Hash|error::PsbtHash::Ripemd + &mut self.ripemd160_preimages <= raw_key|raw_value|ripemd160|error::PsbtHash::Ripemd } } PSBT_IN_SHA256 => { psbt_insert_hash_pair! { - &mut self.sha256_preimages <= raw_key|raw_value|sha256::Hash|error::PsbtHash::Sha256 + &mut self.sha256_preimages <= raw_key|raw_value|sha256|error::PsbtHash::Sha256 } } PSBT_IN_HASH160 => { psbt_insert_hash_pair! { - &mut self.hash160_preimages <= raw_key|raw_value|hash160::Hash|error::PsbtHash::Hash160 + &mut self.hash160_preimages <= raw_key|raw_value|hash160|error::PsbtHash::Hash160 } } PSBT_IN_HASH256 => { psbt_insert_hash_pair! { - &mut self.hash256_preimages <= raw_key|raw_value|sha256d::Hash|error::PsbtHash::Hash256 + &mut self.hash256_preimages <= raw_key|raw_value|sha256d|error::PsbtHash::Hash256 } } PSBT_IN_TAP_KEY_SIG => { diff --git a/hashes/src/internal_macros.rs b/hashes/src/internal_macros.rs index fe5d6aa71..41ffab593 100644 --- a/hashes/src/internal_macros.rs +++ b/hashes/src/internal_macros.rs @@ -71,6 +71,15 @@ pub(crate) use hash_trait_impls; /// [`hash_trait_impls`]. macro_rules! general_hash_type { ($bits:expr, $reverse:expr, $doc:literal) => { + /// Hashes some bytes. + pub fn hash(data: &[u8]) -> Hash { + use crate::HashEngine as _; + + let mut engine = Hash::engine(); + engine.input(data); + engine.finalize() + } + $crate::internal_macros::hash_type_no_default!($bits, $reverse, $doc); impl Hash { @@ -82,7 +91,7 @@ macro_rules! general_hash_type { /// Hashes some bytes. #[allow(clippy::self_named_constructors)] // Hash is a noun and a verb. - pub fn hash(data: &[u8]) -> Self { ::hash(data) } + pub fn hash(data: &[u8]) -> Self { hash(data) } /// Hashes all the byte slices retrieved from the iterator together. pub fn hash_byte_chunks(byte_slices: I) -> Self diff --git a/hashes/src/sha256/mod.rs b/hashes/src/sha256/mod.rs index 323e4de8f..5d8fe125b 100644 --- a/hashes/src/sha256/mod.rs +++ b/hashes/src/sha256/mod.rs @@ -140,9 +140,7 @@ impl crate::HashEngine for HashEngine { impl Hash { /// Iterate the sha256 algorithm to turn a sha256 hash into a sha256d hash #[must_use] - pub fn hash_again(&self) -> sha256d::Hash { - crate::Hash::from_byte_array(::hash(&self.0).0) - } + pub fn hash_again(&self) -> sha256d::Hash { sha256d::Hash::from_byte_array(hash(&self.0).0) } /// Computes hash from `bytes` in `const` context. /// diff --git a/hashes/src/sha256t/mod.rs b/hashes/src/sha256t/mod.rs index 11e224058..be144f2f2 100644 --- a/hashes/src/sha256t/mod.rs +++ b/hashes/src/sha256t/mod.rs @@ -9,6 +9,18 @@ use core::marker::PhantomData; use crate::sha256::Midstate; use crate::{sha256, HashEngine as _}; +/// Hashes some bytes. +pub fn hash(data: &[u8]) -> Hash +where + T: Tag, +{ + use crate::HashEngine as _; + + let mut engine = HashEngine::default(); + engine.input(data); + engine.finalize() +} + /// Trait representing a tag that can be used as a context for SHA256t hashes. pub trait Tag { /// The [`Midstate`] after pre-tagging the hash engine.