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 , 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 ;
@@ -68,7 +69,7 @@ impl<T> fmt::Debug for Array64<T> {
68
69
}
69
70
70
71
macro_rules! chacha_impl {
71
- ( $ChaChaXCore: ident, $ChaChaXRng: ident, $rounds: expr, $doc: expr, $abst: ident) => {
72
+ ( $ChaChaXCore: ident, $ChaChaXRng: ident, $rounds: expr, $doc: expr, $abst: ident, ) => {
72
73
#[ doc=$doc]
73
74
#[ derive( Clone , PartialEq , Eq ) ]
74
75
pub struct $ChaChaXCore {
@@ -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,18 +166,16 @@ 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
}
171
- #[ inline]
172
- fn try_fill_bytes( & mut self , bytes: & mut [ u8 ] ) -> Result <( ) , Error > {
173
- self . rng. try_fill_bytes( bytes)
174
- }
175
179
}
176
180
177
181
impl $ChaChaXRng {
@@ -209,11 +213,9 @@ macro_rules! chacha_impl {
209
213
#[ inline]
210
214
pub fn set_word_pos( & mut self , word_offset: u128 ) {
211
215
let block = ( word_offset / u128 :: from( BLOCK_WORDS ) ) as u64 ;
216
+ self . rng. core. state. set_block_pos( block) ;
212
217
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 ) ;
218
+ . generate_and_set( ( word_offset % u128 :: from( BLOCK_WORDS ) ) as usize ) ;
217
219
}
218
220
219
221
/// Set the stream number.
@@ -229,10 +231,7 @@ macro_rules! chacha_impl {
229
231
/// indirectly via `set_word_pos`), but this is not directly supported.
230
232
#[ inline]
231
233
pub fn set_stream( & mut self , stream: u64 ) {
232
- self . rng
233
- . core
234
- . state
235
- . set_nonce( stream) ;
234
+ self . rng. core. state. set_nonce( stream) ;
236
235
if self . rng. index( ) != 64 {
237
236
let wp = self . get_word_pos( ) ;
238
237
self . set_word_pos( wp) ;
@@ -242,24 +241,20 @@ macro_rules! chacha_impl {
242
241
/// Get the stream number.
243
242
#[ inline]
244
243
pub fn get_stream( & self ) -> u64 {
245
- self . rng
246
- . core
247
- . state
248
- . get_nonce( )
244
+ self . rng. core. state. get_nonce( )
249
245
}
250
246
251
247
/// Get the seed.
252
248
#[ inline]
253
249
pub fn get_seed( & self ) -> [ u8 ; 32 ] {
254
- self . rng
255
- . core
256
- . state
257
- . get_seed( )
250
+ self . rng. core. state. get_seed( )
258
251
}
259
252
}
260
253
261
254
impl CryptoRng for $ChaChaXRng { }
262
255
256
+ rand_core:: impl_try_crypto_rng_from_crypto_rng!( $ChaChaXRng) ;
257
+
263
258
impl From <$ChaChaXCore> for $ChaChaXRng {
264
259
fn from( core: $ChaChaXCore) -> Self {
265
260
$ChaChaXRng {
@@ -286,22 +281,20 @@ macro_rules! chacha_impl {
286
281
}
287
282
#[ cfg( feature = "serde1" ) ]
288
283
impl <' de> Deserialize <' de> for $ChaChaXRng {
289
- fn deserialize<D >( d: D ) -> Result <Self , D :: Error > where D : Deserializer <' de> {
284
+ fn deserialize<D >( d: D ) -> Result <Self , D :: Error >
285
+ where D : Deserializer <' de> {
290
286
$abst:: $ChaChaXRng:: deserialize( d) . map( |x| Self :: from( & x) )
291
287
}
292
288
}
293
289
294
290
mod $abst {
295
- #[ cfg( feature = "serde1" ) ] use serde:: { Serialize , Deserialize } ;
291
+ #[ cfg( feature = "serde1" ) ] use serde:: { Deserialize , Serialize } ;
296
292
297
293
// The abstract state of a ChaCha stream, independent of implementation choices. The
298
294
// comparison and serialization of this object is considered a semver-covered part of
299
295
// the API.
300
296
#[ derive( Debug , PartialEq , Eq ) ]
301
- #[ cfg_attr(
302
- feature = "serde1" ,
303
- derive( Serialize , Deserialize ) ,
304
- ) ]
297
+ #[ cfg_attr( feature = "serde1" , derive( Serialize , Deserialize ) ) ]
305
298
pub ( crate ) struct $ChaChaXRng {
306
299
seed: [ u8 ; 32 ] ,
307
300
stream: u64 ,
@@ -331,27 +324,45 @@ macro_rules! chacha_impl {
331
324
}
332
325
}
333
326
}
334
- }
327
+ } ;
335
328
}
336
329
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) ;
330
+ chacha_impl ! (
331
+ ChaCha20Core ,
332
+ ChaCha20Rng ,
333
+ 10 ,
334
+ "ChaCha with 20 rounds" ,
335
+ abstract20,
336
+ ) ;
337
+ chacha_impl ! (
338
+ ChaCha12Core ,
339
+ ChaCha12Rng ,
340
+ 6 ,
341
+ "ChaCha with 12 rounds" ,
342
+ abstract12,
343
+ ) ;
344
+ chacha_impl ! (
345
+ ChaCha8Core ,
346
+ ChaCha8Rng ,
347
+ 4 ,
348
+ "ChaCha with 8 rounds" ,
349
+ abstract8,
350
+ ) ;
340
351
341
352
#[ cfg( test) ]
342
353
mod test {
343
354
use rand_core:: { RngCore , SeedableRng } ;
344
355
345
- #[ cfg( feature = "serde1" ) ] use super :: { ChaCha20Rng , ChaCha12Rng , ChaCha8Rng } ;
356
+ #[ cfg( feature = "serde1" ) ] use super :: { ChaCha12Rng , ChaCha20Rng , ChaCha8Rng } ;
346
357
347
358
type ChaChaRng = super :: ChaCha20Rng ;
348
359
349
360
#[ cfg( feature = "serde1" ) ]
350
361
#[ test]
351
362
fn test_chacha_serde_roundtrip ( ) {
352
363
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 ,
364
+ 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 ,
365
+ 0 , 0 , 0 , 2 , 92 ,
355
366
] ;
356
367
let mut rng1 = ChaCha20Rng :: from_seed ( seed) ;
357
368
let mut rng2 = ChaCha12Rng :: from_seed ( seed) ;
@@ -388,7 +399,7 @@ mod test {
388
399
#[ test]
389
400
fn test_chacha_serde_format_stability ( ) {
390
401
let j = r#"{"seed":[4,8,15,16,23,42,4,8,15,16,23,42,4,8,15,16,23,42,4,8,15,16,23,42,4,8,15,16,23,42,4,8],"stream":27182818284,"word_pos":314159265359}"# ;
391
- let r: ChaChaRng = serde_json:: from_str ( & j) . unwrap ( ) ;
402
+ let r: ChaChaRng = serde_json:: from_str ( j) . unwrap ( ) ;
392
403
let j1 = serde_json:: to_string ( & r) . unwrap ( ) ;
393
404
assert_eq ! ( j, j1) ;
394
405
}
@@ -402,7 +413,7 @@ mod test {
402
413
let mut rng1 = ChaChaRng :: from_seed ( seed) ;
403
414
assert_eq ! ( rng1. next_u32( ) , 137206642 ) ;
404
415
405
- let mut rng2 = ChaChaRng :: from_rng ( rng1) . unwrap ( ) ;
416
+ let mut rng2 = ChaChaRng :: from_rng ( & mut rng1) ;
406
417
assert_eq ! ( rng2. next_u32( ) , 1325750369 ) ;
407
418
}
408
419
@@ -598,7 +609,7 @@ mod test {
598
609
599
610
#[ test]
600
611
fn test_chacha_word_pos_wrap_exact ( ) {
601
- use super :: { BUF_BLOCKS , BLOCK_WORDS } ;
612
+ use super :: { BLOCK_WORDS , BUF_BLOCKS } ;
602
613
let mut rng = ChaChaRng :: from_seed ( Default :: default ( ) ) ;
603
614
// refilling the buffer in set_word_pos will wrap the block counter to 0
604
615
let last_block = ( 1 << 68 ) - u128:: from ( BUF_BLOCKS * BLOCK_WORDS ) ;
0 commit comments