Skip to main content

aes_ndlr/
key.rs

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
8/// Key schedule generated by the key expansion routine.
9pub 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    /// Generates a series of Round Keys from the Cipher Key.
23    /// The Key Expansion generates a total of Nb * (Nr + 1) words: the algorithm requires
24    /// an initial set of Nb words, and each of the Nr rounds requires Nb words of key data. The
25    /// resulting key schedule consists of a linear array of 4-byte words, denoted [w_i ], with
26    /// i in the range 0 <= i < Nb * (Nr + 1).
27    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        // as provided in official paper
74        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        // also known as w
81        let expected_key_schedule: [[u8; 4]; 44] = [
82            // copy of key
83            [0x2b, 0x7e, 0x15, 0x16],
84            [0x28, 0xae, 0xd2, 0xa6],
85            [0xab, 0xf7, 0x15, 0x88],
86            [0x09, 0xcf, 0x4f, 0x3c],
87
88            // rest of expansion
89            [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}