1use cryptoutil::copy_memory;
48
49use rand::{Rng, SeedableRng};
50use time::precise_time_s;
51
52use aessafe::AesSafe256Encryptor;
53use cryptoutil::read_u32_le;
54use digest::Digest;
55use sha2::Sha256;
56use symmetriccipher::BlockEncryptor;
57
58pub const MIN_POOL_SIZE: usize = 64;
62const MAX_GEN_SIZE: usize = (1 << 20);
64const KEY_LEN: usize = 32;
66const CTR_LEN: usize = 16;
68const AES_BLOCK_SIZE: usize = 16;
70const NUM_POOLS: usize = 32;
72
73struct FortunaGenerator {
75 key: [u8; KEY_LEN],
76 ctr: [u8; CTR_LEN],
77}
78
79impl FortunaGenerator {
80 fn new() -> FortunaGenerator {
82 FortunaGenerator {
83 key: [0; KEY_LEN],
84 ctr: [0; CTR_LEN],
85 }
86 }
87
88 fn increment_counter(&mut self) {
90 for i in 0..self.ctr.len() {
91 self.ctr[i] = self.ctr[i].wrapping_add(1);
92 if self.ctr[i] != 0 {
94 break;
95 }
96 }
97 }
98
99 fn reseed(&mut self, s: &[u8]) {
101 let mut hasher = Sha256::new();
103 hasher.input(&self.key[..]);
104 hasher.input(s);
105 hasher.result(&mut self.key);
106 hasher = Sha256::new();
107 hasher.input(&self.key[..]);
108 hasher.result(&mut self.key[..]);
109 self.increment_counter();
111 }
112
113 fn generate_blocks(&mut self, k: usize, out: &mut [u8]) {
116 assert!(self.ctr[..] != [0; CTR_LEN][..]);
117
118 let block_encryptor = AesSafe256Encryptor::new(&self.key[..]);
120 for j in 0..k {
122 block_encryptor.encrypt_block(&self.ctr[..],
123 &mut out[AES_BLOCK_SIZE * j..AES_BLOCK_SIZE * (j + 1)]);
124 self.increment_counter();
125 }
126 }
127
128 fn generate_random_data(&mut self, out: &mut [u8]) {
130 let (n, rem) = (out.len() / AES_BLOCK_SIZE, out.len() % AES_BLOCK_SIZE);
131 assert!(n <= MAX_GEN_SIZE);
132
133 self.generate_blocks(n, &mut out[..(n * AES_BLOCK_SIZE)]);
135 if rem > 0 {
136 let mut buf = [0; AES_BLOCK_SIZE];
137 self.generate_blocks(1, &mut buf);
138 copy_memory(&buf[..rem], &mut out[(n * AES_BLOCK_SIZE)..]);
139 }
140
141 let mut new_key = [0; KEY_LEN];
143 self.generate_blocks(KEY_LEN / AES_BLOCK_SIZE, &mut new_key);
144 self.key = new_key;
145 }
146}
147
148
149#[derive(Clone, Copy)]
151struct Pool {
152 state: Sha256,
153 count: usize
154}
155
156impl Pool {
157 fn new() -> Pool {
158 Pool { state: Sha256::new(), count: 0 }
159 }
160
161 fn input(&mut self, data: &[u8]) {
162 self.state.input(data);
163 self.count += data.len();
164 }
165
166 fn result(&mut self, output: &mut [u8]) {
167 self.state.result(output);
168 self.state = Sha256::new();
170 self.state.input(output);
171 self.state.result(output);
172 self.state = Sha256::new();
174 self.count = 0;
175 }
176}
177
178pub struct Fortuna {
180 pool: [Pool; NUM_POOLS],
181 generator: FortunaGenerator,
182 reseed_count: u32,
183 last_reseed_time: f64
184}
185
186impl Fortuna {
187 pub fn new_unseeded() -> Fortuna {
189 Fortuna {
190 pool: [Pool::new(); NUM_POOLS],
191 generator: FortunaGenerator::new(),
192 reseed_count: 0,
193 last_reseed_time: 0.0
194 }
195 }
196
197 pub fn add_random_event(&mut self, s: u8, i: usize, e: &[u8]) {
199 assert!(i <= NUM_POOLS);
200 assert!(e.len() > 0);
202 assert!(e.len() <= 32);
203 (&mut self.pool[i]).input(&[s]);
204 (&mut self.pool[i]).input(&[e.len() as u8]);
205 (&mut self.pool[i]).input(e);
206 }
207}
208
209impl Rng for Fortuna {
210 fn fill_bytes(&mut self, dest: &mut [u8]) {
218 let now = precise_time_s();
220 if self.pool[0].count >= MIN_POOL_SIZE &&
221 now - self.last_reseed_time > 0.1 {
222 self.reseed_count += 1;
223 self.last_reseed_time = now;
224 let mut hash = [0; (32 * NUM_POOLS)];
226 let mut n_pools = 0;
227 while self.reseed_count % (1 << n_pools) == 0 {
228 (&mut self.pool[n_pools]).result(&mut hash[n_pools * 32..(n_pools + 1) * 32]);
229 n_pools += 1;
230 assert!(n_pools < NUM_POOLS);
231 assert!(n_pools < 32); }
233 self.generator.reseed(&hash[..n_pools * 32]);
234 }
235 if self.reseed_count == 0 {
237 panic!("rust-crypto: an unseeded Fortuna was asked for random bytes!");
238 }
239 for dest in dest.chunks_mut(MAX_GEN_SIZE) {
241 self.generator.generate_random_data(dest);
242 }
243 }
244
245 fn next_u32(&mut self) -> u32 {
246 let mut ret = [0; 4];
247 self.fill_bytes(&mut ret);
248 read_u32_le(&ret[..])
249 }
250}
251
252
253impl<'a> SeedableRng<&'a [u8]> for Fortuna {
254 fn from_seed(seed: &'a [u8]) -> Fortuna {
255 let mut ret = Fortuna::new_unseeded();
256 ret.reseed(seed);
257 ret
258 }
259
260 fn reseed(&mut self, seed: &'a [u8]) {
261 self.reseed_count += 1;
262 self.last_reseed_time = precise_time_s();
263 self.generator.reseed(seed);
264 }
265}
266
267#[cfg(test)]
268fn test_force_reseed(f: &mut Fortuna) {
269 f.last_reseed_time -= 0.2;
270}
271
272#[cfg(test)]
273mod tests {
274 use rand::{SeedableRng, Rng};
275
276 use super::{Fortuna, Pool, NUM_POOLS, test_force_reseed};
277
278 #[test]
279 fn test_create_unseeded() {
280 let _: Fortuna = Fortuna::new_unseeded();
281 }
282
283 #[test]
284 #[should_panic]
285 fn test_use_unseeded() {
286 let mut f: Fortuna = Fortuna::new_unseeded();
287 let _ = f.next_u32();
288 }
289
290 #[test]
291 #[should_panic]
292 fn test_badly_seeded() {
293 let mut f: Fortuna = Fortuna::new_unseeded();
294 f.add_random_event(0, 0, &[10; 32]);
295 let _ = f.next_u32();
296 }
297
298 #[test]
299 #[should_panic]
300 fn test_too_big_event() {
301 let mut f: Fortuna = Fortuna::new_unseeded();
302 f.add_random_event(0, 0, &[10; 33]);
303 }
304
305 #[test]
306 fn test_seeded() {
307 let mut f1: Fortuna = SeedableRng::from_seed(&[0, 1, 2, 3, 4, 5][..]);
311 assert_eq!(f1.next_u32(), 3369034117);
312
313 let mut f2: Fortuna = Fortuna::new_unseeded();
314 f2.reseed(&[0, 1, 2, 3, 4, 5]);
315 assert_eq!(f2.next_u32(), 3369034117);
316
317 let mut f3: Fortuna = Fortuna::new_unseeded();
320 f3.reseed(&[0, 1, 2, 3, 4, 5]);
321 f3.reseed(&[0, 1, 2, 3, 4, 5]);
322 assert_eq!(f3.next_u32(), 2689122182);
323
324 let mut f4: Fortuna = Fortuna::new_unseeded();
326 f4.add_random_event(0, 0, &[10; 32]);
327 f4.add_random_event(0, 0, &[10; 32]);
328 let x = f4.next_u32();
329
330 let mut f5: Fortuna = Fortuna::new_unseeded();
331 f5.add_random_event(0, 0, &[10; 32]);
332 f5.add_random_event(0, 0, &[20; 32]);
333 let y = f5.next_u32();
334
335 let mut f6: Fortuna = Fortuna::new_unseeded();
336 f6.add_random_event(0, 0, &[20; 32]);
337 f6.add_random_event(0, 0, &[10; 32]);
338 let z = f6.next_u32();
339
340 assert!(x != y);
341 assert!(y != z);
342 assert!(x != z);
343 }
344
345 #[test]
346 fn test_generator_correctness() {
347 let mut output = [0; 100];
348 let expected = [ 82, 254, 233, 139, 254, 85, 6, 222, 222, 149,
350 120, 35, 173, 71, 89, 232, 51, 182, 252, 139,
351 153, 153, 111, 30, 16, 7, 124, 185, 159, 24,
352 50, 68, 236, 107, 133, 18, 217, 219, 46, 134,
353 169, 156, 211, 74, 163, 17, 100, 173, 26, 70,
354 246, 193, 57, 164, 167, 175, 233, 220, 160, 114,
355 2, 200, 215, 80, 207, 218, 85, 58, 235, 117,
356 177, 223, 87, 192, 50, 251, 61, 65, 141, 100,
357 59, 228, 23, 215, 58, 107, 248, 248, 103, 57,
358 127, 31, 241, 91, 230, 33, 0, 164, 77, 46];
359 let mut f: Fortuna = SeedableRng::from_seed(&[1, 2, 3, 4][..]);
360 f.fill_bytes(&mut output);
361 assert_eq!(&expected[..], &output[..]);
362
363 let mut scratch = [0; (1 << 20)];
364 f.generator.generate_random_data(&mut scratch);
365
366 let expected = [122, 164, 26, 67, 102, 65, 30, 217, 219, 113,
367 14, 86, 214, 146, 185, 17, 107, 135, 183, 7,
368 18, 162, 126, 206, 46, 38, 54, 172, 248, 194,
369 118, 84, 162, 146, 83, 156, 152, 96, 192, 15,
370 23, 224, 113, 76, 21, 8, 226, 41, 161, 171,
371 197, 180, 138, 236, 126, 137, 101, 25, 219, 225,
372 3, 189, 16, 242, 33, 91, 34, 27, 8, 171,
373 171, 115, 157, 109, 248, 198, 227, 18, 204, 211,
374 42, 184, 92, 42, 171, 222, 198, 117, 162, 134,
375 116, 109, 77, 195, 187, 139, 37, 78, 224, 63];
376 f.fill_bytes(&mut output);
377 assert_eq!(&expected[..], &output[..]);
378
379 f.reseed(&[5]);
380
381 let expected = [217, 168, 141, 167, 46, 9, 218, 188, 98, 124,
382 109, 128, 242, 22, 189, 120, 180, 124, 15, 192,
383 116, 149, 211, 136, 253, 132, 60, 3, 29, 250,
384 95, 66, 133, 195, 37, 78, 242, 255, 160, 209,
385 185, 106, 68, 105, 83, 145, 165, 72, 179, 167,
386 53, 254, 183, 251, 128, 69, 78, 156, 219, 26,
387 124, 202, 35, 9, 174, 167, 41, 128, 184, 25,
388 2, 1, 63, 142, 205, 162, 69, 68, 207, 251,
389 101, 10, 29, 33, 133, 87, 189, 36, 229, 56,
390 17, 100, 138, 49, 79, 239, 210, 189, 141, 46];
391
392 f.fill_bytes(&mut output);
393 assert_eq!(&expected[..], &output[..]);
394 }
395
396 #[test]
397 fn test_accumulator_correctness() {
398 let mut output = [0; 100];
399 let mut f = Fortuna::new_unseeded();
405 f.pool = [Pool::new(); NUM_POOLS];
406 f.add_random_event(0, 0, &[0; 32]);
407 f.add_random_event(0, 0, &[0; 32]);
408 for i in 0..32 {
409 f.add_random_event(1, i, &[1, 2]);
410 }
411
412 let expected = [ 21, 42, 103, 180, 211, 46, 177, 231, 172, 210,
420 109, 198, 34, 40, 245, 199, 76, 114, 105, 185,
421 186, 112, 183, 213, 19, 72, 186, 26, 182, 211,
422 254, 88, 67, 142, 246, 102, 80, 93, 144, 152,
423 123, 191, 168, 26, 21, 194, 69, 214, 249, 80,
424 182, 165, 203, 69, 134, 140, 11, 208, 50, 175,
425 180, 210, 110, 119, 3, 75, 1, 8, 5, 142,
426 226, 168, 179, 246, 82, 42, 223, 239, 201, 23,
427 28, 30, 195, 195, 9, 154, 31, 172, 209, 232,
428 238, 111, 75, 251, 196, 43, 217, 241, 93, 237];
429 f.fill_bytes(&mut output);
430 assert_eq!(&expected[..], &output[..]);
431
432 f.add_random_event(0, 0, &[0; 32]);
434 f.add_random_event(0, 0, &[0; 32]);
435
436 let expected = [101, 123, 175, 157, 142, 202, 211, 47, 149, 214,
440 135, 249, 148, 19, 50, 116, 169, 188, 240, 218,
441 91, 62, 35, 44, 142, 108, 95, 20, 37, 185,
442 19, 121, 128, 231, 213, 23, 94, 147, 14, 41,
443 199, 253, 246, 14, 230, 152, 11, 17, 118, 254,
444 96, 251, 171, 115, 66, 21, 196, 164, 82, 6,
445 139, 238, 135, 22, 179, 6, 6, 252, 115, 87,
446 19, 167, 56, 192, 140, 93, 132, 78, 22, 16,
447 114, 68, 123, 200, 37, 183, 163, 224, 201, 155,
448 233, 71, 111, 26, 8, 114, 232, 181, 13, 51];
449 f.fill_bytes(&mut output);
450 assert_eq!(&expected[..], &output[..]);
451
452 test_force_reseed(&mut f);
454 let expected = [ 62, 147, 205, 228, 22, 3, 225, 217, 211, 202,
457 49, 148, 236, 125, 132, 43, 25, 177, 172, 93,
458 98, 177, 112, 160, 76, 101, 60, 98, 225, 9,
459 223, 120, 161, 98, 173, 178, 71, 15, 90, 153,
460 64, 179, 143, 22, 43, 165, 87, 147, 177, 128,
461 21, 105, 214, 197, 224, 187, 22, 139, 16, 153,
462 251, 48, 244, 87, 10, 104, 119, 179, 27, 255,
463 67, 148, 192, 52, 147, 216, 79, 204, 106, 112,
464 238, 0, 239, 99, 159, 96, 184, 90, 54, 122,
465 184, 241, 221, 151, 169, 29, 197, 45, 80, 6];
466 f.fill_bytes(&mut output);
467 assert_eq!(&expected[..], &output[..]);
468 }
469}
470
471#[cfg(all(test, feature = "with-bench"))]
472mod bench {
473 use rand::{SeedableRng, Rng};
474 use test::Bencher;
475
476 use super::Fortuna;
477
478 #[bench]
479 pub fn fortuna_new_32(bh: &mut Bencher) {
480 let mut f: Fortuna = SeedableRng::from_seed(&[100; 64][..]);
481 bh.iter( || {
482 f.next_u32();
483 });
484 bh.bytes = 4;
485 }
486
487 #[bench]
488 pub fn fortuna_new_64(bh: &mut Bencher) {
489 let mut f: Fortuna = SeedableRng::from_seed(&[100; 64][..]);
490 bh.iter( || {
491 f.next_u64();
492 });
493 bh.bytes = 8;
494 }
495
496 #[bench]
497 pub fn fortuna_new_1k(bh: &mut Bencher) {
498 let mut f: Fortuna = SeedableRng::from_seed(&[100; 64][..]);
499 let mut bytes = [0u8; 1024];
500 bh.iter( || {
501 f.fill_bytes(&mut bytes);
502 });
503 bh.bytes = bytes.len() as u64;
504 }
505
506 #[bench]
507 pub fn fortuna_new_64k(bh: &mut Bencher) {
508 let mut f: Fortuna = SeedableRng::from_seed(&[100; 64][..]);
509 let mut bytes = [0u8; 65536];
510 bh.iter( || {
511 f.fill_bytes(&mut bytes);
512 });
513 bh.bytes = bytes.len() as u64;
514 }
515}