1use core::fmt;
12use rand_core::{CryptoRng, RngCore, SeedableRng, Error, le};
13use rand_core::block::{BlockRngCore, BlockRng};
14
15const SEED_WORDS: usize = 8; #[derive(Clone, Debug)]
70pub struct Hc128Rng(BlockRng<Hc128Core>);
71
72impl RngCore for Hc128Rng {
73 #[inline(always)]
74 fn next_u32(&mut self) -> u32 {
75 self.0.next_u32()
76 }
77
78 #[inline(always)]
79 fn next_u64(&mut self) -> u64 {
80 self.0.next_u64()
81 }
82
83 fn fill_bytes(&mut self, dest: &mut [u8]) {
84 self.0.fill_bytes(dest)
85 }
86
87 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
88 self.0.try_fill_bytes(dest)
89 }
90}
91
92impl SeedableRng for Hc128Rng {
93 type Seed = <Hc128Core as SeedableRng>::Seed;
94
95 fn from_seed(seed: Self::Seed) -> Self {
96 Hc128Rng(BlockRng::<Hc128Core>::from_seed(seed))
97 }
98
99 fn from_rng<R: RngCore>(rng: R) -> Result<Self, Error> {
100 BlockRng::<Hc128Core>::from_rng(rng).map(Hc128Rng)
101 }
102}
103
104impl CryptoRng for Hc128Rng {}
105
106#[derive(Clone)]
108pub struct Hc128Core {
109 t: [u32; 1024],
110 counter1024: usize,
111}
112
113impl fmt::Debug for Hc128Core {
115 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
116 write!(f, "Hc128Core {{}}")
117 }
118}
119
120impl BlockRngCore for Hc128Core {
121 type Item = u32;
122 type Results = [u32; 16];
123
124 fn generate(&mut self, results: &mut Self::Results) {
125 assert!(self.counter1024 % 16 == 0);
126
127 let cc = self.counter1024 % 512;
128 let dd = (cc + 16) % 512;
129 let ee = cc.wrapping_sub(16) % 512;
130
131 if self.counter1024 & 512 == 0 {
132 results[0] = self.step_p(cc+0, cc+1, ee+13, ee+6, ee+4);
134 results[1] = self.step_p(cc+1, cc+2, ee+14, ee+7, ee+5);
135 results[2] = self.step_p(cc+2, cc+3, ee+15, ee+8, ee+6);
136 results[3] = self.step_p(cc+3, cc+4, cc+0, ee+9, ee+7);
137 results[4] = self.step_p(cc+4, cc+5, cc+1, ee+10, ee+8);
138 results[5] = self.step_p(cc+5, cc+6, cc+2, ee+11, ee+9);
139 results[6] = self.step_p(cc+6, cc+7, cc+3, ee+12, ee+10);
140 results[7] = self.step_p(cc+7, cc+8, cc+4, ee+13, ee+11);
141 results[8] = self.step_p(cc+8, cc+9, cc+5, ee+14, ee+12);
142 results[9] = self.step_p(cc+9, cc+10, cc+6, ee+15, ee+13);
143 results[10] = self.step_p(cc+10, cc+11, cc+7, cc+0, ee+14);
144 results[11] = self.step_p(cc+11, cc+12, cc+8, cc+1, ee+15);
145 results[12] = self.step_p(cc+12, cc+13, cc+9, cc+2, cc+0);
146 results[13] = self.step_p(cc+13, cc+14, cc+10, cc+3, cc+1);
147 results[14] = self.step_p(cc+14, cc+15, cc+11, cc+4, cc+2);
148 results[15] = self.step_p(cc+15, dd+0, cc+12, cc+5, cc+3);
149 } else {
150 results[0] = self.step_q(cc+0, cc+1, ee+13, ee+6, ee+4);
152 results[1] = self.step_q(cc+1, cc+2, ee+14, ee+7, ee+5);
153 results[2] = self.step_q(cc+2, cc+3, ee+15, ee+8, ee+6);
154 results[3] = self.step_q(cc+3, cc+4, cc+0, ee+9, ee+7);
155 results[4] = self.step_q(cc+4, cc+5, cc+1, ee+10, ee+8);
156 results[5] = self.step_q(cc+5, cc+6, cc+2, ee+11, ee+9);
157 results[6] = self.step_q(cc+6, cc+7, cc+3, ee+12, ee+10);
158 results[7] = self.step_q(cc+7, cc+8, cc+4, ee+13, ee+11);
159 results[8] = self.step_q(cc+8, cc+9, cc+5, ee+14, ee+12);
160 results[9] = self.step_q(cc+9, cc+10, cc+6, ee+15, ee+13);
161 results[10] = self.step_q(cc+10, cc+11, cc+7, cc+0, ee+14);
162 results[11] = self.step_q(cc+11, cc+12, cc+8, cc+1, ee+15);
163 results[12] = self.step_q(cc+12, cc+13, cc+9, cc+2, cc+0);
164 results[13] = self.step_q(cc+13, cc+14, cc+10, cc+3, cc+1);
165 results[14] = self.step_q(cc+14, cc+15, cc+11, cc+4, cc+2);
166 results[15] = self.step_q(cc+15, dd+0, cc+12, cc+5, cc+3);
167 }
168 self.counter1024 = self.counter1024.wrapping_add(16);
169 }
170}
171
172impl Hc128Core {
173 #[inline(always)]
175 fn step_p(&mut self, i: usize, i511: usize, i3: usize, i10: usize, i12: usize)
176 -> u32
177 {
178 let (p, q) = self.t.split_at_mut(512);
179 unsafe {
183 let temp0 = p.get_unchecked(i511).rotate_right(23);
184 let temp1 = p.get_unchecked(i3).rotate_right(10);
185 let temp2 = p.get_unchecked(i10).rotate_right(8);
186 *p.get_unchecked_mut(i) = p.get_unchecked(i)
187 .wrapping_add(temp2)
188 .wrapping_add(temp0 ^ temp1);
189 let temp3 = {
190 let a = *p.get_unchecked(i12) as u8;
192 let c = (p.get_unchecked(i12) >> 16) as u8;
193 q[a as usize].wrapping_add(q[256 + c as usize])
194 };
195 temp3 ^ p.get_unchecked(i)
196 }
197 }
198
199 #[inline(always)]
203 fn step_q(&mut self, i: usize, i511: usize, i3: usize, i10: usize, i12: usize)
204 -> u32
205 {
206 let (p, q) = self.t.split_at_mut(512);
207 unsafe {
208 let temp0 = q.get_unchecked(i511).rotate_left(23);
209 let temp1 = q.get_unchecked(i3).rotate_left(10);
210 let temp2 = q.get_unchecked(i10).rotate_left(8);
211 *q.get_unchecked_mut(i) = q.get_unchecked(i)
212 .wrapping_add(temp2)
213 .wrapping_add(temp0 ^ temp1);
214 let temp3 = {
215 let a = *q.get_unchecked(i12) as u8;
217 let c = (q.get_unchecked(i12) >> 16) as u8;
218 p[a as usize].wrapping_add(p[256 + c as usize])
219 };
220 temp3 ^ q.get_unchecked(i)
221 }
222 }
223
224 fn sixteen_steps(&mut self) {
225 assert!(self.counter1024 % 16 == 0);
226
227 let cc = self.counter1024 % 512;
228 let dd = (cc + 16) % 512;
229 let ee = cc.wrapping_sub(16) % 512;
230
231 if self.counter1024 < 512 {
232 self.t[cc+0] = self.step_p(cc+0, cc+1, ee+13, ee+6, ee+4);
234 self.t[cc+1] = self.step_p(cc+1, cc+2, ee+14, ee+7, ee+5);
235 self.t[cc+2] = self.step_p(cc+2, cc+3, ee+15, ee+8, ee+6);
236 self.t[cc+3] = self.step_p(cc+3, cc+4, cc+0, ee+9, ee+7);
237 self.t[cc+4] = self.step_p(cc+4, cc+5, cc+1, ee+10, ee+8);
238 self.t[cc+5] = self.step_p(cc+5, cc+6, cc+2, ee+11, ee+9);
239 self.t[cc+6] = self.step_p(cc+6, cc+7, cc+3, ee+12, ee+10);
240 self.t[cc+7] = self.step_p(cc+7, cc+8, cc+4, ee+13, ee+11);
241 self.t[cc+8] = self.step_p(cc+8, cc+9, cc+5, ee+14, ee+12);
242 self.t[cc+9] = self.step_p(cc+9, cc+10, cc+6, ee+15, ee+13);
243 self.t[cc+10] = self.step_p(cc+10, cc+11, cc+7, cc+0, ee+14);
244 self.t[cc+11] = self.step_p(cc+11, cc+12, cc+8, cc+1, ee+15);
245 self.t[cc+12] = self.step_p(cc+12, cc+13, cc+9, cc+2, cc+0);
246 self.t[cc+13] = self.step_p(cc+13, cc+14, cc+10, cc+3, cc+1);
247 self.t[cc+14] = self.step_p(cc+14, cc+15, cc+11, cc+4, cc+2);
248 self.t[cc+15] = self.step_p(cc+15, dd+0, cc+12, cc+5, cc+3);
249 } else {
250 self.t[cc+512+0] = self.step_q(cc+0, cc+1, ee+13, ee+6, ee+4);
252 self.t[cc+512+1] = self.step_q(cc+1, cc+2, ee+14, ee+7, ee+5);
253 self.t[cc+512+2] = self.step_q(cc+2, cc+3, ee+15, ee+8, ee+6);
254 self.t[cc+512+3] = self.step_q(cc+3, cc+4, cc+0, ee+9, ee+7);
255 self.t[cc+512+4] = self.step_q(cc+4, cc+5, cc+1, ee+10, ee+8);
256 self.t[cc+512+5] = self.step_q(cc+5, cc+6, cc+2, ee+11, ee+9);
257 self.t[cc+512+6] = self.step_q(cc+6, cc+7, cc+3, ee+12, ee+10);
258 self.t[cc+512+7] = self.step_q(cc+7, cc+8, cc+4, ee+13, ee+11);
259 self.t[cc+512+8] = self.step_q(cc+8, cc+9, cc+5, ee+14, ee+12);
260 self.t[cc+512+9] = self.step_q(cc+9, cc+10, cc+6, ee+15, ee+13);
261 self.t[cc+512+10] = self.step_q(cc+10, cc+11, cc+7, cc+0, ee+14);
262 self.t[cc+512+11] = self.step_q(cc+11, cc+12, cc+8, cc+1, ee+15);
263 self.t[cc+512+12] = self.step_q(cc+12, cc+13, cc+9, cc+2, cc+0);
264 self.t[cc+512+13] = self.step_q(cc+13, cc+14, cc+10, cc+3, cc+1);
265 self.t[cc+512+14] = self.step_q(cc+14, cc+15, cc+11, cc+4, cc+2);
266 self.t[cc+512+15] = self.step_q(cc+15, dd+0, cc+12, cc+5, cc+3);
267 }
268 self.counter1024 += 16;
269 }
270
271 fn init(seed: [u32; SEED_WORDS]) -> Self {
275 #[inline]
276 fn f1(x: u32) -> u32 {
277 x.rotate_right(7) ^ x.rotate_right(18) ^ (x >> 3)
278 }
279
280 #[inline]
281 fn f2(x: u32) -> u32 {
282 x.rotate_right(17) ^ x.rotate_right(19) ^ (x >> 10)
283 }
284
285 let mut t = [0u32; 1024];
286
287 let (key, iv) = seed.split_at(4);
289 t[..4].copy_from_slice(key);
290 t[4..8].copy_from_slice(key);
291 t[8..12].copy_from_slice(iv);
292 t[12..16].copy_from_slice(iv);
293
294 for i in 16..256+16 {
297 t[i] = f2(t[i-2]).wrapping_add(t[i-7]).wrapping_add(f1(t[i-15]))
298 .wrapping_add(t[i-16]).wrapping_add(i as u32);
299 }
300 {
301 let (p1, p2) = t.split_at_mut(256);
302 p1[0..16].copy_from_slice(&p2[0..16]);
303 }
304
305 for i in 16..1024 {
307 t[i] = f2(t[i-2]).wrapping_add(t[i-7]).wrapping_add(f1(t[i-15]))
308 .wrapping_add(t[i-16]).wrapping_add(256 + i as u32);
309 }
310
311 let mut core = Self { t, counter1024: 0 };
312
313 for _ in 0..64 { core.sixteen_steps() };
315 core.counter1024 = 0;
316 core
317 }
318}
319
320impl SeedableRng for Hc128Core {
321 type Seed = [u8; SEED_WORDS*4];
322
323 fn from_seed(seed: Self::Seed) -> Self {
327 let mut seed_u32 = [0u32; SEED_WORDS];
328 le::read_u32_into(&seed, &mut seed_u32);
329 Self::init(seed_u32)
330 }
331}
332
333impl CryptoRng for Hc128Core {}
334
335#[cfg(test)]
336mod test {
337 use ::rand_core::{RngCore, SeedableRng};
338 use super::Hc128Rng;
339
340 #[test]
341 fn test_hc128_true_values_a() {
343 let seed = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0]; let mut rng = Hc128Rng::from_seed(seed);
346
347 let mut results = [0u32; 16];
348 for i in results.iter_mut() { *i = rng.next_u32(); }
349 let expected = [0x73150082, 0x3bfd03a0, 0xfb2fd77f, 0xaa63af0e,
350 0xde122fc6, 0xa7dc29b6, 0x62a68527, 0x8b75ec68,
351 0x9036db1e, 0x81896005, 0x00ade078, 0x491fbf9a,
352 0x1cdc3013, 0x6c3d6e24, 0x90f664b2, 0x9cd57102];
353 assert_eq!(results, expected);
354 }
355
356 #[test]
357 fn test_hc128_true_values_b() {
359 let seed = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0]; let mut rng = Hc128Rng::from_seed(seed);
362
363 let mut results = [0u32; 16];
364 for i in results.iter_mut() { *i = rng.next_u32(); }
365 let expected = [0xc01893d5, 0xb7dbe958, 0x8f65ec98, 0x64176604,
366 0x36fc6724, 0xc82c6eec, 0x1b1c38a7, 0xc9b42a95,
367 0x323ef123, 0x0a6a908b, 0xce757b68, 0x9f14f7bb,
368 0xe4cde011, 0xaeb5173f, 0x89608c94, 0xb5cf46ca];
369 assert_eq!(results, expected);
370 }
371
372 #[test]
373 fn test_hc128_true_values_c() {
375 let seed = [0x55,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0]; let mut rng = Hc128Rng::from_seed(seed);
378
379 let mut results = [0u32; 16];
380 for i in results.iter_mut() { *i = rng.next_u32(); }
381 let expected = [0x518251a4, 0x04b4930a, 0xb02af931, 0x0639f032,
382 0xbcb4a47a, 0x5722480b, 0x2bf99f72, 0xcdc0e566,
383 0x310f0c56, 0xd3cc83e8, 0x663db8ef, 0x62dfe07f,
384 0x593e1790, 0xc5ceaa9c, 0xab03806f, 0xc9a6e5a0];
385 assert_eq!(results, expected);
386 }
387
388 #[test]
389 fn test_hc128_true_values_u64() {
390 let seed = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0]; let mut rng = Hc128Rng::from_seed(seed);
393
394 let mut results = [0u64; 8];
395 for i in results.iter_mut() { *i = rng.next_u64(); }
396 let expected = [0x3bfd03a073150082, 0xaa63af0efb2fd77f,
397 0xa7dc29b6de122fc6, 0x8b75ec6862a68527,
398 0x818960059036db1e, 0x491fbf9a00ade078,
399 0x6c3d6e241cdc3013, 0x9cd5710290f664b2];
400 assert_eq!(results, expected);
401
402 for _ in 0..800 { rng.next_u64(); }
406
407 for i in results.iter_mut() { *i = rng.next_u64(); }
408 let expected = [0xd8c4d6ca84d0fc10, 0xf16a5d91dc66e8e7,
409 0xd800de5bc37a8653, 0x7bae1f88c0dfbb4c,
410 0x3bfe1f374e6d4d14, 0x424b55676be3fa06,
411 0xe3a1e8758cbff579, 0x417f7198c5652bcd];
412 assert_eq!(results, expected);
413 }
414
415 #[test]
416 fn test_hc128_true_values_bytes() {
417 let seed = [0x55,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0]; let mut rng = Hc128Rng::from_seed(seed);
420 let expected = [0x31, 0xf9, 0x2a, 0xb0, 0x32, 0xf0, 0x39, 0x06,
421 0x7a, 0xa4, 0xb4, 0xbc, 0x0b, 0x48, 0x22, 0x57,
422 0x72, 0x9f, 0xf9, 0x2b, 0x66, 0xe5, 0xc0, 0xcd,
423 0x56, 0x0c, 0x0f, 0x31, 0xe8, 0x83, 0xcc, 0xd3,
424 0xef, 0xb8, 0x3d, 0x66, 0x7f, 0xe0, 0xdf, 0x62,
425 0x90, 0x17, 0x3e, 0x59, 0x9c, 0xaa, 0xce, 0xc5,
426 0x6f, 0x80, 0x03, 0xab, 0xa0, 0xe5, 0xa6, 0xc9,
427 0x60, 0x95, 0x84, 0x7a, 0xa5, 0x68, 0x5a, 0x84,
428 0xea, 0xd5, 0xf3, 0xea, 0x73, 0xa9, 0xad, 0x01,
429 0x79, 0x7d, 0xbe, 0x9f, 0xea, 0xe3, 0xf9, 0x74,
430 0x0e, 0xda, 0x2f, 0xa0, 0xe4, 0x7b, 0x4b, 0x1b,
431 0xdd, 0x17, 0x69, 0x4a, 0xfe, 0x9f, 0x56, 0x95,
432 0xad, 0x83, 0x6b, 0x9d, 0x60, 0xa1, 0x99, 0x96,
433 0x90, 0x00, 0x66, 0x7f, 0xfa, 0x7e, 0x65, 0xe9,
434 0xac, 0x8b, 0x92, 0x34, 0x77, 0xb4, 0x23, 0xd0,
435 0xb9, 0xab, 0xb1, 0x47, 0x7d, 0x4a, 0x13, 0x0a];
436
437 let mut buffer = [0u8; 16*4*2];
441 assert!(rng.next_u64() == 0x04b4930a518251a4);
443 rng.fill_bytes(&mut buffer);
444
445 assert_eq!(buffer.len(), expected.len());
447 for (b, e) in buffer.iter().zip(expected.iter()) {
448 assert_eq!(b, e);
449 }
450 }
451
452 #[test]
453 fn test_hc128_clone() {
454 let seed = [0x55,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0]; let mut rng1 = Hc128Rng::from_seed(seed);
457 let mut rng2 = rng1.clone();
458 for _ in 0..16 {
459 assert_eq!(rng1.next_u32(), rng2.next_u32());
460 }
461 }
462}