1use aes::BlockEncrypt;
8use aes::NewBlockCipher;
9use std::error;
10use std::fmt;
11
12pub trait RNGState {
15 fn randombytes(&mut self, x: &mut [u8]) -> Result<(), Box<dyn error::Error>>;
18 fn randombytes_init(&mut self, entropy_input: [u8; 48]);
20}
21
22#[derive(Clone, Debug, PartialEq)]
26pub struct AesState {
27 pub key: [u8; 32],
28 pub v: [u8; 16],
29 pub reseed_counter: i32,
30}
31
32impl AesState {
33 pub fn new() -> AesState {
35 AesState {
36 key: [0; 32],
37 v: [0; 16],
38 reseed_counter: 0,
39 }
40 }
41
42 fn aes256_ecb(key: &[u8; 32], ctr: &[u8; 16], buffer: &mut [u8; 16]) {
46 let cipher = aes::Aes256::new(key.into());
47 buffer.copy_from_slice(ctr);
48 cipher.encrypt_block(buffer.into());
49 }
50
51 fn aes256_ctr_update(
53 provided_data: &mut Option<[u8; 48]>,
54 key: &mut [u8; 32],
55 v: &mut [u8; 16],
56 ) {
57 let mut temp = [[0u8; 16]; 3];
58
59 for tmp in &mut temp[0..3] {
60 let count = u128::from_be_bytes(*v);
61 v.copy_from_slice(&(count + 1).to_be_bytes());
62
63 Self::aes256_ecb(key, v, tmp);
64 }
65
66 if let Some(d) = provided_data {
67 for j in 0..3 {
68 for i in 0..16 {
69 temp[j][i] ^= d[16 * j + i];
70 }
71 }
72 }
73
74 key[0..16].copy_from_slice(&temp[0]);
75 key[16..32].copy_from_slice(&temp[1]);
76 v.copy_from_slice(&temp[2]);
77 }
78}
79
80impl RNGState for AesState {
81 fn randombytes(&mut self, x: &mut [u8]) -> Result<(), Box<dyn error::Error>> {
84 for chunk in x.chunks_mut(16) {
85 let count = u128::from_be_bytes(self.v);
86 self.v.copy_from_slice(&(count + 1).to_be_bytes());
87
88 let mut block = [0u8; 16];
89 Self::aes256_ecb(&self.key, &self.v, &mut block);
90
91 (*chunk).copy_from_slice(&block[..chunk.len()]);
92 }
93
94 Self::aes256_ctr_update(&mut None, &mut self.key, &mut self.v);
95 self.reseed_counter += 1;
96
97 Ok(())
98 }
99
100 fn randombytes_init(&mut self, entropy_input: [u8; 48]) {
102 self.key = [0u8; 32];
103 self.v = [0u8; 16];
104 self.reseed_counter = 1i32;
105
106 Self::aes256_ctr_update(&mut Some(entropy_input), &mut self.key, &mut self.v);
107 self.reseed_counter = 1;
108 }
109}
110
111impl Default for AesState {
112 fn default() -> Self {
113 Self::new()
114 }
115}
116
117impl Eq for AesState {}
118
119impl fmt::Display for AesState {
120 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
121 writeln!(f, "AesState {{")?;
122 writeln!(f, " key = {:?}", self.key)?;
123 writeln!(f, " v = {:?}", self.v)?;
124 writeln!(f, " reseed_counter = {}", self.reseed_counter)?;
125 writeln!(f, "}}")
126 }
127}
128
129#[cfg(test)]
130mod tests {
131 use super::*;
132
133 #[test]
134 fn test_rng() -> Result<(), Box<dyn error::Error>> {
135 let mut data = [0u8; 256];
136 let mut entropy_input = [0u8; 48];
137 let mut personalization_string = [0u8; 48];
138 let mut rng_state = AesState::new();
139
140 for i in 0..48 {
141 entropy_input[i] = i as u8;
142 personalization_string[i] = 0 as u8;
143 }
144
145 rng_state.randombytes_init(entropy_input);
146
147 rng_state.randombytes(&mut data)?;
148 let ref1 = [
149 0x06u8, 0x15, 0x50, 0x23, 0x4D, 0x15, 0x8C, 0x5E, 0xC9, 0x55, 0x95, 0xFE, 0x04, 0xEF,
150 0x7A, 0x25, 0x76, 0x7F, 0x2E, 0x24, 0xCC, 0x2B, 0xC4, 0x79, 0xD0, 0x9D, 0x86, 0xDC,
151 0x9A, 0xBC, 0xFD, 0xE7, 0x05, 0x6A, 0x8C, 0x26, 0x6F, 0x9E, 0xF9, 0x7E, 0xD0, 0x85,
152 0x41, 0xDB, 0xD2, 0xE1, 0xFF, 0xA1, 0x98, 0x10, 0xF5, 0x39, 0x2D, 0x07, 0x62, 0x76,
153 0xEF, 0x41, 0x27, 0x7C, 0x3A, 0xB6, 0xE9, 0x4A, 0x4E, 0x3B, 0x7D, 0xCC, 0x10, 0x4A,
154 0x05, 0xBB, 0x08, 0x9D, 0x33, 0x8B, 0xF5, 0x5C, 0x72, 0xCA, 0xB3, 0x75, 0x38, 0x9A,
155 0x94, 0xBB, 0x92, 0x0B, 0xD5, 0xD6, 0xDC, 0x9E, 0x7F, 0x2E, 0xC6, 0xFD, 0xE0, 0x28,
156 0xB6, 0xF5, 0x72, 0x4B, 0xB0, 0x39, 0xF3, 0x65, 0x2A, 0xD9, 0x8D, 0xF8, 0xCE, 0x6C,
157 0x97, 0x01, 0x32, 0x10, 0xB8, 0x4B, 0xBE, 0x81, 0x38, 0x8C, 0x3D, 0x14, 0x1D, 0x61,
158 0x95, 0x7C, 0x73, 0xBC, 0xDC, 0x5E, 0x5C, 0xD9, 0x25, 0x25, 0xF4, 0x6A, 0x2B, 0x75,
159 0x7B, 0x03, 0xCA, 0xB5, 0xC3, 0x37, 0x00, 0x4A, 0x2D, 0xA3, 0x53, 0x24, 0xA3, 0x25,
160 0x71, 0x35, 0x64, 0xDA, 0xE2, 0x8F, 0x57, 0xAC, 0xC6, 0xDB, 0xE3, 0x2A, 0x07, 0x26,
161 0x19, 0x0B, 0xAA, 0x6B, 0x8A, 0x0A, 0x25, 0x5A, 0xA1, 0xAD, 0x01, 0xE8, 0xDD, 0x56,
162 0x9A, 0xA3, 0x6D, 0x09, 0x62, 0x56, 0xC4, 0x20, 0x71, 0x8A, 0x69, 0xD4, 0x6D, 0x8D,
163 0xB1, 0xC6, 0xDD, 0x40, 0x60, 0x6A, 0x0B, 0xE3, 0xC2, 0x35, 0xBE, 0xFE, 0x62, 0x3A,
164 0x90, 0x59, 0x3F, 0x82, 0xD6, 0xA8, 0xF9, 0xF9, 0x24, 0xE4, 0x4E, 0x36, 0xBE, 0x87,
165 0xF7, 0xD2, 0x6B, 0x84, 0x45, 0x96, 0x6F, 0x9E, 0xE3, 0x29, 0xC4, 0x26, 0xC1, 0x25,
166 0x21, 0xE8, 0x5F, 0x6F, 0xD4, 0xEC, 0xD5, 0xD5, 0x66, 0xBA, 0x0A, 0x34, 0x87, 0x12,
167 0x5D, 0x79, 0xCC, 0x64,
168 ];
169 assert_eq!(data, ref1);
170
171 rng_state.randombytes(&mut data)?;
172 let ref2 = [
173 0xC1u8, 0x7E, 0x03, 0x40, 0x61, 0xED, 0x5E, 0xA8, 0x17, 0xC4, 0x1D, 0x61, 0x63, 0x62,
174 0x81, 0xE8, 0x16, 0xF8, 0x17, 0xDC, 0xF7, 0x53, 0xA9, 0x1D, 0x97, 0xC0, 0x18, 0xFF,
175 0x82, 0xFB, 0xC9, 0xB1, 0x72, 0x8F, 0xC6, 0x6A, 0xF1, 0x14, 0xB5, 0x79, 0x78, 0xFB,
176 0x60, 0x82, 0xB7, 0x0D, 0x28, 0x51, 0x40, 0xB2, 0x67, 0x25, 0xAA, 0x5F, 0x7B, 0xB4,
177 0x40, 0x98, 0x20, 0xF6, 0x7E, 0x2D, 0x65, 0x6E, 0xDA, 0xCA, 0x30, 0xB5, 0xBB, 0x12,
178 0xEB, 0x52, 0x49, 0xCC, 0x38, 0x09, 0xB1, 0x88, 0xCF, 0x0C, 0xC9, 0x5B, 0x5A, 0xE0,
179 0xEF, 0xE8, 0xFC, 0x58, 0x87, 0x15, 0x2C, 0xB6, 0x60, 0x1B, 0x4C, 0xCF, 0x9F, 0xC4,
180 0x11, 0x89, 0x4F, 0xA0, 0xC0, 0x26, 0x4E, 0xB5, 0x1A, 0x48, 0x1D, 0x4D, 0x70, 0x74,
181 0xFD, 0xF0, 0x65, 0x05, 0x30, 0x30, 0xC8, 0xA9, 0x2B, 0xFC, 0xDD, 0x06, 0xBF, 0x18,
182 0xC8, 0x48, 0x9C, 0x38, 0xD0, 0x37, 0x84, 0xFD, 0x63, 0x00, 0x18, 0x30, 0xE5, 0xA3,
183 0x85, 0xA4, 0xA3, 0x78, 0x66, 0x69, 0x3F, 0x5B, 0xDA, 0xB8, 0xA8, 0xA2, 0x5B, 0x51,
184 0x9D, 0xDB, 0xF2, 0xD2, 0x82, 0x68, 0x60, 0x1D, 0x95, 0xBE, 0xED, 0x64, 0x7E, 0x43,
185 0x04, 0x84, 0xA2, 0x27, 0xC0, 0x23, 0xB0, 0x29, 0x7A, 0x28, 0x2F, 0x06, 0xC9, 0x13,
186 0x76, 0x43, 0x3B, 0xDE, 0x5E, 0xC3, 0xAB, 0xBA, 0x8C, 0x06, 0xB8, 0x30, 0xC2, 0x64,
187 0x52, 0xEA, 0x2F, 0xA7, 0xED, 0xEA, 0x8D, 0xCF, 0xE2, 0x0E, 0xAF, 0xCF, 0x89, 0x80,
188 0xB3, 0xD5, 0xAE, 0xCE, 0xF8, 0x9D, 0xD8, 0x61, 0xAC, 0xEC, 0x1F, 0x5F, 0x7C, 0xD2,
189 0xAE, 0x6B, 0x3C, 0xDE, 0x3C, 0x1D, 0x80, 0xA2, 0x83, 0x0D, 0xD0, 0xB9, 0xE8, 0x46,
190 0x8A, 0xFA, 0xD1, 0x61, 0x98, 0x10, 0x74, 0xBE, 0xB3, 0x3D, 0xF1, 0xCD, 0xFF, 0x9A,
191 0x52, 0x14, 0xF9, 0xF0,
192 ];
193 assert_eq!(data, ref2);
194
195 Ok(())
196 }
197}