Skip to content
This repository has been archived by the owner on Sep 4, 2024. It is now read-only.

Commit

Permalink
Rename hmac types
Browse files Browse the repository at this point in the history
The `hmac` types are named differently to the other hash types. At this
stage there is not that much difference between them and it is not
immediately obvious why they get a different naming scheme.

As we do for the other hash types use `Hash` and `HashEngine` with the
expectation that user differentiate by using the module path.

With this patch applied users use `hmac::Hash` instead of `Hmac`.
  • Loading branch information
tcharding committed May 14, 2024
1 parent b257a6c commit 5ebfa0f
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 61 deletions.
97 changes: 48 additions & 49 deletions src/hmac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ use core::{fmt, ops, str};

use hex::DisplayHex;

use crate::{FromSliceError, HashEngine};
use crate::FromSliceError;

/// A hash computed from a RFC 2104 HMAC. Parameterized by the underlying hash function.
/// A hash computed from a RFC 2104 HMAC. Parameterized by the size of the underlying hash function.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Hmac<const N: usize>([u8; N]);
pub struct Hash<const N: usize>([u8; N]);

impl<const N: usize> Hmac<N> {
impl<const N: usize> Hash<N> {
/// Returns a hash engine that is ready to be used for the data.
pub fn engine<E>() -> E
where
E: HashEngine<Digest = [u8; N]>,
E: crate::HashEngine<Digest = [u8; N]>,
{
E::new()
}
Expand All @@ -32,7 +32,7 @@ impl<const N: usize> Hmac<N> {
/// This is equivalent to calling `Hash::from_byte_array(engine.finalize())`.
pub fn from_engine<E>(engine: E) -> Self
where
E: HashEngine<Digest = [u8; N]>,
E: crate::HashEngine<Digest = [u8; N]>,
{
let digest = engine.finalize();
Self::from_byte_array(digest)
Expand Down Expand Up @@ -88,8 +88,8 @@ impl<const N: usize> Hmac<N> {
}

#[cfg(feature = "schemars")]
impl<const N: usize> schemars::JsonSchema for Hmac<N> {
fn schema_name() -> std::string::String { "Hmac".to_owned() }
impl<const N: usize> schemars::JsonSchema for Hash<N> {
fn schema_name() -> std::string::String { "Hash".to_owned() }

fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
let mut schema: schemars::schema::SchemaObject = <String>::json_schema(gen).into();
Expand All @@ -102,7 +102,7 @@ impl<const N: usize> schemars::JsonSchema for Hmac<N> {
}
}

impl<const N: usize> str::FromStr for Hmac<N> {
impl<const N: usize> str::FromStr for Hash<N> {
type Err = hex::HexToArrayError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
use hex::FromHex;
Expand All @@ -112,78 +112,78 @@ impl<const N: usize> str::FromStr for Hmac<N> {
}
}

impl<const N: usize> fmt::Display for Hmac<N> {
impl<const N: usize> fmt::Display for Hash<N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(self, f) }
}

impl<const N: usize> fmt::Debug for Hmac<N> {
impl<const N: usize> fmt::Debug for Hash<N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:#}", self) }
}

impl<const N: usize> fmt::LowerHex for Hmac<N> {
impl<const N: usize> fmt::LowerHex for Hash<N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// FIXME: Can't use hex_fmt_exact because of N.
fmt::LowerHex::fmt(&self.0.as_hex(), f)
}
}

impl<const N: usize> fmt::UpperHex for Hmac<N> {
impl<const N: usize> fmt::UpperHex for Hash<N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// FIXME: Can't use hex_fmt_exact because of N.
fmt::UpperHex::fmt(&self.0.as_hex(), f)
}
}
impl<const N: usize> ops::Index<usize> for Hmac<N> {
impl<const N: usize> ops::Index<usize> for Hash<N> {
type Output = u8;
fn index(&self, index: usize) -> &u8 { &self.0[index] }
}

impl<const N: usize> ops::Index<ops::Range<usize>> for Hmac<N> {
impl<const N: usize> ops::Index<ops::Range<usize>> for Hash<N> {
type Output = [u8];
fn index(&self, index: ops::Range<usize>) -> &[u8] { &self.0[index] }
}

impl<const N: usize> ops::Index<ops::RangeFrom<usize>> for Hmac<N> {
impl<const N: usize> ops::Index<ops::RangeFrom<usize>> for Hash<N> {
type Output = [u8];
fn index(&self, index: ops::RangeFrom<usize>) -> &[u8] { &self.0[index] }
}

impl<const N: usize> ops::Index<ops::RangeTo<usize>> for Hmac<N> {
impl<const N: usize> ops::Index<ops::RangeTo<usize>> for Hash<N> {
type Output = [u8];
fn index(&self, index: ops::RangeTo<usize>) -> &[u8] { &self.0[index] }
}

impl<const N: usize> ops::Index<ops::RangeFull> for Hmac<N> {
impl<const N: usize> ops::Index<ops::RangeFull> for Hash<N> {
type Output = [u8];
fn index(&self, index: ops::RangeFull) -> &[u8] { &self.0[index] }
}

impl<const N: usize> AsRef<[u8]> for Hmac<N> {
impl<const N: usize> AsRef<[u8]> for Hash<N> {
fn as_ref(&self) -> &[u8] { &self.0 }
}

#[cfg(feature = "serde")]
impl<const N: usize> crate::serde_macros::serde_details::SerdeHash for Hmac<N> {
impl<const N: usize> crate::serde_macros::serde_details::SerdeHash for Hash<N> {
const N: usize = N;
fn from_slice_delegated(sl: &[u8]) -> Result<Self, FromSliceError> { Hmac::from_slice(sl) }
fn from_slice_delegated(sl: &[u8]) -> Result<Self, FromSliceError> { Hash::from_slice(sl) }
}

#[cfg(feature = "serde")]
impl<const N: usize> serde::Serialize for Hmac<N> {
impl<const N: usize> serde::Serialize for Hash<N> {
fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
crate::serde_macros::serde_details::SerdeHash::serialize(self, s)
}
}

#[cfg(feature = "serde")]
impl<'de, const N: usize> crate::serde::Deserialize<'de> for Hmac<N> {
impl<'de, const N: usize> crate::serde::Deserialize<'de> for Hash<N> {
fn deserialize<D: crate::serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
crate::serde_macros::serde_details::SerdeHash::deserialize(d)
}
}

/// Pair of underlying hash midstates which represent the current state of an `HmacEngine`.
pub struct HmacMidState<E: HashEngine> {
/// Pair of underlying hash midstates which represent the current state of an `HashEngine`.
pub struct MidState<E: crate::HashEngine> {
/// Midstate of the inner hash engine
pub inner: E::Midstate,
/// Midstate of the outer hash engine
Expand All @@ -192,32 +192,32 @@ pub struct HmacMidState<E: HashEngine> {

/// Pair of underlying hash engines, used for the inner and outer hash of HMAC.
#[derive(Clone)]
pub struct HmacEngine<E: HashEngine> {
pub struct HashEngine<E: crate::HashEngine> {
iengine: E,
oengine: E,
}

impl<E: HashEngine> Default for HmacEngine<E> {
fn default() -> Self { HmacEngine::new(&[]) }
impl<E: crate::HashEngine> Default for HashEngine<E> {
fn default() -> Self { HashEngine::new(&[]) }
}

impl<E: HashEngine> HmacEngine<E> {
impl<E: crate::HashEngine> HashEngine<E> {
/// Constructs a new keyed HMAC from `key`.
///
/// We only support hash engines whose internal block sizes are ≤ 128 bytes.
///
/// # Panics
///
/// Larger block sizes will result in a panic.
pub fn new(key: &[u8]) -> HmacEngine<E> {
pub fn new(key: &[u8]) -> HashEngine<E> {
debug_assert!(E::BLOCK_SIZE <= 128);

let mut ipad = [0x36u8; 128];
let mut opad = [0x5cu8; 128];
let mut ret = HmacEngine { iengine: E::default(), oengine: E::default() };
let mut ret = HashEngine { iengine: E::default(), oengine: E::default() };

if key.len() > E::BLOCK_SIZE {
let hash = <E as HashEngine>::hash(key);
let hash = <E as crate::HashEngine>::hash(key);
for (b_i, b_h) in ipad.iter_mut().zip(hash.as_ref()) {
*b_i ^= *b_h;
}
Expand All @@ -239,9 +239,9 @@ impl<E: HashEngine> HmacEngine<E> {
}
}

impl<E: HashEngine> HashEngine for HmacEngine<E> {
impl<E: crate::HashEngine> crate::HashEngine for HashEngine<E> {
type Digest = E::Digest;
type Midstate = HmacMidstate<E>;
type Midstate = Midstate<E>;
const BLOCK_SIZE: usize = E::BLOCK_SIZE;

#[inline]
Expand All @@ -259,22 +259,22 @@ impl<E: HashEngine> HashEngine for HmacEngine<E> {

#[inline]
fn midstate(&self) -> Self::Midstate {
HmacMidstate { inner: self.iengine.midstate(), outer: self.oengine.midstate() }
Midstate { inner: self.iengine.midstate(), outer: self.oengine.midstate() }
}

#[inline]
fn from_midstate(midstate: HmacMidstate<E>, length: usize) -> Self {
HmacEngine {
fn from_midstate(midstate: Midstate<E>, length: usize) -> Self {
HashEngine {
iengine: E::from_midstate(midstate.inner, length),
oengine: E::from_midstate(midstate.outer, length),
}
}
}

/// Pair of underlying hash engine midstates which represent the current state of an `HmacEngine`.
/// Pair of underlying hash engine midstates which represent the current state of an `HashEngine`.
// TODO: Use derives?
//#[derive(Copy, Clone, PartialEq, Eq, Default, PartialOrd, Ord, Hash)]
pub struct HmacMidstate<E: HashEngine> {
pub struct Midstate<E: crate::HashEngine> {
/// Midstate of the inner hash engine.
pub inner: E::Midstate,
/// Midstate of the outer hash engine.
Expand Down Expand Up @@ -402,7 +402,7 @@ mod tests {
];

for test in tests {
let mut engine = HmacEngine::<sha256::HashEngine>::new(&test.key);
let mut engine = HashEngine::<sha256::HashEngine>::new(&test.key);
engine.input(&test.input);
let hash = engine.finalize();
assert_eq!(&hash[..], &test.output[..]);
Expand All @@ -413,10 +413,9 @@ mod tests {
#[cfg(feature = "serde")]
#[test]
fn hmac_sha512_serde() {
use crate::hmac;
use serde_test::{assert_tokens, Configure, Token};

use crate::Hmac;

#[rustfmt::skip]
static HASH_BYTES: [u8; 64] = [
0x8b, 0x41, 0xe1, 0xb7, 0x8a, 0xd1, 0x15, 0x21,
Expand All @@ -429,7 +428,7 @@ mod tests {
0x0b, 0x2d, 0x8a, 0x60, 0x0b, 0xdf, 0x4c, 0x0c,
];

let hash = Hmac::<64>::from_slice(&HASH_BYTES).expect("right number of bytes");
let hash = hmac::Hash::<64>::from_slice(&HASH_BYTES).expect("right number of bytes");

assert_tokens(&hash.compact(), &[Token::BorrowedBytes(&HASH_BYTES[..])]);
assert_tokens(
Expand All @@ -446,8 +445,8 @@ mod tests {
use super::*;
use crate::sha256;

let engine: HmacEngine<sha256::HashEngine> = Default::default();
let hmac = Hmac::from_engine(engine);
let engine: HashEngine<sha256::HashEngine> = Default::default();
let hmac = Hash::from_engine(engine);
let hint = hmac.0.iter().size_hint().1;

println!("hint: {:?}", hint);
Expand All @@ -458,11 +457,11 @@ mod tests {
mod benches {
use test::Bencher;

use crate::{sha256, HashEngine, HmacEngine};
use crate::{sha256, HashEngine, HashEngine};

#[bench]
pub fn hmac_sha256_10(bh: &mut Bencher) {
let mut engine: HmacEngine<sha256::HashEngine> = Default::default();
let mut engine: HashEngine<sha256::HashEngine> = Default::default();
let bytes = [1u8; 10];
bh.iter(|| {
engine.input(&bytes);
Expand All @@ -472,7 +471,7 @@ mod benches {

#[bench]
pub fn hmac_sha256_1k(bh: &mut Bencher) {
let mut engine: HmacEngine<sha256::HashEngine> = Default::default();
let mut engine: HashEngine<sha256::HashEngine> = Default::default();
let bytes = [1u8; 1024];
bh.iter(|| {
engine.input(&bytes);
Expand All @@ -482,7 +481,7 @@ mod benches {

#[bench]
pub fn hmac_sha256_64k(bh: &mut Bencher) {
let mut engine: HmacEngine<sha256::HashEngine> = Default::default();
let mut engine: HashEngine<sha256::HashEngine> = Default::default();
let bytes = [1u8; 65536];
bh.iter(|| {
engine.input(&bytes);
Expand Down
20 changes: 10 additions & 10 deletions src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

use bitcoin_io::impl_write;

use crate::{ripemd160, sha1, sha256, sha256t, sha512, siphash24, HashEngine, HmacEngine};
use crate::{hmac, ripemd160, sha1, sha256, sha256t, sha512, siphash24, HashEngine as _};

impl_write!(
sha1::HashEngine,
Expand Down Expand Up @@ -54,7 +54,7 @@ impl_write!(
|_us| { Ok(()) }
);

impl<E: HashEngine> bitcoin_io::Write for HmacEngine<E> {
impl<E: crate::HashEngine> bitcoin_io::Write for hmac::HashEngine<E> {
#[inline]
fn write(&mut self, buf: &[u8]) -> Result<usize, bitcoin_io::Error> {
use crate::HashEngine as _;
Expand All @@ -67,7 +67,7 @@ impl<E: HashEngine> bitcoin_io::Write for HmacEngine<E> {
}

#[cfg(feature = "std")]
impl<E: HashEngine> std::io::Write for HmacEngine<E> {
impl<E: crate::HashEngine> std::io::Write for hmac::HashEngine<E> {
#[inline]
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.input(buf);
Expand All @@ -92,7 +92,7 @@ impl_write!(
mod tests {
use bitcoin_io::Write;

use crate::{ripemd160, sha1, sha256, sha512, siphash24, HashEngine as _, Hmac, HmacEngine};
use crate::{hmac, ripemd160, sha1, sha256, sha512, siphash24, HashEngine as _};

macro_rules! write_test {
($mod:ident, $exp_empty:expr, $exp_256:expr, $exp_64k:expr,) => {
Expand Down Expand Up @@ -151,24 +151,24 @@ mod tests {

#[test]
fn hmac() {
let mut engine = HmacEngine::<sha256::HashEngine>::new(&[0xde, 0xad, 0xbe, 0xef]);
let mut engine = hmac::HashEngine::<sha256::HashEngine>::new(&[0xde, 0xad, 0xbe, 0xef]);
engine.write_all(&[]).unwrap();
assert_eq!(
format!("{}", Hmac::from_engine(engine)),
format!("{}", hmac::Hash::from_engine(engine)),
"bf5515149cf797955c4d3194cca42472883281951697c8375d9d9b107f384225"
);

let mut engine = HmacEngine::<sha256::HashEngine>::new(&[0xde, 0xad, 0xbe, 0xef]);
let mut engine = hmac::HashEngine::<sha256::HashEngine>::new(&[0xde, 0xad, 0xbe, 0xef]);
engine.write_all(&[1; 256]).unwrap();
assert_eq!(
format!("{}", Hmac::from_engine(engine)),
format!("{}", hmac::Hash::from_engine(engine)),
"59c9aca10c81c73cb4c196d94db741b6bf2050e0153d5a45f2526bff34675ac5"
);

let mut engine = HmacEngine::<sha256::HashEngine>::new(&[0xde, 0xad, 0xbe, 0xef]);
let mut engine = hmac::HashEngine::<sha256::HashEngine>::new(&[0xde, 0xad, 0xbe, 0xef]);
engine.write_all(&[99; 64000]).unwrap();
assert_eq!(
format!("{}", Hmac::from_engine(engine)),
format!("{}", hmac::Hash::from_engine(engine)),
"30df499717415a395379a1eaabe50038036e4abb5afc94aa55c952f4aa57be08"
);
}
Expand Down
2 changes: 0 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,6 @@ pub mod siphash24;

use core::{convert, fmt, hash};

pub use hmac::{Hmac, HmacEngine};

/// A hashing engine which bytes can be serialized into.
pub trait HashEngine: Clone + Default {
/// The digest returned by this hash engine.
Expand Down

0 comments on commit 5ebfa0f

Please sign in to comment.