From 766397d4066dbba846037a3984dd74b6d8d2fde1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 18 Feb 2026 17:10:45 +0300 Subject: [PATCH 1/5] crypto-common: remove `BlockSizes` trait --- Cargo.lock | 15 +++--- Cargo.toml | 1 + cipher/src/block/ctx.rs | 26 +++++------ cipher/src/stream/core_api.rs | 33 ++++++++------ cipher/src/stream/wrapper.rs | 71 +++++++++++++++++++++++------ cipher/src/tweak/ctx.rs | 12 ++--- cipher/src/tweak/zero.rs | 22 ++++----- crypto-common/src/lib.rs | 15 +----- digest/src/block_api.rs | 33 +++++++++++--- digest/src/block_api/ct_variable.rs | 17 +++++++ digest/src/buffer_macros/fixed.rs | 32 +++++++++---- universal-hash/src/lib.rs | 11 +++-- 12 files changed, 190 insertions(+), 98 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 13c6a6f5a..7aefc424a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -81,8 +81,7 @@ checksum = "89af0b093cc13baa4e51e64e65ec2422f7e73aea0e612e5ad3872986671622f1" [[package]] name = "block-buffer" version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96eb4cdd6cf1b31d671e9efe75c5d1ec614776856cefbe109ca373554a6d514f" +source = "git+https://github.com/RustCrypto/utils?branch=block-buffer%2Fblock-sizes#e198dacd7a62ffcaa426467fd3cdcda0aeafe01a" dependencies = [ "hybrid-array", "zeroize", @@ -500,7 +499,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.114", + "syn 2.0.116", ] [[package]] @@ -624,7 +623,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.116", ] [[package]] @@ -698,9 +697,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.114" +version = "2.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +checksum = "3df424c70518695237746f84cede799c9c58fcb37450d7b23716568cc8bc69cb" dependencies = [ "proc-macro2", "quote", @@ -827,7 +826,7 @@ dependencies = [ "heck", "indexmap", "prettyplease", - "syn 2.0.114", + "syn 2.0.116", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -843,7 +842,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.116", "wit-bindgen-core", "wit-bindgen-rust", ] diff --git a/Cargo.toml b/Cargo.toml index 79c85b5b2..a3b33a5b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,3 +57,4 @@ unused_qualifications = "warn" crypto-common = { path = "crypto-common" } digest = { path = "digest" } signature = { path = "signature" } +block-buffer = { git = "https://github.com/RustCrypto/utils", branch = "block-buffer/block-sizes" } diff --git a/cipher/src/block/ctx.rs b/cipher/src/block/ctx.rs index fb51d601b..72b53a2a5 100644 --- a/cipher/src/block/ctx.rs +++ b/cipher/src/block/ctx.rs @@ -1,4 +1,4 @@ -use common::{Block, BlockSizeUser, BlockSizes, typenum::Unsigned}; +use common::{Block, BlockSizeUser, array::ArraySize, typenum::Unsigned}; use inout::{InOut, InOutBuf}; use super::{ @@ -7,51 +7,51 @@ use super::{ }; /// Closure used in methods which operate over separate blocks. -pub(super) struct BlockCtx<'inp, 'out, BS: BlockSizes> { +pub(super) struct BlockCtx<'inp, 'out, BS: ArraySize> { pub block: InOut<'inp, 'out, Block>, } -impl BlockSizeUser for BlockCtx<'_, '_, BS> { +impl BlockSizeUser for BlockCtx<'_, '_, BS> { type BlockSize = BS; } -impl BlockCipherEncClosure for BlockCtx<'_, '_, BS> { +impl BlockCipherEncClosure for BlockCtx<'_, '_, BS> { #[inline(always)] fn call>(self, backend: &B) { backend.encrypt_block(self.block); } } -impl BlockCipherDecClosure for BlockCtx<'_, '_, BS> { +impl BlockCipherDecClosure for BlockCtx<'_, '_, BS> { #[inline(always)] fn call>(self, backend: &B) { backend.decrypt_block(self.block); } } -impl BlockModeEncClosure for BlockCtx<'_, '_, BS> { +impl BlockModeEncClosure for BlockCtx<'_, '_, BS> { #[inline(always)] fn call>(self, backend: &mut B) { backend.encrypt_block(self.block); } } -impl BlockModeDecClosure for BlockCtx<'_, '_, BS> { +impl BlockModeDecClosure for BlockCtx<'_, '_, BS> { #[inline(always)] fn call>(self, backend: &mut B) { backend.decrypt_block(self.block); } } /// Closure used in methods which operate over slice of blocks. -pub(super) struct BlocksCtx<'inp, 'out, BS: BlockSizes> { +pub(super) struct BlocksCtx<'inp, 'out, BS: ArraySize> { pub blocks: InOutBuf<'inp, 'out, Block>, } -impl BlockSizeUser for BlocksCtx<'_, '_, BS> { +impl BlockSizeUser for BlocksCtx<'_, '_, BS> { type BlockSize = BS; } -impl BlockCipherEncClosure for BlocksCtx<'_, '_, BS> { +impl BlockCipherEncClosure for BlocksCtx<'_, '_, BS> { #[inline(always)] fn call>(self, backend: &B) { if B::ParBlocksSize::USIZE > 1 { @@ -68,7 +68,7 @@ impl BlockCipherEncClosure for BlocksCtx<'_, '_, BS> { } } -impl BlockCipherDecClosure for BlocksCtx<'_, '_, BS> { +impl BlockCipherDecClosure for BlocksCtx<'_, '_, BS> { #[inline(always)] fn call>(self, backend: &B) { if B::ParBlocksSize::USIZE > 1 { @@ -85,7 +85,7 @@ impl BlockCipherDecClosure for BlocksCtx<'_, '_, BS> { } } -impl BlockModeEncClosure for BlocksCtx<'_, '_, BS> { +impl BlockModeEncClosure for BlocksCtx<'_, '_, BS> { #[inline(always)] fn call>(self, backend: &mut B) { if B::ParBlocksSize::USIZE > 1 { @@ -102,7 +102,7 @@ impl BlockModeEncClosure for BlocksCtx<'_, '_, BS> { } } -impl BlockModeDecClosure for BlocksCtx<'_, '_, BS> { +impl BlockModeDecClosure for BlocksCtx<'_, '_, BS> { #[inline(always)] fn call>(self, backend: &mut B) { if B::ParBlocksSize::USIZE > 1 { diff --git a/cipher/src/stream/core_api.rs b/cipher/src/stream/core_api.rs index d9b447077..3ad926cbd 100644 --- a/cipher/src/stream/core_api.rs +++ b/cipher/src/stream/core_api.rs @@ -1,6 +1,9 @@ use super::StreamCipherError; -use crate::{array::Array, typenum::Unsigned}; -use common::{Block, BlockSizeUser, BlockSizes, ParBlocks, ParBlocksSizeUser}; +use crate::{ + array::{Array, ArraySize}, + typenum::Unsigned, +}; +use common::{Block, BlockSizeUser, ParBlocks, ParBlocksSizeUser}; use inout::{InOut, InOutBuf}; /// Trait implemented by stream cipher backends. @@ -197,26 +200,28 @@ macro_rules! impl_counter { impl_counter! { u32 u64 u128 } -struct WriteBlockCtx<'a, BS: BlockSizes> { +struct WriteBlockCtx<'a, BS: ArraySize> { block: &'a mut Block, } -impl BlockSizeUser for WriteBlockCtx<'_, BS> { +impl BlockSizeUser for WriteBlockCtx<'_, BS> { type BlockSize = BS; } -impl StreamCipherClosure for WriteBlockCtx<'_, BS> { +impl StreamCipherClosure for WriteBlockCtx<'_, BS> { #[inline(always)] fn call>(self, backend: &mut B) { backend.gen_ks_block(self.block); } } -struct WriteBlocksCtx<'a, BS: BlockSizes> { +struct WriteBlocksCtx<'a, BS: ArraySize> { blocks: &'a mut [Block], } -impl BlockSizeUser for WriteBlocksCtx<'_, BS> { + +impl BlockSizeUser for WriteBlocksCtx<'_, BS> { type BlockSize = BS; } -impl StreamCipherClosure for WriteBlocksCtx<'_, BS> { + +impl StreamCipherClosure for WriteBlocksCtx<'_, BS> { #[inline(always)] fn call>(self, backend: &mut B) { if B::ParBlocksSize::USIZE > 1 { @@ -233,15 +238,15 @@ impl StreamCipherClosure for WriteBlocksCtx<'_, BS> { } } -struct ApplyBlockCtx<'inp, 'out, BS: BlockSizes> { +struct ApplyBlockCtx<'inp, 'out, BS: ArraySize> { block: InOut<'inp, 'out, Block>, } -impl BlockSizeUser for ApplyBlockCtx<'_, '_, BS> { +impl BlockSizeUser for ApplyBlockCtx<'_, '_, BS> { type BlockSize = BS; } -impl StreamCipherClosure for ApplyBlockCtx<'_, '_, BS> { +impl StreamCipherClosure for ApplyBlockCtx<'_, '_, BS> { #[inline(always)] fn call>(mut self, backend: &mut B) { let mut t = Default::default(); @@ -250,15 +255,15 @@ impl StreamCipherClosure for ApplyBlockCtx<'_, '_, BS> { } } -struct ApplyBlocksCtx<'inp, 'out, BS: BlockSizes> { +struct ApplyBlocksCtx<'inp, 'out, BS: ArraySize> { blocks: InOutBuf<'inp, 'out, Block>, } -impl BlockSizeUser for ApplyBlocksCtx<'_, '_, BS> { +impl BlockSizeUser for ApplyBlocksCtx<'_, '_, BS> { type BlockSize = BS; } -impl StreamCipherClosure for ApplyBlocksCtx<'_, '_, BS> { +impl StreamCipherClosure for ApplyBlocksCtx<'_, '_, BS> { #[inline(always)] #[allow(clippy::needless_range_loop)] fn call>(self, backend: &mut B) { diff --git a/cipher/src/stream/wrapper.rs b/cipher/src/stream/wrapper.rs index 282d7cb82..63a13034f 100644 --- a/cipher/src/stream/wrapper.rs +++ b/cipher/src/stream/wrapper.rs @@ -4,7 +4,7 @@ use super::{ OverflowError, SeekNum, StreamCipher, StreamCipherCore, StreamCipherSeek, StreamCipherSeekCore, errors::StreamCipherError, }; -use block_buffer::ReadBuffer; +use block_buffer::{BlockSizes, ReadBuffer}; use common::{ Iv, IvSizeUser, Key, KeyInit, KeyIvInit, KeySizeUser, array::Array, typenum::Unsigned, }; @@ -16,12 +16,20 @@ use zeroize::ZeroizeOnDrop; /// Buffering wrapper around a [`StreamCipherCore`] implementation. /// /// It handles data buffering and implements the slice-based traits. -pub struct StreamCipherCoreWrapper { +pub struct StreamCipherCoreWrapper +where + T: StreamCipherCore, + T::BlockSize: BlockSizes, +{ core: T, buffer: ReadBuffer, } -impl Clone for StreamCipherCoreWrapper { +impl Clone for StreamCipherCoreWrapper +where + T: StreamCipherCore + Clone, + T::BlockSize: BlockSizes, +{ #[inline] fn clone(&self) -> Self { Self { @@ -31,14 +39,22 @@ impl Clone for StreamCipherCoreWrapper { } } -impl fmt::Debug for StreamCipherCoreWrapper { +impl fmt::Debug for StreamCipherCoreWrapper +where + T: StreamCipherCore + fmt::Debug, + T::BlockSize: BlockSizes, +{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("StreamCipherCoreWrapper") .finish_non_exhaustive() } } -impl StreamCipherCoreWrapper { +impl StreamCipherCoreWrapper +where + T: StreamCipherCore, + T::BlockSize: BlockSizes, +{ /// Initialize from a [`StreamCipherCore`] instance. pub fn from_core(core: T) -> Self { Self { @@ -53,7 +69,11 @@ impl StreamCipherCoreWrapper { } } -impl StreamCipher for StreamCipherCoreWrapper { +impl StreamCipher for StreamCipherCoreWrapper +where + T: StreamCipherCore, + T::BlockSize: BlockSizes, +{ #[inline] fn check_remaining(&self, data_len: usize) -> Result<(), StreamCipherError> { let Some(rem_blocks) = self.core.remaining_blocks() else { @@ -107,7 +127,11 @@ impl StreamCipher for StreamCipherCoreWrapper { } } -impl StreamCipherSeek for StreamCipherCoreWrapper { +impl StreamCipherSeek for StreamCipherCoreWrapper +where + T: StreamCipherSeekCore, + T::BlockSize: BlockSizes, +{ #[allow(clippy::unwrap_in_result)] fn try_current_pos(&self) -> Result { let pos = u8::try_from(self.buffer.get_pos()) @@ -142,15 +166,27 @@ impl StreamCipherSeek for StreamCipherCoreWrapper { // not work properly without mutually exclusive traits, see: // https://github.com/rust-lang/rfcs/issues/1053 -impl KeySizeUser for StreamCipherCoreWrapper { +impl KeySizeUser for StreamCipherCoreWrapper +where + T: KeySizeUser + StreamCipherCore, + T::BlockSize: BlockSizes, +{ type KeySize = T::KeySize; } -impl IvSizeUser for StreamCipherCoreWrapper { +impl IvSizeUser for StreamCipherCoreWrapper +where + T: IvSizeUser + StreamCipherCore, + T::BlockSize: BlockSizes, +{ type IvSize = T::IvSize; } -impl KeyIvInit for StreamCipherCoreWrapper { +impl KeyIvInit for StreamCipherCoreWrapper +where + T: KeyIvInit + StreamCipherCore, + T::BlockSize: BlockSizes, +{ #[inline] fn new(key: &Key, iv: &Iv) -> Self { Self { @@ -160,7 +196,11 @@ impl KeyIvInit for StreamCipherCoreWrapper { } } -impl KeyInit for StreamCipherCoreWrapper { +impl KeyInit for StreamCipherCoreWrapper +where + T: KeyInit + StreamCipherCore, + T::BlockSize: BlockSizes, +{ #[inline] fn new(key: &Key) -> Self { Self { @@ -171,13 +211,18 @@ impl KeyInit for StreamCipherCoreWrapper { } #[cfg(feature = "zeroize")] -impl ZeroizeOnDrop for StreamCipherCoreWrapper {} +impl ZeroizeOnDrop for StreamCipherCoreWrapper +where + T: StreamCipherCore + ZeroizeOnDrop, + T::BlockSize: BlockSizes, +{ +} // Assert that `ReadBuffer` implements `ZeroizeOnDrop` #[cfg(feature = "zeroize")] const _: () = { #[allow(dead_code, trivial_casts)] - fn check_buffer(v: &ReadBuffer) { + fn check_buffer(v: &ReadBuffer) { let _ = v as &dyn ZeroizeOnDrop; } }; diff --git a/cipher/src/tweak/ctx.rs b/cipher/src/tweak/ctx.rs index b0b60792c..cbab8ee92 100644 --- a/cipher/src/tweak/ctx.rs +++ b/cipher/src/tweak/ctx.rs @@ -1,4 +1,4 @@ -use common::{Block, BlockSizeUser, BlockSizes, array::ArraySize}; +use common::{Block, BlockSizeUser, array::ArraySize}; use inout::InOut; use super::{ @@ -7,20 +7,20 @@ use super::{ }; /// Closure used in methods which operate over separate blocks. -pub(super) struct BlockCtx<'a, TS: ArraySize, BS: BlockSizes> { +pub(super) struct BlockCtx<'a, TS: ArraySize, BS: ArraySize> { pub tweak: &'a Tweak, pub block: InOut<'a, 'a, Block>, } -impl BlockSizeUser for BlockCtx<'_, TS, BS> { +impl BlockSizeUser for BlockCtx<'_, TS, BS> { type BlockSize = BS; } -impl TweakSizeUser for BlockCtx<'_, TS, BS> { +impl TweakSizeUser for BlockCtx<'_, TS, BS> { type TweakSize = TS; } -impl TweakBlockCipherEncClosure for BlockCtx<'_, TS, BS> { +impl TweakBlockCipherEncClosure for BlockCtx<'_, TS, BS> { #[inline] fn call(self, backend: &B) where @@ -30,7 +30,7 @@ impl TweakBlockCipherEncClosure for BlockCtx<'_, } } -impl TweakBlockCipherDecClosure for BlockCtx<'_, TS, BS> { +impl TweakBlockCipherDecClosure for BlockCtx<'_, TS, BS> { #[inline] fn call(self, backend: &B) where diff --git a/cipher/src/tweak/zero.rs b/cipher/src/tweak/zero.rs index fb0a1f761..f360fe949 100644 --- a/cipher/src/tweak/zero.rs +++ b/cipher/src/tweak/zero.rs @@ -1,6 +1,6 @@ use core::marker::PhantomData; -use common::{Block, BlockSizes, ParBlocksSizeUser, array::ArraySize}; +use common::{Block, ParBlocksSizeUser, array::ArraySize}; use super::{ TweakBlockCipherDecBackend, TweakBlockCipherDecClosure, TweakBlockCipherDecrypt, @@ -43,20 +43,20 @@ impl BlockCipherDecrypt for ZeroTweak { /// Wrapper around non-tweakble block cipher closures which implements the tweakable /// block cipher closure traits using zero tweak. -struct ClosureWrapper { +struct ClosureWrapper { f: F, _pd: PhantomData<(TS, BS)>, } -impl BlockSizeUser for ClosureWrapper { +impl BlockSizeUser for ClosureWrapper { type BlockSize = BS; } -impl TweakSizeUser for ClosureWrapper { +impl TweakSizeUser for ClosureWrapper { type TweakSize = TS; } -impl TweakBlockCipherEncClosure for ClosureWrapper +impl TweakBlockCipherEncClosure for ClosureWrapper where F: BlockCipherEncClosure, { @@ -69,7 +69,7 @@ where } } -impl TweakBlockCipherDecClosure for ClosureWrapper +impl TweakBlockCipherDecClosure for ClosureWrapper where F: BlockCipherDecClosure, { @@ -84,20 +84,20 @@ where /// Wrapper around tweakable block cipher backend which implements non-tweakable /// block cipher backend traits using zero tweak. -struct BackendWrapper<'a, BS: BlockSizes, B> { +struct BackendWrapper<'a, BS: ArraySize, B> { backend: &'a B, _pd: PhantomData, } -impl BlockSizeUser for BackendWrapper<'_, BS, B> { +impl BlockSizeUser for BackendWrapper<'_, BS, B> { type BlockSize = BS; } -impl ParBlocksSizeUser for BackendWrapper<'_, BS, B> { +impl ParBlocksSizeUser for BackendWrapper<'_, BS, B> { type ParBlocksSize = U1; } -impl BlockCipherEncBackend for BackendWrapper<'_, BS, B> +impl BlockCipherEncBackend for BackendWrapper<'_, BS, B> where B: TweakBlockCipherEncBackend, { @@ -107,7 +107,7 @@ where } } -impl BlockCipherDecBackend for BackendWrapper<'_, BS, B> +impl BlockCipherDecBackend for BackendWrapper<'_, BS, B> where B: TweakBlockCipherDecBackend, { diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 5751575d5..faa39e3d2 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -58,7 +58,7 @@ pub type SubBlockSize = Diff::BlockSize>; /// Types which process data in blocks. pub trait BlockSizeUser { /// Size of the block in bytes. - type BlockSize: BlockSizes; + type BlockSize: ArraySize; /// Return block size in bytes. #[inline(always)] @@ -76,19 +76,6 @@ impl BlockSizeUser for &mut T { type BlockSize = T::BlockSize; } -/// Trait implemented for supported block sizes, i.e. for types from `U1` to `U255`. -pub trait BlockSizes: ArraySize + sealed::BlockSizes {} - -impl BlockSizes for T {} - -mod sealed { - use crate::typenum::{IsLess, NonZero, True, U256, Unsigned}; - - pub trait BlockSizes {} - - impl BlockSizes for T where Self: IsLess + NonZero {} -} - /// Types which can process blocks in parallel. pub trait ParBlocksSizeUser: BlockSizeUser { /// Number of blocks which can be processed in parallel. diff --git a/digest/src/block_api.rs b/digest/src/block_api.rs index 771f89a83..2634af5c9 100644 --- a/digest/src/block_api.rs +++ b/digest/src/block_api.rs @@ -8,7 +8,7 @@ use crate::{Digest, HashMarker, InvalidOutputSize}; pub use block_buffer::{Eager, Lazy}; pub use common::{AlgorithmName, Block, BlockSizeUser, OutputSizeUser, Reset}; -use block_buffer::{BlockBuffer, BufferKind}; +use block_buffer::{BlockBuffer, BlockSizes, BufferKind}; use common::Output; mod ct_variable; @@ -31,7 +31,10 @@ pub trait BufferKindUser: BlockSizeUser { } /// Trait implemented by eager hashes which expose their block-level core. -pub trait EagerHash: BlockSizeUser + Digest { +pub trait EagerHash: BlockSizeUser + Digest +where + ::BlockSize: BlockSizes, +{ /// Block-level core type of the hash. type Core: HashMarker + UpdateCore @@ -52,19 +55,26 @@ where + BufferKindUser + Default + Clone, + <::Core as BlockSizeUser>::BlockSize: BlockSizes, { type Core = T::Core; } /// Core trait for hash functions with fixed output size. -pub trait FixedOutputCore: UpdateCore + BufferKindUser + OutputSizeUser { +pub trait FixedOutputCore: UpdateCore + BufferKindUser + OutputSizeUser +where + Self::BlockSize: BlockSizes, +{ /// Finalize state using remaining data stored in the provided block buffer, /// write result into provided array and leave `self` in a dirty state. fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output); } /// Core trait for hash functions with extendable (XOF) output size. -pub trait ExtendableOutputCore: UpdateCore + BufferKindUser { +pub trait ExtendableOutputCore: UpdateCore + BufferKindUser +where + Self::BlockSize: BlockSizes, +{ /// XOF reader core state. type ReaderCore: XofReaderCore; @@ -90,7 +100,10 @@ pub trait XofReaderCore: BlockSizeUser { /// [`finalize_variable_core`]: VariableOutputCore::finalize_variable_core /// [`new`]: VariableOutputCore::new /// [`TRUNC_SIDE`]: VariableOutputCore::TRUNC_SIDE -pub trait VariableOutputCore: UpdateCore + OutputSizeUser + BufferKindUser + Sized { +pub trait VariableOutputCore: UpdateCore + OutputSizeUser + BufferKindUser + Sized +where + Self::BlockSize: BlockSizes, +{ /// Side which should be used in a truncated result. const TRUNC_SIDE: TruncSide; @@ -115,7 +128,10 @@ pub trait VariableOutputCore: UpdateCore + OutputSizeUser + BufferKindUser + Siz } /// Trait adding customization string to hash functions with variable output. -pub trait VariableOutputCoreCustomized: VariableOutputCore { +pub trait VariableOutputCoreCustomized: VariableOutputCore +where + Self::BlockSize: BlockSizes, +{ /// Create new hasher instance with the given customization string and output size. fn new_customized(customization: &[u8], output_size: usize) -> Self; } @@ -131,7 +147,10 @@ pub enum TruncSide { } /// A proxy trait to the core block-level type. -pub trait CoreProxy { +pub trait CoreProxy +where + ::BlockSize: BlockSizes, +{ /// Core block-level type. type Core: BufferKindUser; diff --git a/digest/src/block_api/ct_variable.rs b/digest/src/block_api/ct_variable.rs index dbfc9fa2f..06336dcc2 100644 --- a/digest/src/block_api/ct_variable.rs +++ b/digest/src/block_api/ct_variable.rs @@ -5,6 +5,7 @@ use super::{ #[cfg(feature = "mac")] use crate::MacMarker; use crate::{CollisionResistance, CustomizedInit, HashMarker}; +use block_buffer::BlockSizes; use common::{ Block, BlockSizeUser, OutputSizeUser, array::{Array, ArraySize}, @@ -19,6 +20,7 @@ pub struct CtOutWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, + T::BlockSize: BlockSizes, { inner: T, _out: PhantomData, @@ -27,6 +29,7 @@ where impl HashMarker for CtOutWrapper where T: VariableOutputCore + HashMarker, + T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { } @@ -35,6 +38,7 @@ where impl MacMarker for CtOutWrapper where T: VariableOutputCore + MacMarker, + T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { } @@ -42,6 +46,7 @@ where impl CollisionResistance for CtOutWrapper where T: VariableOutputCore + CollisionResistance, + T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { type CollisionResistance = T::CollisionResistance; @@ -50,6 +55,7 @@ where impl BlockSizeUser for CtOutWrapper where T: VariableOutputCore, + T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { type BlockSize = T::BlockSize; @@ -58,6 +64,7 @@ where impl UpdateCore for CtOutWrapper where T: VariableOutputCore, + T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { #[inline] @@ -69,6 +76,7 @@ where impl OutputSizeUser for CtOutWrapper where T: VariableOutputCore, + T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { type OutputSize = OutSize; @@ -77,6 +85,7 @@ where impl BufferKindUser for CtOutWrapper where T: VariableOutputCore, + T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { type BufferKind = T::BufferKind; @@ -85,6 +94,7 @@ where impl FixedOutputCore for CtOutWrapper where T: VariableOutputCore, + T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { #[inline] @@ -107,6 +117,7 @@ where impl Default for CtOutWrapper where T: VariableOutputCore, + T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { #[inline] @@ -121,6 +132,7 @@ where impl CustomizedInit for CtOutWrapper where T: VariableOutputCoreCustomized, + T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { #[inline] @@ -135,6 +147,7 @@ where impl Reset for CtOutWrapper where T: VariableOutputCore, + T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { #[inline] @@ -146,6 +159,7 @@ where impl AlgorithmName for CtOutWrapper where T: VariableOutputCore + AlgorithmName, + T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -159,6 +173,7 @@ where impl zeroize::ZeroizeOnDrop for CtOutWrapper where T: VariableOutputCore + zeroize::ZeroizeOnDrop, + T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { } @@ -166,6 +181,7 @@ where impl fmt::Debug for CtOutWrapper where T: VariableOutputCore + AlgorithmName, + T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -176,6 +192,7 @@ where impl SerializableState for CtOutWrapper where T: VariableOutputCore + SerializableState, + T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { type SerializedStateSize = ::SerializedStateSize; diff --git a/digest/src/buffer_macros/fixed.rs b/digest/src/buffer_macros/fixed.rs index f17e68376..4cf813498 100644 --- a/digest/src/buffer_macros/fixed.rs +++ b/digest/src/buffer_macros/fixed.rs @@ -163,7 +163,9 @@ macro_rules! buffer_fixed { ($core_ty:ty); OutputSizeUser $($trait_name:ident)*; ) => { - impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::OutputSizeUser for $name$(< $( $lt ),+ >)? { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::OutputSizeUser for $name$(< $( $lt ),+ >)? + where ::BlockSize: $crate::block_buffer::BlockSizes, + { type OutputSize = <$core_ty as $crate::block_api::OutputSizeUser>::OutputSize; } @@ -177,7 +179,9 @@ macro_rules! buffer_fixed { ($core_ty:ty); CoreProxy $($trait_name:ident)*; ) => { - impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::block_api::CoreProxy for $name$(< $( $lt ),+ >)? { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::block_api::CoreProxy for $name$(< $( $lt ),+ >)? + where ::BlockSize: $crate::block_buffer::BlockSizes, + { type Core = $core_ty; fn compose(core: Self::Core, buffer: $crate::block_api::Buffer) -> Self { Self { core, buffer } @@ -198,7 +202,9 @@ macro_rules! buffer_fixed { ($core_ty:ty); Update $($trait_name:ident)*; ) => { - impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::Update for $name$(< $( $lt ),+ >)? { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::Update for $name$(< $( $lt ),+ >)? + where ::BlockSize: $crate::block_buffer::BlockSizes, + { #[inline] fn update(&mut self, data: &[u8]) { let Self { core, buffer } = self; @@ -218,7 +224,9 @@ macro_rules! buffer_fixed { ($core_ty:ty); FixedOutput $($trait_name:ident)*; ) => { - impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::FixedOutput for $name$(< $( $lt ),+ >)? { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::FixedOutput for $name$(< $( $lt ),+ >)? + where ::BlockSize: $crate::block_buffer::BlockSizes, + { #[inline] fn finalize_into(mut self, out: &mut $crate::Output) { let Self { core, buffer } = &mut self; @@ -276,7 +284,9 @@ macro_rules! buffer_fixed { ($core_ty:ty); Clone $($trait_name:ident)*; ) => { - impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? Clone for $name$(< $( $lt ),+ >)? { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? Clone for $name$(< $( $lt ),+ >)? + where ::BlockSize: $crate::block_buffer::BlockSizes, + { #[inline] fn clone(&self) -> Self { Self { @@ -362,7 +372,9 @@ macro_rules! buffer_fixed { type KeySize = <$core_ty as $crate::common::KeySizeUser>::KeySize; } - impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::KeyInit for $name$(< $( $lt ),+ >)? { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::KeyInit for $name$(< $( $lt ),+ >)? + where ::BlockSize: $crate::block_buffer::BlockSizes, + { #[inline] fn new(key: &$crate::Key) -> Self { Self { @@ -389,7 +401,9 @@ macro_rules! buffer_fixed { ($core_ty:ty); Reset $($trait_name:ident)*; ) => { - impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::Reset for $name$(< $( $lt ),+ >)? { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::Reset for $name$(< $( $lt ),+ >)? + where ::BlockSize: $crate::block_buffer::BlockSizes, + { #[inline] fn reset(&mut self) { $crate::Reset::reset(&mut self.core); @@ -407,7 +421,9 @@ macro_rules! buffer_fixed { ($core_ty:ty); FixedOutputReset $($trait_name:ident)*; ) => { - impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::FixedOutputReset for $name$(< $( $lt ),+ >)? { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::FixedOutputReset for $name$(< $( $lt ),+ >)? + where ::BlockSize: $crate::block_buffer::BlockSizes, + { #[inline] fn finalize_into_reset(&mut self, out: &mut $crate::Output) { let Self { core, buffer } = self; diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index 0948e2c93..54ea65309 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -13,7 +13,10 @@ pub use common::{ typenum::{self, consts}, }; -use common::{BlockSizeUser, BlockSizes, ParBlocksSizeUser, array::Array}; +use common::{ + BlockSizeUser, ParBlocksSizeUser, + array::{Array, ArraySize}, +}; use core::slice; use subtle::ConstantTimeEq; use typenum::Unsigned; @@ -56,15 +59,15 @@ pub trait UniversalHash: BlockSizeUser + Sized { /// Update hash function state with the provided block. #[inline] fn update(&mut self, blocks: &[Block]) { - struct Ctx<'a, BS: BlockSizes> { + struct Ctx<'a, BS: ArraySize> { blocks: &'a [Block], } - impl BlockSizeUser for Ctx<'_, BS> { + impl BlockSizeUser for Ctx<'_, BS> { type BlockSize = BS; } - impl UhfClosure for Ctx<'_, BS> { + impl UhfClosure for Ctx<'_, BS> { #[inline(always)] fn call>(self, backend: &mut B) { let pb = B::ParBlocksSize::USIZE; From aa55a920999ad62fc20cfa440134e71ab8ec132a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 18 Feb 2026 18:42:19 +0300 Subject: [PATCH 2/5] use workaround hack for the `where` propagation issue --- digest/src/block_api.rs | 61 ++++++++++++++++--------------- digest/src/buffer_macros/fixed.rs | 32 ++++------------ 2 files changed, 40 insertions(+), 53 deletions(-) diff --git a/digest/src/block_api.rs b/digest/src/block_api.rs index 2634af5c9..e94e4d65d 100644 --- a/digest/src/block_api.rs +++ b/digest/src/block_api.rs @@ -24,22 +24,41 @@ pub trait UpdateCore: BlockSizeUser { fn update_blocks(&mut self, blocks: &[Block]); } +/// Sub-trait of [`BlockSizeUser`] implemented if `BlockSize` is +/// bigger than `U0` and smaller than `U256`. +/// +/// This trait relies on the hack suggested [here][0] to work around +/// the long standing Rust issue regarding non-propagation of `where` bounds. +/// +/// [0]: https://github.com/rust-lang/rust/issues/20671#issuecomment-1905186183 +pub trait SmallBlockSizeUser: + BlockSizeUser::_BlockSize> +{ + /// Helper associated type equal to `Self::BlockSize`. + type _BlockSize: BlockSizes; +} + +impl SmallBlockSizeUser for T +where + T::BlockSize: BlockSizes, +{ + type _BlockSize = T::BlockSize; +} + /// Types which use [`BlockBuffer`] functionality. -pub trait BufferKindUser: BlockSizeUser { +pub trait BufferKindUser: SmallBlockSizeUser { /// Block buffer kind over which type operates. type BufferKind: BufferKind; } /// Trait implemented by eager hashes which expose their block-level core. -pub trait EagerHash: BlockSizeUser + Digest -where - ::BlockSize: BlockSizes, -{ +pub trait EagerHash: SmallBlockSizeUser + Digest { /// Block-level core type of the hash. type Core: HashMarker + UpdateCore + FixedOutputCore - + BlockSizeUser::BlockSize> + // + BlockSizeUser::BlockSize> + + SmallBlockSizeUser<_BlockSize = ::_BlockSize> + BufferKindUser + Default + Clone; @@ -47,34 +66,27 @@ where impl EagerHash for T where - T: CoreProxy + BlockSizeUser + Digest, + T: CoreProxy + SmallBlockSizeUser + Digest, ::Core: HashMarker + UpdateCore + FixedOutputCore - + BlockSizeUser::BlockSize> + + SmallBlockSizeUser<_BlockSize = ::_BlockSize> + BufferKindUser + Default + Clone, - <::Core as BlockSizeUser>::BlockSize: BlockSizes, { type Core = T::Core; } /// Core trait for hash functions with fixed output size. -pub trait FixedOutputCore: UpdateCore + BufferKindUser + OutputSizeUser -where - Self::BlockSize: BlockSizes, -{ +pub trait FixedOutputCore: UpdateCore + BufferKindUser + OutputSizeUser { /// Finalize state using remaining data stored in the provided block buffer, /// write result into provided array and leave `self` in a dirty state. fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output); } /// Core trait for hash functions with extendable (XOF) output size. -pub trait ExtendableOutputCore: UpdateCore + BufferKindUser -where - Self::BlockSize: BlockSizes, -{ +pub trait ExtendableOutputCore: UpdateCore + BufferKindUser { /// XOF reader core state. type ReaderCore: XofReaderCore; @@ -100,10 +112,7 @@ pub trait XofReaderCore: BlockSizeUser { /// [`finalize_variable_core`]: VariableOutputCore::finalize_variable_core /// [`new`]: VariableOutputCore::new /// [`TRUNC_SIDE`]: VariableOutputCore::TRUNC_SIDE -pub trait VariableOutputCore: UpdateCore + OutputSizeUser + BufferKindUser + Sized -where - Self::BlockSize: BlockSizes, -{ +pub trait VariableOutputCore: UpdateCore + OutputSizeUser + BufferKindUser + Sized { /// Side which should be used in a truncated result. const TRUNC_SIDE: TruncSide; @@ -128,10 +137,7 @@ where } /// Trait adding customization string to hash functions with variable output. -pub trait VariableOutputCoreCustomized: VariableOutputCore -where - Self::BlockSize: BlockSizes, -{ +pub trait VariableOutputCoreCustomized: VariableOutputCore { /// Create new hasher instance with the given customization string and output size. fn new_customized(customization: &[u8], output_size: usize) -> Self; } @@ -147,10 +153,7 @@ pub enum TruncSide { } /// A proxy trait to the core block-level type. -pub trait CoreProxy -where - ::BlockSize: BlockSizes, -{ +pub trait CoreProxy { /// Core block-level type. type Core: BufferKindUser; diff --git a/digest/src/buffer_macros/fixed.rs b/digest/src/buffer_macros/fixed.rs index 4cf813498..f17e68376 100644 --- a/digest/src/buffer_macros/fixed.rs +++ b/digest/src/buffer_macros/fixed.rs @@ -163,9 +163,7 @@ macro_rules! buffer_fixed { ($core_ty:ty); OutputSizeUser $($trait_name:ident)*; ) => { - impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::OutputSizeUser for $name$(< $( $lt ),+ >)? - where ::BlockSize: $crate::block_buffer::BlockSizes, - { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::OutputSizeUser for $name$(< $( $lt ),+ >)? { type OutputSize = <$core_ty as $crate::block_api::OutputSizeUser>::OutputSize; } @@ -179,9 +177,7 @@ macro_rules! buffer_fixed { ($core_ty:ty); CoreProxy $($trait_name:ident)*; ) => { - impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::block_api::CoreProxy for $name$(< $( $lt ),+ >)? - where ::BlockSize: $crate::block_buffer::BlockSizes, - { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::block_api::CoreProxy for $name$(< $( $lt ),+ >)? { type Core = $core_ty; fn compose(core: Self::Core, buffer: $crate::block_api::Buffer) -> Self { Self { core, buffer } @@ -202,9 +198,7 @@ macro_rules! buffer_fixed { ($core_ty:ty); Update $($trait_name:ident)*; ) => { - impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::Update for $name$(< $( $lt ),+ >)? - where ::BlockSize: $crate::block_buffer::BlockSizes, - { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::Update for $name$(< $( $lt ),+ >)? { #[inline] fn update(&mut self, data: &[u8]) { let Self { core, buffer } = self; @@ -224,9 +218,7 @@ macro_rules! buffer_fixed { ($core_ty:ty); FixedOutput $($trait_name:ident)*; ) => { - impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::FixedOutput for $name$(< $( $lt ),+ >)? - where ::BlockSize: $crate::block_buffer::BlockSizes, - { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::FixedOutput for $name$(< $( $lt ),+ >)? { #[inline] fn finalize_into(mut self, out: &mut $crate::Output) { let Self { core, buffer } = &mut self; @@ -284,9 +276,7 @@ macro_rules! buffer_fixed { ($core_ty:ty); Clone $($trait_name:ident)*; ) => { - impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? Clone for $name$(< $( $lt ),+ >)? - where ::BlockSize: $crate::block_buffer::BlockSizes, - { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? Clone for $name$(< $( $lt ),+ >)? { #[inline] fn clone(&self) -> Self { Self { @@ -372,9 +362,7 @@ macro_rules! buffer_fixed { type KeySize = <$core_ty as $crate::common::KeySizeUser>::KeySize; } - impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::KeyInit for $name$(< $( $lt ),+ >)? - where ::BlockSize: $crate::block_buffer::BlockSizes, - { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::KeyInit for $name$(< $( $lt ),+ >)? { #[inline] fn new(key: &$crate::Key) -> Self { Self { @@ -401,9 +389,7 @@ macro_rules! buffer_fixed { ($core_ty:ty); Reset $($trait_name:ident)*; ) => { - impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::Reset for $name$(< $( $lt ),+ >)? - where ::BlockSize: $crate::block_buffer::BlockSizes, - { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::Reset for $name$(< $( $lt ),+ >)? { #[inline] fn reset(&mut self) { $crate::Reset::reset(&mut self.core); @@ -421,9 +407,7 @@ macro_rules! buffer_fixed { ($core_ty:ty); FixedOutputReset $($trait_name:ident)*; ) => { - impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::FixedOutputReset for $name$(< $( $lt ),+ >)? - where ::BlockSize: $crate::block_buffer::BlockSizes, - { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::FixedOutputReset for $name$(< $( $lt ),+ >)? { #[inline] fn finalize_into_reset(&mut self, out: &mut $crate::Output) { let Self { core, buffer } = self; From 58b2303192faf5b3d4517c02b2a5c94fc109fe6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 18 Feb 2026 18:56:27 +0300 Subject: [PATCH 3/5] revert `ct_variable` changes --- digest/src/block_api/ct_variable.rs | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/digest/src/block_api/ct_variable.rs b/digest/src/block_api/ct_variable.rs index 06336dcc2..dbfc9fa2f 100644 --- a/digest/src/block_api/ct_variable.rs +++ b/digest/src/block_api/ct_variable.rs @@ -5,7 +5,6 @@ use super::{ #[cfg(feature = "mac")] use crate::MacMarker; use crate::{CollisionResistance, CustomizedInit, HashMarker}; -use block_buffer::BlockSizes; use common::{ Block, BlockSizeUser, OutputSizeUser, array::{Array, ArraySize}, @@ -20,7 +19,6 @@ pub struct CtOutWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, - T::BlockSize: BlockSizes, { inner: T, _out: PhantomData, @@ -29,7 +27,6 @@ where impl HashMarker for CtOutWrapper where T: VariableOutputCore + HashMarker, - T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { } @@ -38,7 +35,6 @@ where impl MacMarker for CtOutWrapper where T: VariableOutputCore + MacMarker, - T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { } @@ -46,7 +42,6 @@ where impl CollisionResistance for CtOutWrapper where T: VariableOutputCore + CollisionResistance, - T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { type CollisionResistance = T::CollisionResistance; @@ -55,7 +50,6 @@ where impl BlockSizeUser for CtOutWrapper where T: VariableOutputCore, - T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { type BlockSize = T::BlockSize; @@ -64,7 +58,6 @@ where impl UpdateCore for CtOutWrapper where T: VariableOutputCore, - T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { #[inline] @@ -76,7 +69,6 @@ where impl OutputSizeUser for CtOutWrapper where T: VariableOutputCore, - T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { type OutputSize = OutSize; @@ -85,7 +77,6 @@ where impl BufferKindUser for CtOutWrapper where T: VariableOutputCore, - T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { type BufferKind = T::BufferKind; @@ -94,7 +85,6 @@ where impl FixedOutputCore for CtOutWrapper where T: VariableOutputCore, - T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { #[inline] @@ -117,7 +107,6 @@ where impl Default for CtOutWrapper where T: VariableOutputCore, - T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { #[inline] @@ -132,7 +121,6 @@ where impl CustomizedInit for CtOutWrapper where T: VariableOutputCoreCustomized, - T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { #[inline] @@ -147,7 +135,6 @@ where impl Reset for CtOutWrapper where T: VariableOutputCore, - T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { #[inline] @@ -159,7 +146,6 @@ where impl AlgorithmName for CtOutWrapper where T: VariableOutputCore + AlgorithmName, - T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -173,7 +159,6 @@ where impl zeroize::ZeroizeOnDrop for CtOutWrapper where T: VariableOutputCore + zeroize::ZeroizeOnDrop, - T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { } @@ -181,7 +166,6 @@ where impl fmt::Debug for CtOutWrapper where T: VariableOutputCore + AlgorithmName, - T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -192,7 +176,6 @@ where impl SerializableState for CtOutWrapper where T: VariableOutputCore + SerializableState, - T::BlockSize: BlockSizes, OutSize: ArraySize + IsLessOrEqual, { type SerializedStateSize = ::SerializedStateSize; From 6e3dc47890bbf49986abd8a31624a31ba9c717aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 18 Feb 2026 19:04:42 +0300 Subject: [PATCH 4/5] Manual impl of `Clone` for `CtOutWrapper` --- digest/src/block_api/ct_variable.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/digest/src/block_api/ct_variable.rs b/digest/src/block_api/ct_variable.rs index dbfc9fa2f..8c8dba038 100644 --- a/digest/src/block_api/ct_variable.rs +++ b/digest/src/block_api/ct_variable.rs @@ -14,7 +14,6 @@ use common::{ use core::{fmt, marker::PhantomData}; /// Wrapper around [`VariableOutputCore`] which selects output size at compile time. -#[derive(Clone)] pub struct CtOutWrapper where T: VariableOutputCore, @@ -24,6 +23,19 @@ where _out: PhantomData, } +impl Clone for CtOutWrapper +where + T: VariableOutputCore + Clone, + OutSize: ArraySize + IsLessOrEqual, +{ + fn clone(&self) -> Self { + Self { + inner: self.inner.clone(), + _out: PhantomData, + } + } +} + impl HashMarker for CtOutWrapper where T: VariableOutputCore + HashMarker, From 1722a3eaab9c083264b1a7b1eeaed4557008e049 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 18 Feb 2026 19:09:24 +0300 Subject: [PATCH 5/5] minor tweaks --- digest/src/block_api.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/digest/src/block_api.rs b/digest/src/block_api.rs index e94e4d65d..7edf8fce6 100644 --- a/digest/src/block_api.rs +++ b/digest/src/block_api.rs @@ -34,7 +34,7 @@ pub trait UpdateCore: BlockSizeUser { pub trait SmallBlockSizeUser: BlockSizeUser::_BlockSize> { - /// Helper associated type equal to `Self::BlockSize`. + /// Helper associated type equal to `::BlockSize`. type _BlockSize: BlockSizes; } @@ -57,7 +57,6 @@ pub trait EagerHash: SmallBlockSizeUser + Digest { type Core: HashMarker + UpdateCore + FixedOutputCore - // + BlockSizeUser::BlockSize> + SmallBlockSizeUser<_BlockSize = ::_BlockSize> + BufferKindUser + Default