1 /* rijndael-alg-fst.c v2.0 August '99
2 * Optimised ANSI C code
3 * authors: v1.0: Antoon Bosselaers
4 * v2.0: Vincent Rijmen
5 */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9
10 #include "rijndael-alg-fst.h"
11
12 #define SC ((BC - 4) >> 1)
13
14 #include "boxes-fst.dat"
15
16 static word8 shifts[3][4][2] = {
17 {{0, 0},
18 {1, 3},
19 {2, 2},
20 {3, 1}},
21
22 {{0, 0},
23 {1, 5},
24 {2, 4},
25 {3, 3}},
26
27 {{0, 0},
28 {1, 7},
29 {3, 5},
30 {4, 4}}
31 };
32
33
mul(word8 a,word8 b)34 word8 mul(word8 a, word8 b) {
35 /* multiply two elements of GF(2^m)
36 * needed for MixColumn and InvMixColumn
37 */
38 if (a && b)
39 return Alogtable[(Logtable[a] + Logtable[b])%255];
40 else
41 return 0;
42 }
43
KeyAddition(word8 a[4][4],word8 rk[4][4],word8 BC)44 void KeyAddition(word8 a[4][4], word8 rk[4][4], word8 BC) {
45 /* Exor corresponding text input and round key input bytes
46 */
47 int i, j;
48
49 for(i = 0; i < BC; i++)
50 for(j = 0; j < 4; j++)
51 a[i][j] ^= rk[i][j];
52 }
53
ShiftRow(word8 a[4][4],word8 d,word8 BC)54 void ShiftRow(word8 a[4][4], word8 d, word8 BC) {
55 /* Row 0 remains unchanged
56 * The other three rows are shifted a variable amount
57 */
58 word8 tmp[4];
59 int i, j;
60
61 for(i = 1; i < 4; i++) {
62 for(j = 0; j < BC; j++)
63 tmp[j] = a[(j + shifts[SC][i][d]) % BC][i];
64 for(j = 0; j < BC; j++)
65 a[j][i] = tmp[j];
66 }
67 }
68
Substitution(word8 a[4][4],word8 box[256],word8 BC)69 void Substitution(word8 a[4][4], word8 box[256], word8 BC) {
70 /* Replace every byte of the input by the byte at that place
71 * in the nonlinear S-box
72 */
73 int i, j;
74
75 for(i = 0; i < BC; i++)
76 for(j = 0; j < 4; j++)
77 a[i][j] = box[a[i][j]] ;
78 }
79
MixColumn(word8 a[4][4],word8 BC)80 void MixColumn(word8 a[4][4], word8 BC) {
81 /* Mix the four bytes of every column in a linear way
82 */
83 word8 b[4][4];
84 int i, j;
85
86 for(j = 0; j < BC; j++)
87 for(i = 0; i < 4; i++)
88 b[j][i] = mul(2,a[j][i])
89 ^ mul(3,a[j][(i + 1) % 4])
90 ^ a[j][(i + 2) % 4]
91 ^ a[j][(i + 3) % 4];
92 for(i = 0; i < 4; i++)
93 for(j = 0; j < BC; j++)
94 a[j][i] = b[j][i];
95 }
96
InvMixColumn(word8 a[4][4],word8 BC)97 void InvMixColumn(word8 a[4][4], word8 BC) {
98 /* Mix the four bytes of every column in a linear way
99 * This is the opposite operation of Mixcolumn
100 */
101 int j;
102
103 for(j = 0; j < BC; j++)
104 *((word32*)a[j]) = *((word32*)U1[a[j][0]])
105 ^ *((word32*)U2[a[j][1]])
106 ^ *((word32*)U3[a[j][2]])
107 ^ *((word32*)U4[a[j][3]]);
108
109
110 }
111
rijndaelKeySched(word8 k[MAXKC][4],int keyBits,word8 W[MAXROUNDS+1][4][4])112 int rijndaelKeySched (word8 k[MAXKC][4], int keyBits, word8 W[MAXROUNDS+1][4][4])
113 {
114 /* Calculate the necessary round keys
115 * The number of calculations depends on keyBits and blockBits
116 */
117 int j, r, t, rconpointer = 0;
118 word8 tk[MAXKC][4];
119 int KC = ROUNDS - 6;
120
121 for(j = KC-1; j >= 0; j--)
122 *((word32*)tk[j]) = *((word32*)k[j]);
123 r = 0;
124 t = 0;
125 /* copy values into round key array */
126 for(j = 0; (j < KC) && (r < (ROUNDS+1)); ) {
127 for (; (j < KC) && (t < 4); j++, t++)
128 *((word32*)W[r][t]) = *((word32*)tk[j]);
129 if (t == 4) {
130 r++;
131 t = 0;
132 }
133 }
134
135 while (r < (ROUNDS+1)) { /* while not enough round key material calculated */
136 /* calculate new values */
137 tk[0][0] ^= S[tk[KC-1][1]];
138 tk[0][1] ^= S[tk[KC-1][2]];
139 tk[0][2] ^= S[tk[KC-1][3]];
140 tk[0][3] ^= S[tk[KC-1][0]];
141 tk[0][0] ^= rcon[rconpointer++];
142
143 if (KC != 8)
144 for(j = 1; j < KC; j++)
145 *((word32*)tk[j]) ^= *((word32*)tk[j-1]);
146 else {
147 for(j = 1; j < KC/2; j++)
148 *((word32*)tk[j]) ^= *((word32*)tk[j-1]);
149 tk[KC/2][0] ^= S[tk[KC/2 - 1][0]];
150 tk[KC/2][1] ^= S[tk[KC/2 - 1][1]];
151 tk[KC/2][2] ^= S[tk[KC/2 - 1][2]];
152 tk[KC/2][3] ^= S[tk[KC/2 - 1][3]];
153 for(j = KC/2 + 1; j < KC; j++)
154 *((word32*)tk[j]) ^= *((word32*)tk[j-1]);
155 }
156 /* copy values into round key array */
157 for(j = 0; (j < KC) && (r < (ROUNDS+1)); ) {
158 for (; (j < KC) && (t < 4); j++, t++)
159 *((word32*)W[r][t]) = *((word32*)tk[j]);
160 if (t == 4) {
161 r++;
162 t = 0;
163 }
164 }
165 }
166
167 return 0;
168 }
169
rijndaelKeyEnctoDec(int keyBits,word8 W[MAXROUNDS+1][4][4])170 int rijndaelKeyEnctoDec (int keyBits, word8 W[MAXROUNDS+1][4][4])
171 {
172 int r;
173
174 for (r = 1; r < ROUNDS; r++) {
175 InvMixColumn(W[r], 4);
176 }
177 return 0;
178 }
179
rijndaelEncrypt(word8 a[16],word8 b[16],word8 rk[MAXROUNDS+1][4][4])180 int rijndaelEncrypt (word8 a[16], word8 b[16], word8 rk[MAXROUNDS+1][4][4])
181 {
182 /* Encryption of one block.
183 */
184 int r;
185 word8 temp[4][4];
186
187 *((word32*)temp[0]) = *((word32*)a) ^ *((word32*)rk[0][0]);
188 *((word32*)temp[1]) = *((word32*)(a+4)) ^ *((word32*)rk[0][1]);
189 *((word32*)temp[2]) = *((word32*)(a+8)) ^ *((word32*)rk[0][2]);
190 *((word32*)temp[3]) = *((word32*)(a+12)) ^ *((word32*)rk[0][3]);
191 *((word32*)b) = *((word32*)T1[temp[0][0]])
192 ^ *((word32*)T2[temp[1][1]])
193 ^ *((word32*)T3[temp[2][2]])
194 ^ *((word32*)T4[temp[3][3]]);
195 *((word32*)(b+4)) = *((word32*)T1[temp[1][0]])
196 ^ *((word32*)T2[temp[2][1]])
197 ^ *((word32*)T3[temp[3][2]])
198 ^ *((word32*)T4[temp[0][3]]);
199 *((word32*)(b+8)) = *((word32*)T1[temp[2][0]])
200 ^ *((word32*)T2[temp[3][1]])
201 ^ *((word32*)T3[temp[0][2]])
202 ^ *((word32*)T4[temp[1][3]]);
203 *((word32*)(b+12)) = *((word32*)T1[temp[3][0]])
204 ^ *((word32*)T2[temp[0][1]])
205 ^ *((word32*)T3[temp[1][2]])
206 ^ *((word32*)T4[temp[2][3]]);
207 for(r = 1; r < ROUNDS-1; r++) {
208 *((word32*)temp[0]) = *((word32*)b) ^ *((word32*)rk[r][0]);
209 *((word32*)temp[1]) = *((word32*)(b+4)) ^ *((word32*)rk[r][1]);
210 *((word32*)temp[2]) = *((word32*)(b+8)) ^ *((word32*)rk[r][2]);
211 *((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[r][3]);
212 *((word32*)b) = *((word32*)T1[temp[0][0]])
213 ^ *((word32*)T2[temp[1][1]])
214 ^ *((word32*)T3[temp[2][2]])
215 ^ *((word32*)T4[temp[3][3]]);
216 *((word32*)(b+4)) = *((word32*)T1[temp[1][0]])
217 ^ *((word32*)T2[temp[2][1]])
218 ^ *((word32*)T3[temp[3][2]])
219 ^ *((word32*)T4[temp[0][3]]);
220 *((word32*)(b+8)) = *((word32*)T1[temp[2][0]])
221 ^ *((word32*)T2[temp[3][1]])
222 ^ *((word32*)T3[temp[0][2]])
223 ^ *((word32*)T4[temp[1][3]]);
224 *((word32*)(b+12)) = *((word32*)T1[temp[3][0]])
225 ^ *((word32*)T2[temp[0][1]])
226 ^ *((word32*)T3[temp[1][2]])
227 ^ *((word32*)T4[temp[2][3]]);
228 }
229 /* last round is special */
230 *((word32*)temp[0]) = *((word32*)b) ^ *((word32*)rk[ROUNDS-1][0]);
231 *((word32*)temp[1]) = *((word32*)(b+4)) ^ *((word32*)rk[ROUNDS-1][1]);
232 *((word32*)temp[2]) = *((word32*)(b+8)) ^ *((word32*)rk[ROUNDS-1][2]);
233 *((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[ROUNDS-1][3]);
234 b[0] = T1[temp[0][0]][1];
235 b[1] = T1[temp[1][1]][1];
236 b[2] = T1[temp[2][2]][1];
237 b[3] = T1[temp[3][3]][1];
238 b[4] = T1[temp[1][0]][1];
239 b[5] = T1[temp[2][1]][1];
240 b[6] = T1[temp[3][2]][1];
241 b[7] = T1[temp[0][3]][1];
242 b[8] = T1[temp[2][0]][1];
243 b[9] = T1[temp[3][1]][1];
244 b[10] = T1[temp[0][2]][1];
245 b[11] = T1[temp[1][3]][1];
246 b[12] = T1[temp[3][0]][1];
247 b[13] = T1[temp[0][1]][1];
248 b[14] = T1[temp[1][2]][1];
249 b[15] = T1[temp[2][3]][1];
250 *((word32*)b) ^= *((word32*)rk[ROUNDS][0]);
251 *((word32*)(b+4)) ^= *((word32*)rk[ROUNDS][1]);
252 *((word32*)(b+8)) ^= *((word32*)rk[ROUNDS][2]);
253 *((word32*)(b+12)) ^= *((word32*)rk[ROUNDS][3]);
254
255 return 0;
256 }
257
rijndaelEncryptRound(word8 a[4][4],word8 rk[MAXROUNDS+1][4][4],int rounds)258 int rijndaelEncryptRound (word8 a[4][4],
259 word8 rk[MAXROUNDS+1][4][4], int rounds)
260 /* Encrypt only a certain number of rounds.
261 * Only used in the Intermediate Value Known Answer Test.
262 */
263 {
264 int r;
265 word8 temp[4][4];
266
267
268 /* make number of rounds sane */
269 if (rounds > ROUNDS) rounds = ROUNDS;
270
271 *((word32*)a[0]) = *((word32*)a[0]) ^ *((word32*)rk[0][0]);
272 *((word32*)a[1]) = *((word32*)a[1]) ^ *((word32*)rk[0][1]);
273 *((word32*)a[2]) = *((word32*)a[2]) ^ *((word32*)rk[0][2]);
274 *((word32*)a[3]) = *((word32*)a[3]) ^ *((word32*)rk[0][3]);
275
276 for(r = 1; (r <= rounds) && (r < ROUNDS); r++) {
277 *((word32*)temp[0]) = *((word32*)T1[a[0][0]])
278 ^ *((word32*)T2[a[1][1]])
279 ^ *((word32*)T3[a[2][2]])
280 ^ *((word32*)T4[a[3][3]]);
281 *((word32*)temp[1]) = *((word32*)T1[a[1][0]])
282 ^ *((word32*)T2[a[2][1]])
283 ^ *((word32*)T3[a[3][2]])
284 ^ *((word32*)T4[a[0][3]]);
285 *((word32*)temp[2]) = *((word32*)T1[a[2][0]])
286 ^ *((word32*)T2[a[3][1]])
287 ^ *((word32*)T3[a[0][2]])
288 ^ *((word32*)T4[a[1][3]]);
289 *((word32*)temp[3]) = *((word32*)T1[a[3][0]])
290 ^ *((word32*)T2[a[0][1]])
291 ^ *((word32*)T3[a[1][2]])
292 ^ *((word32*)T4[a[2][3]]);
293 *((word32*)a[0]) = *((word32*)temp[0]) ^ *((word32*)rk[r][0]);
294 *((word32*)a[1]) = *((word32*)temp[1]) ^ *((word32*)rk[r][1]);
295 *((word32*)a[2]) = *((word32*)temp[2]) ^ *((word32*)rk[r][2]);
296 *((word32*)a[3]) = *((word32*)temp[3]) ^ *((word32*)rk[r][3]);
297 }
298 if (rounds == ROUNDS) {
299 /* last round is special */
300 temp[0][0] = T1[a[0][0]][1];
301 temp[0][1] = T1[a[1][1]][1];
302 temp[0][2] = T1[a[2][2]][1];
303 temp[0][3] = T1[a[3][3]][1];
304 temp[1][0] = T1[a[1][0]][1];
305 temp[1][1] = T1[a[2][1]][1];
306 temp[1][2] = T1[a[3][2]][1];
307 temp[1][3] = T1[a[0][3]][1];
308 temp[2][0] = T1[a[2][0]][1];
309 temp[2][1] = T1[a[3][1]][1];
310 temp[2][2] = T1[a[0][2]][1];
311 temp[2][3] = T1[a[1][3]][1];
312 temp[3][0] = T1[a[3][0]][1];
313 temp[3][1] = T1[a[0][1]][1];
314 temp[3][2] = T1[a[1][2]][1];
315 temp[3][3] = T1[a[2][3]][1];
316 *((word32*)a[0]) = *((word32*)temp[0]) ^ *((word32*)rk[ROUNDS][0]);
317 *((word32*)a[1]) = *((word32*)temp[1]) ^ *((word32*)rk[ROUNDS][1]);
318 *((word32*)a[2]) = *((word32*)temp[2]) ^ *((word32*)rk[ROUNDS][2]);
319 *((word32*)a[3]) = *((word32*)temp[3]) ^ *((word32*)rk[ROUNDS][3]);
320 }
321
322 return 0;
323 }
324
325
rijndaelDecrypt(word8 a[16],word8 b[16],word8 rk[MAXROUNDS+1][4][4])326 int rijndaelDecrypt (word8 a[16], word8 b[16], word8 rk[MAXROUNDS+1][4][4])
327 {
328 int r;
329 word8 temp[4][4];
330
331
332 *((word32*)temp[0]) = *((word32*)a) ^ *((word32*)rk[ROUNDS][0]);
333 *((word32*)temp[1]) = *((word32*)(a+4)) ^ *((word32*)rk[ROUNDS][1]);
334 *((word32*)temp[2]) = *((word32*)(a+8)) ^ *((word32*)rk[ROUNDS][2]);
335 *((word32*)temp[3]) = *((word32*)(a+12)) ^ *((word32*)rk[ROUNDS][3]);
336 *((word32*)b) = *((word32*)T5[temp[0][0]])
337 ^ *((word32*)T6[temp[3][1]])
338 ^ *((word32*)T7[temp[2][2]])
339 ^ *((word32*)T8[temp[1][3]]);
340 *((word32*)(b+4)) = *((word32*)T5[temp[1][0]])
341 ^ *((word32*)T6[temp[0][1]])
342 ^ *((word32*)T7[temp[3][2]])
343 ^ *((word32*)T8[temp[2][3]]);
344 *((word32*)(b+8)) = *((word32*)T5[temp[2][0]])
345 ^ *((word32*)T6[temp[1][1]])
346 ^ *((word32*)T7[temp[0][2]])
347 ^ *((word32*)T8[temp[3][3]]);
348 *((word32*)(b+12)) = *((word32*)T5[temp[3][0]])
349 ^ *((word32*)T6[temp[2][1]])
350 ^ *((word32*)T7[temp[1][2]])
351 ^ *((word32*)T8[temp[0][3]]);
352 for(r = ROUNDS-1; r > 1; r--) {
353 *((word32*)temp[0]) = *((word32*)b) ^ *((word32*)rk[r][0]);
354 *((word32*)temp[1]) = *((word32*)(b+4)) ^ *((word32*)rk[r][1]);
355 *((word32*)temp[2]) = *((word32*)(b+8)) ^ *((word32*)rk[r][2]);
356 *((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[r][3]);
357 *((word32*)b) = *((word32*)T5[temp[0][0]])
358 ^ *((word32*)T6[temp[3][1]])
359 ^ *((word32*)T7[temp[2][2]])
360 ^ *((word32*)T8[temp[1][3]]);
361 *((word32*)(b+4)) = *((word32*)T5[temp[1][0]])
362 ^ *((word32*)T6[temp[0][1]])
363 ^ *((word32*)T7[temp[3][2]])
364 ^ *((word32*)T8[temp[2][3]]);
365 *((word32*)(b+8)) = *((word32*)T5[temp[2][0]])
366 ^ *((word32*)T6[temp[1][1]])
367 ^ *((word32*)T7[temp[0][2]])
368 ^ *((word32*)T8[temp[3][3]]);
369 *((word32*)(b+12)) = *((word32*)T5[temp[3][0]])
370 ^ *((word32*)T6[temp[2][1]])
371 ^ *((word32*)T7[temp[1][2]])
372 ^ *((word32*)T8[temp[0][3]]);
373 }
374 /* last round is special */
375 *((word32*)temp[0]) = *((word32*)b) ^ *((word32*)rk[1][0]);
376 *((word32*)temp[1]) = *((word32*)(b+4)) ^ *((word32*)rk[1][1]);
377 *((word32*)temp[2]) = *((word32*)(b+8)) ^ *((word32*)rk[1][2]);
378 *((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[1][3]);
379 b[0] = S5[temp[0][0]];
380 b[1] = S5[temp[3][1]];
381 b[2] = S5[temp[2][2]];
382 b[3] = S5[temp[1][3]];
383 b[4] = S5[temp[1][0]];
384 b[5] = S5[temp[0][1]];
385 b[6] = S5[temp[3][2]];
386 b[7] = S5[temp[2][3]];
387 b[8] = S5[temp[2][0]];
388 b[9] = S5[temp[1][1]];
389 b[10] = S5[temp[0][2]];
390 b[11] = S5[temp[3][3]];
391 b[12] = S5[temp[3][0]];
392 b[13] = S5[temp[2][1]];
393 b[14] = S5[temp[1][2]];
394 b[15] = S5[temp[0][3]];
395 *((word32*)b) ^= *((word32*)rk[0][0]);
396 *((word32*)(b+4)) ^= *((word32*)rk[0][1]);
397 *((word32*)(b+8)) ^= *((word32*)rk[0][2]);
398 *((word32*)(b+12)) ^= *((word32*)rk[0][3]);
399
400 return 0;
401 }
402
403
rijndaelDecryptRound(word8 a[4][4],word8 rk[MAXROUNDS+1][4][4],int rounds)404 int rijndaelDecryptRound (word8 a[4][4],
405 word8 rk[MAXROUNDS+1][4][4], int rounds)
406 /* Decrypt only a certain number of rounds.
407 * Only used in the Intermediate Value Known Answer Test.
408 * Operations rearranged such that the intermediate values
409 * of decryption correspond with the intermediate values
410 * of encryption.
411 */
412 {
413 int r;
414
415
416 /* make number of rounds sane */
417 if (rounds > ROUNDS) rounds = ROUNDS;
418
419 /* First the special round:
420 * without InvMixColumn
421 * with extra KeyAddition
422 */
423 KeyAddition(a,rk[ROUNDS],4);
424 Substitution(a,Si,4);
425 ShiftRow(a,1,4);
426
427 /* ROUNDS-1 ordinary rounds
428 */
429 for(r = ROUNDS-1; r > rounds; r--) {
430 KeyAddition(a,rk[r],4);
431 InvMixColumn(a,4);
432 Substitution(a,Si,4);
433 ShiftRow(a,1,4);
434 }
435
436 if (rounds == 0) {
437 /* End with the extra key addition
438 */
439 KeyAddition(a,rk[0],4);
440 }
441
442 return 0;
443 }
444