1use super::generic::{create_u8x4x4, u8x4x4, Ops, Permutation};
2
3pub struct LED {
5 pub key: Vec<u8>,
7 ns: u8,
9 keysize: u8,
11 sbox: [u8; 16],
12 rsbox: [u8; 16],
13}
14
15type LEDstate = u8x4x4;
16
17impl LED {
18 pub fn new(key: &[u8]) -> Self {
20 let keysize = key.len() * 4;
21 let ns = match keysize {
22 64 => 8,
23 80 => 10,
24 128 => 12,
25 _ => unimplemented!(),
26 };
27 LED {
28 key: key.to_vec(),
29 ns,
30 keysize: keysize as u8,
31 sbox: SBOX,
32 rsbox: RSBOX,
33 }
34 }
35
36 pub fn encrypt(&self, data: &[u8]) -> Vec<u8> {
38 let mut state = create_u8x4x4(data);
39 for i in 0..self.ns {
40 state = add_round_key(&state, &self.key, self.keysize, i);
41 state = step(&state, self.keysize, i, &self.sbox);
42 }
43 state = add_round_key(&state, &self.key, self.keysize, self.ns);
44 state.concat()
45 }
46
47 pub fn decrypt(&self, data: &[u8]) -> Vec<u8> {
49 let mut state = create_u8x4x4(data);
50 for i in (0..self.ns).rev() {
51 state = add_round_key(&state, &self.key, self.keysize, i);
52 state = inv_step(&state, self.keysize, i, &self.rsbox);
53 }
54 state = add_round_key(&state, &self.key, self.keysize, 0);
55 state.concat()
56 }
57
58 pub fn with_sbox_byte(mut self, faulty_idx: usize, faulty_val: u8) -> Self {
60 let mut sbox = SBOX;
61 sbox[faulty_idx] = faulty_val;
62 self.sbox = sbox;
63 self
64 }
65
66 pub fn with_rsbox_byte(mut self, faulty_idx: usize, faulty_val: u8) -> Self {
67 let mut rsbox = RSBOX;
68 rsbox[faulty_idx] = faulty_val;
69 self.rsbox = rsbox;
70 self
71 }
72}
73
74fn step(state: &LEDstate, keysize: u8, round: u8, sbox: &[u8]) -> LEDstate {
75 let mut out = *state;
76 for i in 0..4 {
77 out = add_constants(&out, round * 4 + i, keysize);
78 out = sub_cells(&out, sbox);
79 out = shift_rows(&out);
80 out = mix_columns_serial(&out);
81 }
82 out
83}
84fn inv_step(state: &LEDstate, keysize: u8, round: u8, rsbox: &[u8]) -> LEDstate {
85 let mut out = *state;
86 for i in (0..4).rev() {
87 out = inv_mix_columns_serial(&out);
88 out = inv_shift_rows(&out);
89 out = inv_sub_cells(&out, rsbox);
90 out = add_constants(&out, round * 4 + i, keysize);
91 }
92 out
93}
94fn add_round_key(state: &LEDstate, key: &[u8], keysize: u8, round: u8) -> LEDstate {
95 let mut rkey: [u8; 16] = [0; 16];
96 for i in 0..16 {
97 rkey[i] = key[((round * 16 + i as u8) % (keysize / 4)) as usize];
98 }
99 state.xor(&create_u8x4x4(&rkey))
100}
101fn add_constants(state: &LEDstate, r: u8, keysize: u8) -> LEDstate {
102 state.xor(&[
103 [keysize >> 4, (RCON[r as usize] >> 3) & 0x7, 0, 0],
104 [1 ^ ((keysize >> 4) & 0xf), RCON[r as usize] & 0x7, 0, 0],
105 [2 ^ (keysize & 0xf), (RCON[r as usize] >> 3) & 0x7, 0, 0],
106 [3 ^ (keysize & 0xf), RCON[r as usize] & 0x7, 0, 0],
107 ])
108}
109fn sub_cells(state: &LEDstate, sbox: &[u8]) -> LEDstate {
110 state.sub_sbox(sbox)
111}
112fn inv_sub_cells(state: &LEDstate, rsbox: &[u8]) -> LEDstate {
113 state.sub_sbox(rsbox)
114}
115fn shift_rows(state: &LEDstate) -> LEDstate {
116 state.lrot()
117}
118fn inv_shift_rows(state: &LEDstate) -> LEDstate {
119 state.rrot()
120}
121fn mix_columns_serial(state: &LEDstate) -> LEDstate {
122 state.gmul(&MDS, 4)
123}
124fn inv_mix_columns_serial(state: &LEDstate) -> LEDstate {
125 state.gmul(&RMDS, 4)
126}
127
128pub static RCON: [u8; 48] = [
129 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3E, 0x3D, 0x3B, 0x37, 0x2F, 0x1E, 0x3C, 0x39, 0x33, 0x27, 0x0E,
130 0x1D, 0x3A, 0x35, 0x2B, 0x16, 0x2C, 0x18, 0x30, 0x21, 0x02, 0x05, 0x0B, 0x17, 0x2E, 0x1C, 0x38,
131 0x31, 0x23, 0x06, 0x0D, 0x1B, 0x36, 0x2D, 0x1A, 0x34, 0x29, 0x12, 0x24, 0x08, 0x11, 0x22, 0x04,
132];
133
134pub static SBOX: [u8; 16] = [
135 0xC, 0x5, 0x6, 0xB, 0x9, 0x0, 0xA, 0xD, 0x3, 0xE, 0xF, 0x8, 0x4, 0x7, 0x1, 0x2,
136];
137
138pub static RSBOX: [u8; 16] = [
139 0x5, 0xe, 0xF, 0x8, 0xC, 0x1, 0x2, 0xD, 0xB, 0x4, 0x6, 0x3, 0x0, 0x7, 0x9, 0xA,
140];
141
142pub static MDS: [[u8; 4]; 4] = [
143 [0x4, 0x1, 0x2, 0x2],
144 [0x8, 0x6, 0x5, 0x6],
145 [0xB, 0xE, 0xA, 0x9],
146 [0x2, 0x2, 0xF, 0xB],
147];
148
149pub static RMDS: [[u8; 4]; 4] = [
150 [0xc, 0xc, 0xd, 0x4],
151 [0x3, 0x8, 0x4, 0x5],
152 [0x7, 0x6, 0x2, 0xe],
153 [0xd, 0x9, 0x9, 0xd],
154];