Skip to content

Commit 7f42739

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

File tree

1 file changed

+21
-21
lines changed

1 file changed

+21
-21
lines changed

src/prng/hc128.rs

Lines changed: 21 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,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)]
6165
pub 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

Comments
 (0)