aes/backends/fixslice/
aes192.rs1use super::{BatchBlocks, State, Word, mix_columns::*, sbox::*, utils::*};
2
3pub(crate) type RoundKeys<W> = [W; 104];
5
6pub(crate) fn key_schedule<W: Word>(key: &[u8; 24]) -> RoundKeys<W> {
8 let mut rkeys = [W::default(); 104];
9 let mut tmp = [W::default(); 8];
10
11 W::bitslice(&mut rkeys[..8], &broadcast::<W>(&key[..16]));
12 W::bitslice(&mut tmp, &broadcast::<W>(&key[8..]));
13
14 let mut rcon = 0;
15 let mut rk_off = 8;
16
17 loop {
18 for i in 0..8 {
19 rkeys[rk_off + i] = (W::uniform_row(0x0f) & (tmp[i] >> W::HALF_ROW))
20 | (W::uniform_row(0xf0) & (rkeys[(rk_off - 8) + i] << W::HALF_ROW));
21 }
22
23 sub_bytes(&mut tmp);
24 sub_bytes_nots(&mut tmp);
25
26 add_round_constant_bit(&mut tmp, rcon);
27 rcon += 1;
28
29 for i in 0..8 {
30 let mut ti = rkeys[rk_off + i];
31 ti ^= W::uniform_row(0x30) & tmp[i].ror(W::ror_distance(1, 1));
32 ti ^= W::uniform_row(0xc0) & (ti << W::QUARTER_ROW);
33 tmp[i] = ti;
34 }
35 rkeys[rk_off..(rk_off + 8)].copy_from_slice(&tmp);
36 rk_off += 8;
37
38 for i in 0..8 {
39 let ui = tmp[i];
40 let mut ti = (W::uniform_row(0x0f) & (rkeys[(rk_off - 16) + i] >> W::HALF_ROW))
41 | (W::uniform_row(0xf0) & (ui << W::HALF_ROW));
42 ti ^= W::uniform_row(0x03) & (ui >> (3 * W::QUARTER_ROW));
43 tmp[i] = ti
44 ^ (W::uniform_row(0xfc) & (ti << W::QUARTER_ROW))
45 ^ (W::uniform_row(0xf0) & (ti << W::HALF_ROW))
46 ^ (W::uniform_row(0xc0) & (ti << (3 * W::QUARTER_ROW)));
47 }
48 rkeys[rk_off..(rk_off + 8)].copy_from_slice(&tmp);
49 rk_off += 8;
50
51 sub_bytes(&mut tmp);
52 sub_bytes_nots(&mut tmp);
53
54 add_round_constant_bit(&mut tmp, rcon);
55 rcon += 1;
56
57 for i in 0..8 {
58 let mut ti = (W::uniform_row(0x0f) & (rkeys[(rk_off - 16) + i] >> W::HALF_ROW))
59 | (W::uniform_row(0xf0) & (rkeys[(rk_off - 8) + i] << W::HALF_ROW));
60 ti ^= W::uniform_row(0x03) & tmp[i].ror(W::ror_distance(1, 3));
61 rkeys[rk_off + i] = ti
62 ^ (W::uniform_row(0xfc) & (ti << W::QUARTER_ROW))
63 ^ (W::uniform_row(0xf0) & (ti << W::HALF_ROW))
64 ^ (W::uniform_row(0xc0) & (ti << (3 * W::QUARTER_ROW)));
65 }
66 rk_off += 8;
67
68 if rcon >= 8 {
69 break;
70 }
71
72 for i in 0..8 {
73 let ui = rkeys[(rk_off - 8) + i];
74 let mut ti = rkeys[(rk_off - 16) + i];
75 ti ^= W::uniform_row(0x30) & (ui >> W::QUARTER_ROW);
76 ti ^= W::uniform_row(0xc0) & (ti << W::QUARTER_ROW);
77 tmp[i] = ti;
78 }
79 }
80
81 #[cfg(aes_backend_soft = "compact")]
83 {
84 for i in (8..104).step_by(16) {
85 inv_shift_rows_1(&mut rkeys[i..(i + 8)]);
86 }
87 }
88 #[cfg(not(aes_backend_soft = "compact"))]
89 {
90 for i in (0..96).step_by(32) {
91 inv_shift_rows_1(&mut rkeys[(i + 8)..(i + 16)]);
92 inv_shift_rows_2(&mut rkeys[(i + 16)..(i + 24)]);
93 inv_shift_rows_3(&mut rkeys[(i + 24)..(i + 32)]);
94 }
95 }
96
97 for i in 1..13 {
99 sub_bytes_nots(&mut rkeys[(i * 8)..(i * 8 + 8)]);
100 }
101
102 rkeys
103}
104
105pub(crate) fn encrypt<W: Word>(rkeys: &RoundKeys<W>, blocks: &BatchBlocks<W>) -> BatchBlocks<W> {
109 let mut state = State::<W>::default();
110
111 W::bitslice(&mut state, blocks);
112
113 add_round_key(&mut state, &rkeys[..8]);
114
115 let mut rk_off = 8;
116 loop {
117 sub_bytes(&mut state);
118 mix_columns_1(&mut state);
119 add_round_key(&mut state, &rkeys[rk_off..(rk_off + 8)]);
120 rk_off += 8;
121
122 #[cfg(aes_backend_soft = "compact")]
123 {
124 shift_rows_2(&mut state);
125 }
126 #[cfg(not(aes_backend_soft = "compact"))]
127 {
128 sub_bytes(&mut state);
129 mix_columns_2(&mut state);
130 add_round_key(&mut state, &rkeys[rk_off..(rk_off + 8)]);
131 rk_off += 8;
132
133 sub_bytes(&mut state);
134 mix_columns_3(&mut state);
135 add_round_key(&mut state, &rkeys[rk_off..(rk_off + 8)]);
136 rk_off += 8;
137 }
138
139 if rk_off == 96 {
140 break;
141 }
142
143 sub_bytes(&mut state);
144 mix_columns_0(&mut state);
145 add_round_key(&mut state, &rkeys[rk_off..(rk_off + 8)]);
146 rk_off += 8;
147 }
148
149 sub_bytes(&mut state);
150 add_round_key(&mut state, &rkeys[96..]);
151
152 W::inv_bitslice(&state)
153}
154
155pub(crate) fn decrypt<W: Word>(rkeys: &RoundKeys<W>, blocks: &BatchBlocks<W>) -> BatchBlocks<W> {
159 let mut state = State::<W>::default();
160
161 W::bitslice(&mut state, blocks);
162
163 add_round_key(&mut state, &rkeys[96..]);
164 inv_sub_bytes(&mut state);
165
166 let mut rk_off = 88;
167 loop {
168 #[cfg(aes_backend_soft = "compact")]
169 {
170 inv_shift_rows_2(&mut state);
171 }
172 #[cfg(not(aes_backend_soft = "compact"))]
173 {
174 add_round_key(&mut state, &rkeys[rk_off..(rk_off + 8)]);
175 inv_mix_columns_3(&mut state);
176 inv_sub_bytes(&mut state);
177 rk_off -= 8;
178
179 add_round_key(&mut state, &rkeys[rk_off..(rk_off + 8)]);
180 inv_mix_columns_2(&mut state);
181 inv_sub_bytes(&mut state);
182 rk_off -= 8;
183 }
184
185 add_round_key(&mut state, &rkeys[rk_off..(rk_off + 8)]);
186 inv_mix_columns_1(&mut state);
187 inv_sub_bytes(&mut state);
188 rk_off -= 8;
189
190 if rk_off == 0 {
191 break;
192 }
193
194 add_round_key(&mut state, &rkeys[rk_off..(rk_off + 8)]);
195 inv_mix_columns_0(&mut state);
196 inv_sub_bytes(&mut state);
197 rk_off -= 8;
198 }
199
200 add_round_key(&mut state, &rkeys[..8]);
201
202 W::inv_bitslice(&state)
203}