1use std::convert::TryInto;
2
3const NB: usize = 4;
4pub const BLOCK_SIZE: usize = NB << 2;
5const S_BOX: [u8; 256] = [
6 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
7 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
8 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
9 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
10 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
11 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
12 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
13 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
14 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
15 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
16 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
17 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
18 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
19 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
20 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
21 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16,
22];
23const INV_S_BOX: [u8; 256] = [
24 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
25 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
26 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
27 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
28 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
29 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
30 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
31 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
32 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
33 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
34 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
35 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
36 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
37 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
38 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
39 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d,
40];
41
42pub fn encrypt(input: &[u8; BLOCK_SIZE], cipher_key: &[u8]) -> [u8; 16] {
43 let mut state = bytes2block(input);
44 let w = key_expansion(cipher_key);
45 let round_keys_len = w.len() >> 4;
46 let mut round_key_start = 0;
47
48 let mut round = 1;
49 loop {
50 add_round_key(
51 &mut state,
52 &w[round_key_start..round_key_start + BLOCK_SIZE],
53 );
54 round_key_start += BLOCK_SIZE;
55 round += 1;
56
57 sub_bytes(&mut state);
58 shift_rows(&mut state);
59 if round == round_keys_len {
60 break;
61 }
62 mix_columns(&mut state);
63 }
64
65 add_round_key(&mut state, &w[round_key_start..]);
66 block2bytes(&state)
67}
68
69pub fn decrypt_straight(input: &[u8; BLOCK_SIZE], cipher_key: &[u8]) -> [u8; 16] {
71 let mut state = bytes2block(input);
72 let w = key_expansion(cipher_key);
73 let round_keys_len = w.len() >> 4;
74 let mut round_key_end = w.len() - BLOCK_SIZE;
75 add_round_key(&mut state, &w[round_key_end..]);
76 for _ in (2..round_keys_len).rev() {
77 inv_shift_rows(&mut state);
78 inv_sub_bytes(&mut state);
79 add_round_key(&mut state, &w[round_key_end - BLOCK_SIZE..round_key_end]);
80 round_key_end -= BLOCK_SIZE;
81 inv_mix_columns(&mut state);
82 }
83
84 inv_shift_rows(&mut state);
85 inv_sub_bytes(&mut state);
86 add_round_key(&mut state, &w[..BLOCK_SIZE]);
87 block2bytes(&state)
88}
89
90pub fn decrypt(input: &[u8; BLOCK_SIZE], cipher_key: &[u8]) -> [u8; 16] {
91 let mut state = bytes2block(input);
92 let w = key_expansion_inv(cipher_key);
93 let round_keys_len = w.len() >> 4;
94 let mut round_key_start = w.len() - BLOCK_SIZE;
95
96 let mut round = round_keys_len;
97 loop {
98 add_round_key(
99 &mut state,
100 &w[round_key_start..round_key_start + BLOCK_SIZE],
101 );
102 round_key_start -= BLOCK_SIZE;
103 round -= 1;
104 inv_sub_bytes(&mut state);
105 inv_shift_rows(&mut state);
106 if round == 1 {
107 break;
108 }
109 inv_mix_columns(&mut state);
110 }
111
112 add_round_key(&mut state, &w[..BLOCK_SIZE]);
113 block2bytes(&state)
114}
115
116fn bytes2block(input: &[u8; BLOCK_SIZE]) -> [u8; BLOCK_SIZE] {
117 let mut block = [0u8; BLOCK_SIZE];
118 for r in 0..4 {
119 let base = r << 2;
120 for c in 0..4 {
121 block[base + c] = input[r + (c << 2)];
122 }
123 }
124 block
125}
126
127fn block2bytes(block: &[u8; BLOCK_SIZE]) -> [u8; BLOCK_SIZE] {
128 let mut output = [0u8; BLOCK_SIZE];
129 for r in 0..4 {
130 let base = r << 2;
131 for c in 0..4 {
132 output[r + (c << 2)] = block[base + c];
133 }
134 }
135 output
136}
137
138fn sub_bytes(block: &mut [u8]) {
139 for i in 0..block.len() {
140 block[i] = S_BOX[block[i] as usize]
141 }
142}
143
144fn inv_sub_bytes(block: &mut [u8]) {
145 for i in 0..block.len() {
146 block[i] = INV_S_BOX[block[i] as usize]
147 }
148}
149
150fn shift_rows(state: &mut [u8; BLOCK_SIZE]) {
151 for i in 1..NB {
152 state[i << 2..(i + 1) << 2].rotate_left(i);
153 }
154}
155
156fn inv_shift_rows(state: &mut [u8; BLOCK_SIZE]) {
157 for i in 1..NB {
158 state[i << 2..(i + 1) << 2].rotate_right(i);
159 }
160}
161
162fn mix_columns(state: &mut [u8; BLOCK_SIZE]) {
163 let mut r = [0usize; NB];
164 let mut result = [0u8; BLOCK_SIZE];
165 for c in 0..NB {
166 r[0] = c;
167 r[1] = 4 + c;
168 r[2] = 8 + c;
169 r[3] = 12 + c;
170 result[r[0]] =
171 modular_mul_2(state[r[0]]) ^ modular_mul_3(state[r[1]]) ^ state[r[2]] ^ state[r[3]];
172 result[r[1]] =
173 state[r[0]] ^ modular_mul_2(state[r[1]]) ^ modular_mul_3(state[r[2]]) ^ state[r[3]];
174 result[r[2]] =
175 state[r[0]] ^ state[r[1]] ^ modular_mul_2(state[r[2]]) ^ modular_mul_3(state[r[3]]);
176 result[r[3]] =
177 modular_mul_3(state[r[0]]) ^ state[r[1]] ^ state[r[2]] ^ modular_mul_2(state[r[3]]);
178 }
179 *state = result;
180}
181
182fn inv_mix_columns(state: &mut [u8; BLOCK_SIZE]) {
183 let mut r = [0usize; NB];
184 let mut result = [0u8; BLOCK_SIZE];
185 for c in 0..NB {
186 r[0] = c;
187 r[1] = 4 + c;
188 r[2] = 8 + c;
189 r[3] = 12 + c;
190 result[r[0]] = modular_mul_14(state[r[0]])
191 ^ modular_mul_11(state[r[1]])
192 ^ modular_mul_13(state[r[2]])
193 ^ modular_mul_9(state[r[3]]);
194 result[r[1]] = modular_mul_9(state[r[0]])
195 ^ modular_mul_14(state[r[1]])
196 ^ modular_mul_11(state[r[2]])
197 ^ modular_mul_13(state[r[3]]);
198 result[r[2]] = modular_mul_13(state[r[0]])
199 ^ modular_mul_9(state[r[1]])
200 ^ modular_mul_14(state[r[2]])
201 ^ modular_mul_11(state[r[3]]);
202 result[r[3]] = modular_mul_11(state[r[0]])
203 ^ modular_mul_13(state[r[1]])
204 ^ modular_mul_9(state[r[2]])
205 ^ modular_mul_14(state[r[3]]);
206 }
207 *state = result;
208}
209
210fn modular_mul_2(byte: u8) -> u8 {
212 if byte & 0x80 > 0 {
213 (byte << 1) ^ 0x1b
214 } else {
215 byte << 1
216 }
217}
218
219fn gmul(mut a: u8, mut b: u8) -> u8 {
220 let mut p: u8 = 0;
221 while a > 0 && b > 0 {
222 if b & 1 > 0 {
223 p ^= a;
224 }
225
226 if a & 0x80 > 0 {
227 a = (a << 1) ^ 0x1b;
228 } else {
229 a <<= 1;
230 }
231 b >>= 1;
232 }
233 p
234}
235
236#[inline]
237fn modular_mul_3(byte: u8) -> u8 {
238 modular_mul_2(byte) ^ byte
239}
240
241fn modular_mul_9(byte: u8) -> u8 {
242 let mul2 = modular_mul_2(byte);
243 let mul4 = modular_mul_2(mul2);
244 let mul8 = modular_mul_2(mul4);
245 mul8 ^ byte
246}
247
248#[inline]
249fn modular_mul_11(byte: u8) -> u8 {
250 gmul(11, byte)
251}
252
253#[inline]
254fn modular_mul_13(byte: u8) -> u8 {
255 gmul(13, byte)
256}
257
258#[inline]
259fn modular_mul_14(byte: u8) -> u8 {
260 gmul(14, byte)
261}
262
263fn add_round_key(state: &mut [u8; BLOCK_SIZE], round_key: &[u8]) {
264 for i in 0..NB {
265 let w = i << 2;
266 state[i] ^= round_key[w];
267 state[4 + i] ^= round_key[w + 1];
268 state[8 + i] ^= round_key[w + 2];
269 state[12 + i] ^= round_key[w + 3];
270 }
271}
272
273fn key_expansion(cipher_key: &[u8]) -> Vec<u8> {
274 match cipher_key.len() {
275 16 => key_expansion_128(cipher_key).to_vec(),
276 24 => key_expansion_192(cipher_key).to_vec(),
277 32 => key_expansion_256(cipher_key).to_vec(),
278 _ => panic!(
279 "The key length should be 16 ,24 or 32 bytes for AES-128, AES-192 and AES-256 respectively"
280 ),
281 }
282}
283
284fn key_expansion_inv(cipher_key: &[u8]) -> Vec<u8> {
285 let mut schedule = key_expansion(cipher_key);
286 let mut start = BLOCK_SIZE;
287 let end = schedule.len() - BLOCK_SIZE;
288 while start < end {
289 let range = start..start + BLOCK_SIZE;
290 let mut block = bytes2block(&mut schedule[range.clone()].try_into().unwrap());
291 inv_mix_columns(&mut block);
292 schedule[range].copy_from_slice(&block2bytes(&block));
293 start += BLOCK_SIZE;
294 }
295 schedule
296}
297
298fn key_expansion_128(cipher_key: &[u8]) -> [u8; BLOCK_SIZE * 11] {
299 const NK: usize = 4;
300 const NR: usize = 10;
301 const MAX_I: usize = NB * (NR + 1);
302 let mut w = [0u8; BLOCK_SIZE * (NR + 1)];
303 w[..16].copy_from_slice(cipher_key);
304 let mut i = NK;
305 let mut temp = [0u8; 4];
306 temp.copy_from_slice(&w[(i - 1) << 2..i << 2]);
307 while i < MAX_I {
308 temp.rotate_left(1);
309 sub_bytes(&mut temp);
310 xor_4(&mut temp, &rcon_128(i));
311 i = key_expansion_xor(&mut temp, &mut w, NK, i, MAX_I, NK);
312 }
313 w
314}
315
316fn key_expansion_192(cipher_key: &[u8]) -> [u8; BLOCK_SIZE * 13] {
317 const NK: usize = 6;
318 const NR: usize = 12;
319 const MAX_I: usize = NB * (NR + 1);
320 let mut w = [0u8; BLOCK_SIZE * (NR + 1)];
321 w[..24].copy_from_slice(cipher_key);
322 let mut i = NK;
323 let mut temp = [0u8; 4];
324 temp.copy_from_slice(&w[(i - 1) << 2..i << 2]);
325
326 while i < MAX_I {
327 temp.rotate_left(1);
328 sub_bytes(&mut temp);
329 xor_4(&mut temp, &[0x01 << (i / 6 - 1), 0, 0, 0]);
330 i = key_expansion_xor(&mut temp, &mut w, NK, i, MAX_I, NK);
331 }
332 w
333}
334
335fn key_expansion_256(cipher_key: &[u8]) -> [u8; BLOCK_SIZE * 15] {
336 const NK: usize = 8;
337 const NR: usize = 14;
338 const MAX_I: usize = NB * (NR + 1);
339 let mut w = [0u8; BLOCK_SIZE * (NR + 1)];
340 w[..32].copy_from_slice(cipher_key);
341 let mut i = NK;
342 let mut temp = [0u8; 4];
343 temp.copy_from_slice(&w[(i - 1) << 2..i << 2]);
344
345 while i < MAX_I {
346 temp.rotate_left(1);
347 sub_bytes(&mut temp);
348 xor_4(&mut temp, &[0x01 << ((i >> 3) - 1), 0, 0, 0]);
349 i = key_expansion_xor(&mut temp, &mut w, NK, i, MAX_I, 4);
350 if i == MAX_I {
351 return w;
352 }
353 sub_bytes(&mut temp);
354 i = key_expansion_xor(&mut temp, &mut w, NK, i, MAX_I, 4);
355 }
356 w
357}
358
359fn xor_4(left: &mut [u8; 4], right: &[u8]) {
360 left[0] ^= right[0];
361 left[1] ^= right[1];
362 left[2] ^= right[2];
363 left[3] ^= right[3];
364}
365
366fn rcon_128(i: usize) -> [u8; 4] {
367 let i = (i >> 2) - 1;
368 let (base, i) = if i > 7 { (0x1b, i - 8) } else { (0x01, i) };
369 [base << i, 0u8, 0, 0]
370}
371
372fn key_expansion_xor(
373 temp: &mut [u8; 4],
374 w: &mut [u8],
375 nk: usize,
376 mut i: usize,
377 max_i: usize,
378 iterations: usize,
379) -> usize {
380 for _ in 0..iterations {
381 xor_4(temp, &w[(i - nk) << 2..(i - nk + 1) << 2]);
382 w[i << 2..(i + 1) << 2].copy_from_slice(temp);
383 i += 1;
384 if i == max_i {
385 break;
386 }
387 temp.copy_from_slice(&w[(i - 1) << 2..i << 2]);
388 }
389 return i;
390}
391
392#[cfg(test)]
393mod tests {
394 use super::*;
395
396 #[test]
397 fn test_key_expansion_test() {
398 let cipher_key = [
399 0x2bu8, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf,
400 0x4f, 0x3c,
401 ];
402 let result = key_expansion(&cipher_key);
403 assert_eq!(
404 &result,
405 &[
406 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf,
407 0x4f, 0x3c, 0xa0, 0xfa, 0xfe, 0x17, 0x88, 0x54, 0x2c, 0xb1, 0x23, 0xa3, 0x39, 0x39,
408 0x2a, 0x6c, 0x76, 0x05, 0xf2, 0xc2, 0x95, 0xf2, 0x7a, 0x96, 0xb9, 0x43, 0x59, 0x35,
409 0x80, 0x7a, 0x73, 0x59, 0xf6, 0x7f, 0x3d, 0x80, 0x47, 0x7d, 0x47, 0x16, 0xfe, 0x3e,
410 0x1e, 0x23, 0x7e, 0x44, 0x6d, 0x7a, 0x88, 0x3b, 0xef, 0x44, 0xa5, 0x41, 0xa8, 0x52,
411 0x5b, 0x7f, 0xb6, 0x71, 0x25, 0x3b, 0xdb, 0x0b, 0xad, 0x00, 0xd4, 0xd1, 0xc6, 0xf8,
412 0x7c, 0x83, 0x9d, 0x87, 0xca, 0xf2, 0xb8, 0xbc, 0x11, 0xf9, 0x15, 0xbc, 0x6d, 0x88,
413 0xa3, 0x7a, 0x11, 0x0b, 0x3e, 0xfd, 0xdb, 0xf9, 0x86, 0x41, 0xca, 0x00, 0x93, 0xfd,
414 0x4e, 0x54, 0xf7, 0x0e, 0x5f, 0x5f, 0xc9, 0xf3, 0x84, 0xa6, 0x4f, 0xb2, 0x4e, 0xa6,
415 0xdc, 0x4f, 0xea, 0xd2, 0x73, 0x21, 0xb5, 0x8d, 0xba, 0xd2, 0x31, 0x2b, 0xf5, 0x60,
416 0x7f, 0x8d, 0x29, 0x2f, 0xac, 0x77, 0x66, 0xf3, 0x19, 0xfa, 0xdc, 0x21, 0x28, 0xd1,
417 0x29, 0x41, 0x57, 0x5c, 0x00, 0x6e, 0xd0, 0x14, 0xf9, 0xa8, 0xc9, 0xee, 0x25, 0x89,
418 0xe1, 0x3f, 0x0c, 0xc8, 0xb6, 0x63, 0x0c, 0xa6
419 ]
420 );
421
422 let cipher_key = [
423 0x8eu8, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90,
424 0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b,
425 ];
426 let result = key_expansion(&cipher_key);
427 assert_eq!(
428 &result,
429 &[
430 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90,
431 0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b, 0xfe, 0x0c, 0x91, 0xf7,
432 0x24, 0x02, 0xf5, 0xa5, 0xec, 0x12, 0x06, 0x8e, 0x6c, 0x82, 0x7f, 0x6b, 0x0e, 0x7a,
433 0x95, 0xb9, 0x5c, 0x56, 0xfe, 0xc2, 0x4d, 0xb7, 0xb4, 0xbd, 0x69, 0xb5, 0x41, 0x18,
434 0x85, 0xa7, 0x47, 0x96, 0xe9, 0x25, 0x38, 0xfd, 0xe7, 0x5f, 0xad, 0x44, 0xbb, 0x09,
435 0x53, 0x86, 0x48, 0x5a, 0xf0, 0x57, 0x21, 0xef, 0xb1, 0x4f, 0xa4, 0x48, 0xf6, 0xd9,
436 0x4d, 0x6d, 0xce, 0x24, 0xaa, 0x32, 0x63, 0x60, 0x11, 0x3b, 0x30, 0xe6, 0xa2, 0x5e,
437 0x7e, 0xd5, 0x83, 0xb1, 0xcf, 0x9a, 0x27, 0xf9, 0x39, 0x43, 0x6a, 0x94, 0xf7, 0x67,
438 0xc0, 0xa6, 0x94, 0x07, 0xd1, 0x9d, 0xa4, 0xe1, 0xec, 0x17, 0x86, 0xeb, 0x6f, 0xa6,
439 0x49, 0x71, 0x48, 0x5f, 0x70, 0x32, 0x22, 0xcb, 0x87, 0x55, 0xe2, 0x6d, 0x13, 0x52,
440 0x33, 0xf0, 0xb7, 0xb3, 0x40, 0xbe, 0xeb, 0x28, 0x2f, 0x18, 0xa2, 0x59, 0x67, 0x47,
441 0xd2, 0x6b, 0x45, 0x8c, 0x55, 0x3e, 0xa7, 0xe1, 0x46, 0x6c, 0x94, 0x11, 0xf1, 0xdf,
442 0x82, 0x1f, 0x75, 0x0a, 0xad, 0x07, 0xd7, 0x53, 0xca, 0x40, 0x05, 0x38, 0x8f, 0xcc,
443 0x50, 0x06, 0x28, 0x2d, 0x16, 0x6a, 0xbc, 0x3c, 0xe7, 0xb5, 0xe9, 0x8b, 0xa0, 0x6f,
444 0x44, 0x8c, 0x77, 0x3c, 0x8e, 0xcc, 0x72, 0x04, 0x01, 0x00, 0x22, 0x02
445 ]
446 );
447
448 let cipher_key = [
449 0x60u8, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d,
450 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3,
451 0x09, 0x14, 0xdf, 0xf4,
452 ];
453 let result = key_expansion(&cipher_key);
454 assert_eq!(
455 &result,
456 &[
457 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d,
458 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3,
459 0x09, 0x14, 0xdf, 0xf4, 0x9b, 0xa3, 0x54, 0x11, 0x8e, 0x69, 0x25, 0xaf, 0xa5, 0x1a,
460 0x8b, 0x5f, 0x20, 0x67, 0xfc, 0xde, 0xa8, 0xb0, 0x9c, 0x1a, 0x93, 0xd1, 0x94, 0xcd,
461 0xbe, 0x49, 0x84, 0x6e, 0xb7, 0x5d, 0x5b, 0x9a, 0xd5, 0x9a, 0xec, 0xb8, 0x5b, 0xf3,
462 0xc9, 0x17, 0xfe, 0xe9, 0x42, 0x48, 0xde, 0x8e, 0xbe, 0x96, 0xb5, 0xa9, 0x32, 0x8a,
463 0x26, 0x78, 0xa6, 0x47, 0x98, 0x31, 0x22, 0x29, 0x2f, 0x6c, 0x79, 0xb3, 0x81, 0x2c,
464 0x81, 0xad, 0xda, 0xdf, 0x48, 0xba, 0x24, 0x36, 0x0a, 0xf2, 0xfa, 0xb8, 0xb4, 0x64,
465 0x98, 0xc5, 0xbf, 0xc9, 0xbe, 0xbd, 0x19, 0x8e, 0x26, 0x8c, 0x3b, 0xa7, 0x09, 0xe0,
466 0x42, 0x14, 0x68, 0x00, 0x7b, 0xac, 0xb2, 0xdf, 0x33, 0x16, 0x96, 0xe9, 0x39, 0xe4,
467 0x6c, 0x51, 0x8d, 0x80, 0xc8, 0x14, 0xe2, 0x04, 0x76, 0xa9, 0xfb, 0x8a, 0x50, 0x25,
468 0xc0, 0x2d, 0x59, 0xc5, 0x82, 0x39, 0xde, 0x13, 0x69, 0x67, 0x6c, 0xcc, 0x5a, 0x71,
469 0xfa, 0x25, 0x63, 0x95, 0x96, 0x74, 0xee, 0x15, 0x58, 0x86, 0xca, 0x5d, 0x2e, 0x2f,
470 0x31, 0xd7, 0x7e, 0x0a, 0xf1, 0xfa, 0x27, 0xcf, 0x73, 0xc3, 0x74, 0x9c, 0x47, 0xab,
471 0x18, 0x50, 0x1d, 0xda, 0xe2, 0x75, 0x7e, 0x4f, 0x74, 0x01, 0x90, 0x5a, 0xca, 0xfa,
472 0xaa, 0xe3, 0xe4, 0xd5, 0x9b, 0x34, 0x9a, 0xdf, 0x6a, 0xce, 0xbd, 0x10, 0x19, 0x0d,
473 0xfe, 0x48, 0x90, 0xd1, 0xe6, 0x18, 0x8d, 0x0b, 0x04, 0x6d, 0xf3, 0x44, 0x70, 0x6c,
474 0x63, 0x1e
475 ]
476 );
477 }
478
479 #[test]
480 fn test_aes_encrypt() {
481 let input = [
483 0x32u8, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37,
484 0x07, 0x34,
485 ];
486 let cipher_key = [
487 0x2bu8, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf,
488 0x4f, 0x3c,
489 ];
490 let output = encrypt(&input, &cipher_key);
491 assert_eq!(
492 output,
493 [
494 0x39, 0x25, 0x84, 0x1d, 0x02, 0xdc, 0x09, 0xfb, 0xdc, 0x11, 0x85, 0x97, 0x19, 0x6a,
495 0x0b, 0x32
496 ]
497 );
498
499 let input = [
501 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd,
502 0xee, 0xff,
503 ];
504 let cipher_key = [
505 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
506 0x0e, 0x0f,
507 ];
508 let output = encrypt(&input, &cipher_key);
509 assert_eq!(
510 output,
511 [
512 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4,
513 0xc5, 0x5a
514 ]
515 );
516
517 let input = [
519 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd,
520 0xee, 0xff,
521 ];
522 let cipher_key = [
523 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
524 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
525 ];
526 let output = encrypt(&input, &cipher_key);
527 assert_eq!(
528 output,
529 [
530 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d,
531 0x71, 0x91
532 ]
533 );
534
535 let input = [
537 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd,
538 0xee, 0xff,
539 ];
540 let cipher_key = [
541 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
542 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
543 0x1c, 0x1d, 0x1e, 0x1f,
544 ];
545 let output = encrypt(&input, &cipher_key);
546 assert_eq!(
547 output,
548 [
549 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49,
550 0x60, 0x89
551 ]
552 );
553 }
554
555 #[test]
556 fn test_aes_decrypt() {
557 let input = [
559 0x39, 0x25, 0x84, 0x1d, 0x02, 0xdc, 0x09, 0xfb, 0xdc, 0x11, 0x85, 0x97, 0x19, 0x6a,
560 0x0b, 0x32,
561 ];
562 let cipher_key = [
563 0x2bu8, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf,
564 0x4f, 0x3c,
565 ];
566 let output = decrypt_straight(&input, &cipher_key);
567 assert_eq!(
568 output,
569 [
570 0x32u8, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0,
571 0x37, 0x07, 0x34
572 ]
573 );
574
575 let input = [
577 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4,
578 0xc5, 0x5a,
579 ];
580 let cipher_key = [
581 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
582 0x0e, 0x0f,
583 ];
584 let output = decrypt(&input, &cipher_key);
585 assert_eq!(
586 output,
587 [
588 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd,
589 0xee, 0xff
590 ]
591 );
592
593 let input = [
595 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d,
596 0x71, 0x91,
597 ];
598 let cipher_key = [
599 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
600 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
601 ];
602 let output = decrypt(&input, &cipher_key);
603 assert_eq!(
604 output,
605 [
606 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd,
607 0xee, 0xff
608 ]
609 );
610
611 let input = [
613 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49,
614 0x60, 0x89,
615 ];
616 let cipher_key = [
617 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
618 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
619 0x1c, 0x1d, 0x1e, 0x1f,
620 ];
621 let output = decrypt(&input, &cipher_key);
622 assert_eq!(
623 output,
624 [
625 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd,
626 0xee, 0xff
627 ]
628 );
629 }
630}