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 } ;
1516use crate :: guts:: ChaCha ;
1617use rand_core:: block:: { BlockRng , BlockRngCore } ;
1718use 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)
2526const 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}
0 commit comments