1use ::{Nb, Nk, Nr, xor};
2use word::{rot_word, sub_word};
3use Rcon;
4
5#[derive(PartialEq, Debug)]
6pub struct Key(pub [u8; 16]);
7
8pub struct KeySchedule(pub [[u8; 4]; Nb * (Nr + 1)]);
10
11impl Key {
12 pub fn from_string(string: &str) -> Self {
13 let mut out = [0u8; 16];
14 let bytes = string.as_bytes();
15 for (i, byte) in out.iter_mut().enumerate() {
16 *byte = bytes[i];
17 }
18
19 Key(out)
20 }
21
22 pub fn do_key_expansion(&self) -> KeySchedule {
28 let mut w = [[0u8; Nk]; Nb * (Nr + 1)];
29
30 for i in 0..Nk {
31 let key_part = &self.0[4 * i..4 * i + 4];
32 w[i] = [key_part[0], key_part[1], key_part[2], key_part[3]];
33 }
34
35 for i in Nk..(Nb * (Nr + 1)) {
36 let mut temp = w[i - 1].to_vec();
37 if i % Nk == 0 {
38 let xored = xor::fixed_key_xor(
39 &sub_word(&rot_word(&temp)),
40 &Rcon[(i / Nk) - 1],
41 );
42 temp = xored;
43 } else if Nk > 6 && i % Nk == 4 {
44 temp = sub_word(&temp);
45 }
46 let key = xor::fixed_key_xor(&w[i - Nk][..], &temp);
47 w[i] = [key[0], key[1], key[2], key[3]];
48 }
49
50 KeySchedule(w)
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
59 fn from_string_creates_key_from_string() {
60 let key = Key::from_string("SOME KEY ABCDEFG");
61 let expected_key_value = [
62 0x53, 0x4f, 0x4d, 0x45,
63 0x20, 0x4b, 0x45, 0x59,
64 0x20, 0x41, 0x42, 0x43,
65 0x44, 0x45, 0x46, 0x47
66 ];
67
68 assert_eq!(key.0, expected_key_value);
69 }
70
71 #[test]
72 fn do_key_expansion_produces_corresponding_key_schedule() {
73 let key = &Key([
75 0x2b, 0x7e, 0x15, 0x16,
76 0x28, 0xae, 0xd2, 0xa6,
77 0xab, 0xf7, 0x15, 0x88,
78 0x09, 0xcf, 0x4f, 0x3c
79 ]);
80 let expected_key_schedule: [[u8; 4]; 44] = [
82 [0x2b, 0x7e, 0x15, 0x16],
84 [0x28, 0xae, 0xd2, 0xa6],
85 [0xab, 0xf7, 0x15, 0x88],
86 [0x09, 0xcf, 0x4f, 0x3c],
87
88 [0xa0, 0xfa, 0xfe, 0x17],
90 [0x88, 0x54, 0x2c, 0xb1],
91 [0x23, 0xa3, 0x39, 0x39],
92 [0x2a, 0x6c, 0x76, 0x05],
93 [0xf2, 0xc2, 0x95, 0xf2],
94 [0x7a, 0x96, 0xb9, 0x43],
95 [0x59, 0x35, 0x80, 0x7a],
96 [0x73, 0x59, 0xf6, 0x7f],
97 [0x3d, 0x80, 0x47, 0x7d],
98 [0x47, 0x16, 0xfe, 0x3e],
99 [0x1e, 0x23, 0x7e, 0x44],
100 [0x6d, 0x7a, 0x88, 0x3b],
101 [0xef, 0x44, 0xa5, 0x41],
102 [0xa8, 0x52, 0x5b, 0x7f],
103 [0xb6, 0x71, 0x25, 0x3b],
104 [0xdb, 0x0b, 0xad, 0x00],
105 [0xd4, 0xd1, 0xc6, 0xf8],
106 [0x7c, 0x83, 0x9d, 0x87],
107 [0xca, 0xf2, 0xb8, 0xbc],
108 [0x11, 0xf9, 0x15, 0xbc],
109 [0x6d, 0x88, 0xa3, 0x7a],
110 [0x11, 0x0b, 0x3e, 0xfd],
111 [0xdb, 0xf9, 0x86, 0x41],
112 [0xca, 0x00, 0x93, 0xfd],
113 [0x4e, 0x54, 0xf7, 0x0e],
114 [0x5f, 0x5f, 0xc9, 0xf3],
115 [0x84, 0xa6, 0x4f, 0xb2],
116 [0x4e, 0xa6, 0xdc, 0x4f],
117 [0xea, 0xd2, 0x73, 0x21],
118 [0xb5, 0x8d, 0xba, 0xd2],
119 [0x31, 0x2b, 0xf5, 0x60],
120 [0x7f, 0x8d, 0x29, 0x2f],
121 [0xac, 0x77, 0x66, 0xf3],
122 [0x19, 0xfa, 0xdc, 0x21],
123 [0x28, 0xd1, 0x29, 0x41],
124 [0x57, 0x5c, 0x00, 0x6e],
125 [0xd0, 0x14, 0xf9, 0xa8],
126 [0xc9, 0xee, 0x25, 0x89],
127 [0xe1, 0x3f, 0x0c, 0xc8],
128 [0xb6, 0x63, 0x0c, 0xa6]
129 ];
130
131 let actual_key_schedule = key.do_key_expansion();
132
133 assert_eq!(actual_key_schedule.0.to_vec(), expected_key_schedule.to_vec());
134 }
135}