Merge rust-bitcoin/rust-bitcoin#3981: Do not implement `Default` for `HmacEngine`
18619a6d0b
api: Run just check-api (Tobin C. Harding)1eb8f1f9e0
Add a Hmac::engine function (Tobin C. Harding)c352d376ed
Do not implement Default for HmacEngine (Tobin C. Harding) Pull request description: The `HmacEngine` should be created using a key. Currently we are providing a `Default` impl that uses `&[]` as the key. This is, I believe, a hangover from when we had a `Default` trait bound somewhere else. It is incorrect and an API footgun - remove it. Note this PR includes changes to the bench code in `hmac` that highlights the footgun - pity the poor user we even shot ourselves. Patch 2 adds a constructor `Hmac::engine` and uses it in the bench code. ACKs for top commit: Kixunil: ACK18619a6d0b
apoelstra: ACK 18619a6d0b0bca7b7e3603e260b254b4aae6cebf; successfully ran local tests Tree-SHA512: c96640e7ffba52d5b13b76a6dd9e1381788efcf56ee76300c5111541466bab8018d2546bcecf237c42dbd82e9372a0e43e1ecec37147508e879365d92a4c1451
This commit is contained in:
commit
e45bc0056c
|
@ -458,10 +458,10 @@ impl<T: bitcoin_hashes::GeneralHash> bitcoin_hashes::GeneralHash for bitcoin_has
|
|||
impl<T: bitcoin_hashes::GeneralHash> bitcoin_hashes::Hash for bitcoin_hashes::hmac::Hmac<T>
|
||||
impl<T: bitcoin_hashes::GeneralHash> bitcoin_hashes::HashEngine for bitcoin_hashes::hmac::HmacEngine<T>
|
||||
impl<T: bitcoin_hashes::GeneralHash> bitcoin_hashes::hkdf::Hkdf<T> where <T as bitcoin_hashes::GeneralHash>::Engine: core::default::Default
|
||||
impl<T: bitcoin_hashes::GeneralHash> bitcoin_hashes::hmac::Hmac<T>
|
||||
impl<T: bitcoin_hashes::GeneralHash> bitcoin_hashes::hmac::HmacEngine<T>
|
||||
impl<T: bitcoin_hashes::GeneralHash> bitcoin_io::Write for bitcoin_hashes::hmac::HmacEngine<T>
|
||||
impl<T: bitcoin_hashes::GeneralHash> core::convert::AsRef<[u8]> for bitcoin_hashes::hmac::Hmac<T>
|
||||
impl<T: bitcoin_hashes::GeneralHash> core::default::Default for bitcoin_hashes::hmac::HmacEngine<T> where <T as bitcoin_hashes::GeneralHash>::Engine: core::default::Default
|
||||
impl<T: bitcoin_hashes::GeneralHash> core::marker::StructuralPartialEq for bitcoin_hashes::hmac::Hmac<T>
|
||||
impl<T: bitcoin_hashes::GeneralHash> std::io::Write for bitcoin_hashes::hmac::HmacEngine<T>
|
||||
impl<T: bitcoin_hashes::sha256t::Tag> bitcoin_hashes::GeneralHash for bitcoin_hashes::sha256t::Hash<T>
|
||||
|
@ -668,6 +668,7 @@ pub fn bitcoin_hashes::hmac::Hmac<T>::as_ref(&self) -> &[u8]
|
|||
pub fn bitcoin_hashes::hmac::Hmac<T>::clone(&self) -> bitcoin_hashes::hmac::Hmac<T>
|
||||
pub fn bitcoin_hashes::hmac::Hmac<T>::cmp(&self, other: &bitcoin_hashes::hmac::Hmac<T>) -> core::cmp::Ordering
|
||||
pub fn bitcoin_hashes::hmac::Hmac<T>::deserialize<D: serde::de::Deserializer<'de>>(d: D) -> core::result::Result<bitcoin_hashes::hmac::Hmac<T>, <D as serde::de::Deserializer>::Error>
|
||||
pub fn bitcoin_hashes::hmac::Hmac<T>::engine(key: &[u8]) -> bitcoin_hashes::hmac::HmacEngine<T> where <T as bitcoin_hashes::GeneralHash>::Engine: core::default::Default
|
||||
pub fn bitcoin_hashes::hmac::Hmac<T>::eq(&self, other: &bitcoin_hashes::hmac::Hmac<T>) -> bool
|
||||
pub fn bitcoin_hashes::hmac::Hmac<T>::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
|
||||
pub fn bitcoin_hashes::hmac::Hmac<T>::from_byte_array(bytes: <T as bitcoin_hashes::Hash>::Bytes) -> Self
|
||||
|
@ -679,7 +680,6 @@ pub fn bitcoin_hashes::hmac::Hmac<T>::partial_cmp(&self, other: &bitcoin_hashes:
|
|||
pub fn bitcoin_hashes::hmac::Hmac<T>::serialize<S: serde::ser::Serializer>(&self, s: S) -> core::result::Result<<S as serde::ser::Serializer>::Ok, <S as serde::ser::Serializer>::Error>
|
||||
pub fn bitcoin_hashes::hmac::Hmac<T>::to_byte_array(self) -> Self::Bytes
|
||||
pub fn bitcoin_hashes::hmac::HmacEngine<T>::clone(&self) -> bitcoin_hashes::hmac::HmacEngine<T>
|
||||
pub fn bitcoin_hashes::hmac::HmacEngine<T>::default() -> Self
|
||||
pub fn bitcoin_hashes::hmac::HmacEngine<T>::flush(&mut self) -> bitcoin_io::Result<()>
|
||||
pub fn bitcoin_hashes::hmac::HmacEngine<T>::flush(&mut self) -> std::io::error::Result<()>
|
||||
pub fn bitcoin_hashes::hmac::HmacEngine<T>::from_inner_engines(iengine: <T as bitcoin_hashes::GeneralHash>::Engine, oengine: <T as bitcoin_hashes::GeneralHash>::Engine) -> bitcoin_hashes::hmac::HmacEngine<T>
|
||||
|
|
|
@ -416,9 +416,9 @@ impl<T: bitcoin_hashes::GeneralHash> bitcoin_hashes::GeneralHash for bitcoin_has
|
|||
impl<T: bitcoin_hashes::GeneralHash> bitcoin_hashes::Hash for bitcoin_hashes::hmac::Hmac<T>
|
||||
impl<T: bitcoin_hashes::GeneralHash> bitcoin_hashes::HashEngine for bitcoin_hashes::hmac::HmacEngine<T>
|
||||
impl<T: bitcoin_hashes::GeneralHash> bitcoin_hashes::hkdf::Hkdf<T> where <T as bitcoin_hashes::GeneralHash>::Engine: core::default::Default
|
||||
impl<T: bitcoin_hashes::GeneralHash> bitcoin_hashes::hmac::Hmac<T>
|
||||
impl<T: bitcoin_hashes::GeneralHash> bitcoin_hashes::hmac::HmacEngine<T>
|
||||
impl<T: bitcoin_hashes::GeneralHash> core::convert::AsRef<[u8]> for bitcoin_hashes::hmac::Hmac<T>
|
||||
impl<T: bitcoin_hashes::GeneralHash> core::default::Default for bitcoin_hashes::hmac::HmacEngine<T> where <T as bitcoin_hashes::GeneralHash>::Engine: core::default::Default
|
||||
impl<T: bitcoin_hashes::GeneralHash> core::marker::StructuralPartialEq for bitcoin_hashes::hmac::Hmac<T>
|
||||
impl<T: bitcoin_hashes::sha256t::Tag> bitcoin_hashes::GeneralHash for bitcoin_hashes::sha256t::Hash<T>
|
||||
impl<T: bitcoin_hashes::sha256t::Tag> bitcoin_hashes::Hash for bitcoin_hashes::sha256t::Hash<T>
|
||||
|
@ -597,6 +597,7 @@ pub fn bitcoin_hashes::hmac::Hmac<T>::as_byte_array(&self) -> &Self::Bytes
|
|||
pub fn bitcoin_hashes::hmac::Hmac<T>::as_ref(&self) -> &[u8]
|
||||
pub fn bitcoin_hashes::hmac::Hmac<T>::clone(&self) -> bitcoin_hashes::hmac::Hmac<T>
|
||||
pub fn bitcoin_hashes::hmac::Hmac<T>::cmp(&self, other: &bitcoin_hashes::hmac::Hmac<T>) -> core::cmp::Ordering
|
||||
pub fn bitcoin_hashes::hmac::Hmac<T>::engine(key: &[u8]) -> bitcoin_hashes::hmac::HmacEngine<T> where <T as bitcoin_hashes::GeneralHash>::Engine: core::default::Default
|
||||
pub fn bitcoin_hashes::hmac::Hmac<T>::eq(&self, other: &bitcoin_hashes::hmac::Hmac<T>) -> bool
|
||||
pub fn bitcoin_hashes::hmac::Hmac<T>::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
|
||||
pub fn bitcoin_hashes::hmac::Hmac<T>::from_byte_array(bytes: <T as bitcoin_hashes::Hash>::Bytes) -> Self
|
||||
|
@ -607,7 +608,6 @@ pub fn bitcoin_hashes::hmac::Hmac<T>::hash<__H: core::hash::Hasher>(&self, state
|
|||
pub fn bitcoin_hashes::hmac::Hmac<T>::partial_cmp(&self, other: &bitcoin_hashes::hmac::Hmac<T>) -> core::option::Option<core::cmp::Ordering>
|
||||
pub fn bitcoin_hashes::hmac::Hmac<T>::to_byte_array(self) -> Self::Bytes
|
||||
pub fn bitcoin_hashes::hmac::HmacEngine<T>::clone(&self) -> bitcoin_hashes::hmac::HmacEngine<T>
|
||||
pub fn bitcoin_hashes::hmac::HmacEngine<T>::default() -> Self
|
||||
pub fn bitcoin_hashes::hmac::HmacEngine<T>::from_inner_engines(iengine: <T as bitcoin_hashes::GeneralHash>::Engine, oengine: <T as bitcoin_hashes::GeneralHash>::Engine) -> bitcoin_hashes::hmac::HmacEngine<T>
|
||||
pub fn bitcoin_hashes::hmac::HmacEngine<T>::input(&mut self, buf: &[u8])
|
||||
pub fn bitcoin_hashes::hmac::HmacEngine<T>::n_bytes_hashed(&self) -> u64
|
||||
|
|
|
@ -380,9 +380,9 @@ impl<T: bitcoin_hashes::GeneralHash> bitcoin_hashes::GeneralHash for bitcoin_has
|
|||
impl<T: bitcoin_hashes::GeneralHash> bitcoin_hashes::Hash for bitcoin_hashes::hmac::Hmac<T>
|
||||
impl<T: bitcoin_hashes::GeneralHash> bitcoin_hashes::HashEngine for bitcoin_hashes::hmac::HmacEngine<T>
|
||||
impl<T: bitcoin_hashes::GeneralHash> bitcoin_hashes::hkdf::Hkdf<T> where <T as bitcoin_hashes::GeneralHash>::Engine: core::default::Default
|
||||
impl<T: bitcoin_hashes::GeneralHash> bitcoin_hashes::hmac::Hmac<T>
|
||||
impl<T: bitcoin_hashes::GeneralHash> bitcoin_hashes::hmac::HmacEngine<T>
|
||||
impl<T: bitcoin_hashes::GeneralHash> core::convert::AsRef<[u8]> for bitcoin_hashes::hmac::Hmac<T>
|
||||
impl<T: bitcoin_hashes::GeneralHash> core::default::Default for bitcoin_hashes::hmac::HmacEngine<T> where <T as bitcoin_hashes::GeneralHash>::Engine: core::default::Default
|
||||
impl<T: bitcoin_hashes::GeneralHash> core::marker::StructuralPartialEq for bitcoin_hashes::hmac::Hmac<T>
|
||||
impl<T: bitcoin_hashes::sha256t::Tag> bitcoin_hashes::GeneralHash for bitcoin_hashes::sha256t::Hash<T>
|
||||
impl<T: bitcoin_hashes::sha256t::Tag> bitcoin_hashes::Hash for bitcoin_hashes::sha256t::Hash<T>
|
||||
|
@ -554,6 +554,7 @@ pub fn bitcoin_hashes::hmac::Hmac<T>::as_byte_array(&self) -> &Self::Bytes
|
|||
pub fn bitcoin_hashes::hmac::Hmac<T>::as_ref(&self) -> &[u8]
|
||||
pub fn bitcoin_hashes::hmac::Hmac<T>::clone(&self) -> bitcoin_hashes::hmac::Hmac<T>
|
||||
pub fn bitcoin_hashes::hmac::Hmac<T>::cmp(&self, other: &bitcoin_hashes::hmac::Hmac<T>) -> core::cmp::Ordering
|
||||
pub fn bitcoin_hashes::hmac::Hmac<T>::engine(key: &[u8]) -> bitcoin_hashes::hmac::HmacEngine<T> where <T as bitcoin_hashes::GeneralHash>::Engine: core::default::Default
|
||||
pub fn bitcoin_hashes::hmac::Hmac<T>::eq(&self, other: &bitcoin_hashes::hmac::Hmac<T>) -> bool
|
||||
pub fn bitcoin_hashes::hmac::Hmac<T>::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
|
||||
pub fn bitcoin_hashes::hmac::Hmac<T>::from_byte_array(bytes: <T as bitcoin_hashes::Hash>::Bytes) -> Self
|
||||
|
@ -564,7 +565,6 @@ pub fn bitcoin_hashes::hmac::Hmac<T>::hash<__H: core::hash::Hasher>(&self, state
|
|||
pub fn bitcoin_hashes::hmac::Hmac<T>::partial_cmp(&self, other: &bitcoin_hashes::hmac::Hmac<T>) -> core::option::Option<core::cmp::Ordering>
|
||||
pub fn bitcoin_hashes::hmac::Hmac<T>::to_byte_array(self) -> Self::Bytes
|
||||
pub fn bitcoin_hashes::hmac::HmacEngine<T>::clone(&self) -> bitcoin_hashes::hmac::HmacEngine<T>
|
||||
pub fn bitcoin_hashes::hmac::HmacEngine<T>::default() -> Self
|
||||
pub fn bitcoin_hashes::hmac::HmacEngine<T>::from_inner_engines(iengine: <T as bitcoin_hashes::GeneralHash>::Engine, oengine: <T as bitcoin_hashes::GeneralHash>::Engine) -> bitcoin_hashes::hmac::HmacEngine<T>
|
||||
pub fn bitcoin_hashes::hmac::HmacEngine<T>::input(&mut self, buf: &[u8])
|
||||
pub fn bitcoin_hashes::hmac::HmacEngine<T>::n_bytes_hashed(&self) -> u64
|
||||
|
|
|
@ -19,6 +19,16 @@ use crate::{FromSliceError, GeneralHash, Hash, HashEngine};
|
|||
#[repr(transparent)]
|
||||
pub struct Hmac<T: GeneralHash>(T);
|
||||
|
||||
impl<T: GeneralHash> Hmac<T> {
|
||||
/// Constructs a new keyed HMAC engine from `key`.
|
||||
pub fn engine(key: &[u8]) -> HmacEngine<T>
|
||||
where
|
||||
<T as GeneralHash>::Engine: Default,
|
||||
{
|
||||
HmacEngine::new(key)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: GeneralHash + str::FromStr> str::FromStr for Hmac<T> {
|
||||
type Err = <T as str::FromStr>::Err;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> { Ok(Hmac(str::FromStr::from_str(s)?)) }
|
||||
|
@ -31,15 +41,8 @@ pub struct HmacEngine<T: GeneralHash> {
|
|||
oengine: T::Engine,
|
||||
}
|
||||
|
||||
impl<T: GeneralHash> Default for HmacEngine<T>
|
||||
where
|
||||
<T as GeneralHash>::Engine: Default,
|
||||
{
|
||||
fn default() -> Self { HmacEngine::new(&[]) }
|
||||
}
|
||||
|
||||
impl<T: GeneralHash> HmacEngine<T> {
|
||||
/// Constructs a new keyed HMAC from `key`.
|
||||
/// Constructs a new keyed HMAC engine from `key`.
|
||||
///
|
||||
/// We only support underlying hashes whose block sizes are ≤ 128 bytes.
|
||||
///
|
||||
|
@ -328,7 +331,7 @@ mod benches {
|
|||
|
||||
#[bench]
|
||||
pub fn hmac_sha256_10(bh: &mut Bencher) {
|
||||
let mut engine = Hmac::<sha256::Hash>::engine();
|
||||
let mut engine = Hmac::<sha256::Hash>::engine(&[]);
|
||||
let bytes = [1u8; 10];
|
||||
bh.iter(|| {
|
||||
engine.input(&bytes);
|
||||
|
@ -338,7 +341,7 @@ mod benches {
|
|||
|
||||
#[bench]
|
||||
pub fn hmac_sha256_1k(bh: &mut Bencher) {
|
||||
let mut engine = Hmac::<sha256::Hash>::engine();
|
||||
let mut engine = Hmac::<sha256::Hash>::engine(&[]);
|
||||
let bytes = [1u8; 1024];
|
||||
bh.iter(|| {
|
||||
engine.input(&bytes);
|
||||
|
@ -348,7 +351,7 @@ mod benches {
|
|||
|
||||
#[bench]
|
||||
pub fn hmac_sha256_64k(bh: &mut Bencher) {
|
||||
let mut engine = Hmac::<sha256::Hash>::engine();
|
||||
let mut engine = Hmac::<sha256::Hash>::engine(&[]);
|
||||
let bytes = [1u8; 65536];
|
||||
bh.iter(|| {
|
||||
engine.input(&bytes);
|
||||
|
|
|
@ -56,22 +56,6 @@ fn regression_sha256t() {
|
|||
assert_eq!(got, want);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn regression_hmac_sha256_with_default_key() {
|
||||
let hash = Hmac::<sha256::Hash>::hash(DATA.as_bytes());
|
||||
let got = format!("{}", hash);
|
||||
let want = "58cc7ed8567bd86eba61f7ed2d5a4edab1774dc10488e57de2eb007a2d9ae82d";
|
||||
assert_eq!(got, want);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn regression_hmac_sha512_with_default_key() {
|
||||
let hash = Hmac::<sha512::Hash>::hash(DATA.as_bytes());
|
||||
let got = format!("{}", hash);
|
||||
let want = "5f5db2f3e1178bf19af5db38a0ed04dc5bc52d641648542886eea9b6bbec0db658ed7a5799ca18f5bc1949f39d24151a32990ee85974e40bb8a35e2288f494ce";
|
||||
assert_eq!(got, want);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn regression_hmac_sha256_with_key() {
|
||||
let mut engine = HmacEngine::<sha256::Hash>::new(HMAC_KEY);
|
||||
|
|
Loading…
Reference in New Issue