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:
parent
05a70f5297
commit
9054123d16
22
src/lib.rs
22
src/lib.rs
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
25
src/test.rs
25
src/test.rs
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue