dumb_crypto/
aes.rs

1//! # AES
2//!
3//! Implementation of AES encryption/decryption algorithm according to
4//! [FIPS 197][fips].
5//!
6//! [fips]: https://csrc.nist.gov/csrc/media/publications/fips/197/final/documents/fips-197.pdf
7//!
8
9use std::error::Error;
10use std::fmt;
11use std::fmt::Display;
12
13pub const BLOCK_SIZE: usize = 16;
14const NB: usize = 4;
15
16// Note: block[column][row]
17type Block = [[u8; 4]; 4];
18
19const SBOX: [u8; 256] = [
20    0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
21    0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
22    0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
23    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
24    0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
25    0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
26    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
27    0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
28    0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
29    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
30    0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
31    0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
32    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
33    0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
34    0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
35    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16,
36];
37
38const INV_SBOX: [u8; 256] = [
39    0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
40    0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
41    0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
42    0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
43    0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
44    0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
45    0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
46    0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
47    0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
48    0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
49    0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
50    0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
51    0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
52    0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
53    0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
54    0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d,
55];
56
57// Rcon[i], contains the values given by [ x^(i - 1), 0, 0, 0 ], with x^(i - 1)
58// being powers of x (x denoted as {02}) in the field GF(2^8). (note that i
59// starts at 1, not 0)
60const RCON: [u32; 10] = [
61    0x0100_0000,
62    0x0200_0000,
63    0x0400_0000,
64    0x0800_0000,
65    0x1000_0000,
66    0x2000_0000,
67    0x4000_0000,
68    0x8000_0000,
69    0x1b00_0000,
70    0x3600_0000,
71];
72
73// Double the number in the binary field.
74fn double(b: u8) -> u8 {
75    if (b & 0x80) == 0 {
76        b << 1
77    } else {
78        (b << 1) ^ 0x1b
79    }
80}
81
82// Multiply the number by another number in the binary field.
83fn mul(b: u8, mut by: usize) -> u8 {
84    let mut res: u8 = 0;
85    let mut power = b;
86    while by != 0 {
87        if (by & 1) != 0 {
88            res ^= power;
89        }
90        power = double(power);
91        by >>= 1;
92    }
93    res
94}
95
96fn sub_word(b: u32) -> u32 {
97    let b0 = (b >> 24) as usize;
98    let b1 = ((b >> 16) & 0xff) as usize;
99    let b2 = ((b >> 8) & 0xff) as usize;
100    let b3 = (b & 0xff) as usize;
101
102    (u32::from(SBOX[b0]) << 24)
103        | (u32::from(SBOX[b1]) << 16)
104        | (u32::from(SBOX[b2]) << 8)
105        | u32::from(SBOX[b3])
106}
107
108fn rot_word(b: u32) -> u32 {
109    (b << 8) | (b >> 24)
110}
111
112fn expand_key(key: &[u8], round_count: usize) -> Vec<u32> {
113    // byte key[4*Nk]
114    let nk = key.len() / 4;
115
116    // word w[Nb*(Nr+1)]
117    let mut w = Vec::with_capacity(NB * (round_count + 1));
118
119    //  word  temp
120    //  i = 0
121    //  while (i < Nk)
122    //      w[i] = word(key[4*i], key[4*i+1], key[4*i+2], key[4*i+3])
123    //      i = i+1
124    //  end while
125
126    let mut i: usize = 0;
127    while i < nk {
128        w.push(
129            (u32::from(key[4 * i]) << 24)
130                | (u32::from(key[4 * i + 1]) << 16)
131                | (u32::from(key[4 * i + 2]) << 8)
132                | u32::from(key[4 * i + 3]),
133        );
134        i += 1;
135    }
136
137    //  i = Nk
138    //  while (i < Nb * (Nr+1)]
139    //      temp = w[i-1]
140    //      if (i mod Nk = 0)
141    //          temp = SubWord(RotWord(temp)) xor Rcon[i/Nk]
142    //      else if (Nk > 6 and i mod Nk = 4)
143    //          temp = SubWord(temp)
144    //      end if
145    //      w[i] = w[i-Nk] xor temp
146    //      i = i + 1
147    //  end while
148    while i < NB * (round_count + 1) {
149        let mut temp = w[i - 1];
150        if i % nk == 0 {
151            temp = sub_word(rot_word(temp)) ^ RCON[i / nk - 1];
152        } else if nk > 6 && i % nk == 4 {
153            temp = sub_word(temp);
154        }
155        w.push(w[i - nk] ^ temp);
156        i += 1;
157    }
158
159    w
160}
161
162trait AESSide {
163    fn lookup_sbox(b: u8) -> u8;
164    fn mix_column(col: [u8; 4]) -> [u8; 4];
165    fn shift_rows(s: &Block) -> Block;
166
167    // Common methods
168
169    fn add_round_key(s: &mut Block, round_key: &[u32]) {
170        for (col, &key) in s.iter_mut().zip(round_key) {
171            col[0] ^= (key >> 24) as u8;
172            col[1] ^= ((key >> 16) & 0xff) as u8;
173            col[2] ^= ((key >> 8) & 0xff) as u8;
174            col[3] ^= (key & 0xff) as u8;
175        }
176    }
177
178    fn sub_bytes(s: &mut Block) {
179        for col in s.iter_mut() {
180            for cell in col.iter_mut() {
181                *cell = Self::lookup_sbox(*cell);
182            }
183        }
184    }
185
186    fn mix_columns(s: &mut Block) {
187        for column in s.iter_mut() {
188            *column = Self::mix_column(*column);
189        }
190    }
191}
192
193struct AESEncrypt {}
194struct AESDecrypt {}
195
196impl AESSide for AESEncrypt {
197    fn lookup_sbox(b: u8) -> u8 {
198        SBOX[usize::from(b)]
199    }
200
201    fn mix_column(col: [u8; 4]) -> [u8; 4] {
202        [
203            mul(col[0], 2) ^ mul(col[1], 3) ^ col[2] ^ col[3],
204            mul(col[1], 2) ^ mul(col[2], 3) ^ col[3] ^ col[0],
205            mul(col[2], 2) ^ mul(col[3], 3) ^ col[0] ^ col[1],
206            mul(col[3], 2) ^ mul(col[0], 3) ^ col[1] ^ col[2],
207        ]
208    }
209
210    fn shift_rows(s: &Block) -> Block {
211        [
212            [s[0][0], s[1][1], s[2][2], s[3][3]],
213            [s[1][0], s[2][1], s[3][2], s[0][3]],
214            [s[2][0], s[3][1], s[0][2], s[1][3]],
215            [s[3][0], s[0][1], s[1][2], s[2][3]],
216        ]
217    }
218}
219
220impl AESSide for AESDecrypt {
221    fn lookup_sbox(b: u8) -> u8 {
222        INV_SBOX[usize::from(b)]
223    }
224
225    fn mix_column(col: [u8; 4]) -> [u8; 4] {
226        [
227            mul(col[0], 0x0e) ^ mul(col[1], 0x0b) ^ mul(col[2], 0x0d) ^ mul(col[3], 0x09),
228            mul(col[1], 0x0e) ^ mul(col[2], 0x0b) ^ mul(col[3], 0x0d) ^ mul(col[0], 0x09),
229            mul(col[2], 0x0e) ^ mul(col[3], 0x0b) ^ mul(col[0], 0x0d) ^ mul(col[1], 0x09),
230            mul(col[3], 0x0e) ^ mul(col[0], 0x0b) ^ mul(col[1], 0x0d) ^ mul(col[2], 0x09),
231        ]
232    }
233
234    fn shift_rows(s: &Block) -> Block {
235        [
236            [s[0][0], s[3][1], s[2][2], s[1][3]],
237            [s[1][0], s[0][1], s[3][2], s[2][3]],
238            [s[2][0], s[1][1], s[0][2], s[3][3]],
239            [s[3][0], s[2][1], s[1][2], s[0][3]],
240        ]
241    }
242}
243
244fn to_block(b: &[u8; BLOCK_SIZE]) -> Block {
245    [
246        [b[0], b[1], b[2], b[3]],
247        [b[4], b[5], b[6], b[7]],
248        [b[8], b[9], b[10], b[11]],
249        [b[12], b[13], b[14], b[15]],
250    ]
251}
252
253fn from_block(s: &Block) -> [u8; BLOCK_SIZE] {
254    [
255        s[0][0], s[0][1], s[0][2], s[0][3], s[1][0], s[1][1], s[1][2], s[1][3], s[2][0], s[2][1],
256        s[2][2], s[2][3], s[3][0], s[3][1], s[3][2], s[3][3],
257    ]
258}
259
260/// Possible initialization errors
261#[derive(Debug, PartialEq)]
262pub enum AESError {
263    /// Returned when key size is neither of: 128, 192, or 256 bits.
264    InvalidKeySize,
265
266    /// Returned when attempting encryption/decryption on non-initialized AES
267    /// instance
268    NotInitialized,
269}
270
271impl Display for AESError {
272    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
273        write!(f, "AESError: {}", self.description())
274    }
275}
276
277impl Error for AESError {
278    fn description(&self) -> &str {
279        match self {
280            AESError::InvalidKeySize => "key size must be either of: 128, 192, or 256 bits",
281            AESError::NotInitialized => "AES instance must be initialized prior to use",
282        }
283    }
284}
285
286///
287/// Main AES structure.
288///
289/// Usage:
290/// ```rust
291/// extern crate dumb_crypto;
292///
293/// use::dumb_crypto::aes::{AES, BLOCK_SIZE};
294///
295/// let mut aes = AES::new();
296/// let key: [u8; 16] = [
297///     0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
298///     0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
299/// ];
300/// aes.init(&key).unwrap();
301///
302/// let cleartext: [u8; BLOCK_SIZE] = [
303///     0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d,
304///     0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34,
305/// ];
306///
307/// let ciphertext = aes.encrypt(&cleartext).unwrap();
308///
309/// assert_eq!(aes.decrypt(&ciphertext).unwrap(), cleartext);
310/// ```
311///
312pub struct AES {
313    round_count: usize,
314    round_keys: Option<Vec<u32>>,
315}
316
317impl AES {
318    /// Create new uninitialized instance of AES.
319    pub fn new() -> Self {
320        AES {
321            round_count: 0,
322            round_keys: None,
323        }
324    }
325
326    /// Initialize an instance with a encryption/decryption key.
327    pub fn init(&mut self, key: &[u8]) -> Result<(), AESError> {
328        self.round_count = match key.len() {
329            // 128 bits
330            16 => 10,
331
332            // 192 bits
333            24 => 12,
334
335            // 256 bits
336            32 => 14,
337
338            // Invalid key size
339            _ => {
340                return Err(AESError::InvalidKeySize);
341            }
342        };
343        self.round_keys = Some(expand_key(key, self.round_count));
344
345        Ok(())
346    }
347
348    /// Encrypt block of data.
349    pub fn encrypt(&self, b: &[u8; BLOCK_SIZE]) -> Result<[u8; BLOCK_SIZE], AESError> {
350        let nr = self.round_count;
351
352        let mut state = to_block(b);
353        let round_keys = match &self.round_keys {
354            Some(keys) => keys,
355            None => {
356                return Err(AESError::NotInitialized);
357            }
358        };
359
360        AESEncrypt::add_round_key(&mut state, &round_keys[0..NB]);
361
362        for round in 1..nr {
363            AESEncrypt::sub_bytes(&mut state);
364            state = AESEncrypt::shift_rows(&state);
365            AESEncrypt::mix_columns(&mut state);
366            AESEncrypt::add_round_key(&mut state, &round_keys[(round * NB)..((round + 1) * NB)]);
367        }
368
369        AESEncrypt::sub_bytes(&mut state);
370        state = AESEncrypt::shift_rows(&state);
371        AESEncrypt::add_round_key(&mut state, &round_keys[(nr * NB)..]);
372
373        Ok(from_block(&state))
374    }
375
376    /// Decrypt block of data.
377    pub fn decrypt(&self, b: &[u8; BLOCK_SIZE]) -> Result<[u8; BLOCK_SIZE], AESError> {
378        let nr = self.round_count;
379
380        let mut state = to_block(b);
381        let round_keys = match &self.round_keys {
382            Some(keys) => keys,
383            None => {
384                return Err(AESError::NotInitialized);
385            }
386        };
387
388        AESDecrypt::add_round_key(&mut state, &round_keys[(nr * NB)..]);
389
390        for round in (1..nr).rev() {
391            state = AESDecrypt::shift_rows(&state);
392            AESDecrypt::sub_bytes(&mut state);
393            AESDecrypt::add_round_key(&mut state, &round_keys[(round * NB)..((round + 1) * NB)]);
394            AESDecrypt::mix_columns(&mut state);
395        }
396
397        state = AESDecrypt::shift_rows(&state);
398        AESDecrypt::sub_bytes(&mut state);
399        AESDecrypt::add_round_key(&mut state, &round_keys[0..NB]);
400
401        Ok(from_block(&state))
402    }
403}
404
405impl Default for AES {
406    fn default() -> Self {
407        Self::new()
408    }
409}
410
411#[cfg(test)]
412mod tests {
413    use super::*;
414    use crate::common::hex_to_vec;
415
416    const TEST_BLOCK: Block = [
417        [0x37, 0xd7, 0xa0, 0x2d],
418        [0x8a, 0x65, 0xc1, 0x96],
419        [0xda, 0xee, 0x01, 0x99],
420        [0xb9, 0x9e, 0x55, 0x65],
421    ];
422
423    #[test]
424    fn it_should_multiply_in_field() {
425        assert_eq!(mul(1, 2), 2);
426        assert_eq!(mul(1, 3), 3);
427
428        assert_eq!(mul(0x57, 0x02), 0xae);
429        assert_eq!(mul(0x57, 0x04), 0x47);
430        assert_eq!(mul(0x57, 0x08), 0x8e);
431        assert_eq!(mul(0x57, 0x10), 0x07);
432        assert_eq!(mul(0x57, 0x13), 0xfe);
433    }
434
435    #[test]
436    fn it_should_inverse_sub_bytes() {
437        let mut s: Block = TEST_BLOCK;
438        AESEncrypt::sub_bytes(&mut s);
439        AESDecrypt::sub_bytes(&mut s);
440        assert_eq!(s, TEST_BLOCK);
441    }
442
443    #[test]
444    fn it_should_inverse_mix_columns() {
445        let mut s: Block = TEST_BLOCK;
446        AESEncrypt::mix_columns(&mut s);
447        AESDecrypt::mix_columns(&mut s);
448        assert_eq!(s, TEST_BLOCK);
449    }
450
451    #[test]
452    fn it_should_inverse_shift_rows() {
453        let t = AESEncrypt::shift_rows(&TEST_BLOCK);
454        assert_eq!(AESDecrypt::shift_rows(&t), TEST_BLOCK);
455    }
456
457    #[test]
458    fn it_should_expand_128bit_key() {
459        assert_eq!(
460            expand_key(
461                &[
462                    0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09,
463                    0xcf, 0x4f, 0x3c
464                ],
465                10
466            ),
467            vec![
468                0x2b7e_1516,
469                0x28ae_d2a6,
470                0xabf7_1588,
471                0x09cf_4f3c,
472                0xa0fa_fe17,
473                0x8854_2cb1,
474                0x23a3_3939,
475                0x2a6c_7605,
476                0xf2c2_95f2,
477                0x7a96_b943,
478                0x5935_807a,
479                0x7359_f67f,
480                0x3d80_477d,
481                0x4716_fe3e,
482                0x1e23_7e44,
483                0x6d7a_883b,
484                0xef44_a541,
485                0xa852_5b7f,
486                0xb671_253b,
487                0xdb0b_ad00,
488                0xd4d1_c6f8,
489                0x7c83_9d87,
490                0xcaf2_b8bc,
491                0x11f9_15bc,
492                0x6d88_a37a,
493                0x110b_3efd,
494                0xdbf9_8641,
495                0xca00_93fd,
496                0x4e54_f70e,
497                0x5f5f_c9f3,
498                0x84a6_4fb2,
499                0x4ea6_dc4f,
500                0xead2_7321,
501                0xb58d_bad2,
502                0x312b_f560,
503                0x7f8d_292f,
504                0xac77_66f3,
505                0x19fa_dc21,
506                0x28d1_2941,
507                0x575c_006e,
508                0xd014_f9a8,
509                0xc9ee_2589,
510                0xe13f_0cc8,
511                0xb663_0ca6,
512            ],
513        );
514    }
515
516    #[test]
517    fn it_should_expand_192bit_key() {
518        assert_eq!(
519            expand_key(
520                &[
521                    0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80,
522                    0x90, 0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b,
523                ],
524                12
525            ),
526            vec![
527                0x8e73_b0f7,
528                0xda0e_6452,
529                0xc810_f32b,
530                0x8090_79e5,
531                0x62f8_ead2,
532                0x522c_6b7b,
533                0xfe0c_91f7,
534                0x2402_f5a5,
535                0xec12_068e,
536                0x6c82_7f6b,
537                0x0e7a_95b9,
538                0x5c56_fec2,
539                0x4db7_b4bd,
540                0x69b5_4118,
541                0x85a7_4796,
542                0xe925_38fd,
543                0xe75f_ad44,
544                0xbb09_5386,
545                0x485a_f057,
546                0x21ef_b14f,
547                0xa448_f6d9,
548                0x4d6d_ce24,
549                0xaa32_6360,
550                0x113b_30e6,
551                0xa25e_7ed5,
552                0x83b1_cf9a,
553                0x27f9_3943,
554                0x6a94_f767,
555                0xc0a6_9407,
556                0xd19d_a4e1,
557                0xec17_86eb,
558                0x6fa6_4971,
559                0x485f_7032,
560                0x22cb_8755,
561                0xe26d_1352,
562                0x33f0_b7b3,
563                0x40be_eb28,
564                0x2f18_a259,
565                0x6747_d26b,
566                0x458c_553e,
567                0xa7e1_466c,
568                0x9411_f1df,
569                0x821f_750a,
570                0xad07_d753,
571                0xca40_0538,
572                0x8fcc_5006,
573                0x282d_166a,
574                0xbc3c_e7b5,
575                0xe98b_a06f,
576                0x448c_773c,
577                0x8ecc_7204,
578                0x0100_2202,
579            ],
580        );
581    }
582
583    #[test]
584    fn it_should_expand_256bit_key() {
585        assert_eq!(
586            expand_key(
587                &[
588                    0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85,
589                    0x7d, 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98,
590                    0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4,
591                ],
592                14
593            ),
594            vec![
595                0x603d_eb10,
596                0x15ca_71be,
597                0x2b73_aef0,
598                0x857d_7781,
599                0x1f35_2c07,
600                0x3b61_08d7,
601                0x2d98_10a3,
602                0x0914_dff4,
603                0x9ba3_5411,
604                0x8e69_25af,
605                0xa51a_8b5f,
606                0x2067_fcde,
607                0xa8b0_9c1a,
608                0x93d1_94cd,
609                0xbe49_846e,
610                0xb75d_5b9a,
611                0xd59a_ecb8,
612                0x5bf3_c917,
613                0xfee9_4248,
614                0xde8e_be96,
615                0xb5a9_328a,
616                0x2678_a647,
617                0x9831_2229,
618                0x2f6c_79b3,
619                0x812c_81ad,
620                0xdadf_48ba,
621                0x2436_0af2,
622                0xfab8_b464,
623                0x98c5_bfc9,
624                0xbebd_198e,
625                0x268c_3ba7,
626                0x09e0_4214,
627                0x6800_7bac,
628                0xb2df_3316,
629                0x96e9_39e4,
630                0x6c51_8d80,
631                0xc814_e204,
632                0x76a9_fb8a,
633                0x5025_c02d,
634                0x59c5_8239,
635                0xde13_6967,
636                0x6ccc_5a71,
637                0xfa25_6395,
638                0x9674_ee15,
639                0x5886_ca5d,
640                0x2e2f_31d7,
641                0x7e0a_f1fa,
642                0x27cf_73c3,
643                0x749c_47ab,
644                0x1850_1dda,
645                0xe275_7e4f,
646                0x7401_905a,
647                0xcafa_aae3,
648                0xe4d5_9b34,
649                0x9adf_6ace,
650                0xbd10_190d,
651                0xfe48_90d1,
652                0xe618_8d0b,
653                0x046d_f344,
654                0x706c_631e,
655            ],
656        );
657    }
658
659    #[test]
660    fn it_should_encrypt_first_test_from_the_spec() {
661        let mut aes = AES::new();
662        let key: [u8; 16] = [
663            0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf,
664            0x4f, 0x3c,
665        ];
666        aes.init(&key).expect("init to not fail");
667
668        let cleartext: [u8; BLOCK_SIZE] = [
669            0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37,
670            0x07, 0x34,
671        ];
672
673        let ciphertext = aes.encrypt(&cleartext).expect("encrypt to not fail");
674
675        assert_eq!(
676            ciphertext,
677            [
678                0x39, 0x25, 0x84, 0x1d, 0x02, 0xdc, 0x09, 0xfb, 0xdc, 0x11, 0x85, 0x97, 0x19, 0x6a,
679                0x0b, 0x32,
680            ]
681        );
682    }
683
684    fn hex_to_block(hex: &str) -> [u8; 16] {
685        let vec = hex_to_vec(hex);
686        let mut b = [0; 16];
687
688        for (i, elem) in vec.into_iter().enumerate() {
689            b[i] = elem;
690        }
691
692        b
693    }
694
695    fn check_cipher_vector(key: &str, input: &str, output: &str) {
696        let mut aes = AES::new();
697        aes.init(&hex_to_vec(key)).expect("init to not fail");
698
699        assert_eq!(
700            aes.encrypt(&hex_to_block(input))
701                .expect("encrypt to not fail"),
702            hex_to_block(output)
703        );
704        assert_eq!(
705            aes.decrypt(&hex_to_block(output))
706                .expect("decrypt to not fail"),
707            hex_to_block(input)
708        );
709    }
710
711    #[test]
712    fn it_should_encrypt_test_vector_0() {
713        check_cipher_vector(
714            "000102030405060708090a0b0c0d0e0f",
715            "00112233445566778899aabbccddeeff",
716            "69c4e0d86a7b0430d8cdb78070b4c55a",
717        );
718    }
719
720    #[test]
721    fn it_should_encrypt_test_vector_1() {
722        check_cipher_vector(
723            "000102030405060708090a0b0c0d0e0f1011121314151617",
724            "00112233445566778899aabbccddeeff",
725            "dda97ca4864cdfe06eaf70a0ec0d7191",
726        );
727    }
728
729    #[test]
730    fn it_should_encrypt_test_vector_2() {
731        check_cipher_vector(
732            "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
733            "00112233445566778899aabbccddeeff",
734            "8ea2b7ca516745bfeafc49904b496089",
735        );
736    }
737}