From b9f082d9ecf0e831bcbd08a54f7a11cd6b116e2b Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Tue, 14 May 2024 11:50:27 +1000 Subject: [PATCH 1/8] Remove unused public macro We don't need to provide this macro, it is never called by this crate. --- src/util.rs | 45 --------------------------------------------- 1 file changed, 45 deletions(-) diff --git a/src/util.rs b/src/util.rs index 3dde545..4a229a0 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,50 +1,5 @@ // SPDX-License-Identifier: CC0-1.0 -#[macro_export] -/// Adds hexadecimal formatting implementation of a trait `$imp` to a given type `$ty`. -macro_rules! hex_fmt_impl( - ($reverse:expr, $len:expr, $ty:ident) => ( - $crate::hex_fmt_impl!($reverse, $len, $ty, ); - ); - ($reverse:expr, $len:expr, $ty:ident, $($gen:ident: $gent:ident),*) => ( - impl<$($gen: $gent),*> $crate::_export::_core::fmt::LowerHex for $ty<$($gen),*> { - #[inline] - fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result { - if $reverse { - $crate::hex::fmt_hex_exact!(f, $len, ::as_byte_array(&self).iter().rev(), $crate::hex::Case::Lower) - } else { - $crate::hex::fmt_hex_exact!(f, $len, ::as_byte_array(&self), $crate::hex::Case::Lower) - } - } - } - - impl<$($gen: $gent),*> $crate::_export::_core::fmt::UpperHex for $ty<$($gen),*> { - #[inline] - fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result { - if $reverse { - $crate::hex::fmt_hex_exact!(f, $len, ::as_byte_array(&self).iter().rev(), $crate::hex::Case::Upper) - } else { - $crate::hex::fmt_hex_exact!(f, $len, ::as_byte_array(&self), $crate::hex::Case::Upper) - } - } - } - - impl<$($gen: $gent),*> $crate::_export::_core::fmt::Display for $ty<$($gen),*> { - #[inline] - fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result { - $crate::_export::_core::fmt::LowerHex::fmt(&self, f) - } - } - - impl<$($gen: $gent),*> $crate::_export::_core::fmt::Debug for $ty<$($gen),*> { - #[inline] - fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result { - write!(f, "{}", self) - } - } - ); -); - /// Adds `AsRef` implementation to a given type `$ty`. #[macro_export] macro_rules! as_ref_impl( From e25d12b571f3a570326341f9c7ffdaf394ad827a Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Tue, 14 May 2024 11:51:47 +1000 Subject: [PATCH 2/8] Manually format macro The formatter is not getting this line, do it manually. --- src/util.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/util.rs b/src/util.rs index 4a229a0..0c80f74 100644 --- a/src/util.rs +++ b/src/util.rs @@ -8,9 +8,7 @@ macro_rules! as_ref_impl( ); ($ty:ident, $($gen:ident: $gent:ident),*) => ( impl<$($gen: $gent),*> $crate::_export::_core::convert::AsRef<[u8]> for $ty<$($gen),*> { - fn as_ref(&self) -> &[u8] { - &self[..] - } + fn as_ref(&self) -> &[u8] { &self[..] } } ) ); From be21c940dc7d3c57fbb3974ee85aebca11b0e54b Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Tue, 14 May 2024 11:52:45 +1000 Subject: [PATCH 3/8] Use fully qualified path in macro Its better style to use fully qualified paths in macros. Refactor only, no logic changes. --- src/ripemd160.rs | 2 +- src/sha1.rs | 2 +- src/sha256.rs | 2 +- src/sha512.rs | 2 +- src/util.rs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ripemd160.rs b/src/ripemd160.rs index ee10b77..4855566 100644 --- a/src/ripemd160.rs +++ b/src/ripemd160.rs @@ -2,7 +2,7 @@ //! RIPEMD160 implementation. -use core::{cmp, str}; +use core::str; use crate::HashEngine as _; diff --git a/src/sha1.rs b/src/sha1.rs index 36f8f61..f70b429 100644 --- a/src/sha1.rs +++ b/src/sha1.rs @@ -2,7 +2,7 @@ //! SHA-1 implementation. -use core::{cmp, str}; +use core::str; use crate::HashEngine as _; diff --git a/src/sha256.rs b/src/sha256.rs index 56255f0..9ee9e13 100644 --- a/src/sha256.rs +++ b/src/sha256.rs @@ -8,7 +8,7 @@ use core::arch::x86::*; use core::arch::x86_64::*; use core::ops::Index; use core::slice::SliceIndex; -use core::{cmp, str}; +use core::str; use crate::{FromSliceError, HashEngine as _}; diff --git a/src/sha512.rs b/src/sha512.rs index c325ec9..b46fec5 100644 --- a/src/sha512.rs +++ b/src/sha512.rs @@ -2,7 +2,7 @@ //! SHA-512 implementation. -use core::{cmp, str}; +use core::str; use crate::HashEngine as _; diff --git a/src/util.rs b/src/util.rs index 0c80f74..af1850a 100644 --- a/src/util.rs +++ b/src/util.rs @@ -20,7 +20,7 @@ macro_rules! engine_input_impl( while !inp.is_empty() { let buf_idx = self.length % ::BLOCK_SIZE; let rem_len = ::BLOCK_SIZE - buf_idx; - let write_len = cmp::min(rem_len, inp.len()); + let write_len = $crate::_export::_core::cmp::min(rem_len, inp.len()); self.buffer[buf_idx..buf_idx + write_len] .copy_from_slice(&inp[..write_len]); From 406ed1213581dd1c55392014b525e2f5d8194936 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Tue, 14 May 2024 11:56:09 +1000 Subject: [PATCH 4/8] Do not export macro The `as_ref_impl` macro is just for internal use, don't export it. --- src/util.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util.rs b/src/util.rs index af1850a..ba56bea 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,10 +1,9 @@ // SPDX-License-Identifier: CC0-1.0 /// Adds `AsRef` implementation to a given type `$ty`. -#[macro_export] macro_rules! as_ref_impl( ($ty:ident) => ( - $crate::as_ref_impl!($ty, ); + $crate::util::as_ref_impl!($ty, ); ); ($ty:ident, $($gen:ident: $gent:ident),*) => ( impl<$($gen: $gent),*> $crate::_export::_core::convert::AsRef<[u8]> for $ty<$($gen),*> { @@ -12,6 +11,7 @@ macro_rules! as_ref_impl( } ) ); +pub(crate) use as_ref_impl; macro_rules! engine_input_impl( ($n:literal) => ( From aff3165b02be4b3002d0a81da4aa476c89ff4132 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Tue, 14 May 2024 11:59:54 +1000 Subject: [PATCH 5/8] Remove util module The `util` module now contains only two private macros, move them to `internal_macros` and remove the `util` module. --- src/internal_macros.rs | 46 +++++++++++++++++++++++++++++++++++++++++- src/lib.rs | 2 -- src/ripemd160.rs | 2 +- src/sha1.rs | 2 +- src/sha256.rs | 4 ++-- src/sha512.rs | 2 +- src/util.rs | 43 --------------------------------------- 7 files changed, 50 insertions(+), 51 deletions(-) delete mode 100644 src/util.rs diff --git a/src/internal_macros.rs b/src/internal_macros.rs index 20b9272..9f360ac 100644 --- a/src/internal_macros.rs +++ b/src/internal_macros.rs @@ -2,6 +2,50 @@ //! Non-public macros +/// Adds `AsRef` implementation to a given type `$ty`. +macro_rules! as_ref_impl( + ($ty:ident) => ( + $crate::internal_macros::as_ref_impl!($ty, ); + ); + ($ty:ident, $($gen:ident: $gent:ident),*) => ( + impl<$($gen: $gent),*> $crate::_export::_core::convert::AsRef<[u8]> for $ty<$($gen),*> { + fn as_ref(&self) -> &[u8] { &self[..] } + } + ) +); +pub(crate) use as_ref_impl; + +/// Adds an implementation of the `HashEngine::input` method. +macro_rules! engine_input_impl( + ($n:literal) => ( + #[cfg(not(hashes_fuzz))] + fn input(&mut self, mut inp: &[u8]) { + while !inp.is_empty() { + let buf_idx = self.length % ::BLOCK_SIZE; + let rem_len = ::BLOCK_SIZE - buf_idx; + let write_len = $crate::_export::_core::cmp::min(rem_len, inp.len()); + + self.buffer[buf_idx..buf_idx + write_len] + .copy_from_slice(&inp[..write_len]); + self.length += write_len; + if self.length % ::BLOCK_SIZE == 0 { + self.process_block(); + } + inp = &inp[write_len..]; + } + } + + #[cfg(hashes_fuzz)] + fn input(&mut self, inp: &[u8]) { + for c in inp { + self.buffer[0] ^= *c; + } + self.length += inp.len(); + } + ) +); +pub(crate) use engine_input_impl; + macro_rules! arr_newtype_fmt_impl { ($ty:ident, $bytes:expr $(, $gen:ident: $gent:ident)*) => { impl<$($gen: $gent),*> $crate::_export::_core::fmt::LowerHex for $ty<$($gen),*> { @@ -68,7 +112,7 @@ macro_rules! hash_trait_impls { $crate::internal_macros::arr_newtype_fmt_impl!(Hash, $bits / 8 $(, $gen: $gent)*); serde_impl!(Hash, $bits / 8 $(, $gen: $gent)*); - as_ref_impl!(Hash $(, $gen: $gent)*); + $crate::internal_macros::as_ref_impl!(Hash $(, $gen: $gent)*); impl<$($gen: $gent),*> $crate::_export::_core::convert::AsRef<[u8; $bits / 8]> for Hash<$($gen),*> { fn as_ref(&self) -> &[u8; $bits / 8] { &self.0 } diff --git a/src/lib.rs b/src/lib.rs index f67804c..dfbb959 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -113,8 +113,6 @@ extern crate schemars; mod internal_macros; #[macro_use] -mod util; -#[macro_use] pub mod serde_macros; pub mod cmp; pub mod hmac; diff --git a/src/ripemd160.rs b/src/ripemd160.rs index 4855566..541a64e 100644 --- a/src/ripemd160.rs +++ b/src/ripemd160.rs @@ -39,7 +39,7 @@ impl crate::HashEngine for HashEngine { #[inline] fn n_bytes_hashed(&self) -> usize { self.length } - engine_input_impl!(20); + crate::internal_macros::engine_input_impl!(20); #[cfg(not(hashes_fuzz))] #[inline] diff --git a/src/sha1.rs b/src/sha1.rs index f70b429..1f3d760 100644 --- a/src/sha1.rs +++ b/src/sha1.rs @@ -39,7 +39,7 @@ impl crate::HashEngine for HashEngine { #[inline] fn n_bytes_hashed(&self) -> usize { self.length } - engine_input_impl!(20); + crate::internal_macros::engine_input_impl!(20); #[inline] fn finalize(mut self) -> Self::Digest { diff --git a/src/sha256.rs b/src/sha256.rs index 9ee9e13..692bf01 100644 --- a/src/sha256.rs +++ b/src/sha256.rs @@ -49,7 +49,7 @@ impl crate::HashEngine for HashEngine { #[inline] fn n_bytes_hashed(&self) -> usize { self.length } - engine_input_impl!(32); + crate::internal_macros::engine_input_impl!(32); #[cfg(not(hashes_fuzz))] #[inline] @@ -126,7 +126,7 @@ pub struct Midstate(pub [u8; 32]); crate::internal_macros::arr_newtype_fmt_impl!(Midstate, 32); serde_impl!(Midstate, 32); -as_ref_impl!(Midstate); +crate::internal_macros::as_ref_impl!(Midstate); impl> Index for Midstate { type Output = I::Output; diff --git a/src/sha512.rs b/src/sha512.rs index b46fec5..d75e67e 100644 --- a/src/sha512.rs +++ b/src/sha512.rs @@ -71,7 +71,7 @@ impl crate::HashEngine for HashEngine { #[inline] fn n_bytes_hashed(&self) -> usize { self.length } - engine_input_impl!(64); + crate::internal_macros::engine_input_impl!(64); #[cfg(not(hashes_fuzz))] #[inline] diff --git a/src/util.rs b/src/util.rs deleted file mode 100644 index ba56bea..0000000 --- a/src/util.rs +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: CC0-1.0 - -/// Adds `AsRef` implementation to a given type `$ty`. -macro_rules! as_ref_impl( - ($ty:ident) => ( - $crate::util::as_ref_impl!($ty, ); - ); - ($ty:ident, $($gen:ident: $gent:ident),*) => ( - impl<$($gen: $gent),*> $crate::_export::_core::convert::AsRef<[u8]> for $ty<$($gen),*> { - fn as_ref(&self) -> &[u8] { &self[..] } - } - ) -); -pub(crate) use as_ref_impl; - -macro_rules! engine_input_impl( - ($n:literal) => ( - #[cfg(not(hashes_fuzz))] - fn input(&mut self, mut inp: &[u8]) { - while !inp.is_empty() { - let buf_idx = self.length % ::BLOCK_SIZE; - let rem_len = ::BLOCK_SIZE - buf_idx; - let write_len = $crate::_export::_core::cmp::min(rem_len, inp.len()); - - self.buffer[buf_idx..buf_idx + write_len] - .copy_from_slice(&inp[..write_len]); - self.length += write_len; - if self.length % ::BLOCK_SIZE == 0 { - self.process_block(); - } - inp = &inp[write_len..]; - } - } - - #[cfg(hashes_fuzz)] - fn input(&mut self, inp: &[u8]) { - for c in inp { - self.buffer[0] ^= *c; - } - self.length += inp.len(); - } - ) -); From dbca2622119eb4ef6698de9300d02bc3a91a7d59 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Tue, 14 May 2024 12:02:03 +1000 Subject: [PATCH 6/8] Document arr_newtype_fmt_impl macro --- src/internal_macros.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/internal_macros.rs b/src/internal_macros.rs index 9f360ac..6844fd9 100644 --- a/src/internal_macros.rs +++ b/src/internal_macros.rs @@ -46,6 +46,7 @@ macro_rules! engine_input_impl( ); pub(crate) use engine_input_impl; +/// Adds `fmt::{LowerHex, UpperHex, Display, Debug}` trait impls to `$ty`. macro_rules! arr_newtype_fmt_impl { ($ty:ident, $bytes:expr $(, $gen:ident: $gent:ident)*) => { impl<$($gen: $gent),*> $crate::_export::_core::fmt::LowerHex for $ty<$($gen),*> { From d1dee9f7969431fbe4d0e664d33288234ee0eee6 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Tue, 14 May 2024 12:06:23 +1000 Subject: [PATCH 7/8] Fix stale docs on hash_type macro --- src/internal_macros.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/internal_macros.rs b/src/internal_macros.rs index 6844fd9..8617919 100644 --- a/src/internal_macros.rs +++ b/src/internal_macros.rs @@ -129,20 +129,15 @@ macro_rules! hash_trait_impls { } pub(crate) use hash_trait_impls; -/// Creates a type called `Hash` and implements standard interface for it. +/// Creates a type called `Hash` and implements the standard interface for it. /// -/// The created type will have all standard derives, `Hash` impl and implementation of -/// `internal_engine` returning default. The created type has a single field. +/// The created type has a single private field, an array that is the digest bytes. The digest bytes +/// can be accessed using the expected API for a byte array and includes all standard derives. /// /// Arguments: /// /// * `$bits` - the number of bits of the hash type -/// * `$reverse` - `true` if the hash should be displayed backwards, `false` otherwise /// * `$doc` - doc string to put on the type -/// * `$schemars` - a literal that goes into `schema_with`. -/// -/// The `from_engine` free-standing function is still required with this macro. See the doc of -/// [`hash_trait_impls`]. macro_rules! hash_type { ($bits:expr, $doc:literal) => { #[doc = $doc] From 42ebe298317bcec8aef56325ea928d9826ec9c88 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Tue, 14 May 2024 12:12:01 +1000 Subject: [PATCH 8/8] Add as_bytes and to_bytes functions As discussed and implemented in `rust-bitcoin` PR #2585 its useful to get a byte slice as well as the already provided method for a array reference. Also, if "alloc" feature is enabled its useful to be able to get a vector. --- src/hmac.rs | 7 +++++++ src/internal_macros.rs | 9 +++++++++ src/sha256t.rs | 7 +++++++ 3 files changed, 23 insertions(+) diff --git a/src/hmac.rs b/src/hmac.rs index 2794a9d..a1da810 100644 --- a/src/hmac.rs +++ b/src/hmac.rs @@ -72,6 +72,13 @@ impl Hmac { /// Returns a reference to the underlying byte array. pub fn as_byte_array(&self) -> &[u8; N] { &self.0 } + /// Returns a reference to the underlying byte array as a slice. + pub fn as_bytes(&self) -> &[u8] { &self.0 } + + /// Copies the underlying bytes into a new `Vec`. + #[cfg(feature = "alloc")] + pub fn to_bytes(&self) -> Vec { self.0.to_vec() } + /// Returns an all zero hash. /// /// An all zeros hash is a made up construct because there is not a known input that can diff --git a/src/internal_macros.rs b/src/internal_macros.rs index 8617919..b310273 100644 --- a/src/internal_macros.rs +++ b/src/internal_macros.rs @@ -206,6 +206,15 @@ macro_rules! hash_type { /// Returns a reference to the underlying byte array. pub fn as_byte_array(&self) -> &[u8; $bits / 8] { &self.0 } + /// Returns a reference to the underlying byte array as a slice. + #[inline] + pub fn as_bytes(&self) -> &[u8] { &self.0 } + + /// Copies the underlying bytes into a new `Vec`. + #[cfg(feature = "alloc")] + #[inline] + pub fn to_bytes(&self) -> Vec { self.0.to_vec() } + /// Returns an all zero hash. /// /// An all zeros hash is a made up construct because there is not a known input that can diff --git a/src/sha256t.rs b/src/sha256t.rs index 8b9859c..4482cc0 100644 --- a/src/sha256t.rs +++ b/src/sha256t.rs @@ -113,6 +113,13 @@ impl Hash { /// Returns a reference to the underlying byte array. pub fn as_byte_array(&self) -> &[u8; 32] { &self.0 } + /// Returns a reference to the underlying byte array as a slice. + pub fn as_bytes(&self) -> &[u8] { &self.0 } + + /// Copies the underlying bytes into a new `Vec`. + #[cfg(feature = "alloc")] + pub fn to_bytes(&self) -> Vec { self.0.to_vec() } + /// Returns an all zero hash. /// /// An all zeros hash is a made up construct because there is not a known input that can