Skip to content

Commit

Permalink
Merge pull request #63 from dhardy/master
Browse files Browse the repository at this point in the history
Add rand_core::RngCore implementation to chacha20
  • Loading branch information
tarcieri authored Oct 23, 2019
2 parents 4d155a9 + 9817b4f commit 46afd2b
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 1 deletion.
2 changes: 2 additions & 0 deletions chacha20/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ travis-ci = { repository = "RustCrypto/stream-ciphers" }
byteorder = { version = "1", default-features = false }
stream-cipher = "0.3"
salsa20-core = { version = "0.2", path = "../salsa20-core" }
rand_core = { version = "0.5", optional = true }

[dev-dependencies]
stream-cipher = { version = "0.3", features = ["dev"] }
Expand All @@ -30,6 +31,7 @@ default = ["xchacha20"]
legacy = []
xchacha20 = []
zeroize = ["salsa20-core/zeroize"]
rng = ["rand_core"]

[[bench]]
name = "chacha20"
Expand Down
2 changes: 1 addition & 1 deletion chacha20/src/cipher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use salsa20_core::{SalsaFamilyCipher, IV_WORDS, KEY_WORDS, STATE_WORDS};
use super::MAX_BLOCKS;

/// ChaCha20 core cipher functionality
#[derive(Debug)]
#[derive(Clone, Debug)]
pub(crate) struct Cipher {
/// Secret key
key: [u32; KEY_WORDS],
Expand Down
8 changes: 8 additions & 0 deletions chacha20/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ extern crate salsa20_core;
// TODO: replace with `u32::from_le_bytes`/`to_le_bytes` in libcore (1.32+)
#[cfg(feature = "xchacha20")]
extern crate byteorder;
#[cfg(feature = "rand_core")]
extern crate rand_core;

mod block;
pub(crate) mod cipher;
Expand All @@ -68,6 +70,9 @@ mod legacy;
#[cfg(feature = "xchacha20")]
mod xchacha20;

#[cfg(feature = "rng")]
mod rng;

use self::cipher::Cipher;
use salsa20_core::Ctr;
use stream_cipher::generic_array::{
Expand All @@ -81,6 +86,9 @@ pub use self::legacy::ChaCha20Legacy;
#[cfg(feature = "xchacha20")]
pub use self::xchacha20::XChaCha20;

#[cfg(feature = "rng")]
pub use rng::{ChaCha20Rng, ChaCha20RngCore};

/// Maximum number of blocks that can be encrypted with ChaCha20 before the
/// counter overflows.
pub const MAX_BLOCKS: usize = core::u32::MAX as usize;
Expand Down
71 changes: 71 additions & 0 deletions chacha20/src/rng.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//! Block RNG based on rand_core::BlockRng
use rand_core::{RngCore, SeedableRng, Error};
use rand_core::block::{BlockRng, BlockRngCore};
use salsa20_core::{SalsaFamilyCipher, IV_BYTES, KEY_BYTES, STATE_WORDS};

use crate::cipher::Cipher;

/// Random number generator over the ChaCha20 stream cipher.
#[derive(Clone, Debug)]
pub struct ChaCha20Rng(BlockRng<ChaCha20RngCore>);

impl SeedableRng for ChaCha20Rng {
type Seed = [u8; KEY_BYTES];
#[inline]
fn from_seed(seed: Self::Seed) -> Self {
let core = ChaCha20RngCore::from_seed(seed);
Self(BlockRng::new(core))
}
}

impl RngCore for ChaCha20Rng {
#[inline]
fn next_u32(&mut self) -> u32 {
self.0.next_u32()
}
#[inline]
fn next_u64(&mut self) -> u64 {
self.0.next_u64()
}
#[inline]
fn fill_bytes(&mut self, bytes: &mut [u8]) {
self.0.fill_bytes(bytes)
}
#[inline]
fn try_fill_bytes(&mut self, bytes: &mut [u8]) -> Result<(), Error> {
self.0.try_fill_bytes(bytes)
}
}


/// Core of the [`ChaCha20Rng`] random number generator, for use with
/// [`rand_core::block::BlockRng`].
#[derive(Clone, Debug)]
pub struct ChaCha20RngCore {
cipher: Cipher,
counter: u64,
}

impl SeedableRng for ChaCha20RngCore {
type Seed = [u8; KEY_BYTES];
#[inline]
fn from_seed(seed: Self::Seed) -> Self {
let iv = [0; IV_BYTES];
let cipher = Cipher::new(&seed, &iv, 0);
Self {
cipher,
counter: 0,
}
}
}

impl BlockRngCore for ChaCha20RngCore {
type Item = u32;
type Results = [u32; STATE_WORDS];
fn generate(&mut self, results: &mut Self::Results) {
let out = self.cipher.block(self.counter);
self.counter += 1;
*results = out;
}
}

0 comments on commit 46afd2b

Please sign in to comment.