From 48a85f09f7307197635ed7b4b5dc5788e21d7744 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: Sun, 13 Dec 2020 11:55:32 +0300 Subject: [PATCH 1/9] cipher: v0.3 changes --- cipher/Cargo.toml | 3 ++ cipher/src/block.rs | 2 +- cipher/src/common.rs | 79 ++++++++++++++++++++++++++++ cipher/src/errors.rs | 13 +++++ cipher/src/lib.rs | 10 +++- cipher/src/mode.rs | 87 +++++++++++++++++++++++++++++++ cipher/src/stream.rs | 119 ++++--------------------------------------- 7 files changed, 201 insertions(+), 112 deletions(-) create mode 100644 cipher/src/common.rs create mode 100644 cipher/src/mode.rs diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 9c37e7aa6..483cef598 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -14,9 +14,12 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" blobby = { version = "0.3", optional = true } +block-padding = { verstion = "0.2", optional = true } [features] +default = ["block-mode"] std = [] +block-mode = ["block-padding"] dev = ["blobby"] [package.metadata.docs.rs] diff --git a/cipher/src/block.rs b/cipher/src/block.rs index 16205ba86..5efaa30b2 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -38,7 +38,7 @@ pub trait NewBlockCipher: Sized { /// /// Default implementation will accept only keys with length equal to /// `KeySize`, but some ciphers can accept range of key lengths. - fn new_varkey(key: &[u8]) -> Result { + fn new_var(key: &[u8]) -> Result { if key.len() != Self::KeySize::to_usize() { Err(InvalidLength) } else { diff --git a/cipher/src/common.rs b/cipher/src/common.rs new file mode 100644 index 000000000..c937802fc --- /dev/null +++ b/cipher/src/common.rs @@ -0,0 +1,79 @@ +use generic_array::{ArrayLength, GenericArray, typenum::Unsigned}; +use crate::{BlockCipher, NewBlockCipher, errors::InvalidLength}; + +/// Key for an algorithm that implements [`NewCipher`]. +pub type Key = GenericArray::KeySize>; + +/// Nonce for an algorithm that implements [`NewCipher`]. +pub type Nonce = GenericArray::NonceSize>; + +/// Cipher creation trait. +/// +/// It can be used for creation of block modes, synchronous and asynchronous stream ciphers. +pub trait NewCipher: Sized { + /// Key size in bytes + type KeySize: ArrayLength; + + /// Nonce size in bytes + type NonceSize: ArrayLength; + + /// Create new stream cipher instance from variable length key and nonce. + fn new(key: &Key, nonce: &Nonce) -> Self; + + /// Create new stream cipher instance from variable length key and nonce. + #[inline] + fn new_var(key: &[u8], nonce: &[u8]) -> Result { + let kl = Self::KeySize::to_usize(); + let nl = Self::NonceSize::to_usize(); + if key.len() != kl || nonce.len() != nl { + Err(InvalidLength) + } else { + let key = GenericArray::from_slice(key); + let nonce = GenericArray::from_slice(nonce); + Ok(Self::new(key, nonce)) + } + } +} + +/// Trait for initializing a stream cipher from a block cipher +pub trait FromBlockCipher { + /// Block cipher + type BlockCipher: BlockCipher; + /// Nonce size in bytes + type NonceSize: ArrayLength; + + /// Instantiate a stream cipher from a block cipher + fn from_block_cipher( + cipher: Self::BlockCipher, + nonce: &GenericArray, + ) -> Self; +} + +impl NewCipher for C +where + C: FromBlockCipher, + C::BlockCipher: NewBlockCipher, +{ + type KeySize = <::BlockCipher as NewBlockCipher>::KeySize; + type NonceSize = ::NonceSize; + + fn new(key: &Key, nonce: &Nonce) -> C { + C::from_block_cipher( + <::BlockCipher as NewBlockCipher>::new(key), + nonce, + ) + } + + fn new_var(key: &[u8], nonce: &[u8]) -> Result { + if nonce.len() != Self::NonceSize::USIZE { + Err(InvalidLength) + } else { + C::BlockCipher::new_var(key) + .map_err(|_| InvalidLength) + .map(|cipher| { + let nonce = GenericArray::from_slice(nonce); + Self::from_block_cipher(cipher, nonce) + }) + } + } +} diff --git a/cipher/src/errors.rs b/cipher/src/errors.rs index 089a7a077..2cf96d382 100644 --- a/cipher/src/errors.rs +++ b/cipher/src/errors.rs @@ -48,3 +48,16 @@ impl From for LoopError { #[cfg(feature = "std")] impl std::error::Error for OverflowError {} + +/// Block mode error. +#[derive(Clone, Copy, Debug)] +pub struct BlockModeError; + +impl fmt::Display for BlockModeError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.write_str("BlockModeError") + } +} + +#[cfg(feature = "std")] +impl error::Error for BlockModeError {} diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index 5a9dcd182..a4b329f7e 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -15,15 +15,23 @@ #[cfg(feature = "std")] extern crate std; +#[cfg(feature = "block-mode")] +pub extern crate block_padding; pub mod block; +pub mod common; pub mod errors; +#[cfg(feature = "block-padding")] +pub mod mode; pub mod stream; pub use crate::{ block::{ BlockCipher, BlockDecrypt, BlockDecryptMut, BlockEncrypt, BlockEncryptMut, NewBlockCipher, }, - stream::{NewStreamCipher, StreamCipher, SyncStreamCipher, SyncStreamCipherSeek}, + common::{NewCipher, FromBlockCipher}, + stream::{AsyncStreamCipher, StreamCipher, StreamCipherSeek}, }; +#[cfg(feature = "block-mode")] +pub use crate::mode::{BlockModeCore}; pub use generic_array::{self, typenum::consts}; diff --git a/cipher/src/mode.rs b/cipher/src/mode.rs new file mode 100644 index 000000000..dc14084af --- /dev/null +++ b/cipher/src/mode.rs @@ -0,0 +1,87 @@ +use core::marker::PhantomData; +use block_padding::Padding; +use generic_array::{ArrayLength, GenericArray}; + +/// Block on which a [`BlockModeCore`] operates. +pub type Block = GenericArray::BlockSize>; + +/// Core trait for a block cipher mode of operation. +pub trait BlockModeCore { + /// Block size in bytes + type BlockSize: ArrayLength; + + /// Encrypt blocks of data + fn encrypt_blocks(&mut self, blocks: &mut [Block]); + + /// Decrypt blocks of data + fn decrypt_blocks(&mut self, blocks: &mut [Block]); + + /// + fn into_encryptor<>(self) -> BlockModeEncryptor +} + +pub struct BlockModeEncryptor{ + inner: M, + p: PhantomData

