hashes: Add `Arbitrary` impl for `Hmac`
What changed, and why it matters
This commit adds a standard trait implementation that lets the Hmac type be used with property-testing tools. It is a routine feature addition, not a security fix or vulnerability.
No security action needed; review as normal feature code.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change adds an arbitrary::Arbitrary implementation for Hmac<T> gated behind the existing arbitrary feature. It delegates to the inner hash’s Arbitrary implementation and updates the public API snapshot file accordingly. There is no change to cryptographic logic, parsing, serialization, or memory handling.
Changed components
hashes/src/hmac/mod.rshashes/api/all-features.txtInspect captured patch +11 / −0
diff --git a/hashes/api/all-features.txt b/hashes/api/all-features.txt
index 2c963681..dd964cb5 100644
--- a/hashes/api/all-features.txt
+++ b/hashes/api/all-features.txt
@@ -282,6 +282,8 @@ impl<T> core::convert::From<T> for bitcoin_hashes::hkdf::error::MaxLengthError
pub fn bitcoin_hashes::hkdf::error::MaxLengthError::from(t: T) -> T
pub mod bitcoin_hashes::hmac
#[repr(transparent)] pub struct bitcoin_hashes::hmac::Hmac<T: bitcoin_hashes::Hash>(_)
+impl<'a, T: bitcoin_hashes::Hash + arbitrary::Arbitrary<'a>> arbitrary::Arbitrary<'a> for bitcoin_hashes::hmac::Hmac<T>
+pub fn bitcoin_hashes::hmac::Hmac<T>::arbitrary(u: &mut arbitrary::unstructured::Unstructured<'a>) -> arbitrary::error::Result<Self>
impl<'de, T: bitcoin_hashes::Hash + serde::de::Deserialize<'de>> serde::de::Deserialize<'de> for bitcoin_hashes::hmac::Hmac<T>
pub fn bitcoin_hashes::hmac::Hmac<T>::deserialize<D: serde::de::Deserializer<'de>>(d: D) -> core::result::Result<Self, <D as serde::de::Deserializer>::Error>
impl<T: bitcoin_hashes::Hash + core::fmt::Debug> core::fmt::Debug for bitcoin_hashes::hmac::Hmac<T>
@@ -2172,6 +2174,8 @@ pub unsafe fn bitcoin_hashes::hkdf::Hkdf<T>::clone_to_uninit(&self, dest: *mut u
impl<T> core::convert::From<T> for bitcoin_hashes::hkdf::Hkdf<T>
pub fn bitcoin_hashes::hkdf::Hkdf<T>::from(t: T) -> T
#[repr(transparent)] pub struct bitcoin_hashes::Hmac<T: bitcoin_hashes::Hash>(_)
+impl<'a, T: bitcoin_hashes::Hash + arbitrary::Arbitrary<'a>> arbitrary::Arbitrary<'a> for bitcoin_hashes::hmac::Hmac<T>
+pub fn bitcoin_hashes::hmac::Hmac<T>::arbitrary(u: &mut arbitrary::unstructured::Unstructured<'a>) -> arbitrary::error::Result<Self>
impl<'de, T: bitcoin_hashes::Hash + serde::de::Deserialize<'de>> serde::de::Deserialize<'de> for bitcoin_hashes::hmac::Hmac<T>
pub fn bitcoin_hashes::hmac::Hmac<T>::deserialize<D: serde::de::Deserializer<'de>>(d: D) -> core::result::Result<Self, <D as serde::de::Deserializer>::Error>
impl<T: bitcoin_hashes::Hash + core::fmt::Debug> core::fmt::Debug for bitcoin_hashes::hmac::Hmac<T>
diff --git a/hashes/src/hmac/mod.rs b/hashes/src/hmac/mod.rs
index ffeefb03..0aeea1c6 100644
--- a/hashes/src/hmac/mod.rs
+++ b/hashes/src/hmac/mod.rs
@@ -73,6 +73,13 @@ impl<'de, T: Hash + Deserialize<'de>> Deserialize<'de> for Hmac<T> {
}
}
+#[cfg(feature = "arbitrary")]
+impl<'a, T: Hash + arbitrary::Arbitrary<'a>> arbitrary::Arbitrary<'a> for Hmac<T> {
+ fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
+ Ok(Self(u.arbitrary()?))
+ }
+}
+
/// Pair of underlying hash engines, used for the inner and outer hash of HMAC.
#[derive(Debug, Clone)]
pub struct HmacEngine<T: HashEngine> {
Why this scored 16/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.