Initialize Tizen 2.3
[external/nettle.git] / serpent.c
1 /* serpent.h
2  *
3  * The serpent block cipher.
4  *
5  * For more details on this algorithm, see the Serpent website at
6  * http://www.cl.cam.ac.uk/~rja14/serpent.html
7  */
8
9 /* nettle, low-level cryptographics library
10  *
11  * Copyright (C) 1998, 2000, 2001, Ross Anderson, Eli Biham, Lars
12  *                                 Knudsen, Rafael R. Sevilla, Niels Möller
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License as
16  * published by the Free Software Foundation; either version 2 of the
17  * License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful, but
20  * WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  * General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27  */
28
29 /* I've modified this code a bit so that it interoperates with lsh
30  * properly. 2000-9-5, Rafael R. Sevilla <dido@pacific.net.ph>
31  */
32
33 /* NOTE: The copyright notice for the original version of this code
34  * said "All rights reserved. This code is freely distributed for AES
35  * selection process. No other use is allowed." However, the authors
36  * later decided to GPL the code. /nisse */
37
38 #if HAVE_CONFIG_H
39 # include "config.h"
40 #endif
41
42 #include <assert.h>
43
44 #include "serpent.h"
45 #include "serpent_sboxes.h"
46
47 #include "macros.h"
48
49 void
50 serpent_set_key(struct serpent_ctx *ctx,
51                 unsigned key_size, const uint8_t *key)
52 {
53   unsigned i, j;
54   uint32_t w[132], k[132];
55
56   assert(key_size >= SERPENT_MIN_KEY_SIZE);
57   assert(key_size <= SERPENT_MAX_KEY_SIZE);
58
59   for (i = key_size, j = 0;
60        (i >= 4);
61        i-=4, j++)
62     {
63       assert(j<8);
64       /* Read the key in the reverse direction. Why? */
65       w[j] = READ_UINT32(key + i - 4);
66     }
67
68     if (j < 8)
69     {
70       /* Pad key, "aabbccddeeff" -> 0xccddeeff, 0x01aabb" */
71       uint32_t partial = 0x01;
72       while (i)
73         partial = (partial << 8 ) | *key++;
74       w[j++] = partial;
75
76       while (j < 8)
77         w[j++] = 0;
78     }  
79
80   for(i=8; i<16; i++)
81     w[i]=ROL(w[i-8]^w[i-5]^w[i-3]^w[i-1]^PHI^(i-8),11);
82   for(i=0; i<8; i++)
83     w[i]=w[i+8];
84   for(i=8; i<132; i++)
85     w[i]=ROL(w[i-8]^w[i-5]^w[i-3]^w[i-1]^PHI^i,11);
86
87   RND03(w[  0], w[  1], w[  2], w[  3], k[  0], k[  1], k[  2], k[  3]);
88   RND02(w[  4], w[  5], w[  6], w[  7], k[  4], k[  5], k[  6], k[  7]);
89   RND01(w[  8], w[  9], w[ 10], w[ 11], k[  8], k[  9], k[ 10], k[ 11]);
90   RND00(w[ 12], w[ 13], w[ 14], w[ 15], k[ 12], k[ 13], k[ 14], k[ 15]);
91   RND31(w[ 16], w[ 17], w[ 18], w[ 19], k[ 16], k[ 17], k[ 18], k[ 19]);
92   RND30(w[ 20], w[ 21], w[ 22], w[ 23], k[ 20], k[ 21], k[ 22], k[ 23]);
93   RND29(w[ 24], w[ 25], w[ 26], w[ 27], k[ 24], k[ 25], k[ 26], k[ 27]);
94   RND28(w[ 28], w[ 29], w[ 30], w[ 31], k[ 28], k[ 29], k[ 30], k[ 31]);
95   RND27(w[ 32], w[ 33], w[ 34], w[ 35], k[ 32], k[ 33], k[ 34], k[ 35]);
96   RND26(w[ 36], w[ 37], w[ 38], w[ 39], k[ 36], k[ 37], k[ 38], k[ 39]);
97   RND25(w[ 40], w[ 41], w[ 42], w[ 43], k[ 40], k[ 41], k[ 42], k[ 43]);
98   RND24(w[ 44], w[ 45], w[ 46], w[ 47], k[ 44], k[ 45], k[ 46], k[ 47]);
99   RND23(w[ 48], w[ 49], w[ 50], w[ 51], k[ 48], k[ 49], k[ 50], k[ 51]);
100   RND22(w[ 52], w[ 53], w[ 54], w[ 55], k[ 52], k[ 53], k[ 54], k[ 55]);
101   RND21(w[ 56], w[ 57], w[ 58], w[ 59], k[ 56], k[ 57], k[ 58], k[ 59]);
102   RND20(w[ 60], w[ 61], w[ 62], w[ 63], k[ 60], k[ 61], k[ 62], k[ 63]);
103   RND19(w[ 64], w[ 65], w[ 66], w[ 67], k[ 64], k[ 65], k[ 66], k[ 67]);
104   RND18(w[ 68], w[ 69], w[ 70], w[ 71], k[ 68], k[ 69], k[ 70], k[ 71]);
105   RND17(w[ 72], w[ 73], w[ 74], w[ 75], k[ 72], k[ 73], k[ 74], k[ 75]);
106   RND16(w[ 76], w[ 77], w[ 78], w[ 79], k[ 76], k[ 77], k[ 78], k[ 79]);
107   RND15(w[ 80], w[ 81], w[ 82], w[ 83], k[ 80], k[ 81], k[ 82], k[ 83]);
108   RND14(w[ 84], w[ 85], w[ 86], w[ 87], k[ 84], k[ 85], k[ 86], k[ 87]);
109   RND13(w[ 88], w[ 89], w[ 90], w[ 91], k[ 88], k[ 89], k[ 90], k[ 91]);
110   RND12(w[ 92], w[ 93], w[ 94], w[ 95], k[ 92], k[ 93], k[ 94], k[ 95]);
111   RND11(w[ 96], w[ 97], w[ 98], w[ 99], k[ 96], k[ 97], k[ 98], k[ 99]);
112   RND10(w[100], w[101], w[102], w[103], k[100], k[101], k[102], k[103]);
113   RND09(w[104], w[105], w[106], w[107], k[104], k[105], k[106], k[107]);
114   RND08(w[108], w[109], w[110], w[111], k[108], k[109], k[110], k[111]);
115   RND07(w[112], w[113], w[114], w[115], k[112], k[113], k[114], k[115]);
116   RND06(w[116], w[117], w[118], w[119], k[116], k[117], k[118], k[119]);
117   RND05(w[120], w[121], w[122], w[123], k[120], k[121], k[122], k[123]);
118   RND04(w[124], w[125], w[126], w[127], k[124], k[125], k[126], k[127]);
119   RND03(w[128], w[129], w[130], w[131], k[128], k[129], k[130], k[131]);
120
121   for(i=0; i<=32; i++)
122     for(j=0; j<4; j++)
123       ctx->keys[i][j] = k[4*i+j];
124 }
125
126 void
127 serpent_encrypt(const struct serpent_ctx *ctx,
128                 unsigned length, uint8_t *dst,
129                 const uint8_t *plain)
130 {
131   register uint32_t x0, x1, x2, x3;
132   register uint32_t y0, y1, y2, y3;
133
134   FOR_BLOCKS(length, dst, plain, SERPENT_BLOCK_SIZE)
135     {
136       /* Why the reverse order? */
137       x0=READ_UINT32(plain + 12);
138       x1=READ_UINT32(plain + 8);
139       x2=READ_UINT32(plain + 4);
140       x3=READ_UINT32(plain);
141
142       /* Start to encrypt the plaintext x */
143       keying(x0, x1, x2, x3, ctx->keys[ 0]);
144       RND00(x0, x1, x2, x3, y0, y1, y2, y3);
145       transform(y0, y1, y2, y3, x0, x1, x2, x3);
146       keying(x0, x1, x2, x3, ctx->keys[ 1]);
147       RND01(x0, x1, x2, x3, y0, y1, y2, y3);
148       transform(y0, y1, y2, y3, x0, x1, x2, x3);
149       keying(x0, x1, x2, x3, ctx->keys[ 2]);
150       RND02(x0, x1, x2, x3, y0, y1, y2, y3);
151       transform(y0, y1, y2, y3, x0, x1, x2, x3);
152       keying(x0, x1, x2, x3, ctx->keys[ 3]);
153       RND03(x0, x1, x2, x3, y0, y1, y2, y3);
154       transform(y0, y1, y2, y3, x0, x1, x2, x3);
155       keying(x0, x1, x2, x3, ctx->keys[ 4]);
156       RND04(x0, x1, x2, x3, y0, y1, y2, y3);
157       transform(y0, y1, y2, y3, x0, x1, x2, x3);
158       keying(x0, x1, x2, x3, ctx->keys[ 5]);
159       RND05(x0, x1, x2, x3, y0, y1, y2, y3);
160       transform(y0, y1, y2, y3, x0, x1, x2, x3);
161       keying(x0, x1, x2, x3, ctx->keys[ 6]);
162       RND06(x0, x1, x2, x3, y0, y1, y2, y3);
163       transform(y0, y1, y2, y3, x0, x1, x2, x3);
164       keying(x0, x1, x2, x3, ctx->keys[ 7]);
165       RND07(x0, x1, x2, x3, y0, y1, y2, y3);
166       transform(y0, y1, y2, y3, x0, x1, x2, x3);
167       keying(x0, x1, x2, x3, ctx->keys[ 8]);
168       RND08(x0, x1, x2, x3, y0, y1, y2, y3);
169       transform(y0, y1, y2, y3, x0, x1, x2, x3);
170       keying(x0, x1, x2, x3, ctx->keys[ 9]);
171       RND09(x0, x1, x2, x3, y0, y1, y2, y3);
172       transform(y0, y1, y2, y3, x0, x1, x2, x3);
173       keying(x0, x1, x2, x3, ctx->keys[10]);
174       RND10(x0, x1, x2, x3, y0, y1, y2, y3);
175       transform(y0, y1, y2, y3, x0, x1, x2, x3);
176       keying(x0, x1, x2, x3, ctx->keys[11]);
177       RND11(x0, x1, x2, x3, y0, y1, y2, y3);
178       transform(y0, y1, y2, y3, x0, x1, x2, x3);
179       keying(x0, x1, x2, x3, ctx->keys[12]);
180       RND12(x0, x1, x2, x3, y0, y1, y2, y3);
181       transform(y0, y1, y2, y3, x0, x1, x2, x3);
182       keying(x0, x1, x2, x3, ctx->keys[13]);
183       RND13(x0, x1, x2, x3, y0, y1, y2, y3);
184       transform(y0, y1, y2, y3, x0, x1, x2, x3);
185       keying(x0, x1, x2, x3, ctx->keys[14]);
186       RND14(x0, x1, x2, x3, y0, y1, y2, y3);
187       transform(y0, y1, y2, y3, x0, x1, x2, x3);
188       keying(x0, x1, x2, x3, ctx->keys[15]);
189       RND15(x0, x1, x2, x3, y0, y1, y2, y3);
190       transform(y0, y1, y2, y3, x0, x1, x2, x3);
191       keying(x0, x1, x2, x3, ctx->keys[16]);
192       RND16(x0, x1, x2, x3, y0, y1, y2, y3);
193       transform(y0, y1, y2, y3, x0, x1, x2, x3);
194       keying(x0, x1, x2, x3, ctx->keys[17]);
195       RND17(x0, x1, x2, x3, y0, y1, y2, y3);
196       transform(y0, y1, y2, y3, x0, x1, x2, x3);
197       keying(x0, x1, x2, x3, ctx->keys[18]);
198       RND18(x0, x1, x2, x3, y0, y1, y2, y3);
199       transform(y0, y1, y2, y3, x0, x1, x2, x3);
200       keying(x0, x1, x2, x3, ctx->keys[19]);
201       RND19(x0, x1, x2, x3, y0, y1, y2, y3);
202       transform(y0, y1, y2, y3, x0, x1, x2, x3);
203       keying(x0, x1, x2, x3, ctx->keys[20]);
204       RND20(x0, x1, x2, x3, y0, y1, y2, y3);
205       transform(y0, y1, y2, y3, x0, x1, x2, x3);
206       keying(x0, x1, x2, x3, ctx->keys[21]);
207       RND21(x0, x1, x2, x3, y0, y1, y2, y3);
208       transform(y0, y1, y2, y3, x0, x1, x2, x3);
209       keying(x0, x1, x2, x3, ctx->keys[22]);
210       RND22(x0, x1, x2, x3, y0, y1, y2, y3);
211       transform(y0, y1, y2, y3, x0, x1, x2, x3);
212       keying(x0, x1, x2, x3, ctx->keys[23]);
213       RND23(x0, x1, x2, x3, y0, y1, y2, y3);
214       transform(y0, y1, y2, y3, x0, x1, x2, x3);
215       keying(x0, x1, x2, x3, ctx->keys[24]);
216       RND24(x0, x1, x2, x3, y0, y1, y2, y3);
217       transform(y0, y1, y2, y3, x0, x1, x2, x3);
218       keying(x0, x1, x2, x3, ctx->keys[25]);
219       RND25(x0, x1, x2, x3, y0, y1, y2, y3);
220       transform(y0, y1, y2, y3, x0, x1, x2, x3);
221       keying(x0, x1, x2, x3, ctx->keys[26]);
222       RND26(x0, x1, x2, x3, y0, y1, y2, y3);
223       transform(y0, y1, y2, y3, x0, x1, x2, x3);
224       keying(x0, x1, x2, x3, ctx->keys[27]);
225       RND27(x0, x1, x2, x3, y0, y1, y2, y3);
226       transform(y0, y1, y2, y3, x0, x1, x2, x3);
227       keying(x0, x1, x2, x3, ctx->keys[28]);
228       RND28(x0, x1, x2, x3, y0, y1, y2, y3);
229       transform(y0, y1, y2, y3, x0, x1, x2, x3);
230       keying(x0, x1, x2, x3, ctx->keys[29]);
231       RND29(x0, x1, x2, x3, y0, y1, y2, y3);
232       transform(y0, y1, y2, y3, x0, x1, x2, x3);
233       keying(x0, x1, x2, x3, ctx->keys[30]);
234       RND30(x0, x1, x2, x3, y0, y1, y2, y3);
235       transform(y0, y1, y2, y3, x0, x1, x2, x3);
236       keying(x0, x1, x2, x3, ctx->keys[31]);
237       RND31(x0, x1, x2, x3, y0, y1, y2, y3);
238       x0 = y0; x1 = y1; x2 = y2; x3 = y3;
239       keying(x0, x1, x2, x3, ctx->keys[32]);
240
241       /* The ciphertext is now in x */
242
243       /* Why the reverse order? */
244       WRITE_UINT32(dst, x3);
245       WRITE_UINT32(dst+4, x2);
246       WRITE_UINT32(dst+8, x1);
247       WRITE_UINT32(dst+12, x0);
248     }
249 }
250
251 void
252 serpent_decrypt(const struct serpent_ctx *ctx,
253                 unsigned length, uint8_t *dst,
254                 const uint8_t *cipher)
255 {
256   register uint32_t x0, x1, x2, x3;
257   register uint32_t y0, y1, y2, y3;
258
259   FOR_BLOCKS(length, dst, cipher, SERPENT_BLOCK_SIZE)
260     {
261       /* Why the reverse order? */
262       x0 = READ_UINT32(cipher + 12);
263       x1 = READ_UINT32(cipher + 8);
264       x2 = READ_UINT32(cipher + 4);
265       x3 = READ_UINT32(cipher);
266       
267       /* Start to decrypt the ciphertext x */
268       keying(x0, x1, x2, x3, ctx->keys[32]);
269       InvRND31(x0, x1, x2, x3, y0, y1, y2, y3);
270       keying(y0, y1, y2, y3, ctx->keys[31]);
271       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
272       InvRND30(x0, x1, x2, x3, y0, y1, y2, y3);
273       keying(y0, y1, y2, y3, ctx->keys[30]);
274       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
275       InvRND29(x0, x1, x2, x3, y0, y1, y2, y3);
276       keying(y0, y1, y2, y3, ctx->keys[29]);
277       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
278       InvRND28(x0, x1, x2, x3, y0, y1, y2, y3);
279       keying(y0, y1, y2, y3, ctx->keys[28]);
280       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
281       InvRND27(x0, x1, x2, x3, y0, y1, y2, y3);
282       keying(y0, y1, y2, y3, ctx->keys[27]);
283       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
284       InvRND26(x0, x1, x2, x3, y0, y1, y2, y3);
285       keying(y0, y1, y2, y3, ctx->keys[26]);
286       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
287       InvRND25(x0, x1, x2, x3, y0, y1, y2, y3);
288       keying(y0, y1, y2, y3, ctx->keys[25]);
289       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
290       InvRND24(x0, x1, x2, x3, y0, y1, y2, y3);
291       keying(y0, y1, y2, y3, ctx->keys[24]);
292       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
293       InvRND23(x0, x1, x2, x3, y0, y1, y2, y3);
294       keying(y0, y1, y2, y3, ctx->keys[23]);
295       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
296       InvRND22(x0, x1, x2, x3, y0, y1, y2, y3);
297       keying(y0, y1, y2, y3, ctx->keys[22]);
298       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
299       InvRND21(x0, x1, x2, x3, y0, y1, y2, y3);
300       keying(y0, y1, y2, y3, ctx->keys[21]);
301       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
302       InvRND20(x0, x1, x2, x3, y0, y1, y2, y3);
303       keying(y0, y1, y2, y3, ctx->keys[20]);
304       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
305       InvRND19(x0, x1, x2, x3, y0, y1, y2, y3);
306       keying(y0, y1, y2, y3, ctx->keys[19]);
307       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
308       InvRND18(x0, x1, x2, x3, y0, y1, y2, y3);
309       keying(y0, y1, y2, y3, ctx->keys[18]);
310       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
311       InvRND17(x0, x1, x2, x3, y0, y1, y2, y3);
312       keying(y0, y1, y2, y3, ctx->keys[17]);
313       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
314       InvRND16(x0, x1, x2, x3, y0, y1, y2, y3);
315       keying(y0, y1, y2, y3, ctx->keys[16]);
316       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
317       InvRND15(x0, x1, x2, x3, y0, y1, y2, y3);
318       keying(y0, y1, y2, y3, ctx->keys[15]);
319       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
320       InvRND14(x0, x1, x2, x3, y0, y1, y2, y3);
321       keying(y0, y1, y2, y3, ctx->keys[14]);
322       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
323       InvRND13(x0, x1, x2, x3, y0, y1, y2, y3);
324       keying(y0, y1, y2, y3, ctx->keys[13]);
325       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
326       InvRND12(x0, x1, x2, x3, y0, y1, y2, y3);
327       keying(y0, y1, y2, y3, ctx->keys[12]);
328       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
329       InvRND11(x0, x1, x2, x3, y0, y1, y2, y3);
330       keying(y0, y1, y2, y3, ctx->keys[11]);
331       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
332       InvRND10(x0, x1, x2, x3, y0, y1, y2, y3);
333       keying(y0, y1, y2, y3, ctx->keys[10]);
334       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
335       InvRND09(x0, x1, x2, x3, y0, y1, y2, y3);
336       keying(y0, y1, y2, y3, ctx->keys[ 9]);
337       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
338       InvRND08(x0, x1, x2, x3, y0, y1, y2, y3);
339       keying(y0, y1, y2, y3, ctx->keys[ 8]);
340       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
341       InvRND07(x0, x1, x2, x3, y0, y1, y2, y3);
342       keying(y0, y1, y2, y3, ctx->keys[ 7]);
343       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
344       InvRND06(x0, x1, x2, x3, y0, y1, y2, y3);
345       keying(y0, y1, y2, y3, ctx->keys[ 6]);
346       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
347       InvRND05(x0, x1, x2, x3, y0, y1, y2, y3);
348       keying(y0, y1, y2, y3, ctx->keys[ 5]);
349       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
350       InvRND04(x0, x1, x2, x3, y0, y1, y2, y3);
351       keying(y0, y1, y2, y3, ctx->keys[ 4]);
352       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
353       InvRND03(x0, x1, x2, x3, y0, y1, y2, y3);
354       keying(y0, y1, y2, y3, ctx->keys[ 3]);
355       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
356       InvRND02(x0, x1, x2, x3, y0, y1, y2, y3);
357       keying(y0, y1, y2, y3, ctx->keys[ 2]);
358       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
359       InvRND01(x0, x1, x2, x3, y0, y1, y2, y3);
360       keying(y0, y1, y2, y3, ctx->keys[ 1]);
361       inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
362       InvRND00(x0, x1, x2, x3, y0, y1, y2, y3);
363       x0 = y0; x1 = y1; x2 = y2; x3 = y3;
364       keying(x0, x1, x2, x3, ctx->keys[ 0]);
365
366       /* The plaintext is now in x */
367
368       /* Why the reverse order? */
369       WRITE_UINT32(dst, x3);
370       WRITE_UINT32(dst+4, x2);
371       WRITE_UINT32(dst+8, x1);
372       WRITE_UINT32(dst+12, x0);
373     }
374 }