Commit | Line | Data |
---|---|---|
2fe58dfd | 1 | /* |
c215a4bc IJ |
2 | * serpent.c: Implementation of the Serpent block cipher |
3 | */ | |
4 | /* | |
5 | * This file is Free Software. It has been modified to as part of its | |
6 | * incorporation into secnet. | |
7 | * | |
8 | * Copyright 1998 Ross Anderson, Eli Biham, Lars Knudsen | |
9 | * Copyright 1995-2001 Stephen Early <steve@greenend.org.uk> | |
10 | * Copyright 2011-2013 Ian Jackson | |
11 | * | |
12 | * For more information about Serpent see | |
13 | * http://www.cl.cam.ac.uk/users/rja14/serpent.html | |
14 | * | |
15 | * You may redistribute secnet as a whole and/or modify it under the | |
16 | * terms of the GNU General Public License as published by the Free | |
17 | * Software Foundation; either version 3, or (at your option) any | |
18 | * later version. | |
2fe58dfd | 19 | * |
c215a4bc IJ |
20 | * You may redistribute this file and/or modify it under the terms of |
21 | * the GNU General Public License as published by the Free Software | |
22 | * Foundation; either version 2, or (at your option) any later | |
23 | * version. | |
2fe58dfd | 24 | * |
c215a4bc IJ |
25 | * This software is distributed in the hope that it will be useful, |
26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
28 | * GNU General Public License for more details. | |
2fe58dfd | 29 | * |
c215a4bc IJ |
30 | * You should have received a copy of the GNU General Public License |
31 | * along with this software; if not, see | |
32 | * https://www.gnu.org/licenses/gpl.html. | |
2fe58dfd SE |
33 | */ |
34 | ||
4a1a5919 | 35 | #include <stdint.h> |
2fe58dfd | 36 | |
980d1ab2 | 37 | #include "hexdebug.h" |
2fe58dfd SE |
38 | #include "serpent.h" |
39 | #include "serpentsboxes.h" | |
40 | ||
af43f0b7 IJ |
41 | #ifdef SERPENT_BIGENDIAN |
42 | ||
4a1a5919 IJ |
43 | #define GETPUT_CP(bytenum) \ |
44 | (((basep) + (lenbytes) - (offset) - 4)[(bytenum)]) | |
45 | ||
af43f0b7 IJ |
46 | #define SERPENT_DECORATE(func) serpentbe_##func |
47 | ||
48 | #else /* !defined(SERPENT_BIGENDIAN) */ | |
49 | ||
50 | #define GETPUT_CP(bytenum) \ | |
51 | (((basep) + (offset))[3-(bytenum)]) | |
52 | ||
53 | #define SERPENT_DECORATE(func) serpent_##func | |
54 | ||
55 | #endif /* !defined(SERPENT_BIGENDIAN) */ | |
56 | ||
980d1ab2 IJ |
57 | #if 0 |
58 | ||
59 | #include <stdio.h> | |
60 | ||
61 | static void SERP_DEBUG(const char *str1, | |
62 | const void *ary, int sz, | |
63 | const char *str2) | |
64 | { | |
65 | fprintf(stderr,"%s",str1); | |
66 | hexdebug(stderr,ary,sz); | |
67 | fprintf(stderr,"%s",str2); | |
68 | } | |
69 | ||
70 | #else | |
71 | ||
72 | #define SERP_DEBUG(str1,aryv,sz,str2) /*empty*/ | |
73 | ||
74 | #endif | |
75 | ||
76 | ||
4a1a5919 IJ |
77 | static uint32_t serpent_get_32bit(const uint8_t *basep, |
78 | int lenbytes, int offset) | |
79 | { | |
80 | return (((uint32_t)GETPUT_CP(0) << 24) | | |
81 | ((uint32_t)GETPUT_CP(1) << 16) | | |
82 | ((uint32_t)GETPUT_CP(2) << +8) | | |
83 | ((uint32_t)GETPUT_CP(3))); | |
84 | } | |
85 | ||
86 | static void serpent_put_32bit(uint8_t *basep, int lenbytes, int offset, uint32_t value) | |
87 | { | |
88 | GETPUT_CP(0) = (char)((value) >> 24); | |
89 | GETPUT_CP(1) = (char)((value) >> 16); | |
90 | GETPUT_CP(2) = (char)((value) >> 8); | |
91 | GETPUT_CP(3) = (char)(value); | |
92 | } | |
93 | ||
af43f0b7 | 94 | void SERPENT_DECORATE(makekey)(struct keyInstance *key, int keyLen, |
d357bccb | 95 | const uint8_t *keyMaterial) |
2fe58dfd | 96 | { |
1caa23ff IJ |
97 | int i; |
98 | uint32_t j; | |
2fe58dfd SE |
99 | uint32_t w[132],k[132]; |
100 | ||
980d1ab2 IJ |
101 | SERP_DEBUG("SERPENT makekey ",keyMaterial,keyLen/8,"\n"); |
102 | ||
2fe58dfd | 103 | for(i=0; i<keyLen/32; i++) |
4a1a5919 | 104 | w[i]=serpent_get_32bit(keyMaterial, keyLen/8, i*4); |
2fe58dfd | 105 | if(keyLen<256) |
4a1a5919 | 106 | w[i]=(serpent_get_32bit(keyMaterial, keyLen/8, i*4) |
3b83c932 | 107 | & ((1L<<((keyLen&31)))-1)) | (1L<<((keyLen&31))); |
2fe58dfd SE |
108 | for(i++; i<8; i++) |
109 | w[i]=0; | |
110 | for(i=8; i<16; i++) | |
111 | w[i]=ROL(w[i-8]^w[i-5]^w[i-3]^w[i-1]^PHI^(i-8),11); | |
112 | for(i=0; i<8; i++) | |
113 | w[i]=w[i+8]; | |
114 | for(i=8; i<132; i++) | |
115 | w[i]=ROL(w[i-8]^w[i-5]^w[i-3]^w[i-1]^PHI^i,11); | |
116 | ||
117 | RND03(w[ 0], w[ 1], w[ 2], w[ 3], k[ 0], k[ 1], k[ 2], k[ 3]); | |
118 | RND02(w[ 4], w[ 5], w[ 6], w[ 7], k[ 4], k[ 5], k[ 6], k[ 7]); | |
119 | RND01(w[ 8], w[ 9], w[ 10], w[ 11], k[ 8], k[ 9], k[ 10], k[ 11]); | |
120 | RND00(w[ 12], w[ 13], w[ 14], w[ 15], k[ 12], k[ 13], k[ 14], k[ 15]); | |
121 | RND31(w[ 16], w[ 17], w[ 18], w[ 19], k[ 16], k[ 17], k[ 18], k[ 19]); | |
122 | RND30(w[ 20], w[ 21], w[ 22], w[ 23], k[ 20], k[ 21], k[ 22], k[ 23]); | |
123 | RND29(w[ 24], w[ 25], w[ 26], w[ 27], k[ 24], k[ 25], k[ 26], k[ 27]); | |
124 | RND28(w[ 28], w[ 29], w[ 30], w[ 31], k[ 28], k[ 29], k[ 30], k[ 31]); | |
125 | RND27(w[ 32], w[ 33], w[ 34], w[ 35], k[ 32], k[ 33], k[ 34], k[ 35]); | |
126 | RND26(w[ 36], w[ 37], w[ 38], w[ 39], k[ 36], k[ 37], k[ 38], k[ 39]); | |
127 | RND25(w[ 40], w[ 41], w[ 42], w[ 43], k[ 40], k[ 41], k[ 42], k[ 43]); | |
128 | RND24(w[ 44], w[ 45], w[ 46], w[ 47], k[ 44], k[ 45], k[ 46], k[ 47]); | |
129 | RND23(w[ 48], w[ 49], w[ 50], w[ 51], k[ 48], k[ 49], k[ 50], k[ 51]); | |
130 | RND22(w[ 52], w[ 53], w[ 54], w[ 55], k[ 52], k[ 53], k[ 54], k[ 55]); | |
131 | RND21(w[ 56], w[ 57], w[ 58], w[ 59], k[ 56], k[ 57], k[ 58], k[ 59]); | |
132 | RND20(w[ 60], w[ 61], w[ 62], w[ 63], k[ 60], k[ 61], k[ 62], k[ 63]); | |
133 | RND19(w[ 64], w[ 65], w[ 66], w[ 67], k[ 64], k[ 65], k[ 66], k[ 67]); | |
134 | RND18(w[ 68], w[ 69], w[ 70], w[ 71], k[ 68], k[ 69], k[ 70], k[ 71]); | |
135 | RND17(w[ 72], w[ 73], w[ 74], w[ 75], k[ 72], k[ 73], k[ 74], k[ 75]); | |
136 | RND16(w[ 76], w[ 77], w[ 78], w[ 79], k[ 76], k[ 77], k[ 78], k[ 79]); | |
137 | RND15(w[ 80], w[ 81], w[ 82], w[ 83], k[ 80], k[ 81], k[ 82], k[ 83]); | |
138 | RND14(w[ 84], w[ 85], w[ 86], w[ 87], k[ 84], k[ 85], k[ 86], k[ 87]); | |
139 | RND13(w[ 88], w[ 89], w[ 90], w[ 91], k[ 88], k[ 89], k[ 90], k[ 91]); | |
140 | RND12(w[ 92], w[ 93], w[ 94], w[ 95], k[ 92], k[ 93], k[ 94], k[ 95]); | |
141 | RND11(w[ 96], w[ 97], w[ 98], w[ 99], k[ 96], k[ 97], k[ 98], k[ 99]); | |
142 | RND10(w[100], w[101], w[102], w[103], k[100], k[101], k[102], k[103]); | |
143 | RND09(w[104], w[105], w[106], w[107], k[104], k[105], k[106], k[107]); | |
144 | RND08(w[108], w[109], w[110], w[111], k[108], k[109], k[110], k[111]); | |
145 | RND07(w[112], w[113], w[114], w[115], k[112], k[113], k[114], k[115]); | |
146 | RND06(w[116], w[117], w[118], w[119], k[116], k[117], k[118], k[119]); | |
147 | RND05(w[120], w[121], w[122], w[123], k[120], k[121], k[122], k[123]); | |
148 | RND04(w[124], w[125], w[126], w[127], k[124], k[125], k[126], k[127]); | |
149 | RND03(w[128], w[129], w[130], w[131], k[128], k[129], k[130], k[131]); | |
150 | ||
151 | for(i=0; i<=32; i++) | |
152 | for(j=0; j<4; j++) | |
153 | key->subkeys[i][j] = k[4*i+j]; | |
154 | } | |
155 | ||
af43f0b7 | 156 | void SERPENT_DECORATE(encrypt)(struct keyInstance *key, |
d357bccb | 157 | const uint8_t plaintext[16], |
3b83c932 | 158 | uint8_t ciphertext[16]) |
2fe58dfd SE |
159 | { |
160 | register uint32_t x0, x1, x2, x3; | |
161 | register uint32_t y0, y1, y2, y3; | |
162 | ||
980d1ab2 IJ |
163 | SERP_DEBUG("SERPENT encrypt ",plaintext,16," ->"); |
164 | ||
4a1a5919 IJ |
165 | x0=serpent_get_32bit(plaintext,16,+0); |
166 | x1=serpent_get_32bit(plaintext,16,+4); | |
167 | x2=serpent_get_32bit(plaintext,16,+8); | |
168 | x3=serpent_get_32bit(plaintext,16,12); | |
2fe58dfd SE |
169 | |
170 | /* Start to encrypt the plaintext x */ | |
171 | keying(x0, x1, x2, x3, key->subkeys[ 0]); | |
172 | RND00(x0, x1, x2, x3, y0, y1, y2, y3); | |
173 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
174 | keying(x0, x1, x2, x3, key->subkeys[ 1]); | |
175 | RND01(x0, x1, x2, x3, y0, y1, y2, y3); | |
176 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
177 | keying(x0, x1, x2, x3, key->subkeys[ 2]); | |
178 | RND02(x0, x1, x2, x3, y0, y1, y2, y3); | |
179 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
180 | keying(x0, x1, x2, x3, key->subkeys[ 3]); | |
181 | RND03(x0, x1, x2, x3, y0, y1, y2, y3); | |
182 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
183 | keying(x0, x1, x2, x3, key->subkeys[ 4]); | |
184 | RND04(x0, x1, x2, x3, y0, y1, y2, y3); | |
185 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
186 | keying(x0, x1, x2, x3, key->subkeys[ 5]); | |
187 | RND05(x0, x1, x2, x3, y0, y1, y2, y3); | |
188 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
189 | keying(x0, x1, x2, x3, key->subkeys[ 6]); | |
190 | RND06(x0, x1, x2, x3, y0, y1, y2, y3); | |
191 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
192 | keying(x0, x1, x2, x3, key->subkeys[ 7]); | |
193 | RND07(x0, x1, x2, x3, y0, y1, y2, y3); | |
194 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
195 | keying(x0, x1, x2, x3, key->subkeys[ 8]); | |
196 | RND08(x0, x1, x2, x3, y0, y1, y2, y3); | |
197 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
198 | keying(x0, x1, x2, x3, key->subkeys[ 9]); | |
199 | RND09(x0, x1, x2, x3, y0, y1, y2, y3); | |
200 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
201 | keying(x0, x1, x2, x3, key->subkeys[10]); | |
202 | RND10(x0, x1, x2, x3, y0, y1, y2, y3); | |
203 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
204 | keying(x0, x1, x2, x3, key->subkeys[11]); | |
205 | RND11(x0, x1, x2, x3, y0, y1, y2, y3); | |
206 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
207 | keying(x0, x1, x2, x3, key->subkeys[12]); | |
208 | RND12(x0, x1, x2, x3, y0, y1, y2, y3); | |
209 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
210 | keying(x0, x1, x2, x3, key->subkeys[13]); | |
211 | RND13(x0, x1, x2, x3, y0, y1, y2, y3); | |
212 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
213 | keying(x0, x1, x2, x3, key->subkeys[14]); | |
214 | RND14(x0, x1, x2, x3, y0, y1, y2, y3); | |
215 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
216 | keying(x0, x1, x2, x3, key->subkeys[15]); | |
217 | RND15(x0, x1, x2, x3, y0, y1, y2, y3); | |
218 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
219 | keying(x0, x1, x2, x3, key->subkeys[16]); | |
220 | RND16(x0, x1, x2, x3, y0, y1, y2, y3); | |
221 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
222 | keying(x0, x1, x2, x3, key->subkeys[17]); | |
223 | RND17(x0, x1, x2, x3, y0, y1, y2, y3); | |
224 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
225 | keying(x0, x1, x2, x3, key->subkeys[18]); | |
226 | RND18(x0, x1, x2, x3, y0, y1, y2, y3); | |
227 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
228 | keying(x0, x1, x2, x3, key->subkeys[19]); | |
229 | RND19(x0, x1, x2, x3, y0, y1, y2, y3); | |
230 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
231 | keying(x0, x1, x2, x3, key->subkeys[20]); | |
232 | RND20(x0, x1, x2, x3, y0, y1, y2, y3); | |
233 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
234 | keying(x0, x1, x2, x3, key->subkeys[21]); | |
235 | RND21(x0, x1, x2, x3, y0, y1, y2, y3); | |
236 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
237 | keying(x0, x1, x2, x3, key->subkeys[22]); | |
238 | RND22(x0, x1, x2, x3, y0, y1, y2, y3); | |
239 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
240 | keying(x0, x1, x2, x3, key->subkeys[23]); | |
241 | RND23(x0, x1, x2, x3, y0, y1, y2, y3); | |
242 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
243 | keying(x0, x1, x2, x3, key->subkeys[24]); | |
244 | RND24(x0, x1, x2, x3, y0, y1, y2, y3); | |
245 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
246 | keying(x0, x1, x2, x3, key->subkeys[25]); | |
247 | RND25(x0, x1, x2, x3, y0, y1, y2, y3); | |
248 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
249 | keying(x0, x1, x2, x3, key->subkeys[26]); | |
250 | RND26(x0, x1, x2, x3, y0, y1, y2, y3); | |
251 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
252 | keying(x0, x1, x2, x3, key->subkeys[27]); | |
253 | RND27(x0, x1, x2, x3, y0, y1, y2, y3); | |
254 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
255 | keying(x0, x1, x2, x3, key->subkeys[28]); | |
256 | RND28(x0, x1, x2, x3, y0, y1, y2, y3); | |
257 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
258 | keying(x0, x1, x2, x3, key->subkeys[29]); | |
259 | RND29(x0, x1, x2, x3, y0, y1, y2, y3); | |
260 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
261 | keying(x0, x1, x2, x3, key->subkeys[30]); | |
262 | RND30(x0, x1, x2, x3, y0, y1, y2, y3); | |
263 | transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
264 | keying(x0, x1, x2, x3, key->subkeys[31]); | |
265 | RND31(x0, x1, x2, x3, y0, y1, y2, y3); | |
266 | x0 = y0; x1 = y1; x2 = y2; x3 = y3; | |
267 | keying(x0, x1, x2, x3, key->subkeys[32]); | |
268 | /* The ciphertext is now in x */ | |
269 | ||
4a1a5919 IJ |
270 | serpent_put_32bit(ciphertext,16,+0, x0); |
271 | serpent_put_32bit(ciphertext,16,+4, x1); | |
272 | serpent_put_32bit(ciphertext,16,+8, x2); | |
273 | serpent_put_32bit(ciphertext,16,12, x3); | |
980d1ab2 IJ |
274 | |
275 | SERP_DEBUG(" ",ciphertext,16,"\n"); | |
2fe58dfd SE |
276 | } |
277 | ||
af43f0b7 | 278 | void SERPENT_DECORATE(decrypt)(struct keyInstance *key, |
d357bccb | 279 | const uint8_t ciphertext[16], |
3b83c932 | 280 | uint8_t plaintext[16]) |
2fe58dfd SE |
281 | { |
282 | register uint32_t x0, x1, x2, x3; | |
283 | register uint32_t y0, y1, y2, y3; | |
284 | ||
980d1ab2 IJ |
285 | SERP_DEBUG("SERPENT decrypt ",ciphertext,16," ->"); |
286 | ||
4a1a5919 IJ |
287 | x0=serpent_get_32bit(ciphertext,16,+0); |
288 | x1=serpent_get_32bit(ciphertext,16,+4); | |
289 | x2=serpent_get_32bit(ciphertext,16,+8); | |
290 | x3=serpent_get_32bit(ciphertext,16,12); | |
2fe58dfd SE |
291 | |
292 | /* Start to decrypt the ciphertext x */ | |
293 | keying(x0, x1, x2, x3, key->subkeys[32]); | |
294 | InvRND31(x0, x1, x2, x3, y0, y1, y2, y3); | |
295 | keying(y0, y1, y2, y3, key->subkeys[31]); | |
296 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
297 | InvRND30(x0, x1, x2, x3, y0, y1, y2, y3); | |
298 | keying(y0, y1, y2, y3, key->subkeys[30]); | |
299 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
300 | InvRND29(x0, x1, x2, x3, y0, y1, y2, y3); | |
301 | keying(y0, y1, y2, y3, key->subkeys[29]); | |
302 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
303 | InvRND28(x0, x1, x2, x3, y0, y1, y2, y3); | |
304 | keying(y0, y1, y2, y3, key->subkeys[28]); | |
305 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
306 | InvRND27(x0, x1, x2, x3, y0, y1, y2, y3); | |
307 | keying(y0, y1, y2, y3, key->subkeys[27]); | |
308 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
309 | InvRND26(x0, x1, x2, x3, y0, y1, y2, y3); | |
310 | keying(y0, y1, y2, y3, key->subkeys[26]); | |
311 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
312 | InvRND25(x0, x1, x2, x3, y0, y1, y2, y3); | |
313 | keying(y0, y1, y2, y3, key->subkeys[25]); | |
314 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
315 | InvRND24(x0, x1, x2, x3, y0, y1, y2, y3); | |
316 | keying(y0, y1, y2, y3, key->subkeys[24]); | |
317 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
318 | InvRND23(x0, x1, x2, x3, y0, y1, y2, y3); | |
319 | keying(y0, y1, y2, y3, key->subkeys[23]); | |
320 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
321 | InvRND22(x0, x1, x2, x3, y0, y1, y2, y3); | |
322 | keying(y0, y1, y2, y3, key->subkeys[22]); | |
323 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
324 | InvRND21(x0, x1, x2, x3, y0, y1, y2, y3); | |
325 | keying(y0, y1, y2, y3, key->subkeys[21]); | |
326 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
327 | InvRND20(x0, x1, x2, x3, y0, y1, y2, y3); | |
328 | keying(y0, y1, y2, y3, key->subkeys[20]); | |
329 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
330 | InvRND19(x0, x1, x2, x3, y0, y1, y2, y3); | |
331 | keying(y0, y1, y2, y3, key->subkeys[19]); | |
332 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
333 | InvRND18(x0, x1, x2, x3, y0, y1, y2, y3); | |
334 | keying(y0, y1, y2, y3, key->subkeys[18]); | |
335 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
336 | InvRND17(x0, x1, x2, x3, y0, y1, y2, y3); | |
337 | keying(y0, y1, y2, y3, key->subkeys[17]); | |
338 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
339 | InvRND16(x0, x1, x2, x3, y0, y1, y2, y3); | |
340 | keying(y0, y1, y2, y3, key->subkeys[16]); | |
341 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
342 | InvRND15(x0, x1, x2, x3, y0, y1, y2, y3); | |
343 | keying(y0, y1, y2, y3, key->subkeys[15]); | |
344 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
345 | InvRND14(x0, x1, x2, x3, y0, y1, y2, y3); | |
346 | keying(y0, y1, y2, y3, key->subkeys[14]); | |
347 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
348 | InvRND13(x0, x1, x2, x3, y0, y1, y2, y3); | |
349 | keying(y0, y1, y2, y3, key->subkeys[13]); | |
350 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
351 | InvRND12(x0, x1, x2, x3, y0, y1, y2, y3); | |
352 | keying(y0, y1, y2, y3, key->subkeys[12]); | |
353 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
354 | InvRND11(x0, x1, x2, x3, y0, y1, y2, y3); | |
355 | keying(y0, y1, y2, y3, key->subkeys[11]); | |
356 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
357 | InvRND10(x0, x1, x2, x3, y0, y1, y2, y3); | |
358 | keying(y0, y1, y2, y3, key->subkeys[10]); | |
359 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
360 | InvRND09(x0, x1, x2, x3, y0, y1, y2, y3); | |
361 | keying(y0, y1, y2, y3, key->subkeys[ 9]); | |
362 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
363 | InvRND08(x0, x1, x2, x3, y0, y1, y2, y3); | |
364 | keying(y0, y1, y2, y3, key->subkeys[ 8]); | |
365 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
366 | InvRND07(x0, x1, x2, x3, y0, y1, y2, y3); | |
367 | keying(y0, y1, y2, y3, key->subkeys[ 7]); | |
368 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
369 | InvRND06(x0, x1, x2, x3, y0, y1, y2, y3); | |
370 | keying(y0, y1, y2, y3, key->subkeys[ 6]); | |
371 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
372 | InvRND05(x0, x1, x2, x3, y0, y1, y2, y3); | |
373 | keying(y0, y1, y2, y3, key->subkeys[ 5]); | |
374 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
375 | InvRND04(x0, x1, x2, x3, y0, y1, y2, y3); | |
376 | keying(y0, y1, y2, y3, key->subkeys[ 4]); | |
377 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
378 | InvRND03(x0, x1, x2, x3, y0, y1, y2, y3); | |
379 | keying(y0, y1, y2, y3, key->subkeys[ 3]); | |
380 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
381 | InvRND02(x0, x1, x2, x3, y0, y1, y2, y3); | |
382 | keying(y0, y1, y2, y3, key->subkeys[ 2]); | |
383 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
384 | InvRND01(x0, x1, x2, x3, y0, y1, y2, y3); | |
385 | keying(y0, y1, y2, y3, key->subkeys[ 1]); | |
386 | inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); | |
387 | InvRND00(x0, x1, x2, x3, y0, y1, y2, y3); | |
388 | x0 = y0; x1 = y1; x2 = y2; x3 = y3; | |
389 | keying(x0, x1, x2, x3, key->subkeys[ 0]); | |
390 | /* The plaintext is now in x */ | |
391 | ||
4a1a5919 IJ |
392 | serpent_put_32bit(plaintext,16,+0, x0); |
393 | serpent_put_32bit(plaintext,16,+4, x1); | |
394 | serpent_put_32bit(plaintext,16,+8, x2); | |
395 | serpent_put_32bit(plaintext,16,12, x3); | |
980d1ab2 IJ |
396 | |
397 | SERP_DEBUG(" ",plaintext,16,"\n"); | |
2fe58dfd | 398 | } |