Skip to content

Commit

Permalink
Bit-level counter for BlockRng
Browse files Browse the repository at this point in the history
  • Loading branch information
newpavlov committed Oct 20, 2020
1 parent 73befa4 commit 601038d
Show file tree
Hide file tree
Showing 14 changed files with 311 additions and 304 deletions.
95 changes: 48 additions & 47 deletions rand_chacha/src/chacha.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@

//! The ChaCha random number generator.
// TODO: remove
#[cfg(not(feature = "std"))] use core;
#[cfg(feature = "std")] use std as core;

use self::core::fmt;
use self::core::{fmt, slice};
use crate::guts::ChaCha;
use rand_core::block::{BlockRng, BlockRngCore};
use rand_core::{CryptoRng, Error, RngCore, SeedableRng};
Expand All @@ -24,46 +25,46 @@ const BUF_BLOCKS: u8 = 4;
// number of 32-bit words per ChaCha block (fixed by algorithm definition)
const BLOCK_WORDS: u8 = 16;

pub struct Array64<T>([T; 64]);
impl<T> Default for Array64<T>
where T: Default
{
#[rustfmt::skip]
fn default() -> Self {
Self([
T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
])
}
}
impl<T> AsRef<[T]> for Array64<T> {
fn as_ref(&self) -> &[T] {
&self.0
/// Type representing result of the ChaCha core iteration
#[derive(Eq, PartialEq, Default, Clone, Copy, Debug)]
pub struct Results([u64; 32]);

impl AsRef<[u8]> for Results {
#[inline(always)]
fn as_ref(&self) -> &[u8] {
unsafe {
slice::from_raw_parts(
self.0.as_ptr() as *const u8,
8 * self.0.len(),
)
}
}
}
impl<T> AsMut<[T]> for Array64<T> {
fn as_mut(&mut self) -> &mut [T] {
&mut self.0

impl AsRef<[u32]> for Results {
#[inline(always)]
fn as_ref(&self) -> &[u32] {
unsafe {
slice::from_raw_parts(
self.0.as_ptr() as *const u32,
2 * self.0.len(),
)
}
}
}
impl<T> Clone for Array64<T>
where T: Copy + Default
{
fn clone(&self) -> Self {
let mut new = Self::default();
new.0.copy_from_slice(&self.0);
new
impl AsRef<[u64]> for Results {
#[inline(always)]
fn as_ref(&self) -> &[u64] {
&self.0
}
}
impl<T> fmt::Debug for Array64<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Array64 {{}}")

impl AsMut<[u8; 256]> for Results {
#[inline(always)]
fn as_mut(&mut self) -> &mut [u8; 256] {
unsafe {
&mut *(self.0.as_mut_ptr() as *mut [u8; 256])
}
}
}

Expand All @@ -83,17 +84,11 @@ macro_rules! chacha_impl {
}

impl BlockRngCore for $ChaChaXCore {
type Item = u32;
type Results = Array64<u32>;
type Results = Results;
#[inline]
fn generate(&mut self, r: &mut Self::Results) {
// Fill slice of words by writing to equivalent slice of bytes, then fixing endianness.
self.state.refill4($rounds, unsafe {
&mut *(&mut *r as *mut Array64<u32> as *mut [u8; 256])
});
for x in r.as_mut() {
*x = x.to_le();
}
let r: &mut [u8; 256] = r.as_mut();
self.state.refill4($rounds, r);
}
}

Expand Down Expand Up @@ -162,6 +157,10 @@ macro_rules! chacha_impl {
}

impl RngCore for $ChaChaXRng {
#[inline]
fn next_bool(&mut self) -> bool {
self.rng.next_bool()
}
#[inline]
fn next_u32(&mut self) -> u32 {
self.rng.next_u32()
Expand All @@ -180,6 +179,7 @@ macro_rules! chacha_impl {
}
}

/*
impl $ChaChaXRng {
// The buffer is a 4-block window, i.e. it is always at a block-aligned position in the
// stream but if the stream has been seeked it may not be self-aligned.
Expand Down Expand Up @@ -245,6 +245,7 @@ macro_rules! chacha_impl {
}
}
}
*/

impl CryptoRng for $ChaChaXRng {}

Expand All @@ -258,8 +259,7 @@ macro_rules! chacha_impl {

impl PartialEq<$ChaChaXRng> for $ChaChaXRng {
fn eq(&self, rhs: &$ChaChaXRng) -> bool {
self.rng.core.state.stream64_eq(&rhs.rng.core.state)
&& self.get_word_pos() == rhs.get_word_pos()
self.rng.eq(&rhs.rng)
}
}
impl Eq for $ChaChaXRng {}
Expand Down Expand Up @@ -344,7 +344,7 @@ mod test {
];
assert_eq!(results, expected);
}

/*
#[test]
fn test_chacha_true_values_c() {
// Test vector 4 from
Expand Down Expand Up @@ -506,4 +506,5 @@ mod test {
rng.set_word_pos(0);
assert_eq!(rng.get_word_pos(), 0);
}
*/
}
2 changes: 1 addition & 1 deletion rand_chacha/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
#![doc(test(attr(allow(unused_variables), deny(warnings))))]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(not(feature = "std"), no_std)] // TODO: use `#![no_std]`

pub use rand_core;

Expand Down
Loading

0 comments on commit 601038d

Please sign in to comment.