Skip to main content

aes/backends/fixslice/
sbox.rs

1//! S-box and inverse S-box (Boyar-Peralta-Calik)
2
3use super::Word;
4
5/// Bitsliced implementation of the AES Sbox based on Boyar, Peralta and Calik.
6///
7/// See: <http://www.cs.yale.edu/homes/peralta/CircuitStuff/SLP_AES_113.txt>
8///
9/// Note that the 4 bitwise NOT are moved to the key schedule.
10pub(super) fn sub_bytes<W: Word>(state: &mut [W]) {
11    debug_assert_eq!(state.len(), 8);
12
13    // Scheduled using https://github.com/Ko-/aes-armcortexm/tree/public/scheduler
14    // Inline "stack" comments reflect suggested stores and loads (ARM Cortex-M3 and M4)
15
16    let u7 = state[0];
17    let u6 = state[1];
18    let u5 = state[2];
19    let u4 = state[3];
20    let u3 = state[4];
21    let u2 = state[5];
22    let u1 = state[6];
23    let u0 = state[7];
24
25    let y14 = u3 ^ u5;
26    let y13 = u0 ^ u6;
27    let y12 = y13 ^ y14;
28    let t1 = u4 ^ y12;
29    let y15 = t1 ^ u5;
30    let t2 = y12 & y15;
31    let y6 = y15 ^ u7;
32    let y20 = t1 ^ u1;
33    // y12 -> stack
34    let y9 = u0 ^ u3;
35    // y20 -> stack
36    let y11 = y20 ^ y9;
37    // y9 -> stack
38    let t12 = y9 & y11;
39    // y6 -> stack
40    let y7 = u7 ^ y11;
41    let y8 = u0 ^ u5;
42    let t0 = u1 ^ u2;
43    let y10 = y15 ^ t0;
44    // y15 -> stack
45    let y17 = y10 ^ y11;
46    // y14 -> stack
47    let t13 = y14 & y17;
48    let t14 = t13 ^ t12;
49    // y17 -> stack
50    let y19 = y10 ^ y8;
51    // y10 -> stack
52    let t15 = y8 & y10;
53    let t16 = t15 ^ t12;
54    let y16 = t0 ^ y11;
55    // y11 -> stack
56    let y21 = y13 ^ y16;
57    // y13 -> stack
58    let t7 = y13 & y16;
59    // y16 -> stack
60    let y18 = u0 ^ y16;
61    let y1 = t0 ^ u7;
62    let y4 = y1 ^ u3;
63    // u7 -> stack
64    let t5 = y4 & u7;
65    let t6 = t5 ^ t2;
66    let t18 = t6 ^ t16;
67    let t22 = t18 ^ y19;
68    let y2 = y1 ^ u0;
69    let t10 = y2 & y7;
70    let t11 = t10 ^ t7;
71    let t20 = t11 ^ t16;
72    let t24 = t20 ^ y18;
73    let y5 = y1 ^ u6;
74    let t8 = y5 & y1;
75    let t9 = t8 ^ t7;
76    let t19 = t9 ^ t14;
77    let t23 = t19 ^ y21;
78    let y3 = y5 ^ y8;
79    // y6 <- stack
80    let t3 = y3 & y6;
81    let t4 = t3 ^ t2;
82    // y20 <- stack
83    let t17 = t4 ^ y20;
84    let t21 = t17 ^ t14;
85    let t26 = t21 & t23;
86    let t27 = t24 ^ t26;
87    let t31 = t22 ^ t26;
88    let t25 = t21 ^ t22;
89    // y4 -> stack
90    let t28 = t25 & t27;
91    let t29 = t28 ^ t22;
92    let z14 = t29 & y2;
93    let z5 = t29 & y7;
94    let t30 = t23 ^ t24;
95    let t32 = t31 & t30;
96    let t33 = t32 ^ t24;
97    let t35 = t27 ^ t33;
98    let t36 = t24 & t35;
99    let t38 = t27 ^ t36;
100    let t39 = t29 & t38;
101    let t40 = t25 ^ t39;
102    let t43 = t29 ^ t40;
103    // y16 <- stack
104    let z3 = t43 & y16;
105    let tc12 = z3 ^ z5;
106    // tc12 -> stack
107    // y13 <- stack
108    let z12 = t43 & y13;
109    let z13 = t40 & y5;
110    let z4 = t40 & y1;
111    let tc6 = z3 ^ z4;
112    let t34 = t23 ^ t33;
113    let t37 = t36 ^ t34;
114    let t41 = t40 ^ t37;
115    // y10 <- stack
116    let z8 = t41 & y10;
117    let z17 = t41 & y8;
118    let t44 = t33 ^ t37;
119    // y15 <- stack
120    let z0 = t44 & y15;
121    // z17 -> stack
122    // y12 <- stack
123    let z9 = t44 & y12;
124    let z10 = t37 & y3;
125    let z1 = t37 & y6;
126    let tc5 = z1 ^ z0;
127    let tc11 = tc6 ^ tc5;
128    // y4 <- stack
129    let z11 = t33 & y4;
130    let t42 = t29 ^ t33;
131    let t45 = t42 ^ t41;
132    // y17 <- stack
133    let z7 = t45 & y17;
134    let tc8 = z7 ^ tc6;
135    // y14 <- stack
136    let z16 = t45 & y14;
137    // y11 <- stack
138    let z6 = t42 & y11;
139    let tc16 = z6 ^ tc8;
140    // z14 -> stack
141    // y9 <- stack
142    let z15 = t42 & y9;
143    let tc20 = z15 ^ tc16;
144    let tc1 = z15 ^ z16;
145    let tc2 = z10 ^ tc1;
146    let tc21 = tc2 ^ z11;
147    let tc3 = z9 ^ tc2;
148    let s0 = tc3 ^ tc16;
149    let s3 = tc3 ^ tc11;
150    let s1 = s3 ^ tc16;
151    let tc13 = z13 ^ tc1;
152    // u7 <- stack
153    let z2 = t33 & u7;
154    let tc4 = z0 ^ z2;
155    let tc7 = z12 ^ tc4;
156    let tc9 = z8 ^ tc7;
157    let tc10 = tc8 ^ tc9;
158    // z14 <- stack
159    let tc17 = z14 ^ tc10;
160    let s5 = tc21 ^ tc17;
161    let tc26 = tc17 ^ tc20;
162    // z17 <- stack
163    let s2 = tc26 ^ z17;
164    // tc12 <- stack
165    let tc14 = tc4 ^ tc12;
166    let tc18 = tc13 ^ tc14;
167    let s6 = tc10 ^ tc18;
168    let s7 = z12 ^ tc18;
169    let s4 = tc14 ^ s3;
170
171    state[0] = s7;
172    state[1] = s6;
173    state[2] = s5;
174    state[3] = s4;
175    state[4] = s3;
176    state[5] = s2;
177    state[6] = s1;
178    state[7] = s0;
179}
180
181/// Note that the 4 bitwise NOT are accounted for here so that it is a true
182/// inverse of `sub_bytes`.
183pub(super) fn inv_sub_bytes<W: Word>(state: &mut [W]) {
184    debug_assert_eq!(state.len(), 8);
185
186    // Scheduled using https://github.com/Ko-/aes-armcortexm/tree/public/scheduler
187    // Inline "stack" comments reflect suggested stores and loads (ARM Cortex-M3 and M4)
188
189    let u7 = state[0];
190    let u6 = state[1];
191    let u5 = state[2];
192    let u4 = state[3];
193    let u3 = state[4];
194    let u2 = state[5];
195    let u1 = state[6];
196    let u0 = state[7];
197
198    let t23 = u0 ^ u3;
199    let t8 = u1 ^ t23;
200    let m2 = t23 & t8;
201    let t4 = u4 ^ t8;
202    let t22 = u1 ^ u3;
203    let t2 = u0 ^ u1;
204    let t1 = u3 ^ u4;
205    // t23 -> stack
206    let t9 = u7 ^ t1;
207    // t8 -> stack
208    let m7 = t22 & t9;
209    // t9 -> stack
210    let t24 = u4 ^ u7;
211    // m7 -> stack
212    let t10 = t2 ^ t24;
213    // u4 -> stack
214    let m14 = t2 & t10;
215    let r5 = u6 ^ u7;
216    // m2 -> stack
217    let t3 = t1 ^ r5;
218    // t2 -> stack
219    let t13 = t2 ^ r5;
220    let t19 = t22 ^ r5;
221    // t3 -> stack
222    let t17 = u2 ^ t19;
223    // t4 -> stack
224    let t25 = u2 ^ t1;
225    let r13 = u1 ^ u6;
226    // t25 -> stack
227    let t20 = t24 ^ r13;
228    // t17 -> stack
229    let m9 = t20 & t17;
230    // t20 -> stack
231    let r17 = u2 ^ u5;
232    // t22 -> stack
233    let t6 = t22 ^ r17;
234    // t13 -> stack
235    let m1 = t13 & t6;
236    let y5 = u0 ^ r17;
237    let m4 = t19 & y5;
238    let m5 = m4 ^ m1;
239    let m17 = m5 ^ t24;
240    let r18 = u5 ^ u6;
241    let t27 = t1 ^ r18;
242    let t15 = t10 ^ t27;
243    // t6 -> stack
244    let m11 = t1 & t15;
245    let m15 = m14 ^ m11;
246    let m21 = m17 ^ m15;
247    // t1 -> stack
248    // t4 <- stack
249    let m12 = t4 & t27;
250    let m13 = m12 ^ m11;
251    let t14 = t10 ^ r18;
252    let m3 = t14 ^ m1;
253    // m2 <- stack
254    let m16 = m3 ^ m2;
255    let m20 = m16 ^ m13;
256    // u4 <- stack
257    let r19 = u2 ^ u4;
258    let t16 = r13 ^ r19;
259    // t3 <- stack
260    let t26 = t3 ^ t16;
261    let m6 = t3 & t16;
262    let m8 = t26 ^ m6;
263    // t10 -> stack
264    // m7 <- stack
265    let m18 = m8 ^ m7;
266    let m22 = m18 ^ m13;
267    let m25 = m22 & m20;
268    let m26 = m21 ^ m25;
269    let m10 = m9 ^ m6;
270    let m19 = m10 ^ m15;
271    // t25 <- stack
272    let m23 = m19 ^ t25;
273    let m28 = m23 ^ m25;
274    let m24 = m22 ^ m23;
275    let m30 = m26 & m24;
276    let m39 = m23 ^ m30;
277    let m48 = m39 & y5;
278    let m57 = m39 & t19;
279    // m48 -> stack
280    let m36 = m24 ^ m25;
281    let m31 = m20 & m23;
282    let m27 = m20 ^ m21;
283    let m32 = m27 & m31;
284    let m29 = m28 & m27;
285    let m37 = m21 ^ m29;
286    // m39 -> stack
287    let m42 = m37 ^ m39;
288    let m52 = m42 & t15;
289    // t27 -> stack
290    // t1 <- stack
291    let m61 = m42 & t1;
292    let p0 = m52 ^ m61;
293    let p16 = m57 ^ m61;
294    // m57 -> stack
295    // t20 <- stack
296    let m60 = m37 & t20;
297    // p16 -> stack
298    // t17 <- stack
299    let m51 = m37 & t17;
300    let m33 = m27 ^ m25;
301    let m38 = m32 ^ m33;
302    let m43 = m37 ^ m38;
303    let m49 = m43 & t16;
304    let p6 = m49 ^ m60;
305    let p13 = m49 ^ m51;
306    let m58 = m43 & t3;
307    // t9 <- stack
308    let m50 = m38 & t9;
309    // t22 <- stack
310    let m59 = m38 & t22;
311    // p6 -> stack
312    let p1 = m58 ^ m59;
313    let p7 = p0 ^ p1;
314    let m34 = m21 & m22;
315    let m35 = m24 & m34;
316    let m40 = m35 ^ m36;
317    let m41 = m38 ^ m40;
318    let m45 = m42 ^ m41;
319    // t27 <- stack
320    let m53 = m45 & t27;
321    let p8 = m50 ^ m53;
322    let p23 = p7 ^ p8;
323    // t4 <- stack
324    let m62 = m45 & t4;
325    let p14 = m49 ^ m62;
326    let s6 = p14 ^ p23;
327    // t10 <- stack
328    let m54 = m41 & t10;
329    let p2 = m54 ^ m62;
330    let p22 = p2 ^ p7;
331    let s0 = p13 ^ p22;
332    let p17 = m58 ^ p2;
333    let p15 = m54 ^ m59;
334    // t2 <- stack
335    let m63 = m41 & t2;
336    // m39 <- stack
337    let m44 = m39 ^ m40;
338    // p17 -> stack
339    // t6 <- stack
340    let m46 = m44 & t6;
341    let p5 = m46 ^ m51;
342    // p23 -> stack
343    let p18 = m63 ^ p5;
344    let p24 = p5 ^ p7;
345    // m48 <- stack
346    let p12 = m46 ^ m48;
347    let s3 = p12 ^ p22;
348    // t13 <- stack
349    let m55 = m44 & t13;
350    let p9 = m55 ^ m63;
351    // p16 <- stack
352    let s7 = p9 ^ p16;
353    // t8 <- stack
354    let m47 = m40 & t8;
355    let p3 = m47 ^ m50;
356    let p19 = p2 ^ p3;
357    let s5 = p19 ^ p24;
358    let p11 = p0 ^ p3;
359    let p26 = p9 ^ p11;
360    // t23 <- stack
361    let m56 = m40 & t23;
362    let p4 = m48 ^ m56;
363    // p6 <- stack
364    let p20 = p4 ^ p6;
365    let p29 = p15 ^ p20;
366    let s1 = p26 ^ p29;
367    // m57 <- stack
368    let p10 = m57 ^ p4;
369    let p27 = p10 ^ p18;
370    // p23 <- stack
371    let s4 = p23 ^ p27;
372    let p25 = p6 ^ p10;
373    let p28 = p11 ^ p25;
374    // p17 <- stack
375    let s2 = p17 ^ p28;
376
377    state[0] = s7;
378    state[1] = s6;
379    state[2] = s5;
380    state[3] = s4;
381    state[4] = s3;
382    state[5] = s2;
383    state[6] = s1;
384    state[7] = s0;
385}
386
387/// NOT operations that are omitted in S-box.
388#[inline]
389pub(super) fn sub_bytes_nots<W: Word>(state: &mut [W]) {
390    debug_assert_eq!(state.len(), 8);
391    state[0] = !state[0];
392    state[1] = !state[1];
393    state[5] = !state[5];
394    state[6] = !state[6];
395}