crypto_async_rs/
aes.rs

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
69//less efficient
70pub 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
210//xtime fips-197.pdf
211fn 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        //aes-128
482        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        //aes-128
500        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        //aes-192
518        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        //aes-256
536        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        //aes-128
558        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        //aes-128
576        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        //aes-192
594        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        //aes-256
612        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}