Skip to content

Commit

Permalink
stream-cipher: add FromBlockCipher trait (fixes RustCrypto#32) (RustC…
Browse files Browse the repository at this point in the history
…rypto#164)

Support for instantiating a stream cipher from a block cipher
  • Loading branch information
tarcieri committed Jun 3, 2020
1 parent a853a6f commit 063cd27
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 1 deletion.
1 change: 1 addition & 0 deletions .github/workflows/stream-cipher.yml
Expand Up @@ -51,6 +51,7 @@ jobs:
toolchain: ${{ matrix.rust }}
- run: cargo check --all-features
- run: cargo test --release
- run: cargo test --features block-cipher
- run: cargo test --features dev --release
- run: cargo test --features std --release
- run: cargo test --all-features --release
1 change: 1 addition & 0 deletions Cargo.lock

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

8 changes: 7 additions & 1 deletion stream-cipher/Cargo.toml
Expand Up @@ -15,9 +15,15 @@ categories = ["cryptography", "no-std"]
generic-array = "0.14"
blobby = { version = "0.1", optional = true }

[dependencies.block-cipher]
version = "= 0.7.0-pre"
optional = true
path = "../block-cipher"

[features]
std = []
dev = ["blobby"]

[package.metadata.docs.rs]
features = [ "std" ]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
5 changes: 5 additions & 0 deletions stream-cipher/src/dev.rs
Expand Up @@ -4,6 +4,7 @@ pub use blobby;

/// Test core functionality of synchronous stream cipher
#[macro_export]
#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
macro_rules! new_sync_test {
($name:ident, $cipher:ty, $test_name:expr) => {
#[test]
Expand Down Expand Up @@ -43,6 +44,7 @@ macro_rules! new_sync_test {

/// Test stream synchronous stream cipher seeking capabilities
#[macro_export]
#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
macro_rules! new_seek_test {
($name:ident, $cipher:ty, $test_name:expr) => {
#[test]
Expand Down Expand Up @@ -85,6 +87,7 @@ macro_rules! new_seek_test {

/// Test core functionality of asynchronous stream cipher
#[macro_export]
#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
macro_rules! new_async_test {
($name:ident, $test_name:expr, $cipher:ty) => {
#[test]
Expand Down Expand Up @@ -149,6 +152,7 @@ macro_rules! new_async_test {

/// Create synchronous stream cipher benchmarks
#[macro_export]
#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
macro_rules! bench_sync {
($name:ident, $cipher:path, $data_len:expr) => {
#[bench]
Expand Down Expand Up @@ -187,6 +191,7 @@ macro_rules! bench_sync {

/// Create synchronous stream cipher benchmarks
#[macro_export]
#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
macro_rules! bench_async {
($enc_name:ident, $dec_name:ident, $cipher:path, $data_len:expr) => {
#[bench]
Expand Down
36 changes: 36 additions & 0 deletions stream-cipher/src/lib.rs
Expand Up @@ -5,6 +5,7 @@
//! for ciphers implementation.

#![no_std]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")]
#![forbid(unsafe_code)]
#![warn(missing_docs, rust_2018_idioms)]
Expand All @@ -13,6 +14,7 @@
extern crate std;

#[cfg(feature = "dev")]
#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
pub mod dev;

mod errors;
Expand All @@ -23,6 +25,9 @@ pub use generic_array::{self, typenum::consts};
use generic_array::typenum::Unsigned;
use generic_array::{ArrayLength, GenericArray};

#[cfg(feature = "block-cipher")]
use block_cipher::{BlockCipher, NewBlockCipher};

/// Stream cipher creation trait.
///
/// It can be used for creation of synchronous and asynchronous ciphers.
Expand Down Expand Up @@ -112,3 +117,34 @@ impl<C: SyncStreamCipher> StreamCipher for C {
SyncStreamCipher::apply_keystream(self, data);
}
}

/// Trait for initializing a stream cipher from a block cipher
#[cfg(feature = "block-cipher")]
#[cfg_attr(docsrs, doc(cfg(feature = "block-cipher")))]
pub trait FromBlockCipher {
/// Block cipher
type BlockCipher: BlockCipher + NewBlockCipher;

/// Instantiate a stream cipher from a block cipher
// TODO(tarcieri): add associated type for NonceSize?
fn from_block_cipher(
cipher: Self::BlockCipher,
nonce: &block_cipher::Block<Self::BlockCipher>,
) -> Self;
}

#[cfg(feature = "block-cipher")]
impl<C> NewStreamCipher for C
where
C: FromBlockCipher,
{
type KeySize = <<Self as FromBlockCipher>::BlockCipher as NewBlockCipher>::KeySize;
type NonceSize = <<Self as FromBlockCipher>::BlockCipher as BlockCipher>::BlockSize;

fn new(key: &GenericArray<u8, Self::KeySize>, nonce: &GenericArray<u8, Self::NonceSize>) -> C {
C::from_block_cipher(
<<Self as FromBlockCipher>::BlockCipher as NewBlockCipher>::new(key),
nonce,
)
}
}

0 comments on commit 063cd27

Please sign in to comment.