Skip to content

Commit 601038d

Browse files
committed
Bit-level counter for BlockRng
1 parent 73befa4 commit 601038d

File tree

14 files changed

+311
-304
lines changed

14 files changed

+311
-304
lines changed

rand_chacha/src/chacha.rs

Lines changed: 48 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@
88

99
//! The ChaCha random number generator.
1010
11+
// TODO: remove
1112
#[cfg(not(feature = "std"))] use core;
1213
#[cfg(feature = "std")] use std as core;
1314

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

27-
pub struct Array64<T>([T; 64]);
28-
impl<T> Default for Array64<T>
29-
where T: Default
30-
{
31-
#[rustfmt::skip]
32-
fn default() -> Self {
33-
Self([
34-
T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
35-
T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
36-
T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
37-
T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
38-
T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
39-
T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
40-
T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
41-
T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
42-
])
43-
}
44-
}
45-
impl<T> AsRef<[T]> for Array64<T> {
46-
fn as_ref(&self) -> &[T] {
47-
&self.0
28+
/// Type representing result of the ChaCha core iteration
29+
#[derive(Eq, PartialEq, Default, Clone, Copy, Debug)]
30+
pub struct Results([u64; 32]);
31+
32+
impl AsRef<[u8]> for Results {
33+
#[inline(always)]
34+
fn as_ref(&self) -> &[u8] {
35+
unsafe {
36+
slice::from_raw_parts(
37+
self.0.as_ptr() as *const u8,
38+
8 * self.0.len(),
39+
)
40+
}
4841
}
4942
}
50-
impl<T> AsMut<[T]> for Array64<T> {
51-
fn as_mut(&mut self) -> &mut [T] {
52-
&mut self.0
43+
44+
impl AsRef<[u32]> for Results {
45+
#[inline(always)]
46+
fn as_ref(&self) -> &[u32] {
47+
unsafe {
48+
slice::from_raw_parts(
49+
self.0.as_ptr() as *const u32,
50+
2 * self.0.len(),
51+
)
52+
}
5353
}
5454
}
55-
impl<T> Clone for Array64<T>
56-
where T: Copy + Default
57-
{
58-
fn clone(&self) -> Self {
59-
let mut new = Self::default();
60-
new.0.copy_from_slice(&self.0);
61-
new
55+
impl AsRef<[u64]> for Results {
56+
#[inline(always)]
57+
fn as_ref(&self) -> &[u64] {
58+
&self.0
6259
}
6360
}
64-
impl<T> fmt::Debug for Array64<T> {
65-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
66-
write!(f, "Array64 {{}}")
61+
62+
impl AsMut<[u8; 256]> for Results {
63+
#[inline(always)]
64+
fn as_mut(&mut self) -> &mut [u8; 256] {
65+
unsafe {
66+
&mut *(self.0.as_mut_ptr() as *mut [u8; 256])
67+
}
6768
}
6869
}
6970

@@ -83,17 +84,11 @@ macro_rules! chacha_impl {
8384
}
8485

8586
impl BlockRngCore for $ChaChaXCore {
86-
type Item = u32;
87-
type Results = Array64<u32>;
87+
type Results = Results;
8888
#[inline]
8989
fn generate(&mut self, r: &mut Self::Results) {
90-
// Fill slice of words by writing to equivalent slice of bytes, then fixing endianness.
91-
self.state.refill4($rounds, unsafe {
92-
&mut *(&mut *r as *mut Array64<u32> as *mut [u8; 256])
93-
});
94-
for x in r.as_mut() {
95-
*x = x.to_le();
96-
}
90+
let r: &mut [u8; 256] = r.as_mut();
91+
self.state.refill4($rounds, r);
9792
}
9893
}
9994

@@ -162,6 +157,10 @@ macro_rules! chacha_impl {
162157
}
163158

164159
impl RngCore for $ChaChaXRng {
160+
#[inline]
161+
fn next_bool(&mut self) -> bool {
162+
self.rng.next_bool()
163+
}
165164
#[inline]
166165
fn next_u32(&mut self) -> u32 {
167166
self.rng.next_u32()
@@ -180,6 +179,7 @@ macro_rules! chacha_impl {
180179
}
181180
}
182181

182+
/*
183183
impl $ChaChaXRng {
184184
// The buffer is a 4-block window, i.e. it is always at a block-aligned position in the
185185
// stream but if the stream has been seeked it may not be self-aligned.
@@ -245,6 +245,7 @@ macro_rules! chacha_impl {
245245
}
246246
}
247247
}
248+
*/
248249

249250
impl CryptoRng for $ChaChaXRng {}
250251

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

259260
impl PartialEq<$ChaChaXRng> for $ChaChaXRng {
260261
fn eq(&self, rhs: &$ChaChaXRng) -> bool {
261-
self.rng.core.state.stream64_eq(&rhs.rng.core.state)
262-
&& self.get_word_pos() == rhs.get_word_pos()
262+
self.rng.eq(&rhs.rng)
263263
}
264264
}
265265
impl Eq for $ChaChaXRng {}
@@ -344,7 +344,7 @@ mod test {
344344
];
345345
assert_eq!(results, expected);
346346
}
347-
347+
/*
348348
#[test]
349349
fn test_chacha_true_values_c() {
350350
// Test vector 4 from
@@ -506,4 +506,5 @@ mod test {
506506
rng.set_word_pos(0);
507507
assert_eq!(rng.get_word_pos(), 0);
508508
}
509+
*/
509510
}

rand_chacha/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#![deny(missing_docs)]
1717
#![deny(missing_debug_implementations)]
1818
#![doc(test(attr(allow(unused_variables), deny(warnings))))]
19-
#![cfg_attr(not(feature = "std"), no_std)]
19+
#![cfg_attr(not(feature = "std"), no_std)] // TODO: use `#![no_std]`
2020

2121
pub use rand_core;
2222

0 commit comments

Comments
 (0)