Merge rust-bitcoin/rust-bitcoin#4046: hashes: Add `Copy`, `Clone`, and `Debug` imlps for `Hkdf`

da8b85ed7c Implement Debug for Hkdf (Tobin C. Harding)
85652359e8 hashes: Derive Copy and Clone for Hkdf (Tobin C. Harding)

Pull request description:

  Currently the `Hkdf` type does not derive any traits.

  Derive `Copy` and `Clone` and implement `Debug` based on secret obfuscation algo in `rust-secp` (in the `secret` module).

ACKs for top commit:
  apoelstra:
    ACK da8b85ed7cf34c0510c0b64c67477d3819bee369; successfully ran local tests
  Kixunil:
    ACK da8b85ed7c

Tree-SHA512: 8ae0e8857ea0e32ad5ef8f544979eeb9d530beb1b6f046ce28a286ca2231f8f696a9f4f8d9ea219d3389c4216d6b69766dbd96edbb27e7489803ac583bf3b200
This commit is contained in:
merge-script 2025-02-18 14:14:13 +00:00
commit dfe69354f5
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
1 changed files with 32 additions and 0 deletions

View File

@ -32,6 +32,7 @@ impl fmt::Display for MaxLengthError {
impl std::error::Error for MaxLengthError {} impl std::error::Error for MaxLengthError {}
/// HMAC-based Extract-and-Expand Key Derivation Function (HKDF). /// HMAC-based Extract-and-Expand Key Derivation Function (HKDF).
#[derive(Copy, Clone)]
pub struct Hkdf<T: GeneralHash> { pub struct Hkdf<T: GeneralHash> {
/// Pseudorandom key based on the extract step. /// Pseudorandom key based on the extract step.
prk: Hmac<T>, prk: Hmac<T>,
@ -105,6 +106,26 @@ where
} }
} }
impl<T: GeneralHash> fmt::Debug for Hkdf<T> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use crate::{sha256t, sha256t_tag};
struct Fingerprint([u8; 8]); // Print 16 hex characters as a fingerprint.
impl fmt::Debug for Fingerprint {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { crate::debug_hex(&self.0, f) }
}
sha256t_tag! {
pub struct Tag = hash_str("bitcoin_hashes1DEBUG");
}
let hash = sha256t::Hash::<Tag>::hash(self.prk.as_ref());
let fingerprint = Fingerprint(core::array::from_fn(|i| hash.as_byte_array()[i]));
f.debug_tuple("Hkdf").field(&format_args!("#{:?}", fingerprint)).finish()
}
}
#[cfg(test)] #[cfg(test)]
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
#[cfg(feature = "hex")] #[cfg(feature = "hex")]
@ -192,4 +213,15 @@ mod tests {
"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865" "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865"
); );
} }
#[test]
fn debug() {
let salt = Vec::from_hex("000102030405060708090a0b0c").unwrap();
let ikm = Vec::from_hex("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap();
let hkdf = Hkdf::<sha256::Hash>::new(&salt, &ikm);
let debug = alloc::format!("{:?}", hkdf);
assert_eq!(debug, "Hkdf(#ec7bd36ab2ed4045)");
}
} }