1010
1111//! The HC-128 random number generator.
1212
13- use core:: fmt;
14- use core:: slice;
15-
13+ use core:: { fmt, slice} ;
1614use { Rng , SeedableRng , Rand } ;
1715use impls;
1816
17+ const SEED_WORDS : usize = 8 ; // 128 bit key followed by 128 bit iv
18+
1919/// A cryptographically secure random number generator that uses the HC-128
2020/// algorithm.
2121///
@@ -39,6 +39,11 @@ use impls;
3939/// brute-force search of 2<sup>128</sup>. A very comprehensive analysis of the
4040/// current state of known attacks / weaknesses of HC-128 is given in [4].
4141///
42+ /// The average cycle length is expected to be
43+ /// 2<sup>1024*32-1</sup> = 2<sup>32767</sup>.
44+ /// We support seeding with a 256-bit array, which matches the 128-bit key
45+ /// concatenated with a 128-bit IV from the stream cipher.
46+ ///
4247/// ## References
4348/// [1]: Hongjun Wu (2008). ["The Stream Cipher HC-128"]
4449/// (http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc128_p3.pdf).
@@ -55,8 +60,7 @@ use impls;
5560/// (http://library.isical.ac.in:8080/jspui/bitstream/123456789/6636/1/TH431.pdf).
5661///
5762/// [5]: Internet Engineering Task Force (Februari 2015),
58- /// ["Prohibiting RC4 Cipher Suites"]
59- /// (https://tools.ietf.org/html/rfc7465).
63+ /// ["Prohibiting RC4 Cipher Suites"](https://tools.ietf.org/html/rfc7465).
6064#[ derive( Clone ) ]
6165pub struct Hc128Rng {
6266 state : Hc128 ,
@@ -89,7 +93,7 @@ impl Hc128Rng {
8993 // Initialize an HC-128 random number generator. The seed has to be
9094 // 256 bits in length (`[u32; 8]`), matching the 128 bit `key` followed by
9195 // 128 bit `iv` when HC-128 where to be used as a stream cipher.
92- pub fn init ( seed : & [ u32 ] ) -> Hc128Rng {
96+ fn init ( seed : [ u32 ; SEED_WORDS ] ) -> Self {
9397 #[ inline]
9498 fn f1 ( x : u32 ) -> u32 {
9599 x. rotate_right ( 7 ) ^ x. rotate_right ( 18 ) ^ ( x >> 3 )
@@ -129,15 +133,12 @@ impl Hc128Rng {
129133 let mut state = Hc128Rng {
130134 state : Hc128 { t : t, counter1024 : 0 } ,
131135 results : [ 0 ; 16 ] ,
132- index : 0 ,
136+ index : 16 , // generate on first use
133137 } ;
134138
135139 // run the cipher 1024 steps
136140 for _ in 0 ..64 { state. state . sixteen_steps ( ) } ;
137141 state. state . counter1024 = 0 ;
138-
139- // Prepare the first set of results
140- state. state . update ( & mut state. results ) ;
141142 state
142143 }
143144}
@@ -400,19 +401,18 @@ impl Rand for Hc128Rng {
400401 let slice = slice:: from_raw_parts_mut ( ptr, 8 * 4 ) ;
401402 other. fill_bytes ( slice) ;
402403 }
403- Hc128Rng :: init ( & seed)
404+ Hc128Rng :: init ( seed)
404405 }
405406}
406407
407- impl < ' a > SeedableRng < & ' a [ u32 ] > for Hc128Rng {
408- fn reseed ( & mut self , seed : & ' a [ u32 ] ) {
408+ impl SeedableRng < [ u32 ; SEED_WORDS ] > for Hc128Rng {
409+ fn reseed ( & mut self , seed : [ u32 ; SEED_WORDS ] ) {
409410 * self = Self :: from_seed ( seed) ;
410411 }
411412 /// Create an HC-128 random number generator with a seed. The seed has to be
412413 /// 256 bits in length, matching the 128 bit `key` followed by 128 bit `iv`
413414 /// when HC-128 where to be used as a stream cipher.
414- fn from_seed ( seed : & ' a [ u32 ] ) -> Hc128Rng {
415- assert ! ( seed. len( ) == 8 ) ;
415+ fn from_seed ( seed : [ u32 ; SEED_WORDS ] ) -> Hc128Rng {
416416 Hc128Rng :: init ( seed)
417417 }
418418}
@@ -427,7 +427,7 @@ mod test {
427427 fn test_hc128_true_values_a ( ) {
428428 let seed = [ 0u32 , 0 , 0 , 0 , // key
429429 0 , 0 , 0 , 0 ] ; // iv
430- let mut rng = Hc128Rng :: from_seed ( & seed) ;
430+ let mut rng = Hc128Rng :: from_seed ( seed) ;
431431
432432 let v = ( 0 ..16 ) . map ( |_| rng. next_u32 ( ) ) . collect :: < Vec < _ > > ( ) ;
433433 assert_eq ! ( v,
@@ -442,7 +442,7 @@ mod test {
442442 fn test_hc128_true_values_b ( ) {
443443 let seed = [ 0u32 , 0 , 0 , 0 , // key
444444 1 , 0 , 0 , 0 ] ; // iv
445- let mut rng = Hc128Rng :: from_seed ( & seed) ;
445+ let mut rng = Hc128Rng :: from_seed ( seed) ;
446446
447447 let v = ( 0 ..16 ) . map ( |_| rng. next_u32 ( ) ) . collect :: < Vec < _ > > ( ) ;
448448 assert_eq ! ( v,
@@ -457,7 +457,7 @@ mod test {
457457 fn test_hc128_true_values_c ( ) {
458458 let seed = [ 0x55u32 , 0 , 0 , 0 , // key
459459 0 , 0 , 0 , 0 ] ; // iv
460- let mut rng = Hc128Rng :: from_seed ( & seed) ;
460+ let mut rng = Hc128Rng :: from_seed ( seed) ;
461461
462462 let v = ( 0 ..16 ) . map ( |_| rng. next_u32 ( ) ) . collect :: < Vec < _ > > ( ) ;
463463 assert_eq ! ( v,
@@ -471,7 +471,7 @@ mod test {
471471 fn test_hc128_true_values_u64 ( ) {
472472 let seed = [ 0u32 , 0 , 0 , 0 , // key
473473 0 , 0 , 0 , 0 ] ; // iv
474- let mut rng = Hc128Rng :: from_seed ( & seed) ;
474+ let mut rng = Hc128Rng :: from_seed ( seed) ;
475475
476476 let v = ( 0 ..8 ) . map ( |_| rng. next_u64 ( ) ) . collect :: < Vec < _ > > ( ) ;
477477 assert_eq ! ( v,
@@ -497,7 +497,7 @@ mod test {
497497 fn test_hc128_true_values_bytes ( ) {
498498 let seed = [ 0x55u32 , 0 , 0 , 0 , // key
499499 0 , 0 , 0 , 0 ] ; // iv
500- let mut rng = Hc128Rng :: from_seed ( & seed) ;
500+ let mut rng = Hc128Rng :: from_seed ( seed) ;
501501 let expected =
502502 vec ! ( 0x31 , 0xf9 , 0x2a , 0xb0 , 0x32 , 0xf0 , 0x39 , 0x06 ,
503503 0x7a , 0xa4 , 0xb4 , 0xbc , 0x0b , 0x48 , 0x22 , 0x57 ,
@@ -534,7 +534,7 @@ mod test {
534534 fn test_hc128_clone ( ) {
535535 let seed = [ 0x55 , 0 , 0 , 0 , // key
536536 0 , 0 , 0 , 0 ] ; // iv
537- let mut rng1 = Hc128Rng :: from_seed ( & seed) ;
537+ let mut rng1 = Hc128Rng :: from_seed ( seed) ;
538538 let mut rng2 = rng1. clone ( ) ;
539539 for _ in 0 ..16 {
540540 assert_eq ! ( rng1. next_u32( ) , rng2. next_u32( ) ) ;
0 commit comments