, +} + +/* + /// Encrypt message in-place. + /// + /// `&buffer[..pos]` is used as a message and `&buffer[pos..]` as a reserved + /// space for padding. The padding space should be big enough for padding, + /// otherwise method will return `Err(BlockModeError)`. + fn encrypt(mut self, buffer: &mut [u8], pos: usize) -> Result<&[u8], BlockModeError> { + let bs = C::BlockSize::to_usize(); + let buf = P::pad(buffer, pos, bs).map_err(|_| BlockModeError)?; + self.encrypt_blocks(to_blocks(buf)); + Ok(buf) + } + + /// Decrypt message in-place. + /// + /// Returns an error if `buffer` length is not multiple of block size and + /// if after decoding message has malformed padding. + fn decrypt(mut self, buffer: &mut [u8]) -> Result<&[u8], BlockModeError> { + let bs = C::BlockSize::to_usize(); + if buffer.len() % bs != 0 { + return Err(BlockModeError); + } + self.decrypt_blocks(to_blocks(buffer)); + P::unpad(buffer).map_err(|_| BlockModeError) + } + + /// Encrypt message and store result in vector. + #[cfg(feature = "alloc")] + fn encrypt_to_vec(mut self, plaintext: &[u8]) -> Vec { + let bs = C::BlockSize::to_usize(); + let pos = plaintext.len(); + let n = pos + bs; + let mut buf = Vec::with_capacity(n); + buf.extend_from_slice(plaintext); + // prepare space for padding + let block: Block = Default::default(); + buf.extend_from_slice(&block[..n - pos]); + + let n = P::pad(&mut buf, pos, bs) + .expect("enough space for padding is allocated") + .len(); + buf.truncate(n); + self.encrypt_blocks(to_blocks(&mut buf)); + buf + } + + /// Encrypt message and store result in vector. + #[cfg(feature = "alloc")] + fn decrypt_to_vec(mut self, ciphertext: &[u8]) -> Result, BlockModeError> { + let bs = C::BlockSize::to_usize(); + if ciphertext.len() % bs != 0 { + return Err(BlockModeError); + } + let mut buf = ciphertext.to_vec(); + self.decrypt_blocks(to_blocks(&mut buf)); + let n = P::unpad(&buf).map_err(|_| BlockModeError)?.len(); + buf.truncate(n); + Ok(buf) + } +*/ \ No newline at end of file diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index f5daf01e3..a555cbe5d 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -9,50 +9,11 @@ mod dev; #[cfg(feature = "dev")] pub use blobby; -use crate::{ - block::{BlockCipher, NewBlockCipher}, - errors::{InvalidLength, LoopError, OverflowError}, -}; +use crate::errors::{LoopError, OverflowError}; use core::convert::{TryFrom, TryInto}; -use generic_array::typenum::Unsigned; -use generic_array::{ArrayLength, GenericArray}; - -/// Key for an algorithm that implements [`NewStreamCipher`]. -pub type Key = GenericArray::KeySize>; - -/// Nonce for an algorithm that implements [`NewStreamCipher`]. -pub type Nonce = GenericArray::NonceSize>; - -/// Stream cipher creation trait. -/// -/// It can be used for creation of synchronous and asynchronous ciphers. -pub trait NewStreamCipher: Sized { - /// Key size in bytes - type KeySize: ArrayLength; - - /// Nonce size in bytes - type NonceSize: ArrayLength; - - /// Create new stream cipher instance from variable length key and nonce. - fn new(key: &Key, nonce: &Nonce) -> Self; - - /// Create new stream cipher instance from variable length key and nonce. - #[inline] - fn new_var(key: &[u8], nonce: &[u8]) -> Result { - let kl = Self::KeySize::to_usize(); - let nl = Self::NonceSize::to_usize(); - if key.len() != kl || nonce.len() != nl { - Err(InvalidLength) - } else { - let key = GenericArray::from_slice(key); - let nonce = GenericArray::from_slice(nonce); - Ok(Self::new(key, nonce)) - } - } -} /// Synchronous stream cipher core trait. -pub trait SyncStreamCipher { +pub trait StreamCipher { /// Apply keystream to the data. /// /// It will XOR generated keystream with the data, which can be both @@ -63,10 +24,7 @@ pub trait SyncStreamCipher { /// method will panic without modifying the provided `data`. #[inline] fn apply_keystream(&mut self, data: &mut [u8]) { - let res = self.try_apply_keystream(data); - if res.is_err() { - panic!("stream cipher loop detected"); - } + self.try_apply_keystream(data).unwrap(); } /// Apply keystream to the data, but return an error if end of a keystream @@ -82,7 +40,7 @@ pub trait SyncStreamCipher { /// Methods of this trait are generic over the [`SeekNum`] trait, which is /// implemented for primitive numeric types, i.e.: `i/u8`, `i/u16`, `i/u32`, /// `i/u64`, `i/u128`, and `i/usize`. -pub trait SyncStreamCipherSeek { +pub trait StreamCipherSeek { /// Try to get current keystream position /// /// Returns [`LoopError`] if position can not be represented by type `T` @@ -91,7 +49,7 @@ pub trait SyncStreamCipherSeek { /// Try to seek to the given position /// /// Returns [`LoopError`] if provided position value is bigger than - /// keystream leangth + /// keystream length. fn try_seek(&mut self, pos: T) -> Result<(), LoopError>; /// Get current keystream position @@ -111,12 +69,8 @@ pub trait SyncStreamCipherSeek { } } -/// Stream cipher core trait which covers both synchronous and asynchronous -/// ciphers. -/// -/// Note that for synchronous ciphers `encrypt` and `decrypt` are equivalent to -/// each other. -pub trait StreamCipher { +/// Asynchronous stream cipher core trait. +pub trait AsyncStreamCipher { /// Encrypt data in place. fn encrypt(&mut self, data: &mut [u8]); @@ -124,19 +78,7 @@ pub trait StreamCipher { fn decrypt(&mut self, data: &mut [u8]); } -impl StreamCipher for C { - #[inline(always)] - fn encrypt(&mut self, data: &mut [u8]) { - SyncStreamCipher::apply_keystream(self, data); - } - - #[inline(always)] - fn decrypt(&mut self, data: &mut [u8]) { - SyncStreamCipher::apply_keystream(self, data); - } -} - -impl SyncStreamCipher for &mut C { +impl StreamCipher for &mut C { #[inline] fn apply_keystream(&mut self, data: &mut [u8]) { C::apply_keystream(self, data); @@ -148,51 +90,8 @@ impl SyncStreamCipher for &mut C { } } -/// Trait for initializing a stream cipher from a block cipher -pub trait FromBlockCipher { - /// Block cipher - type BlockCipher: BlockCipher; - /// Nonce size in bytes - type NonceSize: ArrayLength; - - /// Instantiate a stream cipher from a block cipher - fn from_block_cipher( - cipher: Self::BlockCipher, - nonce: &GenericArray, - ) -> Self; -} - -impl NewStreamCipher for C -where - C: FromBlockCipher, - C::BlockCipher: NewBlockCipher, -{ - type KeySize = <::BlockCipher as NewBlockCipher>::KeySize; - type NonceSize = ::NonceSize; - - fn new(key: &Key, nonce: &Nonce) -> C { - C::from_block_cipher( - <::BlockCipher as NewBlockCipher>::new(key), - nonce, - ) - } - - fn new_var(key: &[u8], nonce: &[u8]) -> Result { - if nonce.len() != Self::NonceSize::USIZE { - Err(InvalidLength) - } else { - C::BlockCipher::new_varkey(key) - .map_err(|_| InvalidLength) - .map(|cipher| { - let nonce = GenericArray::from_slice(nonce); - Self::from_block_cipher(cipher, nonce) - }) - } - } -} - /// Trait implemented for numeric types which can be used with the -/// [`SyncStreamCipherSeek`] trait. +/// [`StreamCipherSeek`] trait. /// /// This trait is implemented for primitive numeric types, i.e. `i/u8`, /// `i/u16`, `i/u32`, `i/u64`, `i/u128`, and `i/usize`. It is not intended From 7795e45a69f3b2cde6de087db88a4f2b06252a32 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: Sun, 13 Dec 2020 13:44:33 +0300 Subject: [PATCH 2/9] remove SeekNum impls for signed integers --- Cargo.lock | 7 +++++++ cipher/src/stream.rs | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 58632b46c..eb22b2868 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -71,6 +71,12 @@ dependencies = [ "generic-array 0.14.4", ] +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + [[package]] name = "byteorder" version = "1.3.4" @@ -88,6 +94,7 @@ name = "cipher" version = "0.3.0-pre" dependencies = [ "blobby 0.3.0", + "block-padding", "generic-array 0.14.4", ] diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index a555cbe5d..ec8eb4215 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -94,7 +94,7 @@ impl StreamCipher for &mut C { /// [`StreamCipherSeek`] trait. /// /// This trait is implemented for primitive numeric types, i.e. `i/u8`, -/// `i/u16`, `i/u32`, `i/u64`, `i/u128`, and `i/usize`. It is not intended +/// `u16`, `u32`, `u64`, `u128`, and `usize`. It is not intended /// to be implemented in third-party crates. #[rustfmt::skip] pub trait SeekNum: @@ -136,4 +136,4 @@ macro_rules! impl_seek_num { }; } -impl_seek_num! { u8 i8 u16 i16 u32 i32 u64 i64 u128 i128 isize usize } +impl_seek_num! { u8 u16 u32 u64 u128 usize } From 66e8d64792ec8433231ebc815311d517aec9241b 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: Sun, 13 Dec 2020 13:46:15 +0300 Subject: [PATCH 3/9] fix block mode compilation bug --- cipher/src/mode.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/cipher/src/mode.rs b/cipher/src/mode.rs index dc14084af..cf0f715da 100644 --- a/cipher/src/mode.rs +++ b/cipher/src/mode.rs @@ -15,9 +15,6 @@ pub trait BlockModeCore { /// Decrypt blocks of data fn decrypt_blocks(&mut self, blocks: &mut [Block]); - - /// - fn into_encryptor<>(self) -> BlockModeEncryptor } pub struct BlockModeEncryptor{ From a673eb7b31f7232fee7b06ef7c023f2f320061d2 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: Sun, 13 Dec 2020 13:57:53 +0300 Subject: [PATCH 4/9] change SeekNum impls to fit with the new BlockBuffer --- cipher/src/stream.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index ec8eb4215..8e96f1b8a 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -120,8 +120,17 @@ macro_rules! impl_seek_num { impl SeekNum for $t { fn from_block_byte>(block: T, byte: u8, bs: u8) -> Result { debug_assert!(byte < bs); - let block = block.try_into().map_err(|_| OverflowError)?; - let pos = block.checked_mul(bs as Self).ok_or(OverflowError)? + (byte as Self); + let pos = block + .try_into() + .ok() + .and_then(|v| match byte == 0 { + true => Some(v), + // if `byte` is not zero, then block counter was incremented + false => v.checked_sub(1), + }) + .and_then(|v| v.checked_mul(bs as Self)) + .and_then(|v| v.checked_add(byte as Self)) + .ok_or(OverflowError)?; Ok(pos) } From 2b0f36e74ed83fb69777bf0d3a9befa6c9d43701 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: Sun, 13 Dec 2020 14:26:48 +0300 Subject: [PATCH 5/9] fix block tests --- cipher/src/block/dev.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cipher/src/block/dev.rs b/cipher/src/block/dev.rs index 8c4f2fda9..7ea94e79e 100644 --- a/cipher/src/block/dev.rs +++ b/cipher/src/block/dev.rs @@ -15,7 +15,7 @@ macro_rules! block_cipher_test { use cipher::generic_array::{typenum::Unsigned, GenericArray}; fn run_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool { - let state = <$cipher as NewBlockCipher>::new_varkey(key).unwrap(); + let state = <$cipher as NewBlockCipher>::new_var(key).unwrap(); let mut block = GenericArray::clone_from_slice(pt); state.encrypt_block(&mut block); @@ -37,7 +37,7 @@ macro_rules! block_cipher_test { type Block = GenericArray; type ParBlock = GenericArray; - let state = <$cipher as NewBlockCipher>::new_varkey(key).unwrap(); + let state = <$cipher as NewBlockCipher>::new_var(key).unwrap(); let block = Block::clone_from_slice(pt); let mut blocks1 = ParBlock::default(); @@ -118,7 +118,7 @@ macro_rules! block_cipher_bench { #[bench] pub fn encrypt(bh: &mut Bencher) { - let state = <$cipher>::new_varkey(&[1u8; $key_len]).unwrap(); + let state = <$cipher>::new_var(&[1u8; $key_len]).unwrap(); let mut block = Default::default(); bh.iter(|| { @@ -130,7 +130,7 @@ macro_rules! block_cipher_bench { #[bench] pub fn decrypt(bh: &mut Bencher) { - let state = <$cipher>::new_varkey(&[1u8; $key_len]).unwrap(); + let state = <$cipher>::new_var(&[1u8; $key_len]).unwrap(); let mut block = Default::default(); bh.iter(|| { From d20d04ad7c6e754e483a761b115f461b78866cfd 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: Sun, 13 Dec 2020 14:33:16 +0300 Subject: [PATCH 6/9] fix stream tests --- cipher/src/stream/dev.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cipher/src/stream/dev.rs b/cipher/src/stream/dev.rs index 92e5c9331..3ef664d10 100644 --- a/cipher/src/stream/dev.rs +++ b/cipher/src/stream/dev.rs @@ -3,12 +3,12 @@ /// Test core functionality of synchronous stream cipher #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] -macro_rules! stream_cipher_sync_test { +macro_rules! stream_cipher_test { ($name:ident, $cipher:ty, $test_name:expr) => { #[test] fn $name() { use cipher::generic_array::GenericArray; - use cipher::stream::{blobby::Blob4Iterator, NewStreamCipher, SyncStreamCipher}; + use cipher::{blobby::Blob4Iterator, NewCipher, StreamCipher}; let data = include_bytes!(concat!("data/", $test_name, ".blb")); for (i, row) in Blob4Iterator::new(data).unwrap().enumerate() { @@ -44,7 +44,7 @@ macro_rules! stream_cipher_seek_test { #[test] fn $name() { use cipher::generic_array::GenericArray; - use cipher::stream::{NewStreamCipher, SyncStreamCipher, SyncStreamCipherSeek}; + use cipher::{NewCipher, StreamCipher, StreamCipherSeek}; fn get_cipher() -> $cipher { <$cipher>::new(&Default::default(), &Default::default()) @@ -97,7 +97,7 @@ macro_rules! stream_cipher_async_test { #[test] fn $name() { use cipher::generic_array::GenericArray; - use cipher::stream::{blobby::Blob4Iterator, NewStreamCipher, StreamCipher}; + use cipher::stream::{blobby::Blob4Iterator, NewCipher, AsyncStreamCipher}; fn run_test( key: &[u8], @@ -173,7 +173,7 @@ macro_rules! stream_cipher_sync_bench { extern crate test; use cipher::generic_array::GenericArray; - use cipher::stream::{NewStreamCipher, SyncStreamCipher}; + use cipher::{NewCipher, StreamCipher}; use test::Bencher; #[inline(never)] @@ -226,7 +226,7 @@ macro_rules! stream_cipher_async_bench { extern crate test; use cipher::generic_array::GenericArray; - use cipher::stream::{NewStreamCipher, StreamCipher}; + use cipher::{NewCipher, AsyncStreamCipher}; use test::Bencher; #[inline(never)] From f46f713bec4a2bc0af80026ac032bad8550e8a3f 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: Sun, 13 Dec 2020 14:41:32 +0300 Subject: [PATCH 7/9] return SeenNum impl for i32 --- cipher/src/stream.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index 8e96f1b8a..fa95cd919 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -94,7 +94,7 @@ impl StreamCipher for &mut C { /// [`StreamCipherSeek`] trait. /// /// This trait is implemented for primitive numeric types, i.e. `i/u8`, -/// `u16`, `u32`, `u64`, `u128`, and `usize`. It is not intended +/// `u16`, `u32`, `u64`, `u128`, `usize`, and `i32`. It is not intended /// to be implemented in third-party crates. #[rustfmt::skip] pub trait SeekNum: @@ -145,4 +145,4 @@ macro_rules! impl_seek_num { }; } -impl_seek_num! { u8 u16 u32 u64 u128 usize } +impl_seek_num! { u8 u16 u32 u64 u128 usize i32 } From 014a1a83fd74e1b3829d5acc040076800ef0551f 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: Sun, 13 Dec 2020 14:43:11 +0300 Subject: [PATCH 8/9] re-export blobby from root --- cipher/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index a4b329f7e..41d955f3e 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -17,6 +17,8 @@ extern crate std; #[cfg(feature = "block-mode")] pub extern crate block_padding; +#[cfg(feature = "dev")] +pub extern crate blobby; pub mod block; pub mod common; From 3cc6b10e7bb547c20ad1b98f20338bfdd3de1b21 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: Sun, 13 Dec 2020 14:59:30 +0300 Subject: [PATCH 9/9] reorganize modules --- cipher/src/block.rs | 14 +++++--------- cipher/src/common.rs | 8 ++++---- cipher/src/dev.rs | 2 ++ cipher/src/{block/dev.rs => dev/block.rs} | 6 +++--- cipher/src/{stream/dev.rs => dev/stream.rs} | 8 +++----- cipher/src/errors.rs | 4 ++-- cipher/src/lib.rs | 20 ++++++++++---------- cipher/src/stream.rs | 6 ------ 8 files changed, 29 insertions(+), 39 deletions(-) create mode 100644 cipher/src/dev.rs rename cipher/src/{block/dev.rs => dev/block.rs} (95%) rename cipher/src/{stream/dev.rs => dev/stream.rs} (96%) diff --git a/cipher/src/block.rs b/cipher/src/block.rs index 5efaa30b2..4e08dc259 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -9,21 +9,17 @@ //! [1]: https://en.wikipedia.org/wiki/Block_cipher //! [2]: https://en.wikipedia.org/wiki/Symmetric-key_algorithm -#[cfg(feature = "dev")] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] -pub mod dev; - use crate::errors::InvalidLength; use core::convert::TryInto; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; /// Key for an algorithm that implements [`NewBlockCipher`]. -pub type Key = GenericArray::KeySize>; +pub type BlockCipherKey = GenericArray::KeySize>; /// Block on which a [`BlockCipher`] operates. pub type Block = GenericArray::BlockSize>; -/// Blocks being acted over in parallel. +/// Block on which a [`BlockCipher`] operates in parallel. pub type ParBlocks = GenericArray, ::ParBlocks>; /// Instantiate a [`BlockCipher`] algorithm. @@ -32,7 +28,7 @@ pub trait NewBlockCipher: Sized { type KeySize: ArrayLength; /// Create new block cipher instance from key with fixed size. - fn new(key: &Key) -> Self; + fn new(key: &BlockCipherKey) -> Self; /// Create new block cipher instance from key with variable size. /// @@ -57,7 +53,7 @@ pub trait BlockCipher { type ParBlocks: ArrayLength>; } -/// Encrypt-only functionality for block ciphers +/// Encrypt-only functionality for block ciphers. pub trait BlockEncrypt: BlockCipher { /// Encrypt block in-place fn encrypt_block(&self, block: &mut Block); @@ -94,7 +90,7 @@ pub trait BlockEncrypt: BlockCipher { } } -/// Decrypt-only functionality for block ciphers +/// Decrypt-only functionality for block ciphers. pub trait BlockDecrypt: BlockCipher { /// Decrypt block in-place fn decrypt_block(&self, block: &mut Block); diff --git a/cipher/src/common.rs b/cipher/src/common.rs index c937802fc..7416c956a 100644 --- a/cipher/src/common.rs +++ b/cipher/src/common.rs @@ -2,7 +2,7 @@ use generic_array::{ArrayLength, GenericArray, typenum::Unsigned}; use crate::{BlockCipher, NewBlockCipher, errors::InvalidLength}; /// Key for an algorithm that implements [`NewCipher`]. -pub type Key = GenericArray::KeySize>; +pub type CipherKey = GenericArray::KeySize>; /// Nonce for an algorithm that implements [`NewCipher`]. pub type Nonce = GenericArray::NonceSize>; @@ -18,7 +18,7 @@ pub trait NewCipher: Sized { type NonceSize: ArrayLength; /// Create new stream cipher instance from variable length key and nonce. - fn new(key: &Key, nonce: &Nonce) -> Self; + fn new(key: &CipherKey, nonce: &Nonce) -> Self; /// Create new stream cipher instance from variable length key and nonce. #[inline] @@ -35,7 +35,7 @@ pub trait NewCipher: Sized { } } -/// Trait for initializing a stream cipher from a block cipher +/// Trait for types which can be initialized from a block cipher and nonce. pub trait FromBlockCipher { /// Block cipher type BlockCipher: BlockCipher; @@ -57,7 +57,7 @@ where type KeySize = <::BlockCipher as NewBlockCipher>::KeySize; type NonceSize = ::NonceSize; - fn new(key: &Key, nonce: &Nonce) -> C { + fn new(key: &CipherKey, nonce: &Nonce) -> C { C::from_block_cipher( <::BlockCipher as NewBlockCipher>::new(key), nonce, diff --git a/cipher/src/dev.rs b/cipher/src/dev.rs new file mode 100644 index 000000000..0737a04e1 --- /dev/null +++ b/cipher/src/dev.rs @@ -0,0 +1,2 @@ +mod stream; +mod block; diff --git a/cipher/src/block/dev.rs b/cipher/src/dev/block.rs similarity index 95% rename from cipher/src/block/dev.rs rename to cipher/src/dev/block.rs index 7ea94e79e..f8de973b0 100644 --- a/cipher/src/block/dev.rs +++ b/cipher/src/dev/block.rs @@ -9,8 +9,8 @@ macro_rules! block_cipher_test { ($name:ident, $test_name:expr, $cipher:ty) => { #[test] fn $name() { - use cipher::block::{ - dev::blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher, + use cipher::{ + blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher, }; use cipher::generic_array::{typenum::Unsigned, GenericArray}; @@ -113,7 +113,7 @@ macro_rules! block_cipher_bench { ($cipher:path, $key_len:expr) => { extern crate test; - use cipher::block::{BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher}; + use cipher::{BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher}; use test::Bencher; #[bench] diff --git a/cipher/src/stream/dev.rs b/cipher/src/dev/stream.rs similarity index 96% rename from cipher/src/stream/dev.rs rename to cipher/src/dev/stream.rs index 3ef664d10..4f922bcb6 100644 --- a/cipher/src/stream/dev.rs +++ b/cipher/src/dev/stream.rs @@ -97,7 +97,7 @@ macro_rules! stream_cipher_async_test { #[test] fn $name() { use cipher::generic_array::GenericArray; - use cipher::stream::{blobby::Blob4Iterator, NewCipher, AsyncStreamCipher}; + use cipher::{blobby::Blob4Iterator, NewCipher, AsyncStreamCipher}; fn run_test( key: &[u8], @@ -172,8 +172,7 @@ macro_rules! stream_cipher_sync_bench { ($cipher:path) => { extern crate test; - use cipher::generic_array::GenericArray; - use cipher::{NewCipher, StreamCipher}; + use cipher::{NewCipher, StreamCipher, generic_array::GenericArray}; use test::Bencher; #[inline(never)] @@ -225,8 +224,7 @@ macro_rules! stream_cipher_async_bench { ($cipher:path) => { extern crate test; - use cipher::generic_array::GenericArray; - use cipher::{NewCipher, AsyncStreamCipher}; + use cipher::{NewCipher, AsyncStreamCipher, generic_array::GenericArray}; use test::Bencher; #[inline(never)] diff --git a/cipher/src/errors.rs b/cipher/src/errors.rs index 2cf96d382..787834e52 100644 --- a/cipher/src/errors.rs +++ b/cipher/src/errors.rs @@ -1,4 +1,4 @@ -//! Error types +//! Error types. use core::fmt; @@ -60,4 +60,4 @@ impl fmt::Display for BlockModeError { } #[cfg(feature = "std")] -impl error::Error for BlockModeError {} +impl std::error::Error for BlockModeError {} diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index 41d955f3e..875bab243 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -20,20 +20,20 @@ pub extern crate block_padding; #[cfg(feature = "dev")] pub extern crate blobby; -pub mod block; -pub mod common; pub mod errors; +#[cfg(feature = "dev")] +mod dev; +mod block; +mod common; #[cfg(feature = "block-padding")] -pub mod mode; -pub mod stream; +mod mode; +mod stream; pub use crate::{ - block::{ - BlockCipher, BlockDecrypt, BlockDecryptMut, BlockEncrypt, BlockEncryptMut, NewBlockCipher, - }, - common::{NewCipher, FromBlockCipher}, - stream::{AsyncStreamCipher, StreamCipher, StreamCipherSeek}, + block::*, + common::*, + stream::*, }; #[cfg(feature = "block-mode")] -pub use crate::mode::{BlockModeCore}; +pub use crate::mode::BlockModeCore; pub use generic_array::{self, typenum::consts}; diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index fa95cd919..843ff56eb 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -3,12 +3,6 @@ //! See [RustCrypto/stream-ciphers](https://github.com/RustCrypto/stream-ciphers) //! for ciphers implementation. -#[cfg(feature = "dev")] -mod dev; - -#[cfg(feature = "dev")] -pub use blobby; - use crate::errors::{LoopError, OverflowError}; use core::convert::{TryFrom, TryInto};