Skip to content

Commit 2896dc7

Browse files
committed
Seed with an array stead of a slice
1 parent 30df574 commit 2896dc7

File tree

1 file changed

+20
-21
lines changed

1 file changed

+20
-21
lines changed

src/prng/hc128.rs

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010

1111
//! The HC-128 random number generator.
1212
13-
use core::fmt;
14-
use core::slice;
15-
13+
use core::{fmt, slice};
1614
use {Rng, SeedableRng, Rand};
1715
use 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,10 @@ 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 2^(1024*32-1) = 2^32767.
43+
/// We support seeding with a 256-bit array, which matches the 128-bit key
44+
/// concatenated with a 128-bit IV from the stream cipher.
45+
///
4246
/// ## References
4347
/// [1]: Hongjun Wu (2008). ["The Stream Cipher HC-128"]
4448
/// (http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc128_p3.pdf).
@@ -55,8 +59,7 @@ use impls;
5559
/// (http://library.isical.ac.in:8080/jspui/bitstream/123456789/6636/1/TH431.pdf).
5660
///
5761
/// [5]: Internet Engineering Task Force (Februari 2015),
58-
/// ["Prohibiting RC4 Cipher Suites"]
59-
/// (https://tools.ietf.org/html/rfc7465).
62+
/// ["Prohibiting RC4 Cipher Suites"](https://tools.ietf.org/html/rfc7465).
6063
#[derive(Clone)]
6164
pub struct Hc128Rng {
6265
state: Hc128,
@@ -89,7 +92,7 @@ impl Hc128Rng {
8992
// Initialize an HC-128 random number generator. The seed has to be
9093
// 256 bits in length (`[u32; 8]`), matching the 128 bit `key` followed by
9194
// 128 bit `iv` when HC-128 where to be used as a stream cipher.
92-
pub fn init(seed: &[u32]) -> Hc128Rng {
95+
fn init(seed: [u32; SEED_WORDS]) -> Self {
9396
#[inline]
9497
fn f1(x: u32) -> u32 {
9598
x.rotate_right(7) ^ x.rotate_right(18) ^ (x >> 3)
@@ -129,15 +132,12 @@ impl Hc128Rng {
129132
let mut state = Hc128Rng {
130133
state: Hc128 { t: t, counter1024: 0 },
131134
results: [0; 16],
132-
index: 0,
135+
index: 16, // generate on first use
133136
};
134137

135138
// run the cipher 1024 steps
136139
for _ in 0..64 { state.state.sixteen_steps() };
137140
state.state.counter1024 = 0;
138-
139-
// Prepare the first set of results
140-
state.state.update(&mut state.results);
141141
state
142142
}
143143
}
@@ -400,19 +400,18 @@ impl Rand for Hc128Rng {
400400
let slice = slice::from_raw_parts_mut(ptr, 8 * 4);
401401
other.fill_bytes(slice);
402402
}
403-
Hc128Rng::init(&seed)
403+
Hc128Rng::init(seed)
404404
}
405405
}
406406

407-
impl<'a> SeedableRng<&'a [u32]> for Hc128Rng {
408-
fn reseed(&mut self, seed: &'a [u32]) {
407+
impl SeedableRng<[u32; SEED_WORDS]> for Hc128Rng {
408+
fn reseed(&mut self, seed: [u32; SEED_WORDS]) {
409409
*self = Self::from_seed(seed);
410410
}
411411
/// Create an HC-128 random number generator with a seed. The seed has to be
412412
/// 256 bits in length, matching the 128 bit `key` followed by 128 bit `iv`
413413
/// when HC-128 where to be used as a stream cipher.
414-
fn from_seed(seed: &'a [u32]) -> Hc128Rng {
415-
assert!(seed.len() == 8);
414+
fn from_seed(seed: [u32; SEED_WORDS]) -> Hc128Rng {
416415
Hc128Rng::init(seed)
417416
}
418417
}
@@ -427,7 +426,7 @@ mod test {
427426
fn test_hc128_true_values_a() {
428427
let seed = [0u32, 0, 0, 0, // key
429428
0, 0, 0, 0]; // iv
430-
let mut rng = Hc128Rng::from_seed(&seed);
429+
let mut rng = Hc128Rng::from_seed(seed);
431430

432431
let v = (0..16).map(|_| rng.next_u32()).collect::<Vec<_>>();
433432
assert_eq!(v,
@@ -442,7 +441,7 @@ mod test {
442441
fn test_hc128_true_values_b() {
443442
let seed = [0u32, 0, 0, 0, // key
444443
1, 0, 0, 0]; // iv
445-
let mut rng = Hc128Rng::from_seed(&seed);
444+
let mut rng = Hc128Rng::from_seed(seed);
446445

447446
let v = (0..16).map(|_| rng.next_u32()).collect::<Vec<_>>();
448447
assert_eq!(v,
@@ -457,7 +456,7 @@ mod test {
457456
fn test_hc128_true_values_c() {
458457
let seed = [0x55u32, 0, 0, 0, // key
459458
0, 0, 0, 0]; // iv
460-
let mut rng = Hc128Rng::from_seed(&seed);
459+
let mut rng = Hc128Rng::from_seed(seed);
461460

462461
let v = (0..16).map(|_| rng.next_u32()).collect::<Vec<_>>();
463462
assert_eq!(v,
@@ -471,7 +470,7 @@ mod test {
471470
fn test_hc128_true_values_u64() {
472471
let seed = [0u32, 0, 0, 0, // key
473472
0, 0, 0, 0]; // iv
474-
let mut rng = Hc128Rng::from_seed(&seed);
473+
let mut rng = Hc128Rng::from_seed(seed);
475474

476475
let v = (0..8).map(|_| rng.next_u64()).collect::<Vec<_>>();
477476
assert_eq!(v,
@@ -497,7 +496,7 @@ mod test {
497496
fn test_hc128_true_values_bytes() {
498497
let seed = [0x55u32, 0, 0, 0, // key
499498
0, 0, 0, 0]; // iv
500-
let mut rng = Hc128Rng::from_seed(&seed);
499+
let mut rng = Hc128Rng::from_seed(seed);
501500
let expected =
502501
vec!(0x31, 0xf9, 0x2a, 0xb0, 0x32, 0xf0, 0x39, 0x06,
503502
0x7a, 0xa4, 0xb4, 0xbc, 0x0b, 0x48, 0x22, 0x57,
@@ -534,7 +533,7 @@ mod test {
534533
fn test_hc128_clone() {
535534
let seed = [0x55, 0, 0, 0, // key
536535
0, 0, 0, 0]; // iv
537-
let mut rng1 = Hc128Rng::from_seed(&seed);
536+
let mut rng1 = Hc128Rng::from_seed(seed);
538537
let mut rng2 = rng1.clone();
539538
for _ in 0..16 {
540539
assert_eq!(rng1.next_u32(), rng2.next_u32());

0 commit comments

Comments
 (0)