diff options
| author | Eduardo Leegwater Simões <[email protected]> | 2023-04-12 11:26:53 +0200 |
|---|---|---|
| committer | Jack O'Connor <[email protected]> | 2023-05-01 03:23:16 -0500 |
| commit | 8176a2202dfd3556949cbdab2b669a011231c63b (patch) | |
| tree | b4010c6addc81a361e505c2078b145885775e096 /src | |
| parent | ce48d79f38a8862b749ec6cc12ba5d1da69ab131 (diff) | |
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`.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib.rs | 22 | ||||
| -rw-r--r-- | src/test.rs | 25 |
2 files changed, 39 insertions, 8 deletions
@@ -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) } } diff --git a/src/test.rs b/src/test.rs index 4b6272c..f5b3462 100644 --- a/src/test.rs +++ b/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(); +} |
