1
0
Fork 0
mirror of https://github.com/BLAKE3-team/BLAKE3 synced 2024-05-27 12:46:02 +02:00

add `from_bytes` for conversions from `[u8; 32]`

The function is `const`, so it is fundamentally different from the
`From` trait implementation by allowing compile-time instantiation of a
`Hash`.
This commit is contained in:
Eduardo Leegwater Simões 2023-04-12 11:26:53 +02:00
parent 05a70f5297
commit 9054123d16
No known key found for this signature in database
GPG Key ID: 274958581BB5F978
2 changed files with 39 additions and 8 deletions

View File

@ -176,13 +176,13 @@ fn counter_high(counter: u64) -> u32 {
/// An output of the default size, 32 bytes, which provides constant-time
/// equality checking.
///
/// `Hash` implements [`From`] and [`Into`] for `[u8; 32]`, and it provides an
/// explicit [`as_bytes`] method returning `&[u8; 32]`. However, byte arrays
/// and slices don't provide constant-time equality checking, which is often a
/// security requirement in software that handles private data. `Hash` doesn't
/// implement [`Deref`] or [`AsRef`], to avoid situations where a type
/// conversion happens implicitly and the constant-time property is
/// accidentally lost.
/// `Hash` implements [`From`] and [`Into`] for `[u8; 32]`, and it provides
/// explicit [`from_bytes`], and [`as_bytes`] for conversions between itself
/// and `[u8; 32]`. However, byte arrays and slices don't provide constant-time
/// equality checking, which is often a security requirement in software that
/// handles private data. `Hash` doesn't implement [`Deref`] or [`AsRef`], to
/// avoid situations where a type conversion happens implicitly and the
/// constant-time property is accidentally lost.
///
/// `Hash` provides the [`to_hex`] and [`from_hex`] methods for converting to
/// and from hexadecimal. It also implements [`Display`] and [`FromStr`].
@ -190,6 +190,7 @@ fn counter_high(counter: u64) -> u32 {
/// [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html
/// [`Into`]: https://doc.rust-lang.org/std/convert/trait.Into.html
/// [`as_bytes`]: #method.as_bytes
/// [`from_bytes`]: #method.from_bytes
/// [`Deref`]: https://doc.rust-lang.org/stable/std/ops/trait.Deref.html
/// [`AsRef`]: https://doc.rust-lang.org/std/convert/trait.AsRef.html
/// [`to_hex`]: #method.to_hex
@ -208,6 +209,11 @@ impl Hash {
&self.0
}
/// Create a `Hash` from its raw bytes representation.
pub const fn from_bytes(bytes: [u8; OUT_LEN]) -> Self {
Self(bytes)
}
/// Encode a `Hash` in lowercase hexadecimal.
///
/// The returned [`ArrayString`] is a fixed size and doesn't allocate memory
@ -259,7 +265,7 @@ impl Hash {
impl From<[u8; OUT_LEN]> for Hash {
#[inline]
fn from(bytes: [u8; OUT_LEN]) -> Self {
Self(bytes)
Self::from_bytes(bytes)
}
}

View File

@ -603,3 +603,28 @@ fn test_issue_206_windows_sse2() {
assert_eq!(crate::Hasher::new().update(input).finalize(), expected_hash);
}
}
#[test]
fn test_hash_conversions() {
let bytes1 = [42; 32];
let hash1: crate::Hash = bytes1.into();
let bytes2: [u8; 32] = hash1.into();
assert_eq!(bytes1, bytes2);
let bytes3 = *hash1.as_bytes();
assert_eq!(bytes1, bytes3);
let hash2 = crate::Hash::from_bytes(bytes1);
assert_eq!(hash1, hash2);
let hex = hash1.to_hex();
let hash3 = crate::Hash::from_hex(hex.as_bytes()).unwrap();
assert_eq!(hash1, hash3);
}
#[test]
const fn test_hash_const_conversions() {
let bytes = [42; 32];
let hash = crate::Hash::from_bytes(bytes);
_ = hash.as_bytes();
}