1 /* rijndael-alg-ref.c v2.0 August '99
2 * Reference ANSI C code
3 * authors: Paulo Barreto
4 * Vincent Rijmen, K.U.Leuven
6 * This code is placed in the public domain.
13 #include "mvAesBoxes.dat"
16 MV_U8
mul1(MV_U8 aa
, MV_U8 bb
);
17 void KeyAddition(MV_U8 a
[4][MAXBC
], MV_U8 rk
[4][MAXBC
], MV_U8 BC
);
18 void ShiftRow128Enc(MV_U8 a
[4][MAXBC
]);
19 void ShiftRow128Dec(MV_U8 a
[4][MAXBC
]);
20 void Substitution(MV_U8 a
[4][MAXBC
], MV_U8 box
[256]);
21 void MixColumn(MV_U8 a
[4][MAXBC
], MV_U8 rk
[4][MAXBC
]);
22 void InvMixColumn(MV_U8 a
[4][MAXBC
]);
25 #define mul(aa, bb) (mask[bb] & Alogtable[aa + Logtable[bb]])
27 MV_U8
mul1(MV_U8 aa
, MV_U8 bb
)
29 return mask
[bb
] & Alogtable
[aa
+ Logtable
[bb
]];
33 void KeyAddition(MV_U8 a
[4][MAXBC
], MV_U8 rk
[4][MAXBC
], MV_U8 BC
)
35 /* Exor corresponding text input and round key input bytes
37 ((MV_U32
*)(&(a
[0][0])))[0] ^= ((MV_U32
*)(&(rk
[0][0])))[0];
38 ((MV_U32
*)(&(a
[1][0])))[0] ^= ((MV_U32
*)(&(rk
[1][0])))[0];
39 ((MV_U32
*)(&(a
[2][0])))[0] ^= ((MV_U32
*)(&(rk
[2][0])))[0];
40 ((MV_U32
*)(&(a
[3][0])))[0] ^= ((MV_U32
*)(&(rk
[3][0])))[0];
44 void ShiftRow128Enc(MV_U8 a
[4][MAXBC
]) {
45 /* Row 0 remains unchanged
46 * The other three rows are shifted a variable amount
55 ((MV_U32
*)(&(a
[1][0])))[0] = ((MV_U32
*)(&(tmp
[0])))[0];
67 ((MV_U32
*)(&(a
[2][0])))[0] = ((MV_U32
*)(&(tmp
[0])))[0];
79 ((MV_U32
*)(&(a
[3][0])))[0] = ((MV_U32
*)(&(tmp
[0])))[0];
88 void ShiftRow128Dec(MV_U8 a
[4][MAXBC
]) {
89 /* Row 0 remains unchanged
90 * The other three rows are shifted a variable amount
99 ((MV_U32
*)(&(a
[1][0])))[0] = ((MV_U32
*)(&(tmp
[0])))[0];
112 ((MV_U32
*)(&(a
[2][0])))[0] = ((MV_U32
*)(&(tmp
[0])))[0];
125 ((MV_U32
*)(&(a
[3][0])))[0] = ((MV_U32
*)(&(tmp
[0])))[0];
134 void Substitution(MV_U8 a
[4][MAXBC
], MV_U8 box
[256]) {
135 /* Replace every byte of the input by the byte at that place
136 * in the nonlinear S-box
140 for(i
= 0; i
< 4; i
++)
141 for(j
= 0; j
< 4; j
++) a
[i
][j
] = box
[a
[i
][j
]] ;
144 void MixColumn(MV_U8 a
[4][MAXBC
], MV_U8 rk
[4][MAXBC
]) {
145 /* Mix the four bytes of every column in a linear way
150 for(j
= 0; j
< 4; j
++){
151 b
[0][j
] = mul(25,a
[0][j
]) ^ mul(1,a
[1][j
]) ^ a
[2][j
] ^ a
[3][j
];
152 b
[1][j
] = mul(25,a
[1][j
]) ^ mul(1,a
[2][j
]) ^ a
[3][j
] ^ a
[0][j
];
153 b
[2][j
] = mul(25,a
[2][j
]) ^ mul(1,a
[3][j
]) ^ a
[0][j
] ^ a
[1][j
];
154 b
[3][j
] = mul(25,a
[3][j
]) ^ mul(1,a
[0][j
]) ^ a
[1][j
] ^ a
[2][j
];
156 for(i
= 0; i
< 4; i
++)
157 /*for(j = 0; j < BC; j++) a[i][j] = b[i][j];*/
158 ((MV_U32
*)(&(a
[i
][0])))[0] = ((MV_U32
*)(&(b
[i
][0])))[0] ^ ((MV_U32
*)(&(rk
[i
][0])))[0];;
161 void InvMixColumn(MV_U8 a
[4][MAXBC
]) {
162 /* Mix the four bytes of every column in a linear way
163 * This is the opposite operation of Mixcolumn
168 for(j
= 0; j
< 4; j
++){
169 b
[0][j
] = mul(223,a
[0][j
]) ^ mul(104,a
[1][j
]) ^ mul(238,a
[2][j
]) ^ mul(199,a
[3][j
]);
170 b
[1][j
] = mul(223,a
[1][j
]) ^ mul(104,a
[2][j
]) ^ mul(238,a
[3][j
]) ^ mul(199,a
[0][j
]);
171 b
[2][j
] = mul(223,a
[2][j
]) ^ mul(104,a
[3][j
]) ^ mul(238,a
[0][j
]) ^ mul(199,a
[1][j
]);
172 b
[3][j
] = mul(223,a
[3][j
]) ^ mul(104,a
[0][j
]) ^ mul(238,a
[1][j
]) ^ mul(199,a
[2][j
]);
174 for(i
= 0; i
< 4; i
++)
175 /*for(j = 0; j < BC; j++) a[i][j] = b[i][j];*/
176 ((MV_U32
*)(&(a
[i
][0])))[0] = ((MV_U32
*)(&(b
[i
][0])))[0];
179 int rijndaelKeySched (MV_U8 k
[4][MAXKC
], int keyBits
, int blockBits
, MV_U8 W
[MAXROUNDS
+1][4][MAXBC
])
181 /* Calculate the necessary round keys
182 * The number of calculations depends on keyBits and blockBits
185 int i
, j
, t
, rconpointer
= 0;
189 case 128: KC
= 4; break;
190 case 192: KC
= 6; break;
191 case 256: KC
= 8; break;
192 default : return (-1);
196 case 128: BC
= 4; break;
197 case 192: BC
= 6; break;
198 case 256: BC
= 8; break;
199 default : return (-2);
202 switch (keyBits
>= blockBits
? keyBits
: blockBits
) {
203 case 128: ROUNDS
= 10; break;
204 case 192: ROUNDS
= 12; break;
205 case 256: ROUNDS
= 14; break;
206 default : return (-3); /* this cannot happen */
210 for(j
= 0; j
< KC
; j
++)
211 for(i
= 0; i
< 4; i
++)
214 /* copy values into round key array */
215 for(j
= 0; (j
< KC
) && (t
< (ROUNDS
+1)*BC
); j
++, t
++)
216 for(i
= 0; i
< 4; i
++) W
[t
/ BC
][i
][t
% BC
] = tk
[i
][j
];
218 while (t
< (ROUNDS
+1)*BC
) { /* while not enough round key material calculated */
219 /* calculate new values */
220 for(i
= 0; i
< 4; i
++)
221 tk
[i
][0] ^= S
[tk
[(i
+1)%4][KC
-1]];
222 tk
[0][0] ^= rcon
[rconpointer
++];
225 for(j
= 1; j
< KC
; j
++)
226 for(i
= 0; i
< 4; i
++) tk
[i
][j
] ^= tk
[i
][j
-1];
228 for(j
= 1; j
< KC
/2; j
++)
229 for(i
= 0; i
< 4; i
++) tk
[i
][j
] ^= tk
[i
][j
-1];
230 for(i
= 0; i
< 4; i
++) tk
[i
][KC
/2] ^= S
[tk
[i
][KC
/2 - 1]];
231 for(j
= KC
/2 + 1; j
< KC
; j
++)
232 for(i
= 0; i
< 4; i
++) tk
[i
][j
] ^= tk
[i
][j
-1];
234 /* copy values into round key array */
235 for(j
= 0; (j
< KC
) && (t
< (ROUNDS
+1)*BC
); j
++, t
++)
236 for(i
= 0; i
< 4; i
++) W
[t
/ BC
][i
][t
% BC
] = tk
[i
][j
];
244 int rijndaelEncrypt128(MV_U8 a
[4][MAXBC
], MV_U8 rk
[MAXROUNDS
+1][4][MAXBC
], int rounds
)
246 /* Encryption of one block.
253 /* begin with a key addition
256 KeyAddition(a
,rk
[0],BC
);
258 /* ROUNDS-1 ordinary rounds
260 for(r
= 1; r
< ROUNDS
; r
++) {
264 /*KeyAddition(a,rk[r],BC);*/
267 /* Last round is special: there is no MixColumn
271 KeyAddition(a
,rk
[ROUNDS
],BC
);
277 int rijndaelDecrypt128(MV_U8 a
[4][MAXBC
], MV_U8 rk
[MAXROUNDS
+1][4][MAXBC
], int rounds
)
284 /* To decrypt: apply the inverse operations of the encrypt routine,
287 * (KeyAddition is an involution: it 's equal to its inverse)
288 * (the inverse of Substitution with table S is Substitution with the inverse table of S)
289 * (the inverse of Shiftrow is Shiftrow over a suitable distance)
292 /* First the special round:
293 * without InvMixColumn
294 * with extra KeyAddition
296 KeyAddition(a
,rk
[ROUNDS
],BC
);
300 /* ROUNDS-1 ordinary rounds
302 for(r
= ROUNDS
-1; r
> 0; r
--) {
303 KeyAddition(a
,rk
[r
],BC
);
310 /* End with the extra key addition
313 KeyAddition(a
,rk
[0],BC
);
This page took 0.096567 seconds and 5 git commands to generate.