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 20b9272..b310273 100644 --- a/src/internal_macros.rs +++ b/src/internal_macros.rs @@ -2,6 +2,51 @@ //! 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; + +/// 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),*> { @@ -68,7 +113,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 } @@ -84,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] @@ -166,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/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 ee10b77..541a64e 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 _; @@ -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 36f8f61..1f3d760 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 _; @@ -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 56255f0..692bf01 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 _}; @@ -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/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 diff --git a/src/sha512.rs b/src/sha512.rs index c325ec9..d75e67e 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 _; @@ -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 3dde545..0000000 --- a/src/util.rs +++ /dev/null @@ -1,90 +0,0 @@ -// 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( - ($ty:ident) => ( - $crate::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[..] - } - } - ) -); - -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 = 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(); - } - ) -);