1#![allow(dead_code)]
20
21pub struct Rng {
22 pub s:u64, pub a:u64, pub b:u64, pub c:u64, }
27impl Rng {
28
29 pub fn new( init:Option<[u8;32]> ) -> Rng {
30 let newrng:Rng;
31 let mut eb:[u8;32];
32
33 match init {
34 Some(data) => {
35 eb = data;
36 }
37 None => {
38 eb = [0u8;32];
39 match getrandom::getrandom(&mut eb) {
40 Ok(_x) => {},
41 Err(x) => {panic!("nz::Rng::new() Cannot seed the RNG in a secure manner.\n{:?}", x)}
42 }
43 }
44 };
45
46 let mut bytes = [0u64;4];
47 bytes[0] = u64::from_be_bytes( [eb[0], eb[1], eb[2], eb[3], eb[4], eb[5], eb[6], eb[7]] );
48 bytes[1] = u64::from_be_bytes( [eb[8], eb[9], eb[10], eb[11], eb[12], eb[13], eb[14], eb[15]] );
49 bytes[2] = u64::from_be_bytes( [eb[16], eb[17], eb[18], eb[19], eb[20], eb[21], eb[22], eb[23]] );
50 bytes[3] = u64::from_be_bytes( [eb[24], eb[25], eb[26], eb[27], eb[28], eb[29], eb[30], eb[31]] );
51
52 newrng = Rng {
53 a:bytes[0],
54 b:bytes[1],
55 c:bytes[2],
56 s:bytes[3],
57 };
58
59 return newrng;
60 }
61
62 pub fn get(&mut self) -> u64 {
63 let output = self.a ^ self.b ^ self.c;
64 self.s += 1;
65
66 if self.s % 1024 == 0 {
67 let temp = self.a;
68 self.a = self.c;
69 self.c = temp;
70 }
71 if self.s % 64 == 0 {
72 self.b = ( self.b << 13 ) | ( self.b >> ( 64 - 13 ) );
73 }
74
75 self.a = (self.a << 11) | (self.a >> (64 - 11));
76 self.c = ( ( self.c << 17 ) | ( self.c >> ( 64 - 17 ) ) ).wrapping_add(output);
77
78
79
80 return output;
81 }
82
83}