diff --git a/cipher/src/block.rs b/cipher/src/block.rs index 551e9d14a..4989f027e 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -26,11 +26,11 @@ use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; /// Key for an algorithm that implements [`NewBlockCipher`]. pub type Key = GenericArray::KeySize>; -/// Block on which a [`BlockCipher`] operates. -pub type Block = GenericArray::BlockSize>; - -/// Blocks being acted over in parallel. -pub type ParBlocks = GenericArray, ::ParBlocks>; +// /// Block on which a [`BlockCipher`] operates. +// pub type Block = GenericArray::BlockSize>; +// +// /// Blocks being acted over in parallel. +// pub type ParBlocks = GenericArray, ::ParBlocks>; /// Instantiate a [`BlockCipher`] algorithm. pub trait NewBlockCipher: Sized { @@ -55,26 +55,90 @@ pub trait NewBlockCipher: Sized { /// The trait which defines in-place encryption and decryption /// over single block or several blocks in parallel. -pub trait BlockCipher { +pub trait BlockCipher +where + BlockSize: ArrayLength, + ParBlocks: ArrayLength>, + Self: Encrypt + + Decrypt, +{ +} + +/// Stateful block cipher which permits `&mut self` access. +/// +/// The main use case for this trait is hardware encryption engines which +/// require `&mut self` access to an underlying hardware peripheral. +pub trait BlockCipherMut { + /// Size of the block in bytes + type BlockSize: ArrayLength; + + /// Encrypt block in-place + fn encrypt_block(&mut self, block: &mut GenericArray); + + /// Decrypt block in-place + fn decrypt_block(&mut self, block: &mut GenericArray); +} + +// impl BlockCipherMut for Alg { +// type BlockSize = Alg::BlockSize; +// +// #[inline] +// fn encrypt_block(&mut self, block: &mut GenericArray) { +// ::encrypt_block(self, block); +// } +// +// #[inline] +// fn decrypt_block(&mut self, block: &mut GenericArray) { +// ::decrypt_block(self, block); +// } +// } + +// impl BlockCipher for &Alg { +// type BlockSize = Alg::BlockSize; +// type ParBlocks = Alg::ParBlocks; +// +// #[inline] +// fn encrypt_block(&self, block: &mut Block) { +// Alg::encrypt_block(self, block); +// } +// +// #[inline] +// fn decrypt_block(&self, block: &mut Block) { +// Alg::decrypt_block(self, block); +// } +// +// #[inline] +// fn encrypt_blocks(&self, blocks: &mut ParBlocks) { +// Alg::encrypt_blocks(self, blocks); +// } +// +// #[inline] +// fn decrypt_blocks(&self, blocks: &mut ParBlocks) { +// Alg::decrypt_blocks(self, blocks); +// } +// } + +/// Encrypt-only functionality for block ciphers +pub trait Encrypt { /// Size of the block in bytes type BlockSize: ArrayLength; /// Number of blocks which can be processed in parallel by /// cipher implementation - type ParBlocks: ArrayLength>; + type ParBlocks: ArrayLength>; /// Encrypt block in-place - fn encrypt_block(&self, block: &mut Block); - - /// Decrypt block in-place - fn decrypt_block(&self, block: &mut Block); + fn encrypt_block(&self, block: &mut GenericArray); /// Encrypt several blocks in parallel using instruction level parallelism /// if possible. /// /// If `ParBlocks` equals to 1 it's equivalent to `encrypt_block`. #[inline] - fn encrypt_blocks(&self, blocks: &mut ParBlocks) { + fn encrypt_par_blocks( + &self, + blocks: &mut GenericArray, Self::ParBlocks>, + ) { for block in blocks.iter_mut() { self.encrypt_block(block); } @@ -82,14 +146,14 @@ pub trait BlockCipher { /// Encrypt a slice of blocks, leveraging parallelism when available. #[inline] - fn encrypt_slice(&self, mut blocks: &mut [Block]) { + fn encrypt_blocks(&self, mut blocks: &mut [GenericArray]) { let pb = Self::ParBlocks::to_usize(); if pb > 1 { let mut iter = blocks.chunks_exact_mut(pb); for chunk in &mut iter { - self.encrypt_blocks(chunk.try_into().unwrap()) + self.encrypt_par_blocks(chunk.try_into().unwrap()) } blocks = iter.into_remainder(); @@ -99,13 +163,29 @@ pub trait BlockCipher { self.encrypt_block(block); } } +} + +/// Decrypt-only functionality for block ciphers +pub trait Decrypt { + /// Size of the block in bytes + type BlockSize: ArrayLength; + + /// Number of blocks which can be processed in parallel by + /// cipher implementation + type ParBlocks: ArrayLength>; + + /// Decrypt block in-place + fn decrypt_block(&self, block: &mut GenericArray); /// Decrypt several blocks in parallel using instruction level parallelism /// if possible. /// /// If `ParBlocks` equals to 1 it's equivalent to `decrypt_block`. #[inline] - fn decrypt_blocks(&self, blocks: &mut ParBlocks) { + fn decrypt_par_blocks( + &self, + blocks: &mut GenericArray, Self::ParBlocks>, + ) { for block in blocks.iter_mut() { self.decrypt_block(block); } @@ -113,14 +193,14 @@ pub trait BlockCipher { /// Decrypt a slice of blocks, leveraging parallelism when available. #[inline] - fn decrypt_slice(&self, mut blocks: &mut [Block]) { + fn decrypt_blocks(&self, mut blocks: &mut [GenericArray]) { let pb = Self::ParBlocks::to_usize(); if pb > 1 { let mut iter = blocks.chunks_exact_mut(pb); for chunk in &mut iter { - self.decrypt_blocks(chunk.try_into().unwrap()) + self.decrypt_par_blocks(chunk.try_into().unwrap()) } blocks = iter.into_remainder(); @@ -131,57 +211,3 @@ pub trait BlockCipher { } } } - -/// Stateful block cipher which permits `&mut self` access. -/// -/// The main use case for this trait is hardware encryption engines which -/// require `&mut self` access to an underlying hardware peripheral. -pub trait BlockCipherMut { - /// Size of the block in bytes - type BlockSize: ArrayLength; - - /// Encrypt block in-place - fn encrypt_block(&mut self, block: &mut GenericArray); - - /// Decrypt block in-place - fn decrypt_block(&mut self, block: &mut GenericArray); -} - -impl BlockCipherMut for Alg { - type BlockSize = Alg::BlockSize; - - #[inline] - fn encrypt_block(&mut self, block: &mut GenericArray) { - ::encrypt_block(self, block); - } - - #[inline] - fn decrypt_block(&mut self, block: &mut GenericArray) { - ::decrypt_block(self, block); - } -} - -impl BlockCipher for &Alg { - type BlockSize = Alg::BlockSize; - type ParBlocks = Alg::ParBlocks; - - #[inline] - fn encrypt_block(&self, block: &mut Block) { - Alg::encrypt_block(self, block); - } - - #[inline] - fn decrypt_block(&self, block: &mut Block) { - Alg::decrypt_block(self, block); - } - - #[inline] - fn encrypt_blocks(&self, blocks: &mut ParBlocks) { - Alg::encrypt_blocks(self, blocks); - } - - #[inline] - fn decrypt_blocks(&self, blocks: &mut ParBlocks) { - Alg::decrypt_blocks(self, blocks); - } -} diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index ebc022c5c..c78f259c7 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -155,7 +155,11 @@ impl SyncStreamCipher for &mut C { /// Trait for initializing a stream cipher from a block cipher pub trait FromBlockCipher { /// Block cipher - type BlockCipher: BlockCipher; + type BlockCipher: BlockCipher; + /// Block size + type BlockSize: ArrayLength; + /// Parallel blocks + type ParBlocks: ArrayLength>; /// Nonce size in bytes type NonceSize: ArrayLength; @@ -167,62 +171,62 @@ pub trait FromBlockCipher { } /// Trait for initializing a stream cipher from a mutable block cipher -pub trait FromBlockCipherMut { - /// Block cipher - type BlockCipher: BlockCipherMut; - /// Nonce size in bytes - type NonceSize: ArrayLength; - - /// Instantiate a stream cipher from a block cipher - fn from_block_cipher_mut( - cipher: Self::BlockCipher, - nonce: &GenericArray, - ) -> Self; -} - -impl FromBlockCipherMut for C -where - C: FromBlockCipher, -{ - type BlockCipher = ::BlockCipher; - type NonceSize = ::NonceSize; - - fn from_block_cipher_mut( - cipher: Self::BlockCipher, - nonce: &GenericArray, - ) -> C { - C::from_block_cipher(cipher, nonce) - } -} - -impl NewStreamCipher for C -where - C: FromBlockCipherMut, - C::BlockCipher: NewBlockCipher, -{ - type KeySize = <::BlockCipher as NewBlockCipher>::KeySize; - type NonceSize = ::NonceSize; - - fn new(key: &Key, nonce: &Nonce) -> C { - C::from_block_cipher_mut( - <::BlockCipher as NewBlockCipher>::new(key), - nonce, - ) - } - - fn new_var(key: &[u8], nonce: &[u8]) -> Result { - if nonce.len() != Self::NonceSize::USIZE { - Err(InvalidKeyNonceLength) - } else { - C::BlockCipher::new_varkey(key) - .map_err(|_| InvalidKeyNonceLength) - .map(|cipher| { - let nonce = GenericArray::from_slice(nonce); - Self::from_block_cipher_mut(cipher, nonce) - }) - } - } -} +// pub trait FromBlockCipherMut { +// /// Block cipher +// type BlockCipher: BlockCipherMut; +// /// Nonce size in bytes +// type NonceSize: ArrayLength; +// +// /// Instantiate a stream cipher from a block cipher +// fn from_block_cipher_mut( +// cipher: Self::BlockCipher, +// nonce: &GenericArray, +// ) -> Self; +// } + +// impl FromBlockCipherMut for C +// where +// C: FromBlockCipher, +// { +// type BlockCipher = ::BlockCipher; +// type NonceSize = ::NonceSize; +// +// fn from_block_cipher_mut( +// cipher: Self::BlockCipher, +// nonce: &GenericArray, +// ) -> C { +// C::from_block_cipher(cipher, nonce) +// } +// } + +// impl NewStreamCipher for C +// where +// C: FromBlockCipherMut, +// C::BlockCipher: NewBlockCipher, +// { +// type KeySize = <::BlockCipher as NewBlockCipher>::KeySize; +// type NonceSize = ::NonceSize; +// +// fn new(key: &Key, nonce: &Nonce) -> C { +// C::from_block_cipher_mut( +// <::BlockCipher as NewBlockCipher>::new(key), +// nonce, +// ) +// } +// +// fn new_var(key: &[u8], nonce: &[u8]) -> Result { +// if nonce.len() != Self::NonceSize::USIZE { +// Err(InvalidKeyNonceLength) +// } else { +// C::BlockCipher::new_varkey(key) +// .map_err(|_| InvalidKeyNonceLength) +// .map(|cipher| { +// let nonce = GenericArray::from_slice(nonce); +// Self::from_block_cipher_mut(cipher, nonce) +// }) +// } +// } +// } /// Trait implemented for numeric types which can be used with the /// [`SyncStreamCipherSeek`] trait.