Feature (hashes): Add from_bytes_ref and from_bytes_mut to all Hash types

This commit is contained in:
junderw 2023-03-28 18:27:41 -07:00
parent dc72dfb9f2
commit 91863c8a78
No known key found for this signature in database
GPG Key ID: B256185D3A971908
2 changed files with 29 additions and 1 deletions

View File

@ -84,6 +84,20 @@ macro_rules! hash_trait_impls {
pub fn backward_hex(&self) -> impl '_ + core::fmt::LowerHex + core::fmt::UpperHex {
internals::hex::display::DisplayArray::<_, [u8; $bits / 8 * 2]>::new(self.0.iter().rev())
}
/// Zero cost conversion between a fixed length byte array shared reference and
/// a shared reference to this Hash type.
pub fn from_bytes_ref(bytes: &[u8; $bits / 8]) -> &Self {
// Safety: Sound because Self is #[repr(transparent)] containing [u8; $bits / 8]
unsafe { &*(bytes as *const _ as *const Self) }
}
/// Zero cost conversion between a fixed length byte array exclusive reference and
/// an exclusive reference to this Hash type.
pub fn from_bytes_mut(bytes: &mut [u8; $bits / 8]) -> &mut Self {
// Safety: Sound because Self is #[repr(transparent)] containing [u8; $bits / 8]
unsafe { &mut *(bytes as *mut _ as *mut Self) }
}
}
impl<$($gen: $gent),*> str::FromStr for Hash<$($gen),*> {

View File

@ -405,6 +405,8 @@ mod tests {
#[test]
#[cfg(feature = "alloc")]
fn test() {
use std::convert::TryFrom;
use crate::{ripemd160, Hash, HashEngine};
#[derive(Clone)]
@ -465,12 +467,24 @@ mod tests {
},
];
for test in tests {
for mut test in tests {
// Hash through high-level API, check hex encoding/decoding
let hash = ripemd160::Hash::hash(test.input.as_bytes());
assert_eq!(hash, test.output_str.parse::<ripemd160::Hash>().expect("parse hex"));
assert_eq!(&hash[..], &test.output[..]);
assert_eq!(&hash.to_string(), &test.output_str);
assert_eq!(
ripemd160::Hash::from_bytes_ref(
<&[u8; 20]>::try_from(&*test.output).expect("known length")
),
&hash
);
assert_eq!(
ripemd160::Hash::from_bytes_mut(
<&mut [u8; 20]>::try_from(&mut *test.output).expect("known length")
),
&hash
);
// Hash through engine, checking that we can input byte by byte
let mut engine = ripemd160::Hash::engine();