serpent: Provide little-endian version too, but ours is big
[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 <stdint.h>
24
25 #include "serpent.h"
26 #include "serpentsboxes.h"
27
28 #ifdef SERPENT_BIGENDIAN
29
30 #define GETPUT_CP(bytenum) \
31 (((basep) + (lenbytes) - (offset) - 4)[(bytenum)])
32
33 #define SERPENT_DECORATE(func) serpentbe_##func
34
35 #else /* !defined(SERPENT_BIGENDIAN) */
36
37 #define GETPUT_CP(bytenum) \
38 (((basep) + (offset))[3-(bytenum)])
39
40 #define SERPENT_DECORATE(func) serpent_##func
41
42 #endif /* !defined(SERPENT_BIGENDIAN) */
43
44 static uint32_t serpent_get_32bit(const uint8_t *basep,
45 int lenbytes, int offset)
46 {
47 return (((uint32_t)GETPUT_CP(0) << 24) |
48 ((uint32_t)GETPUT_CP(1) << 16) |
49 ((uint32_t)GETPUT_CP(2) << +8) |
50 ((uint32_t)GETPUT_CP(3)));
51 }
52
53 static void serpent_put_32bit(uint8_t *basep, int lenbytes, int offset, uint32_t value)
54 {
55 GETPUT_CP(0) = (char)((value) >> 24);
56 GETPUT_CP(1) = (char)((value) >> 16);
57 GETPUT_CP(2) = (char)((value) >> 8);
58 GETPUT_CP(3) = (char)(value);
59 }
60
61 void SERPENT_DECORATE(makekey)(struct keyInstance *key, int keyLen,
62 const uint8_t *keyMaterial)
63 {
64 int i;
65 uint32_t j;
66 uint32_t w[132],k[132];
67
68 for(i=0; i<keyLen/32; i++)
69 w[i]=serpent_get_32bit(keyMaterial, keyLen/8, i*4);
70 if(keyLen<256)
71 w[i]=(serpent_get_32bit(keyMaterial, keyLen/8, i*4)
72 & ((1L<<((keyLen&31)))-1)) | (1L<<((keyLen&31)));
73 for(i++; i<8; i++)
74 w[i]=0;
75 for(i=8; i<16; i++)
76 w[i]=ROL(w[i-8]^w[i-5]^w[i-3]^w[i-1]^PHI^(i-8),11);
77 for(i=0; i<8; i++)
78 w[i]=w[i+8];
79 for(i=8; i<132; i++)
80 w[i]=ROL(w[i-8]^w[i-5]^w[i-3]^w[i-1]^PHI^i,11);
81
82 RND03(w[ 0], w[ 1], w[ 2], w[ 3], k[ 0], k[ 1], k[ 2], k[ 3]);
83 RND02(w[ 4], w[ 5], w[ 6], w[ 7], k[ 4], k[ 5], k[ 6], k[ 7]);
84 RND01(w[ 8], w[ 9], w[ 10], w[ 11], k[ 8], k[ 9], k[ 10], k[ 11]);
85 RND00(w[ 12], w[ 13], w[ 14], w[ 15], k[ 12], k[ 13], k[ 14], k[ 15]);
86 RND31(w[ 16], w[ 17], w[ 18], w[ 19], k[ 16], k[ 17], k[ 18], k[ 19]);
87 RND30(w[ 20], w[ 21], w[ 22], w[ 23], k[ 20], k[ 21], k[ 22], k[ 23]);
88 RND29(w[ 24], w[ 25], w[ 26], w[ 27], k[ 24], k[ 25], k[ 26], k[ 27]);
89 RND28(w[ 28], w[ 29], w[ 30], w[ 31], k[ 28], k[ 29], k[ 30], k[ 31]);
90 RND27(w[ 32], w[ 33], w[ 34], w[ 35], k[ 32], k[ 33], k[ 34], k[ 35]);
91 RND26(w[ 36], w[ 37], w[ 38], w[ 39], k[ 36], k[ 37], k[ 38], k[ 39]);
92 RND25(w[ 40], w[ 41], w[ 42], w[ 43], k[ 40], k[ 41], k[ 42], k[ 43]);
93 RND24(w[ 44], w[ 45], w[ 46], w[ 47], k[ 44], k[ 45], k[ 46], k[ 47]);
94 RND23(w[ 48], w[ 49], w[ 50], w[ 51], k[ 48], k[ 49], k[ 50], k[ 51]);
95 RND22(w[ 52], w[ 53], w[ 54], w[ 55], k[ 52], k[ 53], k[ 54], k[ 55]);
96 RND21(w[ 56], w[ 57], w[ 58], w[ 59], k[ 56], k[ 57], k[ 58], k[ 59]);
97 RND20(w[ 60], w[ 61], w[ 62], w[ 63], k[ 60], k[ 61], k[ 62], k[ 63]);
98 RND19(w[ 64], w[ 65], w[ 66], w[ 67], k[ 64], k[ 65], k[ 66], k[ 67]);
99 RND18(w[ 68], w[ 69], w[ 70], w[ 71], k[ 68], k[ 69], k[ 70], k[ 71]);
100 RND17(w[ 72], w[ 73], w[ 74], w[ 75], k[ 72], k[ 73], k[ 74], k[ 75]);
101 RND16(w[ 76], w[ 77], w[ 78], w[ 79], k[ 76], k[ 77], k[ 78], k[ 79]);
102 RND15(w[ 80], w[ 81], w[ 82], w[ 83], k[ 80], k[ 81], k[ 82], k[ 83]);
103 RND14(w[ 84], w[ 85], w[ 86], w[ 87], k[ 84], k[ 85], k[ 86], k[ 87]);
104 RND13(w[ 88], w[ 89], w[ 90], w[ 91], k[ 88], k[ 89], k[ 90], k[ 91]);
105 RND12(w[ 92], w[ 93], w[ 94], w[ 95], k[ 92], k[ 93], k[ 94], k[ 95]);
106 RND11(w[ 96], w[ 97], w[ 98], w[ 99], k[ 96], k[ 97], k[ 98], k[ 99]);
107 RND10(w[100], w[101], w[102], w[103], k[100], k[101], k[102], k[103]);
108 RND09(w[104], w[105], w[106], w[107], k[104], k[105], k[106], k[107]);
109 RND08(w[108], w[109], w[110], w[111], k[108], k[109], k[110], k[111]);
110 RND07(w[112], w[113], w[114], w[115], k[112], k[113], k[114], k[115]);
111 RND06(w[116], w[117], w[118], w[119], k[116], k[117], k[118], k[119]);
112 RND05(w[120], w[121], w[122], w[123], k[120], k[121], k[122], k[123]);
113 RND04(w[124], w[125], w[126], w[127], k[124], k[125], k[126], k[127]);
114 RND03(w[128], w[129], w[130], w[131], k[128], k[129], k[130], k[131]);
115
116 for(i=0; i<=32; i++)
117 for(j=0; j<4; j++)
118 key->subkeys[i][j] = k[4*i+j];
119 }
120
121 void SERPENT_DECORATE(encrypt)(struct keyInstance *key,
122 const uint8_t plaintext[16],
123 uint8_t ciphertext[16])
124 {
125 register uint32_t x0, x1, x2, x3;
126 register uint32_t y0, y1, y2, y3;
127
128 x0=serpent_get_32bit(plaintext,16,+0);
129 x1=serpent_get_32bit(plaintext,16,+4);
130 x2=serpent_get_32bit(plaintext,16,+8);
131 x3=serpent_get_32bit(plaintext,16,12);
132
133 /* Start to encrypt the plaintext x */
134 keying(x0, x1, x2, x3, key->subkeys[ 0]);
135 RND00(x0, x1, x2, x3, y0, y1, y2, y3);
136 transform(y0, y1, y2, y3, x0, x1, x2, x3);
137 keying(x0, x1, x2, x3, key->subkeys[ 1]);
138 RND01(x0, x1, x2, x3, y0, y1, y2, y3);
139 transform(y0, y1, y2, y3, x0, x1, x2, x3);
140 keying(x0, x1, x2, x3, key->subkeys[ 2]);
141 RND02(x0, x1, x2, x3, y0, y1, y2, y3);
142 transform(y0, y1, y2, y3, x0, x1, x2, x3);
143 keying(x0, x1, x2, x3, key->subkeys[ 3]);
144 RND03(x0, x1, x2, x3, y0, y1, y2, y3);
145 transform(y0, y1, y2, y3, x0, x1, x2, x3);
146 keying(x0, x1, x2, x3, key->subkeys[ 4]);
147 RND04(x0, x1, x2, x3, y0, y1, y2, y3);
148 transform(y0, y1, y2, y3, x0, x1, x2, x3);
149 keying(x0, x1, x2, x3, key->subkeys[ 5]);
150 RND05(x0, x1, x2, x3, y0, y1, y2, y3);
151 transform(y0, y1, y2, y3, x0, x1, x2, x3);
152 keying(x0, x1, x2, x3, key->subkeys[ 6]);
153 RND06(x0, x1, x2, x3, y0, y1, y2, y3);
154 transform(y0, y1, y2, y3, x0, x1, x2, x3);
155 keying(x0, x1, x2, x3, key->subkeys[ 7]);
156 RND07(x0, x1, x2, x3, y0, y1, y2, y3);
157 transform(y0, y1, y2, y3, x0, x1, x2, x3);
158 keying(x0, x1, x2, x3, key->subkeys[ 8]);
159 RND08(x0, x1, x2, x3, y0, y1, y2, y3);
160 transform(y0, y1, y2, y3, x0, x1, x2, x3);
161 keying(x0, x1, x2, x3, key->subkeys[ 9]);
162 RND09(x0, x1, x2, x3, y0, y1, y2, y3);
163 transform(y0, y1, y2, y3, x0, x1, x2, x3);
164 keying(x0, x1, x2, x3, key->subkeys[10]);
165 RND10(x0, x1, x2, x3, y0, y1, y2, y3);
166 transform(y0, y1, y2, y3, x0, x1, x2, x3);
167 keying(x0, x1, x2, x3, key->subkeys[11]);
168 RND11(x0, x1, x2, x3, y0, y1, y2, y3);
169 transform(y0, y1, y2, y3, x0, x1, x2, x3);
170 keying(x0, x1, x2, x3, key->subkeys[12]);
171 RND12(x0, x1, x2, x3, y0, y1, y2, y3);
172 transform(y0, y1, y2, y3, x0, x1, x2, x3);
173 keying(x0, x1, x2, x3, key->subkeys[13]);
174 RND13(x0, x1, x2, x3, y0, y1, y2, y3);
175 transform(y0, y1, y2, y3, x0, x1, x2, x3);
176 keying(x0, x1, x2, x3, key->subkeys[14]);
177 RND14(x0, x1, x2, x3, y0, y1, y2, y3);
178 transform(y0, y1, y2, y3, x0, x1, x2, x3);
179 keying(x0, x1, x2, x3, key->subkeys[15]);
180 RND15(x0, x1, x2, x3, y0, y1, y2, y3);
181 transform(y0, y1, y2, y3, x0, x1, x2, x3);
182 keying(x0, x1, x2, x3, key->subkeys[16]);
183 RND16(x0, x1, x2, x3, y0, y1, y2, y3);
184 transform(y0, y1, y2, y3, x0, x1, x2, x3);
185 keying(x0, x1, x2, x3, key->subkeys[17]);
186 RND17(x0, x1, x2, x3, y0, y1, y2, y3);
187 transform(y0, y1, y2, y3, x0, x1, x2, x3);
188 keying(x0, x1, x2, x3, key->subkeys[18]);
189 RND18(x0, x1, x2, x3, y0, y1, y2, y3);
190 transform(y0, y1, y2, y3, x0, x1, x2, x3);
191 keying(x0, x1, x2, x3, key->subkeys[19]);
192 RND19(x0, x1, x2, x3, y0, y1, y2, y3);
193 transform(y0, y1, y2, y3, x0, x1, x2, x3);
194 keying(x0, x1, x2, x3, key->subkeys[20]);
195 RND20(x0, x1, x2, x3, y0, y1, y2, y3);
196 transform(y0, y1, y2, y3, x0, x1, x2, x3);
197 keying(x0, x1, x2, x3, key->subkeys[21]);
198 RND21(x0, x1, x2, x3, y0, y1, y2, y3);
199 transform(y0, y1, y2, y3, x0, x1, x2, x3);
200 keying(x0, x1, x2, x3, key->subkeys[22]);
201 RND22(x0, x1, x2, x3, y0, y1, y2, y3);
202 transform(y0, y1, y2, y3, x0, x1, x2, x3);
203 keying(x0, x1, x2, x3, key->subkeys[23]);
204 RND23(x0, x1, x2, x3, y0, y1, y2, y3);
205 transform(y0, y1, y2, y3, x0, x1, x2, x3);
206 keying(x0, x1, x2, x3, key->subkeys[24]);
207 RND24(x0, x1, x2, x3, y0, y1, y2, y3);
208 transform(y0, y1, y2, y3, x0, x1, x2, x3);
209 keying(x0, x1, x2, x3, key->subkeys[25]);
210 RND25(x0, x1, x2, x3, y0, y1, y2, y3);
211 transform(y0, y1, y2, y3, x0, x1, x2, x3);
212 keying(x0, x1, x2, x3, key->subkeys[26]);
213 RND26(x0, x1, x2, x3, y0, y1, y2, y3);
214 transform(y0, y1, y2, y3, x0, x1, x2, x3);
215 keying(x0, x1, x2, x3, key->subkeys[27]);
216 RND27(x0, x1, x2, x3, y0, y1, y2, y3);
217 transform(y0, y1, y2, y3, x0, x1, x2, x3);
218 keying(x0, x1, x2, x3, key->subkeys[28]);
219 RND28(x0, x1, x2, x3, y0, y1, y2, y3);
220 transform(y0, y1, y2, y3, x0, x1, x2, x3);
221 keying(x0, x1, x2, x3, key->subkeys[29]);
222 RND29(x0, x1, x2, x3, y0, y1, y2, y3);
223 transform(y0, y1, y2, y3, x0, x1, x2, x3);
224 keying(x0, x1, x2, x3, key->subkeys[30]);
225 RND30(x0, x1, x2, x3, y0, y1, y2, y3);
226 transform(y0, y1, y2, y3, x0, x1, x2, x3);
227 keying(x0, x1, x2, x3, key->subkeys[31]);
228 RND31(x0, x1, x2, x3, y0, y1, y2, y3);
229 x0 = y0; x1 = y1; x2 = y2; x3 = y3;
230 keying(x0, x1, x2, x3, key->subkeys[32]);
231 /* The ciphertext is now in x */
232
233 serpent_put_32bit(ciphertext,16,+0, x0);
234 serpent_put_32bit(ciphertext,16,+4, x1);
235 serpent_put_32bit(ciphertext,16,+8, x2);
236 serpent_put_32bit(ciphertext,16,12, x3);
237 }
238
239 void SERPENT_DECORATE(decrypt)(struct keyInstance *key,
240 const uint8_t ciphertext[16],
241 uint8_t plaintext[16])
242 {
243 register uint32_t x0, x1, x2, x3;
244 register uint32_t y0, y1, y2, y3;
245
246 x0=serpent_get_32bit(ciphertext,16,+0);
247 x1=serpent_get_32bit(ciphertext,16,+4);
248 x2=serpent_get_32bit(ciphertext,16,+8);
249 x3=serpent_get_32bit(ciphertext,16,12);
250
251 /* Start to decrypt the ciphertext x */
252 keying(x0, x1, x2, x3, key->subkeys[32]);
253 InvRND31(x0, x1, x2, x3, y0, y1, y2, y3);
254 keying(y0, y1, y2, y3, key->subkeys[31]);
255 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
256 InvRND30(x0, x1, x2, x3, y0, y1, y2, y3);
257 keying(y0, y1, y2, y3, key->subkeys[30]);
258 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
259 InvRND29(x0, x1, x2, x3, y0, y1, y2, y3);
260 keying(y0, y1, y2, y3, key->subkeys[29]);
261 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
262 InvRND28(x0, x1, x2, x3, y0, y1, y2, y3);
263 keying(y0, y1, y2, y3, key->subkeys[28]);
264 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
265 InvRND27(x0, x1, x2, x3, y0, y1, y2, y3);
266 keying(y0, y1, y2, y3, key->subkeys[27]);
267 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
268 InvRND26(x0, x1, x2, x3, y0, y1, y2, y3);
269 keying(y0, y1, y2, y3, key->subkeys[26]);
270 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
271 InvRND25(x0, x1, x2, x3, y0, y1, y2, y3);
272 keying(y0, y1, y2, y3, key->subkeys[25]);
273 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
274 InvRND24(x0, x1, x2, x3, y0, y1, y2, y3);
275 keying(y0, y1, y2, y3, key->subkeys[24]);
276 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
277 InvRND23(x0, x1, x2, x3, y0, y1, y2, y3);
278 keying(y0, y1, y2, y3, key->subkeys[23]);
279 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
280 InvRND22(x0, x1, x2, x3, y0, y1, y2, y3);
281 keying(y0, y1, y2, y3, key->subkeys[22]);
282 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
283 InvRND21(x0, x1, x2, x3, y0, y1, y2, y3);
284 keying(y0, y1, y2, y3, key->subkeys[21]);
285 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
286 InvRND20(x0, x1, x2, x3, y0, y1, y2, y3);
287 keying(y0, y1, y2, y3, key->subkeys[20]);
288 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
289 InvRND19(x0, x1, x2, x3, y0, y1, y2, y3);
290 keying(y0, y1, y2, y3, key->subkeys[19]);
291 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
292 InvRND18(x0, x1, x2, x3, y0, y1, y2, y3);
293 keying(y0, y1, y2, y3, key->subkeys[18]);
294 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
295 InvRND17(x0, x1, x2, x3, y0, y1, y2, y3);
296 keying(y0, y1, y2, y3, key->subkeys[17]);
297 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
298 InvRND16(x0, x1, x2, x3, y0, y1, y2, y3);
299 keying(y0, y1, y2, y3, key->subkeys[16]);
300 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
301 InvRND15(x0, x1, x2, x3, y0, y1, y2, y3);
302 keying(y0, y1, y2, y3, key->subkeys[15]);
303 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
304 InvRND14(x0, x1, x2, x3, y0, y1, y2, y3);
305 keying(y0, y1, y2, y3, key->subkeys[14]);
306 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
307 InvRND13(x0, x1, x2, x3, y0, y1, y2, y3);
308 keying(y0, y1, y2, y3, key->subkeys[13]);
309 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
310 InvRND12(x0, x1, x2, x3, y0, y1, y2, y3);
311 keying(y0, y1, y2, y3, key->subkeys[12]);
312 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
313 InvRND11(x0, x1, x2, x3, y0, y1, y2, y3);
314 keying(y0, y1, y2, y3, key->subkeys[11]);
315 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
316 InvRND10(x0, x1, x2, x3, y0, y1, y2, y3);
317 keying(y0, y1, y2, y3, key->subkeys[10]);
318 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
319 InvRND09(x0, x1, x2, x3, y0, y1, y2, y3);
320 keying(y0, y1, y2, y3, key->subkeys[ 9]);
321 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
322 InvRND08(x0, x1, x2, x3, y0, y1, y2, y3);
323 keying(y0, y1, y2, y3, key->subkeys[ 8]);
324 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
325 InvRND07(x0, x1, x2, x3, y0, y1, y2, y3);
326 keying(y0, y1, y2, y3, key->subkeys[ 7]);
327 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
328 InvRND06(x0, x1, x2, x3, y0, y1, y2, y3);
329 keying(y0, y1, y2, y3, key->subkeys[ 6]);
330 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
331 InvRND05(x0, x1, x2, x3, y0, y1, y2, y3);
332 keying(y0, y1, y2, y3, key->subkeys[ 5]);
333 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
334 InvRND04(x0, x1, x2, x3, y0, y1, y2, y3);
335 keying(y0, y1, y2, y3, key->subkeys[ 4]);
336 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
337 InvRND03(x0, x1, x2, x3, y0, y1, y2, y3);
338 keying(y0, y1, y2, y3, key->subkeys[ 3]);
339 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
340 InvRND02(x0, x1, x2, x3, y0, y1, y2, y3);
341 keying(y0, y1, y2, y3, key->subkeys[ 2]);
342 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
343 InvRND01(x0, x1, x2, x3, y0, y1, y2, y3);
344 keying(y0, y1, y2, y3, key->subkeys[ 1]);
345 inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
346 InvRND00(x0, x1, x2, x3, y0, y1, y2, y3);
347 x0 = y0; x1 = y1; x2 = y2; x3 = y3;
348 keying(x0, x1, x2, x3, key->subkeys[ 0]);
349 /* The plaintext is now in x */
350
351 serpent_put_32bit(plaintext,16,+0, x0);
352 serpent_put_32bit(plaintext,16,+4, x1);
353 serpent_put_32bit(plaintext,16,+8, x2);
354 serpent_put_32bit(plaintext,16,12, x3);
355 }