diff --git a/Cargo.lock b/Cargo.lock index 13c6a6f5a..1d44b956f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,9 +26,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.101" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "arrayvec" @@ -80,9 +80,9 @@ checksum = "89af0b093cc13baa4e51e64e65ec2422f7e73aea0e612e5ad3872986671622f1" [[package]] name = "block-buffer" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96eb4cdd6cf1b31d671e9efe75c5d1ec614776856cefbe109ca373554a6d514f" +checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" dependencies = [ "hybrid-array", "zeroize", @@ -111,7 +111,7 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cipher" -version = "0.5.0" +version = "0.5.1" dependencies = [ "blobby", "block-buffer", @@ -186,7 +186,7 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.2.0" +version = "0.2.1" dependencies = [ "getrandom", "hybrid-array", @@ -216,7 +216,7 @@ dependencies = [ [[package]] name = "digest" -version = "0.11.0" +version = "0.11.1" dependencies = [ "blobby", "block-buffer", @@ -500,7 +500,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -624,7 +624,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -698,9 +698,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.114" +version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", "quote", @@ -827,7 +827,7 @@ dependencies = [ "heck", "indexmap", "prettyplease", - "syn 2.0.114", + "syn 2.0.117", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -843,7 +843,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", "wit-bindgen-core", "wit-bindgen-rust", ] diff --git a/cipher/CHANGELOG.md b/cipher/CHANGELOG.md index a35d5aebb..2913ca7d1 100644 --- a/cipher/CHANGELOG.md +++ b/cipher/CHANGELOG.md @@ -6,12 +6,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## 0.5.1 (UNRELEASED) +### Changed +- Block sizes no longer bounded by `crypto_common::BlockSizes` ([#2309]) +- `StreamCipherCoreWrapper` is now bounded by `block_buffer::BlockSizes` + instead of `crypto_common::BlockSizes` ([#2309]) +- Bump `block-buffer` dependency to v0.12 ([#2309]) + ### Fixed - `Key:` option in the `stream_cipher_bench` macro ([#2290]) [#2290]: https://github.com/RustCrypto/traits/pull/2290 +[#2309]: https://github.com/RustCrypto/traits/pull/2309 -## 0.5.0 (2026-02-04) +## 0.5.0 (2026-02-04) [YANKED] ### Added - Traits for tweakable block ciphers ([#1721]) - Methods for writing keystream ([#1907]) diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 1ef46175f..4399b4fb8 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cipher" -version = "0.5.0" +version = "0.5.1" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" @@ -18,7 +18,7 @@ inout = "0.2.2" # optional dependencies blobby = { version = "0.4", optional = true } -block-buffer = { version = "0.11", optional = true } +block-buffer = { version = "0.12", optional = true } zeroize = { version = "1.8", optional = true, default-features = false } [dev-dependencies] 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/CHANGELOG.md b/crypto-common/CHANGELOG.md index d3dff9395..d9aa66404 100644 --- a/crypto-common/CHANGELOG.md +++ b/crypto-common/CHANGELOG.md @@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.2.1 (UNRELEASED) +### Changed +- `BlockSizeUser::BlockSize` is no longer bounded by `BlockSizes` ([#2309]) + +### Removed +- `BlockSizes` trait ([#2309]) + +[#2309]: https://github.com/RustCrypto/traits/pull/2309 + ## 0.2.0 (2026-02-04) ### Added - Sealed `BlockSizes` trait implemented for types from `U1` to `U255` ([#1172]) diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 59056086f..d9f324bef 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "crypto-common" -version = "0.2.0" +version = "0.2.1" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" 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/CHANGELOG.md b/digest/CHANGELOG.md index ec8bc20c4..420c54d71 100644 --- a/digest/CHANGELOG.md +++ b/digest/CHANGELOG.md @@ -5,7 +5,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.11.0 (2026-02-13) +## 0.11.1 (UNRELEASED) +### Added +- `SmallBlockSizeUser` helper trait. The trait is a sub-trait of `BlockSizeUser` + with `BlockSize` bounded by `block_buffer::BlockSizes`. ([#2309]) + +### Changed +- `BufferKindUser` is now a sub-trait of `SmallBlockSizeUser` ([#2309]) + +[#2309]: https://github.com/RustCrypto/traits/pull/2309 + +## 0.11.0 (2026-02-13) [YANKED] ### Added - `CustomizedInit` trait ([#1334]) - `SerializableState` support ([#1369]) diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 305918d9e..bc08a55c7 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "digest" -version = "0.11.0" +version = "0.11.1" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" @@ -16,7 +16,7 @@ description = "Traits for cryptographic hash functions and message authenticatio common = { version = "0.2", package = "crypto-common" } # optional dependencies -block-buffer = { version = "0.11", optional = true } +block-buffer = { version = "0.12", optional = true } blobby = { version = "0.4", optional = true } const-oid = { version = "0.10", optional = true } ctutils = { version = "0.4", optional = true } diff --git a/digest/src/block_api.rs b/digest/src/block_api.rs index 771f89a83..7edf8fce6 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; @@ -24,19 +24,40 @@ 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 `::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 { +pub trait EagerHash: SmallBlockSizeUser + Digest { /// Block-level core type of the hash. type Core: HashMarker + UpdateCore + FixedOutputCore - + BlockSizeUser::BlockSize> + + SmallBlockSizeUser<_BlockSize = ::_BlockSize> + BufferKindUser + Default + Clone; @@ -44,11 +65,11 @@ pub trait EagerHash: BlockSizeUser + Digest { 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, 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, 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;