1use std::error::Error;
10use std::fmt;
11use std::fmt::Display;
12
13pub const BLOCK_SIZE: usize = 16;
14const NB: usize = 4;
15
16type 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
57const 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
73fn double(b: u8) -> u8 {
75 if (b & 0x80) == 0 {
76 b << 1
77 } else {
78 (b << 1) ^ 0x1b
79 }
80}
81
82fn 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 let nk = key.len() / 4;
115
116 let mut w = Vec::with_capacity(NB * (round_count + 1));
118
119 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 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 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#[derive(Debug, PartialEq)]
262pub enum AESError {
263 InvalidKeySize,
265
266 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
286pub struct AES {
313 round_count: usize,
314 round_keys: Option<Vec<u32>>,
315}
316
317impl AES {
318 pub fn new() -> Self {
320 AES {
321 round_count: 0,
322 round_keys: None,
323 }
324 }
325
326 pub fn init(&mut self, key: &[u8]) -> Result<(), AESError> {
328 self.round_count = match key.len() {
329 16 => 10,
331
332 24 => 12,
334
335 32 => 14,
337
338 _ => {
340 return Err(AESError::InvalidKeySize);
341 }
342 };
343 self.round_keys = Some(expand_key(key, self.round_count));
344
345 Ok(())
346 }
347
348 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 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}