8
8
9
9
//! The ChaCha random number generator.
10
10
11
+ // TODO: remove
11
12
#[ cfg( not( feature = "std" ) ) ] use core;
12
13
#[ cfg( feature = "std" ) ] use std as core;
13
14
14
- use self :: core:: fmt;
15
+ use self :: core:: { fmt, slice } ;
15
16
use crate :: guts:: ChaCha ;
16
17
use rand_core:: block:: { BlockRng , BlockRngCore } ;
17
18
use rand_core:: { CryptoRng , Error , RngCore , SeedableRng } ;
@@ -24,46 +25,46 @@ const BUF_BLOCKS: u8 = 4;
24
25
// number of 32-bit words per ChaCha block (fixed by algorithm definition)
25
26
const BLOCK_WORDS : u8 = 16 ;
26
27
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
+ }
48
41
}
49
42
}
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
+ }
53
53
}
54
54
}
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
62
59
}
63
60
}
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
+ }
67
68
}
68
69
}
69
70
@@ -83,17 +84,11 @@ macro_rules! chacha_impl {
83
84
}
84
85
85
86
impl BlockRngCore for $ChaChaXCore {
86
- type Item = u32 ;
87
- type Results = Array64 <u32 >;
87
+ type Results = Results ;
88
88
#[ inline]
89
89
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) ;
97
92
}
98
93
}
99
94
@@ -162,6 +157,10 @@ macro_rules! chacha_impl {
162
157
}
163
158
164
159
impl RngCore for $ChaChaXRng {
160
+ #[ inline]
161
+ fn next_bool( & mut self ) -> bool {
162
+ self . rng. next_bool( )
163
+ }
165
164
#[ inline]
166
165
fn next_u32( & mut self ) -> u32 {
167
166
self . rng. next_u32( )
@@ -180,6 +179,7 @@ macro_rules! chacha_impl {
180
179
}
181
180
}
182
181
182
+ /*
183
183
impl $ChaChaXRng {
184
184
// The buffer is a 4-block window, i.e. it is always at a block-aligned position in the
185
185
// stream but if the stream has been seeked it may not be self-aligned.
@@ -245,6 +245,7 @@ macro_rules! chacha_impl {
245
245
}
246
246
}
247
247
}
248
+ */
248
249
249
250
impl CryptoRng for $ChaChaXRng { }
250
251
@@ -258,8 +259,7 @@ macro_rules! chacha_impl {
258
259
259
260
impl PartialEq <$ChaChaXRng> for $ChaChaXRng {
260
261
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)
263
263
}
264
264
}
265
265
impl Eq for $ChaChaXRng { }
@@ -344,7 +344,7 @@ mod test {
344
344
] ;
345
345
assert_eq ! ( results, expected) ;
346
346
}
347
-
347
+ /*
348
348
#[test]
349
349
fn test_chacha_true_values_c() {
350
350
// Test vector 4 from
@@ -506,4 +506,5 @@ mod test {
506
506
rng.set_word_pos(0);
507
507
assert_eq!(rng.get_word_pos(), 0);
508
508
}
509
+ */
509
510
}
0 commit comments