Import release 0.1.16
[secnet] / serpent.c
1 /*
2 * This file is
3 * Copyright (C) 1998 Ross Anderson, Eli Biham, Lars Knudsen
4 *
5 * For more information see http://www.cl.cam.ac.uk/users/rja14/serpent.html
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software Foundation,
19 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 */
22
23 #include "secnet.h"
24
25 #include "serpent.h"
26 #include "serpentsboxes.h"
27
28 void serpent_makekey(struct keyInstance *key, int keyLen,
29 uint8_t *keyMaterial)
30 {
31 uint32_t i,j;
32 uint32_t w[132],k[132];
33
34 for(i=0; i<keyLen/32; i++)
35 w[i]=GET_32BIT_MSB_FIRST(keyMaterial + (keyLen/8 - i*4) - 4);
36 if(keyLen<256)
37 w[i]=(GET_32BIT_MSB_FIRST(keyMaterial + (keyLen/8 - i*4) - 4)
38 & ((1L<<((keyLen&31)))-1)) | (1L<<((keyLen&31)));
39 for(i++; i<8; i++)
40 w[i]=0;
41 for(i=8; i<16; i++)
42 w[i]=ROL(w[i-8]^w[i-5]^w[i-3]^w[i-1]^PHI^(i-8),11);
43 for(i=0; i<8; i++)
44 w[i]=w[i+8];
45 for(i=8; i<132; i++)
46 w[i]=ROL(w[i-8]^w[i-5]^w[i-3]^w[i-1]^PHI^i,11);
47
48 RND03(w[ 0], w[ 1], w[ 2], w[ 3], k[ 0], k[ 1], k[ 2], k[ 3]);
49 RND02(w[ 4], w[ 5], w[ 6], w[ 7], k[ 4], k[ 5], k[ 6], k[ 7]);
50 RND01(w[ 8], w[ 9], w[ 10], w[ 11], k[ 8], k[ 9], k[ 10], k[ 11]);
51 RND00(w[ 12], w[ 13], w[ 14], w[ 15], k[ 12], k[ 13], k[ 14], k[ 15]);
52 RND31(w[ 16], w[ 17], w[ 18], w[ 19], k[ 16], k[ 17], k[ 18], k[ 19]);
53 RND30(w[ 20], w[ 21], w[ 22], w[ 23], k[ 20], k[ 21], k[ 22], k[ 23]);
54 RND29(w[ 24], w[ 25], w[ 26], w[ 27], k[ 24], k[ 25], k[ 26], k[ 27]);
55 RND28(w[ 28], w[ 29], w[ 30], w[ 31], k[ 28], k[ 29], k[ 30], k[ 31]);
56 RND27(w[ 32], w[ 33], w[ 34], w[ 35], k[ 32], k[ 33], k[ 34], k[ 35]);
57 RND26(w[ 36], w[ 37], w[ 38], w[ 39], k[ 36], k[ 37], k[ 38], k[ 39]);
58 RND25(w[ 40], w[ 41], w[ 42], w[ 43], k[ 40], k[ 41], k[ 42], k[ 43]);
59 RND24(w[ 44], w[ 45], w[ 46], w[ 47], k[ 44], k[ 45], k[ 46], k[ 47]);
60 RND23(w[ 48], w[ 49], w[ 50], w[ 51], k[ 48], k[ 49], k[ 50], k[ 51]);
61 RND22(w[ 52], w[ 53], w[ 54], w[ 55], k[ 52], k[ 53], k[ 54], k[ 55]);
62 RND21(w[ 56], w[ 57], w[ 58], w[ 59], k[ 56], k[ 57], k[ 58], k[ 59]);
63 RND20(w[ 60], w[ 61], w[ 62], w[ 63], k[ 60], k[ 61], k[ 62], k[ 63]);
64 RND19(w[ 64], w[ 65], w[ 66], w[ 67], k[ 64], k[ 65], k[ 66], k[ 67]);
65 RND18(w[ 68], w[ 69], w[ 70], w[ 71], k[ 68], k[ 69], k[ 70], k[ 71]);
66 RND17(w[ 72], w[ 73], w[ 74], w[ 75], k[ 72], k[ 73], k[ 74], k[ 75]);
67 RND16(w[ 76], w[ 77], w[ 78], w[ 79], k[ 76], k[ 77], k[ 78], k[ 79]);
68 RND15(w[ 80], w[ 81], w[ 82], w[ 83], k[ 80], k[ 81], k[ 82], k[ 83]);
69 RND14(w[ 84], w[ 85], w[ 86], w[ 87], k[ 84], k[ 85], k[ 86], k[ 87]);
70 RND13(w[ 88], w[ 89], w[ 90], w[ 91], k[ 88], k[ 89], k[ 90], k[ 91]);
71 RND12(w[ 92], w[ 93], w[ 94], w[ 95], k[ 92], k[ 93], k[ 94], k[ 95]);
72 RND11(w[ 96], w[ 97], w[ 98], w[ 99], k[ 96], k[ 97], k[ 98], k[ 99]);
73 RND10(w[100], w[101], w[102], w[103], k[100], k[101], k[102], k[103]);
74 RND09(w[104], w[105], w[106], w[107], k[104], k[105], k[106], k[107]);
75 RND08(w[108], w[109], w[110], w[111], k[108], k[109], k[110], k[111]);
76 RND07(w[112], w[113], w[114], w[115], k[112], k[113], k[114], k[115]);
77 RND06(w[116], w[117], w[118], w[119], k[116], k[117], k[118], k[119]);
78 RND05(w[120], w[121], w[122], w[123], k[120], k[121], k[122], k[123]);
79 RND04(w[124], w[125], w[126], w[127], k[124], k[125], k[126], k[127]);
80 RND03(w[128], w[129], w[130], w[131], k[128], k[129], k[130], k[131]);
81
82 for(i=0; i<=32; i++)
83 for(j=0; j<4; j++)
84 key->subkeys[i][j] = k[4*i+j];
85 }
86
87 void serpent_encrypt(struct keyInstance *key,
88 uint8_t plaintext[16],
89 uint8_t ciphertext[16])
90 {
91 register uint32_t x0, x1, x2, x3;
92 register uint32_t y0, y1, y2, y3;
93
94 x0=GET_32BIT_MSB_FIRST(plaintext+12);
95 x1=GET_32BIT_MSB_FIRST(plaintext+8);
96 x2=GET_32BIT_MSB_FIRST(plaintext+4);
97 x3=GET_32BIT_MSB_FIRST(plaintext);
98
99 /* Start to encrypt the plaintext x */
100 keying(x0, x1, x2, x3, key->subkeys[ 0]);
101 RND00(x0, x1, x2, x3, y0, y1, y2, y3);
102 transform(y0, y1, y2, y3, x0, x1, x2, x3);
103 keying(x0, x1, x2, x3, key->subkeys[ 1]);
104 RND01(x0, x1, x2, x3, y0, y1, y2, y3);
105 transform(y0, y1, y2, y3, x0, x1, x2, x3);
106 keying(x0, x1, x2, x3, key->subkeys[ 2]);
107 RND02(x0, x1, x2, x3, y0, y1, y2, y3);
108 transform(y0, y1, y2, y3, x0, x1, x2, x3);
109 keying(x0, x1, x2, x3, key->subkeys[ 3]);
110 RND03(x0, x1, x2, x3, y0, y1, y2, y3);
111 transform(y0, y1, y2, y3, x0, x1, x2, x3);
112 keying(x0, x1, x2, x3, key->subkeys[ 4]);
113 RND04(x0, x1, x2, x3, y0, y1, y2, y3);
114 transform(y0, y1, y2, y3, x0, x1, x2, x3);
115 keying(x0, x1, x2, x3, key->subkeys[ 5]);
116 RND05(x0, x1, x2, x3, y0, y1, y2, y3);
117 transform(y0, y1, y2, y3, x0, x1, x2, x3);
118 keying(x0, x1, x2, x3, key->subkeys[ 6]);
119 RND06(x0, x1, x2, x3, y0, y1, y2, y3);
120 transform(y0, y1, y2, y3, x0, x1, x2, x3);
121 keying(x0, x1, x2, x3, key->subkeys[ 7]);
122 RND07(x0, x1, x2, x3, y0, y1, y2, y3);
123 transform(y0, y1, y2, y3, x0, x1, x2, x3);
124 keying(x0, x1, x2, x3, key->subkeys[ 8]);
125 RND08(x0, x1, x2, x3, y0, y1, y2, y3);
126 transform(y0, y1, y2, y3, x0, x1, x2, x3);
127 keying(x0, x1, x2, x3, key->subkeys[ 9]);
128 RND09(x0, x1, x2, x3, y0, y1, y2, y3);
129 transform(y0, y1, y2, y3, x0, x1, x2, x3);
130 keying(x0, x1, x2, x3, key->subkeys[10]);
131 RND10(x0, x1, x2, x3, y0, y1, y2, y3);
132 transform(y0, y1, y2, y3, x0, x1, x2, x3);
133 keying(x0, x1, x2, x3, key->subkeys[11]);
134 RND11(x0, x1, x2, x3, y0, y1, y2, y3);
135 transform(y0, y1, y2, y3, x0, x1, x2, x3);
136 keying(x0, x1, x2, x3, key->subkeys[12]);
137 RND12(x0, x1, x2, x3, y0, y1, y2, y3);
138 transform(y0, y1, y2, y3, x0, x1, x2, x3);
139 keying(x0, x1, x2, x3, key->subkeys[13]);
140 RND13(x0, x1, x2, x3, y0, y1, y2, y3);
141 transform(y0, y1, y2, y3, x0, x1, x2, x3);
142 keying(x0, x1, x2, x3, key->subkeys[14]);
143 RND14(x0, x1, x2, x3, y0, y1, y2, y3);
144 transform(y0, y1, y2, y3, x0, x1, x2, x3);
145 keying(x0, x1, x2, x3, key->subkeys[15]);
146 RND15(x0, x1, x2, x3, y0, y1, y2, y3);
147 transform(y0, y1, y2, y3, x0, x1, x2, x3);
148 keying(x0, x1, x2, x3, key->subkeys[16]);
149 RND16(x0, x1, x2, x3, y0, y1, y2, y3);
150 transform(y0, y1, y2, y3, x0, x1, x2, x3);
151 keying(x0, x1, x2, x3, key->subkeys[17]);
152 RND17(x0, x1, x2, x3, y0, y1, y2, y3);
153 transform(y0, y1, y2, y3, x0, x1, x2, x3);
154 keying(x0, x1, x2, x3, key->subkeys[18]);
155 RND18(x0, x1, x2, x3, y0, y1, y2, y3);
156 transform(y0, y1, y2, y3, x0, x1, x2, x3);
157 keying(x0, x1, x2, x3, key->subkeys[19]);
158 RND19(x0, x1, x2, x3, y0, y1, y2, y3);
159 transform(y0, y1, y2, y3, x0, x1, x2, x3);
160 keying(x0, x1, x2, x3, key->subkeys[20]);
161 RND20(x0, x1, x2, x3, y0, y1, y2, y3);
162 transform(y0, y1, y2, y3, x0, x1, x2, x3);
163 keying(x0, x1, x2, x3, key->subkeys[21]);
164 RND21(x0, x1, x2, x3, y0, y1, y2, y3);
165 transform(y0, y1, y2, y3, x0, x1, x2, x3);
166 keying(x0, x1, x2, x3, key->subkeys[22]);
167 RND22(x0, x1, x2, x3, y0, y1, y2, y3);
168 transform(y0, y1, y2, y3, x0, x1, x2, x3);
169 keying(x0, x1, x2, x3, key->subkeys[23]);
170 RND23(x0, x1, x2, x3, y0, y1, y2, y3);
171 transform(y0, y1, y2, y3, x0, x1, x2, x3);
172 keying(x0, x1, x2, x3, key->subkeys[24]);
173 RND24(x0, x1, x2, x3, y0, y1, y2, y3);
174 transform(y0, y1, y2, y3, x0, x1, x2, x3);
175 keying(x0, x1, x2, x3, key->subkeys[25]);
176 RND25(x0, x1, x2, x3, y0, y1, y2, y3);
177 transform(y0, y1, y2, y3, x0, x1, x2, x3);
178 keying(x0, x1, x2, x3, key->subkeys[26]);
179 RND26(x0, x1, x2, x3, y0, y1, y2, y3);
180 transform(y0, y1, y2, y3, x0, x1, x2, x3);
181 keying(x0, x1, x2, x3, key->subkeys[27]);
182 RND27(x0, x1, x2, x3, y0, y1, y2, y3);
183 transform(y0, y1, y2, y3, x0, x1, x2, x3);
184 keying(x0, x1, x2, x3, key->subkeys[28]);
185 RND28(x0, x1, x2, x3, y0, y1, y2, y3);
186 transform(y0, y1, y2, y3, x0, x1, x2, x3);
187 keying(x0, x1, x2, x3, key->subkeys[29]);
188 RND29(x0, x1, x2, x3, y0, y1, y2, y3);
189 transform(y0, y1, y2, y3, x0, x1, x2, x3);
190 keying(x0, x1, x2, x3, key->subkeys[30]);
191 RND30(x0, x1, x2, x3, y0, y1, y2, y3);
192 transform(y0, y1, y2, y3, x0, x1, x2, x3);
193 keying(x0, x1, x2, x3, key->subkeys[31]);
194 RND31(x0, x1, x2, x3, y0, y1, y2, y3);
195 x0 = y0; x1 = y1; x2 = y2; x3 = y3;
196 keying(x0, x1, x2, x3, key->subkeys[32]);
197 /* The ciphertext is now in x */
198
199 PUT_32BIT_MSB_FIRST(ciphertext+12, x0);
200 PUT_32BIT_MSB_FIRST(ciphertext+8, x1);
201 PUT_32BIT_MSB_FIRST(ciphertext+4, x2);
202 PUT_32BIT_MSB_FIRST(ciphertext, x3);
203 }
204
205 void serpent_decrypt(struct keyInstance *key,
206 uint8_t ciphertext[16],
207 uint8_t plaintext[16])
208 {
209 register uint32_t x0, x1, x2, x3;
210 register uint32_t y0, y1, y2, y3;
211
212 x0=GET_32BIT_MSB_FIRST(ciphertext+12);
213 x1=GET_32BIT_MSB_FIRST(ciphertext+8);
214 x2=GET_32BIT_MSB_FIRST(ciphertext+4);
215 x3=GET_32BIT_MSB_FIRST(ciphertext);
216
217 /* Start to decrypt the ciphertext x */
218 keying(x0, x1, x2, x3, key->subkeys[32]);
219 InvRND31(x0, x1, x2, x3, y0, y1, y2, y3);
220 keying(y0, y1, y2, y3, key->subkeys[31]);
221 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
222 InvRND30(x0, x1, x2, x3, y0, y1, y2, y3);
223 keying(y0, y1, y2, y3, key->subkeys[30]);
224 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
225 InvRND29(x0, x1, x2, x3, y0, y1, y2, y3);
226 keying(y0, y1, y2, y3, key->subkeys[29]);
227 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
228 InvRND28(x0, x1, x2, x3, y0, y1, y2, y3);
229 keying(y0, y1, y2, y3, key->subkeys[28]);
230 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
231 InvRND27(x0, x1, x2, x3, y0, y1, y2, y3);
232 keying(y0, y1, y2, y3, key->subkeys[27]);
233 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
234 InvRND26(x0, x1, x2, x3, y0, y1, y2, y3);
235 keying(y0, y1, y2, y3, key->subkeys[26]);
236 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
237 InvRND25(x0, x1, x2, x3, y0, y1, y2, y3);
238 keying(y0, y1, y2, y3, key->subkeys[25]);
239 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
240 InvRND24(x0, x1, x2, x3, y0, y1, y2, y3);
241 keying(y0, y1, y2, y3, key->subkeys[24]);
242 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
243 InvRND23(x0, x1, x2, x3, y0, y1, y2, y3);
244 keying(y0, y1, y2, y3, key->subkeys[23]);
245 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
246 InvRND22(x0, x1, x2, x3, y0, y1, y2, y3);
247 keying(y0, y1, y2, y3, key->subkeys[22]);
248 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
249 InvRND21(x0, x1, x2, x3, y0, y1, y2, y3);
250 keying(y0, y1, y2, y3, key->subkeys[21]);
251 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
252 InvRND20(x0, x1, x2, x3, y0, y1, y2, y3);
253 keying(y0, y1, y2, y3, key->subkeys[20]);
254 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
255 InvRND19(x0, x1, x2, x3, y0, y1, y2, y3);
256 keying(y0, y1, y2, y3, key->subkeys[19]);
257 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
258 InvRND18(x0, x1, x2, x3, y0, y1, y2, y3);
259 keying(y0, y1, y2, y3, key->subkeys[18]);
260 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
261 InvRND17(x0, x1, x2, x3, y0, y1, y2, y3);
262 keying(y0, y1, y2, y3, key->subkeys[17]);
263 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
264 InvRND16(x0, x1, x2, x3, y0, y1, y2, y3);
265 keying(y0, y1, y2, y3, key->subkeys[16]);
266 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
267 InvRND15(x0, x1, x2, x3, y0, y1, y2, y3);
268 keying(y0, y1, y2, y3, key->subkeys[15]);
269 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
270 InvRND14(x0, x1, x2, x3, y0, y1, y2, y3);
271 keying(y0, y1, y2, y3, key->subkeys[14]);
272 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
273 InvRND13(x0, x1, x2, x3, y0, y1, y2, y3);
274 keying(y0, y1, y2, y3, key->subkeys[13]);
275 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
276 InvRND12(x0, x1, x2, x3, y0, y1, y2, y3);
277 keying(y0, y1, y2, y3, key->subkeys[12]);
278 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
279 InvRND11(x0, x1, x2, x3, y0, y1, y2, y3);
280 keying(y0, y1, y2, y3, key->subkeys[11]);
281 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
282 InvRND10(x0, x1, x2, x3, y0, y1, y2, y3);
283 keying(y0, y1, y2, y3, key->subkeys[10]);
284 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
285 InvRND09(x0, x1, x2, x3, y0, y1, y2, y3);
286 keying(y0, y1, y2, y3, key->subkeys[ 9]);
287 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
288 InvRND08(x0, x1, x2, x3, y0, y1, y2, y3);
289 keying(y0, y1, y2, y3, key->subkeys[ 8]);
290 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
291 InvRND07(x0, x1, x2, x3, y0, y1, y2, y3);
292 keying(y0, y1, y2, y3, key->subkeys[ 7]);
293 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
294 InvRND06(x0, x1, x2, x3, y0, y1, y2, y3);
295 keying(y0, y1, y2, y3, key->subkeys[ 6]);
296 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
297 InvRND05(x0, x1, x2, x3, y0, y1, y2, y3);
298 keying(y0, y1, y2, y3, key->subkeys[ 5]);
299 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
300 InvRND04(x0, x1, x2, x3, y0, y1, y2, y3);
301 keying(y0, y1, y2, y3, key->subkeys[ 4]);
302 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
303 InvRND03(x0, x1, x2, x3, y0, y1, y2, y3);
304 keying(y0, y1, y2, y3, key->subkeys[ 3]);
305 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
306 InvRND02(x0, x1, x2, x3, y0, y1, y2, y3);
307 keying(y0, y1, y2, y3, key->subkeys[ 2]);
308 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
309 InvRND01(x0, x1, x2, x3, y0, y1, y2, y3);
310 keying(y0, y1, y2, y3, key->subkeys[ 1]);
311 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
312 InvRND00(x0, x1, x2, x3, y0, y1, y2, y3);
313 x0 = y0; x1 = y1; x2 = y2; x3 = y3;
314 keying(x0, x1, x2, x3, key->subkeys[ 0]);
315 /* The plaintext is now in x */
316
317 PUT_32BIT_MSB_FIRST(plaintext+12, x0);
318 PUT_32BIT_MSB_FIRST(plaintext+8, x1);
319 PUT_32BIT_MSB_FIRST(plaintext+4, x2);
320 PUT_32BIT_MSB_FIRST(plaintext, x3);
321 }