Open nickray opened 4 years ago
My suggestion on #43 was to have an associated Block
type which can have a #[repr(align(...))]
Yeah, that might even be easier to parse mentally than having Block
generic over "B
" :)
We use generic-array
for other types like keys because there are real-world cases where they are larger than 32-bytes (e.g. AES-SIV), because 32-bytes special case for trait impls in pre-const generics Rust.
Blocks are a legitimate case where in practice they will probably never be larger than 32-bytes.
I am not sure if such change will be practical, at least with the current state of the Rust language. Don't forget that we build other APIs on top of BlockCipher
. Such change would either require bubbling alignment restrictions to higher-level APIs and thus removing the convenience of using &mut [u8]
, or we would have to keep two parallel sets of methods with and without those restrictions.
On modern x86 unaligned loads of aligned pointers have the same performance, but unfortunately it's indeed not true for ARM...
UPD: We could potentially check alignment and switch between aligned and unaligned loads at runtime, but it would add a branch at each block/parblock computation, which is certainly not ideal, but could be tolerable.
Some hardware implementations (e.g. of AES) need particular alignment of blocks to operate directly over AHB (e.g. NXP LPC55's HASHCRYPT wants 32-bit alignment, I can imagine this is a typical case for ARM microcontrollers). If a large chunk of data needs to be en/de-crypted that's aligned, it would be neat to pass this information through on the type level to avoid stack copies for each block.
The
aligned
crate (which is sadly missing anA1
type) would be one approach to do it, setSplitting this out from https://github.com/RustCrypto/traits/issues/43 for possible discussion.