2 * rijndael-alg.c v2.4 April '2000
4 * Optimised ANSI C code
6 * authors: v1.0: Antoon Bosselaers
7 * v2.0: Vincent Rijmen, K.U.Leuven
9 * v2.4: Vincent Rijmen, K.U.Leuven
11 * This code is placed in the public domain.
17 #include "rijndael-alg.h"
21 int rijndael_KeySched(word8 k
[MAXKC
][4], word8 W
[MAXROUNDS
+1][4][4], int ROUNDS
) {
22 /* Calculate the necessary round keys
23 * The number of calculations depends on keyBits and blockBits
25 int j
, r
, t
, rconpointer
= 0;
29 for (j
= KC
-1; j
>= 0; j
--) {
30 *((word32
*)tk
[j
]) = *((word32
*)k
[j
]);
34 /* copy values into round key array */
35 for (j
= 0; (j
< KC
) && (r
< ROUNDS
+ 1); ) {
36 for (; (j
< KC
) && (t
< 4); j
++, t
++) {
37 *((word32
*)W
[r
][t
]) = *((word32
*)tk
[j
]);
45 while (r
< ROUNDS
+ 1) { /* while not enough round key material calculated */
46 /* calculate new values */
47 tk
[0][0] ^= S
[tk
[KC
-1][1]];
48 tk
[0][1] ^= S
[tk
[KC
-1][2]];
49 tk
[0][2] ^= S
[tk
[KC
-1][3]];
50 tk
[0][3] ^= S
[tk
[KC
-1][0]];
51 tk
[0][0] ^= rcon
[rconpointer
++];
54 for (j
= 1; j
< KC
; j
++) {
55 *((word32
*)tk
[j
]) ^= *((word32
*)tk
[j
-1]);
58 for (j
= 1; j
< KC
/2; j
++) {
59 *((word32
*)tk
[j
]) ^= *((word32
*)tk
[j
-1]);
61 tk
[KC
/2][0] ^= S
[tk
[KC
/2 - 1][0]];
62 tk
[KC
/2][1] ^= S
[tk
[KC
/2 - 1][1]];
63 tk
[KC
/2][2] ^= S
[tk
[KC
/2 - 1][2]];
64 tk
[KC
/2][3] ^= S
[tk
[KC
/2 - 1][3]];
65 for (j
= KC
/2 + 1; j
< KC
; j
++) {
66 *((word32
*)tk
[j
]) ^= *((word32
*)tk
[j
-1]);
69 /* copy values into round key array */
70 for (j
= 0; (j
< KC
) && (r
< ROUNDS
+ 1); ) {
71 for (; (j
< KC
) && (t
< 4); j
++, t
++) {
72 *((word32
*)W
[r
][t
]) = *((word32
*)tk
[j
]);
83 int rijndael_KeyEncToDec(word8 W
[MAXROUNDS
+1][4][4], int ROUNDS
) {
87 for (r
= 1; r
< ROUNDS
; r
++) {
91 ^ *((word32
*)U2
[w
[1]])
92 ^ *((word32
*)U3
[w
[2]])
93 ^ *((word32
*)U4
[w
[3]]);
98 ^ *((word32
*)U2
[w
[1]])
99 ^ *((word32
*)U3
[w
[2]])
100 ^ *((word32
*)U4
[w
[3]]);
105 ^ *((word32
*)U2
[w
[1]])
106 ^ *((word32
*)U3
[w
[2]])
107 ^ *((word32
*)U4
[w
[3]]);
112 ^ *((word32
*)U2
[w
[1]])
113 ^ *((word32
*)U3
[w
[2]])
114 ^ *((word32
*)U4
[w
[3]]);
120 * Encrypt a single block.
122 int rijndael_Encrypt(const void *va
, void *vb
, word8 rk
[MAXROUNDS
+1][4][4], int ROUNDS
) {
128 *((word32
*)temp
[0]) = *((word32
*)(a
)) ^ *((word32
*)rk
[0][0]);
129 *((word32
*)temp
[1]) = *((word32
*)(a
+ 4)) ^ *((word32
*)rk
[0][1]);
130 *((word32
*)temp
[2]) = *((word32
*)(a
+ 8)) ^ *((word32
*)rk
[0][2]);
131 *((word32
*)temp
[3]) = *((word32
*)(a
+12)) ^ *((word32
*)rk
[0][3]);
132 *((word32
*)(b
)) = *((word32
*)T1
[temp
[0][0]])
133 ^ *((word32
*)T2
[temp
[1][1]])
134 ^ *((word32
*)T3
[temp
[2][2]])
135 ^ *((word32
*)T4
[temp
[3][3]]);
136 *((word32
*)(b
+ 4)) = *((word32
*)T1
[temp
[1][0]])
137 ^ *((word32
*)T2
[temp
[2][1]])
138 ^ *((word32
*)T3
[temp
[3][2]])
139 ^ *((word32
*)T4
[temp
[0][3]]);
140 *((word32
*)(b
+ 8)) = *((word32
*)T1
[temp
[2][0]])
141 ^ *((word32
*)T2
[temp
[3][1]])
142 ^ *((word32
*)T3
[temp
[0][2]])
143 ^ *((word32
*)T4
[temp
[1][3]]);
144 *((word32
*)(b
+12)) = *((word32
*)T1
[temp
[3][0]])
145 ^ *((word32
*)T2
[temp
[0][1]])
146 ^ *((word32
*)T3
[temp
[1][2]])
147 ^ *((word32
*)T4
[temp
[2][3]]);
148 for (r
= 1; r
< ROUNDS
-1; r
++) {
149 *((word32
*)temp
[0]) = *((word32
*)(b
)) ^ *((word32
*)rk
[r
][0]);
150 *((word32
*)temp
[1]) = *((word32
*)(b
+ 4)) ^ *((word32
*)rk
[r
][1]);
151 *((word32
*)temp
[2]) = *((word32
*)(b
+ 8)) ^ *((word32
*)rk
[r
][2]);
152 *((word32
*)temp
[3]) = *((word32
*)(b
+12)) ^ *((word32
*)rk
[r
][3]);
154 *((word32
*)(b
)) = *((word32
*)T1
[temp
[0][0]])
155 ^ *((word32
*)T2
[temp
[1][1]])
156 ^ *((word32
*)T3
[temp
[2][2]])
157 ^ *((word32
*)T4
[temp
[3][3]]);
158 *((word32
*)(b
+ 4)) = *((word32
*)T1
[temp
[1][0]])
159 ^ *((word32
*)T2
[temp
[2][1]])
160 ^ *((word32
*)T3
[temp
[3][2]])
161 ^ *((word32
*)T4
[temp
[0][3]]);
162 *((word32
*)(b
+ 8)) = *((word32
*)T1
[temp
[2][0]])
163 ^ *((word32
*)T2
[temp
[3][1]])
164 ^ *((word32
*)T3
[temp
[0][2]])
165 ^ *((word32
*)T4
[temp
[1][3]]);
166 *((word32
*)(b
+12)) = *((word32
*)T1
[temp
[3][0]])
167 ^ *((word32
*)T2
[temp
[0][1]])
168 ^ *((word32
*)T3
[temp
[1][2]])
169 ^ *((word32
*)T4
[temp
[2][3]]);
171 /* last round is special */
172 *((word32
*)temp
[0]) = *((word32
*)(b
)) ^ *((word32
*)rk
[ROUNDS
-1][0]);
173 *((word32
*)temp
[1]) = *((word32
*)(b
+ 4)) ^ *((word32
*)rk
[ROUNDS
-1][1]);
174 *((word32
*)temp
[2]) = *((word32
*)(b
+ 8)) ^ *((word32
*)rk
[ROUNDS
-1][2]);
175 *((word32
*)temp
[3]) = *((word32
*)(b
+12)) ^ *((word32
*)rk
[ROUNDS
-1][3]);
176 b
[ 0] = T1
[temp
[0][0]][1];
177 b
[ 1] = T1
[temp
[1][1]][1];
178 b
[ 2] = T1
[temp
[2][2]][1];
179 b
[ 3] = T1
[temp
[3][3]][1];
180 b
[ 4] = T1
[temp
[1][0]][1];
181 b
[ 5] = T1
[temp
[2][1]][1];
182 b
[ 6] = T1
[temp
[3][2]][1];
183 b
[ 7] = T1
[temp
[0][3]][1];
184 b
[ 8] = T1
[temp
[2][0]][1];
185 b
[ 9] = T1
[temp
[3][1]][1];
186 b
[10] = T1
[temp
[0][2]][1];
187 b
[11] = T1
[temp
[1][3]][1];
188 b
[12] = T1
[temp
[3][0]][1];
189 b
[13] = T1
[temp
[0][1]][1];
190 b
[14] = T1
[temp
[1][2]][1];
191 b
[15] = T1
[temp
[2][3]][1];
192 *((word32
*)(b
)) ^= *((word32
*)rk
[ROUNDS
][0]);
193 *((word32
*)(b
+ 4)) ^= *((word32
*)rk
[ROUNDS
][1]);
194 *((word32
*)(b
+ 8)) ^= *((word32
*)rk
[ROUNDS
][2]);
195 *((word32
*)(b
+12)) ^= *((word32
*)rk
[ROUNDS
][3]);
200 #ifdef INTERMEDIATE_VALUE_KAT
202 * Encrypt only a certain number of rounds.
203 * Only used in the Intermediate Value Known Answer Test.
205 int rijndaelEncryptRound(word8 a
[4][4], word8 rk
[MAXROUNDS
+1][4][4], int ROUNDS
, int rounds
) {
209 /* make number of rounds sane */
210 if (rounds
> ROUNDS
) {
214 *((word32
*)a
[0]) = *((word32
*)a
[0]) ^ *((word32
*)rk
[0][0]);
215 *((word32
*)a
[1]) = *((word32
*)a
[1]) ^ *((word32
*)rk
[0][1]);
216 *((word32
*)a
[2]) = *((word32
*)a
[2]) ^ *((word32
*)rk
[0][2]);
217 *((word32
*)a
[3]) = *((word32
*)a
[3]) ^ *((word32
*)rk
[0][3]);
219 for (r
= 1; (r
<= rounds
) && (r
< ROUNDS
); r
++) {
220 *((word32
*)temp
[0]) = *((word32
*)T1
[a
[0][0]])
221 ^ *((word32
*)T2
[a
[1][1]])
222 ^ *((word32
*)T3
[a
[2][2]])
223 ^ *((word32
*)T4
[a
[3][3]]);
224 *((word32
*)temp
[1]) = *((word32
*)T1
[a
[1][0]])
225 ^ *((word32
*)T2
[a
[2][1]])
226 ^ *((word32
*)T3
[a
[3][2]])
227 ^ *((word32
*)T4
[a
[0][3]]);
228 *((word32
*)temp
[2]) = *((word32
*)T1
[a
[2][0]])
229 ^ *((word32
*)T2
[a
[3][1]])
230 ^ *((word32
*)T3
[a
[0][2]])
231 ^ *((word32
*)T4
[a
[1][3]]);
232 *((word32
*)temp
[3]) = *((word32
*)T1
[a
[3][0]])
233 ^ *((word32
*)T2
[a
[0][1]])
234 ^ *((word32
*)T3
[a
[1][2]])
235 ^ *((word32
*)T4
[a
[2][3]]);
236 *((word32
*)a
[0]) = *((word32
*)temp
[0]) ^ *((word32
*)rk
[r
][0]);
237 *((word32
*)a
[1]) = *((word32
*)temp
[1]) ^ *((word32
*)rk
[r
][1]);
238 *((word32
*)a
[2]) = *((word32
*)temp
[2]) ^ *((word32
*)rk
[r
][2]);
239 *((word32
*)a
[3]) = *((word32
*)temp
[3]) ^ *((word32
*)rk
[r
][3]);
241 if (rounds
== ROUNDS
) {
242 /* last round is special */
243 temp
[0][0] = T1
[a
[0][0]][1];
244 temp
[0][1] = T1
[a
[1][1]][1];
245 temp
[0][2] = T1
[a
[2][2]][1];
246 temp
[0][3] = T1
[a
[3][3]][1];
247 temp
[1][0] = T1
[a
[1][0]][1];
248 temp
[1][1] = T1
[a
[2][1]][1];
249 temp
[1][2] = T1
[a
[3][2]][1];
250 temp
[1][3] = T1
[a
[0][3]][1];
251 temp
[2][0] = T1
[a
[2][0]][1];
252 temp
[2][1] = T1
[a
[3][1]][1];
253 temp
[2][2] = T1
[a
[0][2]][1];
254 temp
[2][3] = T1
[a
[1][3]][1];
255 temp
[3][0] = T1
[a
[3][0]][1];
256 temp
[3][1] = T1
[a
[0][1]][1];
257 temp
[3][2] = T1
[a
[1][2]][1];
258 temp
[3][3] = T1
[a
[2][3]][1];
259 *((word32
*)a
[0]) = *((word32
*)temp
[0]) ^ *((word32
*)rk
[ROUNDS
][0]);
260 *((word32
*)a
[1]) = *((word32
*)temp
[1]) ^ *((word32
*)rk
[ROUNDS
][1]);
261 *((word32
*)a
[2]) = *((word32
*)temp
[2]) ^ *((word32
*)rk
[ROUNDS
][2]);
262 *((word32
*)a
[3]) = *((word32
*)temp
[3]) ^ *((word32
*)rk
[ROUNDS
][3]);
267 #endif /* INTERMEDIATE_VALUE_KAT */
270 * Decrypt a single block.
272 int rijndael_Decrypt(const void *va
, void *vb
, word8 rk
[MAXROUNDS
+1][4][4], int ROUNDS
) {
278 *((word32
*)temp
[0]) = *((word32
*)(a
)) ^ *((word32
*)rk
[ROUNDS
][0]);
279 *((word32
*)temp
[1]) = *((word32
*)(a
+ 4)) ^ *((word32
*)rk
[ROUNDS
][1]);
280 *((word32
*)temp
[2]) = *((word32
*)(a
+ 8)) ^ *((word32
*)rk
[ROUNDS
][2]);
281 *((word32
*)temp
[3]) = *((word32
*)(a
+12)) ^ *((word32
*)rk
[ROUNDS
][3]);
283 *((word32
*)(b
)) = *((word32
*)T5
[temp
[0][0]])
284 ^ *((word32
*)T6
[temp
[3][1]])
285 ^ *((word32
*)T7
[temp
[2][2]])
286 ^ *((word32
*)T8
[temp
[1][3]]);
287 *((word32
*)(b
+ 4)) = *((word32
*)T5
[temp
[1][0]])
288 ^ *((word32
*)T6
[temp
[0][1]])
289 ^ *((word32
*)T7
[temp
[3][2]])
290 ^ *((word32
*)T8
[temp
[2][3]]);
291 *((word32
*)(b
+ 8)) = *((word32
*)T5
[temp
[2][0]])
292 ^ *((word32
*)T6
[temp
[1][1]])
293 ^ *((word32
*)T7
[temp
[0][2]])
294 ^ *((word32
*)T8
[temp
[3][3]]);
295 *((word32
*)(b
+12)) = *((word32
*)T5
[temp
[3][0]])
296 ^ *((word32
*)T6
[temp
[2][1]])
297 ^ *((word32
*)T7
[temp
[1][2]])
298 ^ *((word32
*)T8
[temp
[0][3]]);
299 for (r
= ROUNDS
-1; r
> 1; r
--) {
300 *((word32
*)temp
[0]) = *((word32
*)(b
)) ^ *((word32
*)rk
[r
][0]);
301 *((word32
*)temp
[1]) = *((word32
*)(b
+ 4)) ^ *((word32
*)rk
[r
][1]);
302 *((word32
*)temp
[2]) = *((word32
*)(b
+ 8)) ^ *((word32
*)rk
[r
][2]);
303 *((word32
*)temp
[3]) = *((word32
*)(b
+12)) ^ *((word32
*)rk
[r
][3]);
304 *((word32
*)(b
)) = *((word32
*)T5
[temp
[0][0]])
305 ^ *((word32
*)T6
[temp
[3][1]])
306 ^ *((word32
*)T7
[temp
[2][2]])
307 ^ *((word32
*)T8
[temp
[1][3]]);
308 *((word32
*)(b
+ 4)) = *((word32
*)T5
[temp
[1][0]])
309 ^ *((word32
*)T6
[temp
[0][1]])
310 ^ *((word32
*)T7
[temp
[3][2]])
311 ^ *((word32
*)T8
[temp
[2][3]]);
312 *((word32
*)(b
+ 8)) = *((word32
*)T5
[temp
[2][0]])
313 ^ *((word32
*)T6
[temp
[1][1]])
314 ^ *((word32
*)T7
[temp
[0][2]])
315 ^ *((word32
*)T8
[temp
[3][3]]);
316 *((word32
*)(b
+12)) = *((word32
*)T5
[temp
[3][0]])
317 ^ *((word32
*)T6
[temp
[2][1]])
318 ^ *((word32
*)T7
[temp
[1][2]])
319 ^ *((word32
*)T8
[temp
[0][3]]);
321 /* last round is special */
322 *((word32
*)temp
[0]) = *((word32
*)(b
)) ^ *((word32
*)rk
[1][0]);
323 *((word32
*)temp
[1]) = *((word32
*)(b
+ 4)) ^ *((word32
*)rk
[1][1]);
324 *((word32
*)temp
[2]) = *((word32
*)(b
+ 8)) ^ *((word32
*)rk
[1][2]);
325 *((word32
*)temp
[3]) = *((word32
*)(b
+12)) ^ *((word32
*)rk
[1][3]);
326 b
[ 0] = S5
[temp
[0][0]];
327 b
[ 1] = S5
[temp
[3][1]];
328 b
[ 2] = S5
[temp
[2][2]];
329 b
[ 3] = S5
[temp
[1][3]];
330 b
[ 4] = S5
[temp
[1][0]];
331 b
[ 5] = S5
[temp
[0][1]];
332 b
[ 6] = S5
[temp
[3][2]];
333 b
[ 7] = S5
[temp
[2][3]];
334 b
[ 8] = S5
[temp
[2][0]];
335 b
[ 9] = S5
[temp
[1][1]];
336 b
[10] = S5
[temp
[0][2]];
337 b
[11] = S5
[temp
[3][3]];
338 b
[12] = S5
[temp
[3][0]];
339 b
[13] = S5
[temp
[2][1]];
340 b
[14] = S5
[temp
[1][2]];
341 b
[15] = S5
[temp
[0][3]];
342 *((word32
*)(b
)) ^= *((word32
*)rk
[0][0]);
343 *((word32
*)(b
+ 4)) ^= *((word32
*)rk
[0][1]);
344 *((word32
*)(b
+ 8)) ^= *((word32
*)rk
[0][2]);
345 *((word32
*)(b
+12)) ^= *((word32
*)rk
[0][3]);
350 #ifdef INTERMEDIATE_VALUE_KAT
352 * Decrypt only a certain number of rounds.
353 * Only used in the Intermediate Value Known Answer Test.
354 * Operations rearranged such that the intermediate values
355 * of decryption correspond with the intermediate values
358 int rijndaelDecryptRound(word8 a
[4][4], word8 rk
[MAXROUNDS
+1][4][4], int ROUNDS
, int rounds
) {
360 word8 temp
[4], shift
;
362 /* make number of rounds sane */
363 if (rounds
> ROUNDS
) {
366 /* first round is special: */
367 *(word32
*)a
[0] ^= *(word32
*)rk
[ROUNDS
][0];
368 *(word32
*)a
[1] ^= *(word32
*)rk
[ROUNDS
][1];
369 *(word32
*)a
[2] ^= *(word32
*)rk
[ROUNDS
][2];
370 *(word32
*)a
[3] ^= *(word32
*)rk
[ROUNDS
][3];
371 for (i
= 0; i
< 4; i
++) {
372 a
[i
][0] = Si
[a
[i
][0]];
373 a
[i
][1] = Si
[a
[i
][1]];
374 a
[i
][2] = Si
[a
[i
][2]];
375 a
[i
][3] = Si
[a
[i
][3]];
377 for (i
= 1; i
< 4; i
++) {
379 temp
[0] = a
[(0 + shift
) & 3][i
];
380 temp
[1] = a
[(1 + shift
) & 3][i
];
381 temp
[2] = a
[(2 + shift
) & 3][i
];
382 temp
[3] = a
[(3 + shift
) & 3][i
];
388 /* ROUNDS-1 ordinary rounds */
389 for (r
= ROUNDS
-1; r
> rounds
; r
--) {
390 *(word32
*)a
[0] ^= *(word32
*)rk
[r
][0];
391 *(word32
*)a
[1] ^= *(word32
*)rk
[r
][1];
392 *(word32
*)a
[2] ^= *(word32
*)rk
[r
][2];
393 *(word32
*)a
[3] ^= *(word32
*)rk
[r
][3];
396 *((word32
*)U1
[a
[0][0]])
397 ^ *((word32
*)U2
[a
[0][1]])
398 ^ *((word32
*)U3
[a
[0][2]])
399 ^ *((word32
*)U4
[a
[0][3]]);
402 *((word32
*)U1
[a
[1][0]])
403 ^ *((word32
*)U2
[a
[1][1]])
404 ^ *((word32
*)U3
[a
[1][2]])
405 ^ *((word32
*)U4
[a
[1][3]]);
408 *((word32
*)U1
[a
[2][0]])
409 ^ *((word32
*)U2
[a
[2][1]])
410 ^ *((word32
*)U3
[a
[2][2]])
411 ^ *((word32
*)U4
[a
[2][3]]);
414 *((word32
*)U1
[a
[3][0]])
415 ^ *((word32
*)U2
[a
[3][1]])
416 ^ *((word32
*)U3
[a
[3][2]])
417 ^ *((word32
*)U4
[a
[3][3]]);
418 for (i
= 0; i
< 4; i
++) {
419 a
[i
][0] = Si
[a
[i
][0]];
420 a
[i
][1] = Si
[a
[i
][1]];
421 a
[i
][2] = Si
[a
[i
][2]];
422 a
[i
][3] = Si
[a
[i
][3]];
424 for (i
= 1; i
< 4; i
++) {
426 temp
[0] = a
[(0 + shift
) & 3][i
];
427 temp
[1] = a
[(1 + shift
) & 3][i
];
428 temp
[2] = a
[(2 + shift
) & 3][i
];
429 temp
[3] = a
[(3 + shift
) & 3][i
];
437 /* End with the extra key addition */
438 *(word32
*)a
[0] ^= *(word32
*)rk
[0][0];
439 *(word32
*)a
[1] ^= *(word32
*)rk
[0][1];
440 *(word32
*)a
[2] ^= *(word32
*)rk
[0][2];
441 *(word32
*)a
[3] ^= *(word32
*)rk
[0][3];
445 #endif /* INTERMEDIATE_VALUE_KAT */
448 * $PchId: rijndael_alg.c,v 1.2 2001/01/10 21:57:12 philip Exp $