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..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;