Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cipher/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "cipher"
description = "Traits for describing block ciphers and stream ciphers"
version = "0.2.5"
version = "0.3.0-pre"
authors = ["RustCrypto Developers"]
license = "MIT OR Apache-2.0"
readme = "README.md"
Expand Down
83 changes: 32 additions & 51 deletions cipher/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,43 +53,42 @@ pub trait NewBlockCipher: Sized {
}
}

/// The trait which defines in-place encryption and decryption
/// over single block or several blocks in parallel.
/// Trait which marks a type as being a block cipher.
pub trait BlockCipher {
/// Size of the block in bytes
type BlockSize: ArrayLength<u8>;

/// Number of blocks which can be processed in parallel by
/// cipher implementation
type ParBlocks: ArrayLength<Block<Self>>;
}

/// Encrypt-only functionality for block ciphers
pub trait BlockEncrypt: BlockCipher {
/// Encrypt block in-place
fn encrypt_block(&self, block: &mut Block<Self>);

/// Decrypt block in-place
fn decrypt_block(&self, block: &mut Block<Self>);

/// 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<Self>) {
fn encrypt_par_blocks(&self, blocks: &mut ParBlocks<Self>) {
for block in blocks.iter_mut() {
self.encrypt_block(block);
}
}

/// Encrypt a slice of blocks, leveraging parallelism when available.
#[inline]
fn encrypt_slice(&self, mut blocks: &mut [Block<Self>]) {
fn encrypt_blocks(&self, mut blocks: &mut [Block<Self>]) {
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();
Expand All @@ -99,28 +98,34 @@ pub trait BlockCipher {
self.encrypt_block(block);
}
}
}

/// Decrypt-only functionality for block ciphers
pub trait BlockDecrypt: BlockCipher {
/// Decrypt block in-place
fn decrypt_block(&self, block: &mut Block<Self>);

/// 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<Self>) {
fn decrypt_par_blocks(&self, blocks: &mut ParBlocks<Self>) {
for block in blocks.iter_mut() {
self.decrypt_block(block);
}
}

/// Decrypt a slice of blocks, leveraging parallelism when available.
#[inline]
fn decrypt_slice(&self, mut blocks: &mut [Block<Self>]) {
fn decrypt_blocks(&self, mut blocks: &mut [Block<Self>]) {
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();
Expand All @@ -132,56 +137,32 @@ pub trait BlockCipher {
}
}

/// Stateful block cipher which permits `&mut self` access.
/// Encrypt-only functionality for block ciphers with mutable access to `self`.
///
/// 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<u8>;

pub trait BlockEncryptMut: BlockCipher {
/// Encrypt block in-place
fn encrypt_block(&mut self, block: &mut GenericArray<u8, Self::BlockSize>);
fn encrypt_block_mut(&mut self, block: &mut Block<Self>);
}

/// Decrypt-only functionality for block ciphers with mutable access to `self`.
///
/// The main use case for this trait is hardware encryption engines which
/// require `&mut self` access to an underlying hardware peripheral.
pub trait BlockDecryptMut: BlockCipher {
/// Decrypt block in-place
fn decrypt_block(&mut self, block: &mut GenericArray<u8, Self::BlockSize>);
fn decrypt_block_mut(&mut self, block: &mut Block<Self>);
}

impl<Alg: BlockCipher> BlockCipherMut for Alg {
type BlockSize = Alg::BlockSize;

#[inline]
fn encrypt_block(&mut self, block: &mut GenericArray<u8, Self::BlockSize>) {
<Self as BlockCipher>::encrypt_block(self, block);
}

#[inline]
fn decrypt_block(&mut self, block: &mut GenericArray<u8, Self::BlockSize>) {
<Self as BlockCipher>::decrypt_block(self, block);
impl<Alg: BlockEncrypt> BlockEncryptMut for Alg {
fn encrypt_block_mut(&mut self, block: &mut Block<Self>) {
self.encrypt_block(block);
}
}

impl<Alg: BlockCipher> BlockCipher for &Alg {
type BlockSize = Alg::BlockSize;
type ParBlocks = Alg::ParBlocks;

#[inline]
fn encrypt_block(&self, block: &mut Block<Self>) {
Alg::encrypt_block(self, block);
}

#[inline]
fn decrypt_block(&self, block: &mut Block<Self>) {
Alg::decrypt_block(self, block);
}

#[inline]
fn encrypt_blocks(&self, blocks: &mut ParBlocks<Self>) {
Alg::encrypt_blocks(self, blocks);
}

#[inline]
fn decrypt_blocks(&self, blocks: &mut ParBlocks<Self>) {
Alg::decrypt_blocks(self, blocks);
impl<Alg: BlockDecrypt> BlockDecryptMut for Alg {
fn decrypt_block_mut(&mut self, block: &mut Block<Self>) {
self.decrypt_block(block);
}
}
4 changes: 3 additions & 1 deletion cipher/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ pub mod block;
pub mod stream;

pub use crate::{
block::{BlockCipher, BlockCipherMut, NewBlockCipher},
block::{
BlockCipher, BlockDecrypt, BlockDecryptMut, BlockEncrypt, BlockEncryptMut, NewBlockCipher,
},
stream::{NewStreamCipher, StreamCipher, SyncStreamCipher, SyncStreamCipherSeek},
};
pub use generic_array::{self, typenum::consts};
43 changes: 7 additions & 36 deletions cipher/src/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub use generic_array::{self, typenum::consts};
#[cfg(feature = "dev")]
pub use blobby;

use crate::block::{BlockCipher, BlockCipherMut, NewBlockCipher};
use crate::block::{BlockCipher, NewBlockCipher};
use core::convert::{TryFrom, TryInto};
use generic_array::typenum::Unsigned;
use generic_array::{ArrayLength, GenericArray};
Expand Down Expand Up @@ -166,46 +166,17 @@ pub trait FromBlockCipher {
) -> Self;
}

/// 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<u8>;

/// Instantiate a stream cipher from a block cipher
fn from_block_cipher_mut(
cipher: Self::BlockCipher,
nonce: &GenericArray<u8, Self::NonceSize>,
) -> Self;
}

impl<C> FromBlockCipherMut for C
where
C: FromBlockCipher,
{
type BlockCipher = <Self as FromBlockCipher>::BlockCipher;
type NonceSize = <Self as FromBlockCipher>::NonceSize;

fn from_block_cipher_mut(
cipher: Self::BlockCipher,
nonce: &GenericArray<u8, Self::NonceSize>,
) -> C {
C::from_block_cipher(cipher, nonce)
}
}

impl<C> NewStreamCipher for C
where
C: FromBlockCipherMut,
C: FromBlockCipher,
C::BlockCipher: NewBlockCipher,
{
type KeySize = <<Self as FromBlockCipherMut>::BlockCipher as NewBlockCipher>::KeySize;
type NonceSize = <Self as FromBlockCipherMut>::NonceSize;
type KeySize = <<Self as FromBlockCipher>::BlockCipher as NewBlockCipher>::KeySize;
type NonceSize = <Self as FromBlockCipher>::NonceSize;

fn new(key: &Key<Self>, nonce: &Nonce<Self>) -> C {
C::from_block_cipher_mut(
<<Self as FromBlockCipherMut>::BlockCipher as NewBlockCipher>::new(key),
C::from_block_cipher(
<<Self as FromBlockCipher>::BlockCipher as NewBlockCipher>::new(key),
nonce,
)
}
Expand All @@ -218,7 +189,7 @@ where
.map_err(|_| InvalidKeyNonceLength)
.map(|cipher| {
let nonce = GenericArray::from_slice(nonce);
Self::from_block_cipher_mut(cipher, nonce)
Self::from_block_cipher(cipher, nonce)
})
}
}
Expand Down
4 changes: 2 additions & 2 deletions crypto-mac/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "crypto-mac"
description = "Trait for Message Authentication Code (MAC) algorithms"
version = "0.10.0"
version = "0.11.0-pre"
authors = ["RustCrypto Developers"]
license = "MIT OR Apache-2.0"
readme = "README.md"
Expand All @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"]

[dependencies]
generic-array = "0.14"
cipher = { version = "0.2", optional = true, path = "../cipher" }
cipher = { version = "=0.3.0-pre", optional = true, path = "../cipher" }
subtle = { version = "2", default-features = false }
blobby = { version = "0.3", optional = true }

Expand Down
4 changes: 2 additions & 2 deletions crypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ edition = "2018"

[dependencies]
aead = { version = "0.3", optional = true, path = "../aead" }
cipher = { version = "0.2", optional = true, path = "../cipher" }
cipher = { version = "=0.3.0-pre", optional = true, path = "../cipher" }
digest = { version = "0.9", optional = true, path = "../digest" }
elliptic-curve = { version = "=0.7.0-pre", optional = true, path = "../elliptic-curve" }
mac = { version = "0.10", package = "crypto-mac", optional = true, path = "../crypto-mac" }
mac = { version = "=0.11.0-pre", package = "crypto-mac", optional = true, path = "../crypto-mac" }
signature = { version = "1.2.0", optional = true, default-features = false, path = "../signature" }
universal-hash = { version = "0.4", optional = true, path = "../universal-hash" }

Expand Down