14
14
use self :: core:: fmt;
15
15
use crate :: guts:: ChaCha ;
16
16
use rand_core:: block:: { BlockRng , BlockRngCore , CryptoBlockRng } ;
17
- use rand_core:: { CryptoRng , Error , RngCore , SeedableRng } ;
17
+ use rand_core:: { CryptoRng , Error , InfallibleRng , RngCore , SeedableRng } ;
18
18
19
- #[ cfg( feature = "serde1" ) ] use serde:: { Serialize , Deserialize , Serializer , Deserializer } ;
19
+ #[ cfg( feature = "serde1" ) ]
20
+ use serde:: { Deserialize , Deserializer , Serialize , Serializer } ;
20
21
21
22
// NB. this must remain consistent with some currently hard-coded numbers in this module
22
23
const BUF_BLOCKS : u8 = 4 ;
@@ -85,6 +86,7 @@ macro_rules! chacha_impl {
85
86
impl BlockRngCore for $ChaChaXCore {
86
87
type Item = u32 ;
87
88
type Results = Array64 <u32 >;
89
+
88
90
#[ inline]
89
91
fn generate( & mut self , r: & mut Self :: Results ) {
90
92
self . state. refill4( $rounds, & mut r. 0 ) ;
@@ -93,9 +95,12 @@ macro_rules! chacha_impl {
93
95
94
96
impl SeedableRng for $ChaChaXCore {
95
97
type Seed = [ u8 ; 32 ] ;
98
+
96
99
#[ inline]
97
100
fn from_seed( seed: Self :: Seed ) -> Self {
98
- $ChaChaXCore { state: ChaCha :: new( & seed, & [ 0u8 ; 8 ] ) }
101
+ $ChaChaXCore {
102
+ state: ChaCha :: new( & seed, & [ 0u8 ; 8 ] ) ,
103
+ }
99
104
}
100
105
}
101
106
@@ -146,6 +151,7 @@ macro_rules! chacha_impl {
146
151
147
152
impl SeedableRng for $ChaChaXRng {
148
153
type Seed = [ u8 ; 32 ] ;
154
+
149
155
#[ inline]
150
156
fn from_seed( seed: Self :: Seed ) -> Self {
151
157
let core = $ChaChaXCore:: from_seed( seed) ;
@@ -160,14 +166,17 @@ macro_rules! chacha_impl {
160
166
fn next_u32( & mut self ) -> u32 {
161
167
self . rng. next_u32( )
162
168
}
169
+
163
170
#[ inline]
164
171
fn next_u64( & mut self ) -> u64 {
165
172
self . rng. next_u64( )
166
173
}
174
+
167
175
#[ inline]
168
176
fn fill_bytes( & mut self , bytes: & mut [ u8 ] ) {
169
177
self . rng. fill_bytes( bytes)
170
178
}
179
+
171
180
#[ inline]
172
181
fn try_fill_bytes( & mut self , bytes: & mut [ u8 ] ) -> Result <( ) , Error > {
173
182
self . rng. try_fill_bytes( bytes)
@@ -209,11 +218,9 @@ macro_rules! chacha_impl {
209
218
#[ inline]
210
219
pub fn set_word_pos( & mut self , word_offset: u128 ) {
211
220
let block = ( word_offset / u128 :: from( BLOCK_WORDS ) ) as u64 ;
221
+ self . rng. core. state. set_block_pos( block) ;
212
222
self . rng
213
- . core
214
- . state
215
- . set_block_pos( block) ;
216
- self . rng. generate_and_set( ( word_offset % u128 :: from( BLOCK_WORDS ) ) as usize ) ;
223
+ . generate_and_set( ( word_offset % u128 :: from( BLOCK_WORDS ) ) as usize ) ;
217
224
}
218
225
219
226
/// Set the stream number.
@@ -229,10 +236,7 @@ macro_rules! chacha_impl {
229
236
/// indirectly via `set_word_pos`), but this is not directly supported.
230
237
#[ inline]
231
238
pub fn set_stream( & mut self , stream: u64 ) {
232
- self . rng
233
- . core
234
- . state
235
- . set_nonce( stream) ;
239
+ self . rng. core. state. set_nonce( stream) ;
236
240
if self . rng. index( ) != 64 {
237
241
let wp = self . get_word_pos( ) ;
238
242
self . set_word_pos( wp) ;
@@ -242,24 +246,20 @@ macro_rules! chacha_impl {
242
246
/// Get the stream number.
243
247
#[ inline]
244
248
pub fn get_stream( & self ) -> u64 {
245
- self . rng
246
- . core
247
- . state
248
- . get_nonce( )
249
+ self . rng. core. state. get_nonce( )
249
250
}
250
251
251
252
/// Get the seed.
252
253
#[ inline]
253
254
pub fn get_seed( & self ) -> [ u8 ; 32 ] {
254
- self . rng
255
- . core
256
- . state
257
- . get_seed( )
255
+ self . rng. core. state. get_seed( )
258
256
}
259
257
}
260
258
261
259
impl CryptoRng for $ChaChaXRng { }
262
260
261
+ impl InfallibleRng for $ChaChaXRng { }
262
+
263
263
impl From <$ChaChaXCore> for $ChaChaXRng {
264
264
fn from( core: $ChaChaXCore) -> Self {
265
265
$ChaChaXRng {
@@ -286,22 +286,20 @@ macro_rules! chacha_impl {
286
286
}
287
287
#[ cfg( feature = "serde1" ) ]
288
288
impl <' de> Deserialize <' de> for $ChaChaXRng {
289
- fn deserialize<D >( d: D ) -> Result <Self , D :: Error > where D : Deserializer <' de> {
289
+ fn deserialize<D >( d: D ) -> Result <Self , D :: Error >
290
+ where D : Deserializer <' de> {
290
291
$abst:: $ChaChaXRng:: deserialize( d) . map( |x| Self :: from( & x) )
291
292
}
292
293
}
293
294
294
295
mod $abst {
295
- #[ cfg( feature = "serde1" ) ] use serde:: { Serialize , Deserialize } ;
296
+ #[ cfg( feature = "serde1" ) ] use serde:: { Deserialize , Serialize } ;
296
297
297
298
// The abstract state of a ChaCha stream, independent of implementation choices. The
298
299
// comparison and serialization of this object is considered a semver-covered part of
299
300
// the API.
300
301
#[ derive( Debug , PartialEq , Eq ) ]
301
- #[ cfg_attr(
302
- feature = "serde1" ,
303
- derive( Serialize , Deserialize ) ,
304
- ) ]
302
+ #[ cfg_attr( feature = "serde1" , derive( Serialize , Deserialize ) ) ]
305
303
pub ( crate ) struct $ChaChaXRng {
306
304
seed: [ u8 ; 32 ] ,
307
305
stream: u64 ,
@@ -331,27 +329,45 @@ macro_rules! chacha_impl {
331
329
}
332
330
}
333
331
}
334
- }
332
+ } ;
335
333
}
336
334
337
- chacha_impl ! ( ChaCha20Core , ChaCha20Rng , 10 , "ChaCha with 20 rounds" , abstract20) ;
338
- chacha_impl ! ( ChaCha12Core , ChaCha12Rng , 6 , "ChaCha with 12 rounds" , abstract12) ;
339
- chacha_impl ! ( ChaCha8Core , ChaCha8Rng , 4 , "ChaCha with 8 rounds" , abstract8) ;
335
+ chacha_impl ! (
336
+ ChaCha20Core ,
337
+ ChaCha20Rng ,
338
+ 10 ,
339
+ "ChaCha with 20 rounds" ,
340
+ abstract20
341
+ ) ;
342
+ chacha_impl ! (
343
+ ChaCha12Core ,
344
+ ChaCha12Rng ,
345
+ 6 ,
346
+ "ChaCha with 12 rounds" ,
347
+ abstract12
348
+ ) ;
349
+ chacha_impl ! (
350
+ ChaCha8Core ,
351
+ ChaCha8Rng ,
352
+ 4 ,
353
+ "ChaCha with 8 rounds" ,
354
+ abstract8
355
+ ) ;
340
356
341
357
#[ cfg( test) ]
342
358
mod test {
343
359
use rand_core:: { RngCore , SeedableRng } ;
344
360
345
- #[ cfg( feature = "serde1" ) ] use super :: { ChaCha20Rng , ChaCha12Rng , ChaCha8Rng } ;
361
+ #[ cfg( feature = "serde1" ) ] use super :: { ChaCha12Rng , ChaCha20Rng , ChaCha8Rng } ;
346
362
347
363
type ChaChaRng = super :: ChaCha20Rng ;
348
364
349
365
#[ cfg( feature = "serde1" ) ]
350
366
#[ test]
351
367
fn test_chacha_serde_roundtrip ( ) {
352
368
let seed = [
353
- 1 , 0 , 52 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 10 , 0 , 22 , 32 , 0 , 0 , 2 , 0 , 55 , 49 , 0 , 11 , 0 , 0 , 3 , 0 , 0 , 0 , 0 ,
354
- 0 , 2 , 92 ,
369
+ 1 , 0 , 52 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 10 , 0 , 22 , 32 , 0 , 0 , 2 , 0 , 55 , 49 , 0 , 11 , 0 , 0 , 3 , 0 , 0 ,
370
+ 0 , 0 , 0 , 2 , 92 ,
355
371
] ;
356
372
let mut rng1 = ChaCha20Rng :: from_seed ( seed) ;
357
373
let mut rng2 = ChaCha12Rng :: from_seed ( seed) ;
@@ -598,7 +614,7 @@ mod test {
598
614
599
615
#[ test]
600
616
fn test_chacha_word_pos_wrap_exact ( ) {
601
- use super :: { BUF_BLOCKS , BLOCK_WORDS } ;
617
+ use super :: { BLOCK_WORDS , BUF_BLOCKS } ;
602
618
let mut rng = ChaChaRng :: from_seed ( Default :: default ( ) ) ;
603
619
// refilling the buffer in set_word_pos will wrap the block counter to 0
604
620
let last_block = ( 1 << 68 ) - u128:: from ( BUF_BLOCKS * BLOCK_WORDS ) ;
0 commit comments