From a37e1528a47b99d4a03669a50ebf96af267c3bed Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 9 Jan 2024 06:34:38 -0700 Subject: [PATCH] hmac: add `EagerHash` (#151) Provides a trait for hash functions which expose their block-level core which can be used in an optimized implementation of HMAC without polluting the bounds of code which uses HMAC generically over hash functions. Originally from #123. --- hmac/src/lib.rs | 2 +- hmac/src/optim.rs | 194 +++++++++------------------------------------- 2 files changed, 38 insertions(+), 158 deletions(-) diff --git a/hmac/src/lib.rs b/hmac/src/lib.rs index a7da7f9..710bcd6 100644 --- a/hmac/src/lib.rs +++ b/hmac/src/lib.rs @@ -104,7 +104,7 @@ use digest::{ mod optim; mod simple; -pub use optim::{Hmac, HmacCore}; +pub use optim::{EagerHash, Hmac, HmacCore}; pub use simple::SimpleHmac; const IPAD: u8 = 0x36; diff --git a/hmac/src/optim.rs b/hmac/src/optim.rs index 7fa4d7b..655f1f1 100644 --- a/hmac/src/optim.rs +++ b/hmac/src/optim.rs @@ -1,13 +1,10 @@ use super::{get_der_key, IPAD, OPAD}; use core::{fmt, slice}; -#[cfg(feature = "reset")] -use digest::Reset; use digest::{ - array::typenum::{IsLess, Le, NonZero, U256}, block_buffer::Eager, core_api::{ - AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreProxy, CoreWrapper, - FixedOutputCore, OutputSizeUser, UpdateCore, + AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore, + OutputSizeUser, UpdateCore, }, crypto_common::{Key, KeySizeUser}, HashMarker, InvalidLength, KeyInit, MacMarker, Output, @@ -16,37 +13,38 @@ use digest::{ /// Generic HMAC instance. pub type Hmac = CoreWrapper>; -/// Generic core HMAC instance, which operates over blocks. -pub struct HmacCore -where - D: CoreProxy, - D::Core: HashMarker +/// Trait implemented by eager hashes which expose their block-level core. +pub trait EagerHash { + /// Block-level core type of the hash. + type Core: HashMarker + UpdateCore + FixedOutputCore + BufferKindUser + Default - + Clone, - ::BlockSize: IsLess, - Le<::BlockSize, U256>: NonZero, -{ - digest: D::Core, - opad_digest: D::Core, - #[cfg(feature = "reset")] - ipad_digest: D::Core, + + Clone; } -impl Clone for HmacCore +impl EagerHash for CoreWrapper where - D: CoreProxy, - D::Core: HashMarker + C: HashMarker + UpdateCore + FixedOutputCore + BufferKindUser + Default + Clone, - ::BlockSize: IsLess, - Le<::BlockSize, U256>: NonZero, { + type Core = C; +} + +/// Generic core HMAC instance, which operates over blocks. +pub struct HmacCore { + digest: D::Core, + opad_digest: D::Core, + #[cfg(feature = "reset")] + ipad_digest: D::Core, +} + +impl Clone for HmacCore { fn clone(&self) -> Self { Self { digest: self.digest.clone(), @@ -57,92 +55,25 @@ where } } -impl MacMarker for HmacCore -where - D: CoreProxy, - D::Core: HashMarker - + UpdateCore - + FixedOutputCore - + BufferKindUser - + Default - + Clone, - ::BlockSize: IsLess, - Le<::BlockSize, U256>: NonZero, -{ -} +impl MacMarker for HmacCore {} -impl BufferKindUser for HmacCore -where - D: CoreProxy, - D::Core: HashMarker - + UpdateCore - + FixedOutputCore - + BufferKindUser - + Default - + Clone, - ::BlockSize: IsLess, - Le<::BlockSize, U256>: NonZero, -{ +impl BufferKindUser for HmacCore { type BufferKind = Eager; } -impl KeySizeUser for HmacCore -where - D: CoreProxy, - D::Core: HashMarker - + UpdateCore - + FixedOutputCore - + BufferKindUser - + Default - + Clone, - ::BlockSize: IsLess, - Le<::BlockSize, U256>: NonZero, -{ - type KeySize = <::Core as BlockSizeUser>::BlockSize; +impl KeySizeUser for HmacCore { + type KeySize = <::Core as BlockSizeUser>::BlockSize; } -impl BlockSizeUser for HmacCore -where - D: CoreProxy, - D::Core: HashMarker - + UpdateCore - + FixedOutputCore - + BufferKindUser - + Default - + Clone, - ::BlockSize: IsLess, - Le<::BlockSize, U256>: NonZero, -{ - type BlockSize = <::Core as BlockSizeUser>::BlockSize; +impl BlockSizeUser for HmacCore { + type BlockSize = <::Core as BlockSizeUser>::BlockSize; } -impl OutputSizeUser for HmacCore -where - D: CoreProxy, - D::Core: HashMarker - + UpdateCore - + FixedOutputCore - + BufferKindUser - + Default - + Clone, - ::BlockSize: IsLess, - Le<::BlockSize, U256>: NonZero, -{ - type OutputSize = <::Core as OutputSizeUser>::OutputSize; +impl OutputSizeUser for HmacCore { + type OutputSize = <::Core as OutputSizeUser>::OutputSize; } -impl KeyInit for HmacCore -where - D: CoreProxy, - D::Core: HashMarker - + UpdateCore - + FixedOutputCore - + BufferKindUser - + Default - + Clone, - ::BlockSize: IsLess, - Le<::BlockSize, U256>: NonZero, -{ +impl KeyInit for HmacCore { #[inline(always)] fn new(key: &Key) -> Self { Self::new_from_slice(key.as_slice()).unwrap() @@ -173,36 +104,14 @@ where } } -impl UpdateCore for HmacCore -where - D: CoreProxy, - D::Core: HashMarker - + UpdateCore - + FixedOutputCore - + BufferKindUser - + Default - + Clone, - ::BlockSize: IsLess, - Le<::BlockSize, U256>: NonZero, -{ +impl UpdateCore for HmacCore { #[inline(always)] fn update_blocks(&mut self, blocks: &[Block]) { self.digest.update_blocks(blocks); } } -impl FixedOutputCore for HmacCore -where - D: CoreProxy, - D::Core: HashMarker - + UpdateCore - + FixedOutputCore - + BufferKindUser - + Default - + Clone, - ::BlockSize: IsLess, - Le<::BlockSize, U256>: NonZero, -{ +impl FixedOutputCore for HmacCore { #[inline(always)] fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { let mut hash = Output::::default(); @@ -221,36 +130,16 @@ where #[cfg(feature = "reset")] #[cfg_attr(docsrs, doc(cfg(feature = "reset")))] -impl Reset for HmacCore -where - D: CoreProxy, - D::Core: HashMarker - + UpdateCore - + FixedOutputCore - + BufferKindUser - + Default - + Clone, - ::BlockSize: IsLess, - Le<::BlockSize, U256>: NonZero, -{ +impl digest::Reset for HmacCore { #[inline(always)] fn reset(&mut self) { self.digest = self.ipad_digest.clone(); } } -impl AlgorithmName for HmacCore +impl AlgorithmName for HmacCore where - D: CoreProxy, - D::Core: HashMarker - + AlgorithmName - + UpdateCore - + FixedOutputCore - + BufferKindUser - + Default - + Clone, - ::BlockSize: IsLess, - Le<::BlockSize, U256>: NonZero, + D::Core: AlgorithmName, { fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("Hmac<")?; @@ -259,18 +148,9 @@ where } } -impl fmt::Debug for HmacCore +impl fmt::Debug for HmacCore where - D: CoreProxy, - D::Core: HashMarker - + AlgorithmName - + UpdateCore - + FixedOutputCore - + BufferKindUser - + Default - + Clone, - ::BlockSize: IsLess, - Le<::BlockSize, U256>: NonZero, + D::Core: AlgorithmName, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("HmacCore<")?;