]> git.cryptolib.org Git - avr-crypto-lib.git/blob - cast5.c
insereated GPLv3 stub
[avr-crypto-lib.git] / cast5.c
1 /* cast5.c */
2 /*
3     This file is part of the Crypto-avr-lib/microcrypt-lib.
4     Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
5
6     This program is free software: you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation, either version 3 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 /* 
20  * \file        cast5.c
21  * \author      Daniel Otte
22  * \date        26.07.2006
23  * \par License:
24  *  GPL
25  * \brief Implementation of the CAST5 (aka CAST-128) cipher algorithm as described in RFC 2144
26  * 
27  */
28  
29  #include <stdint.h>
30  #include <string.h>
31  #include "cast5.h"
32  #include "config.h"
33  #include "debug.h"
34  
35  #undef DEBUG
36  
37  #ifdef DEBUG
38   #include "uart.h"
39  #endif
40  
41 #include "cast5-sbox.h"
42
43
44  
45 #define S5(x) pgm_read_dword(&s5[(x)])
46 #define S6(x) pgm_read_dword(&s6[(x)])
47 #define S7(x) pgm_read_dword(&s7[(x)])
48 #define S8(x) pgm_read_dword(&s8[(x)])
49
50  
51 void cast5_init_A(uint8_t *dest, uint8_t *src, bool bmode){
52         uint8_t mask = bmode?0x8:0;
53         *((uint32_t*)(&dest[0x0])) = *((uint32_t*)(&src[0x0^mask])) ^ S5(src[0xD^mask]) ^ S6(src[0xF^mask]) ^ S7(src[0xC^mask]) ^ S8(src[0xE^mask]) ^ S7(src[0x8^mask]);
54         *((uint32_t*)(&dest[0x4])) = *((uint32_t*)(&src[0x8^mask])) ^ S5(dest[0x0]) ^ S6(dest[0x2]) ^ S7(dest[0x1]) ^ S8(dest[0x3]) ^ S8(src[0xA^mask]);
55         *((uint32_t*)(&dest[0x8])) = *((uint32_t*)(&src[0xC^mask])) ^ S5(dest[0x7]) ^ S6(dest[0x6]) ^ S7(dest[0x5]) ^ S8(dest[0x4]) ^ S5(src[0x9^mask]);
56         *((uint32_t*)(&dest[0xC])) = *((uint32_t*)(&src[0x4^mask])) ^ S5(dest[0xA]) ^ S6(dest[0x9]) ^ S7(dest[0xB]) ^ S8(dest[0x8]) ^ S6(src[0xB^mask]);
57 }
58
59 void cast5_init_M(uint8_t *dest, uint8_t *src, bool nmode, bool xmode){
60         uint8_t nmt[] = {0xB, 0xA, 0x9, 0x8, 0xF, 0xE, 0xD, 0xC, 0x3, 0x2, 0x1, 0x0, 0x7, 0x6, 0x5, 0x4}; /* nmode table */
61         uint8_t xmt[4][4] = {{0x2, 0x6, 0x9, 0xC}, {0x8, 0xD, 0x3, 0x7}, {0x3, 0x7, 0x8, 0xD}, {0x9, 0xC, 0x2, 0x6}};
62         #define NMT(x) (src[nmode?nmt[(x)]:(x)])
63         #define XMT(x) (src[xmt[(xmode<<1) + nmode][(x)]])
64         *((uint32_t*)(&dest[0x0])) = S5(NMT(0x8)) ^ S6(NMT(0x9)) ^ S7(NMT(0x7)) ^ S8(NMT(0x6)) ^ S5(XMT(0));
65         *((uint32_t*)(&dest[0x4])) = S5(NMT(0xA)) ^ S6(NMT(0xB)) ^ S7(NMT(0x5)) ^ S8(NMT(0x4)) ^ S6(XMT(1));
66         *((uint32_t*)(&dest[0x8])) = S5(NMT(0xC)) ^ S6(NMT(0xD)) ^ S7(NMT(0x3)) ^ S8(NMT(0x2)) ^ S7(XMT(2));
67         *((uint32_t*)(&dest[0xC])) = S5(NMT(0xE)) ^ S6(NMT(0xF)) ^ S7(NMT(0x1)) ^ S8(NMT(0x0)) ^ S8(XMT(3));
68 }
69
70 #define S5B(x) pgm_read_byte(3+(uint8_t*)(&s5[(x)]))
71 #define S6B(x) pgm_read_byte(3+(uint8_t*)(&s6[(x)]))
72 #define S7B(x) pgm_read_byte(3+(uint8_t*)(&s7[(x)]))
73 #define S8B(x) pgm_read_byte(3+(uint8_t*)(&s8[(x)]))
74
75 void cast5_init_rM(uint8_t *klo, uint8_t *khi, uint8_t offset, uint8_t *src, bool nmode, bool xmode){
76         uint8_t nmt[] = {0xB, 0xA, 0x9, 0x8, 0xF, 0xE, 0xD, 0xC, 0x3, 0x2, 0x1, 0x0, 0x7, 0x6, 0x5, 0x4}; /* nmode table */
77         uint8_t xmt[4][4] = {{0x2, 0x6, 0x9, 0xC}, {0x8, 0xD, 0x3, 0x7}, {0x3, 0x7, 0x8, 0xD}, {0x9, 0xC, 0x2, 0x6}};
78         uint8_t t, h=0; 
79         t = S5B(NMT(0x8)) ^ S6B(NMT(0x9)) ^ S7B(NMT(0x7)) ^ S8B(NMT(0x6)) ^ S5B(XMT(0));
80                 klo[offset*2] |= (t & 0x0f);
81                 h |= (t&0x10); h>>=1;
82         t = S5B(NMT(0xA)) ^ S6B(NMT(0xB)) ^ S7B(NMT(0x5)) ^ S8B(NMT(0x4)) ^ S6B(XMT(1));
83                 klo[offset*2] |= (t<<4) & 0xf0;
84                 h |= t&0x10; h>>=1;
85         t = S5B(NMT(0xC)) ^ S6B(NMT(0xD)) ^ S7B(NMT(0x3)) ^ S8B(NMT(0x2)) ^ S7B(XMT(2));
86                 klo[offset*2+1] |= t&0xf;
87                 h |= t&0x10; h>>=1;
88         t = S5B(NMT(0xE)) ^ S6B(NMT(0xF)) ^ S7B(NMT(0x1)) ^ S8B(NMT(0x0)) ^ S8B(XMT(3));
89                 klo[offset*2+1] |= t<<4;
90                 h |= t&0x10; h >>=1;
91         #ifdef DEBUG
92                 uart_putstr("\r\n\t h="); uart_hexdump(&h,1);
93         #endif
94         khi[offset>>1] |= h<<((offset&0x1)?4:0);
95 }
96
97 #define S_5X(s) pgm_read_dword(&s5[BPX[(s)]])
98 #define S_6X(s) pgm_read_dword(&s6[BPX[(s)]])
99 #define S_7X(s) pgm_read_dword(&s7[BPX[(s)]])
100 #define S_8X(s) pgm_read_dword(&s8[BPX[(s)]])
101
102 #define S_5Z(s) pgm_read_dword(&s5[BPZ[(s)]])
103 #define S_6Z(s) pgm_read_dword(&s6[BPZ[(s)]])
104 #define S_7Z(s) pgm_read_dword(&s7[BPZ[(s)]])
105 #define S_8Z(s) pgm_read_dword(&s8[BPZ[(s)]])
106
107
108
109 /**
110  * \brief sets up round keys (context) for cast5 en/decryption.
111  * @param s Pointer to cast5 context.
112  * @param key Pointer to binary key.
113  * @param keylength length of keydata in bits.
114  */
115 void cast5_init(cast5_ctx_t* s, uint8_t* key, uint8_t keylength){
116          /* we migth return if the key is valid and if setup was sucessfull */
117         uint32_t x[4], z[4];
118         #define BPX ((uint8_t*)&(x[0]))
119         #define BPZ ((uint8_t*)&(z[0]))
120         s->shortkey = (keylength<=80);
121         /* littel endian only! */
122         memset(&(x[0]), 0 ,16); /* set x to zero */
123         if(keylength > 128)
124                 keylength=128;
125         memcpy(&(x[0]), key, (keylength+7)/8);
126         
127
128         /* todo: merge a and b and compress the whole stuff */
129         /***** A *****/
130         cast5_init_A((uint8_t*)(&z[0]), (uint8_t*)(&x[0]), false);      
131         /***** M *****/
132         cast5_init_M((uint8_t*)(&(s->mask[0])), (uint8_t*)(&z[0]), false, false);
133         /***** B *****/
134         cast5_init_A((uint8_t*)(&x[0]), (uint8_t*)(&z[0]), true);
135         /***** N *****/
136         cast5_init_M((uint8_t*)(&(s->mask[4])), (uint8_t*)(&x[0]), true, false);
137         /***** A *****/
138         cast5_init_A((uint8_t*)(&z[0]), (uint8_t*)(&x[0]), false);
139         /***** N' *****/
140         cast5_init_M((uint8_t*)(&(s->mask[8])), (uint8_t*)(&z[0]), true, true);
141         /***** B *****/
142         cast5_init_A((uint8_t*)(&x[0]), (uint8_t*)(&z[0]), true);
143         /***** M' *****/
144         cast5_init_M((uint8_t*)(&(s->mask[12])), (uint8_t*)(&x[0]), false, true);
145         
146         /* that were the masking keys, now the rotation keys */
147         /* set the keys to zero */
148         memset(&(s->rotl[0]),0,8);
149         s->roth[0]=s->roth[1]=0;
150         /***** A *****/
151         cast5_init_A((uint8_t*)(&z[0]), (uint8_t*)(&x[0]), false);
152         /***** M *****/
153         cast5_init_rM(&(s->rotl[0]), &(s->roth[0]), 0, (uint8_t*)(&z[0]), false, false);
154         /***** B *****/
155         cast5_init_A((uint8_t*)(&x[0]), (uint8_t*)(&z[0]), true);
156         /***** N *****/
157         cast5_init_rM(&(s->rotl[0]), &(s->roth[0]), 1, (uint8_t*)(&x[0]), true, false);
158         /***** A *****/
159         cast5_init_A((uint8_t*)(&z[0]), (uint8_t*)(&x[0]), false);
160         /***** N' *****/
161         cast5_init_rM(&(s->rotl[0]), &(s->roth[0]), 2, (uint8_t*)(&z[0]), true, true);
162         /***** B *****/
163         cast5_init_A((uint8_t*)(&x[0]), (uint8_t*)(&z[0]), true);
164         /***** M' *****/
165         cast5_init_rM(&(s->rotl[0]), &(s->roth[0]), 3, (uint8_t*)(&x[0]), false, true);
166         /* done ;-) */
167 }
168
169
170
171 /********************************************************************************************************/
172
173 #define ROTL32(a,n) ((a)<<(n) | (a)>>(32-(n)))
174 #define CHANGE_ENDIAN32(x) ((x)<<24 | (x)>>24 | ((x)&0xff00)<<8 | ((x)&0xff0000)>>8 )
175
176 typedef uint32_t cast5_f_t(uint32_t,uint32_t,uint8_t);
177
178 #define IA 3
179 #define IB 2
180 #define IC 1
181 #define ID 0
182
183
184 uint32_t cast5_f1(uint32_t d, uint32_t m, uint8_t r){
185         uint32_t t;
186         t = ROTL32((d + m),r);
187 #ifdef DEBUG
188         uint32_t ia,ib,ic,id;
189         uart_putstr("\r\n f1("); uart_hexdump(&d, 4); uart_putc(',');
190                 uart_hexdump(&m , 4); uart_putc(','); uart_hexdump(&r, 1);uart_putstr("): I=");
191                 uart_hexdump(&t, 4);
192         ia = pgm_read_dword(&s1[((uint8_t*)&t)[IA]] );
193         ib = pgm_read_dword(&s2[((uint8_t*)&t)[IB]] );
194         ic = pgm_read_dword(&s3[((uint8_t*)&t)[IC]] );
195         id = pgm_read_dword(&s4[((uint8_t*)&t)[ID]] );
196         uart_putstr("\r\n\tIA="); uart_hexdump(&ia, 4);
197         uart_putstr("\r\n\tIB="); uart_hexdump(&ib, 4);
198         uart_putstr("\r\n\tIC="); uart_hexdump(&ic, 4);
199         uart_putstr("\r\n\tID="); uart_hexdump(&id, 4);
200
201         return (((ia ^ ib) - ic) + id);
202
203 #else
204         
205         return (((pgm_read_dword(&s1[((uint8_t*)&t)[IA]] ) ^ pgm_read_dword(&s2[((uint8_t*)&t)[IB]] )) 
206                 - pgm_read_dword(&s3[((uint8_t*)&t)[IC]] )) + pgm_read_dword(&s4[((uint8_t*)&t)[ID]]));
207
208 #endif
209 }
210
211
212 uint32_t cast5_f2(uint32_t d, uint32_t m, uint8_t r){
213         uint32_t t;
214         t = ROTL32((d ^ m),r);
215 #ifdef DEBUG
216         uint32_t ia,ib,ic,id;
217         uart_putstr("\r\n f2("); uart_hexdump(&d, 4); uart_putc(',');
218                 uart_hexdump(&m , 4); uart_putc(','); uart_hexdump(&r, 1);uart_putstr("): I=");
219                 uart_hexdump(&t, 4);
220
221         ia = pgm_read_dword(&s1[((uint8_t*)&t)[IA]] );
222         ib = pgm_read_dword(&s2[((uint8_t*)&t)[IB]] );
223         ic = pgm_read_dword(&s3[((uint8_t*)&t)[IC]] );
224         id = pgm_read_dword(&s4[((uint8_t*)&t)[ID]] );
225         
226         uart_putstr("\r\n\tIA="); uart_hexdump(&ia, 4);
227         uart_putstr("\r\n\tIB="); uart_hexdump(&ib, 4);
228         uart_putstr("\r\n\tIC="); uart_hexdump(&ic, 4);
229         uart_putstr("\r\n\tID="); uart_hexdump(&id, 4);
230
231         return (((ia - ib) + ic) ^ id);
232 #else
233         
234         return (((pgm_read_dword(&s1[((uint8_t*)&t)[IA]]) 
235                 - pgm_read_dword(&s2[((uint8_t*)&t)[IB]]) ) 
236                     + pgm_read_dword(&s3[((uint8_t*)&t)[IC]]) ) 
237                     ^ pgm_read_dword(&s4[((uint8_t*)&t)[ID]]) );
238
239 #endif
240 }
241
242 uint32_t cast5_f3(uint32_t d, uint32_t m, uint8_t r){
243         uint32_t t;
244         t = ROTL32((m - d),r);
245
246 #ifdef DEBUG
247         uint32_t ia,ib,ic,id;
248
249         uart_putstr("\r\n f3("); uart_hexdump(&d, 4); uart_putc(',');
250                 uart_hexdump(&m , 4); uart_putc(','); uart_hexdump(&r, 1);uart_putstr("): I=");
251                 uart_hexdump(&t, 4);
252
253         ia = pgm_read_dword(&s1[((uint8_t*)&t)[IA]] );
254         ib = pgm_read_dword(&s2[((uint8_t*)&t)[IB]] );
255         ic = pgm_read_dword(&s3[((uint8_t*)&t)[IC]] );
256         id = pgm_read_dword(&s4[((uint8_t*)&t)[ID]] );
257         
258         uart_putstr("\r\n\tIA="); uart_hexdump(&ia, 4);
259         uart_putstr("\r\n\tIB="); uart_hexdump(&ib, 4);
260         uart_putstr("\r\n\tIC="); uart_hexdump(&ic, 4);
261         uart_putstr("\r\n\tID="); uart_hexdump(&id, 4);
262         return (((ia + ib) ^ ic) - id);
263 #else
264         return ((pgm_read_dword(&s1[((uint8_t*)&t)[IA]] ) + pgm_read_dword(&s2[((uint8_t*)&t)[IB]] )) 
265                 ^ pgm_read_dword(&s3[((uint8_t*)&t)[IC]] )) - pgm_read_dword(&s4[((uint8_t*)&t)[ID]] );
266
267 #endif
268 }
269
270 /*************************************************************************/
271
272 /**
273  * \brief encrypts a datablock with cast5
274  * @param s Pointer to cast5 roundkeys (context)
275  * @param block Pointer to datablock
276  */
277 void cast5_enc(cast5_ctx_t *s, void* block){
278         uint32_t l,r, x, y;
279         uint8_t i;
280         cast5_f_t* f[]={cast5_f1,cast5_f2,cast5_f3};
281         l=((uint32_t*)block)[0];
282         r=((uint32_t*)block)[1];
283 //      uart_putstr("\r\n round[-1] = ");
284 //      uart_hexdump(&r, 4);
285         for (i=0;i<(s->shortkey?12:16);++i){
286                 x = r;
287                 y = (f[i%3])(CHANGE_ENDIAN32(r), CHANGE_ENDIAN32(s->mask[i]), 
288                         (((s->roth[i>>3]) & (1<<(i&0x7)))?0x10:0x00) 
289                          + ( ((s->rotl[i>>1])>>((i&1)?4:0)) & 0x0f) );
290                 r = l ^ CHANGE_ENDIAN32(y);
291 //              uart_putstr("\r\n round["); DEBUG_B(i); uart_putstr("] = ");
292 //              uart_hexdump(&r, 4);
293                 l = x;
294         }
295         ((uint32_t*)block)[0]=r;
296         ((uint32_t*)block)[1]=l;
297 }
298
299 /*************************************************************************/
300
301 /**
302  * \brief decrypts a datablock with cast5
303  * @param s Pointer to cast5 roundkeys (context)
304  * @param block Pointer to datablock
305  */
306 void cast5_dec(cast5_ctx_t *s, void* block){
307         uint32_t l,r, x, y;
308         int8_t i, rounds;
309         cast5_f_t* f[]={cast5_f1,cast5_f2,cast5_f3};
310         l=((uint32_t*)block)[0];
311         r=((uint32_t*)block)[1];
312         rounds = (s->shortkey?12:16);
313         for (i=rounds-1; i>=0 ;--i){
314                 x = r;
315                 y = (f[i%3])(CHANGE_ENDIAN32(r), CHANGE_ENDIAN32(s->mask[i]), 
316                         (((s->roth[i>>3]) & (1<<(i&0x7)))?0x10:0x00) 
317                          + ( ((s->rotl[i>>1])>>((i&1)?4:0)) & 0x0f) );
318                 r = l ^ CHANGE_ENDIAN32(y);
319                 l = x;
320         }
321         ((uint32_t*)block)[0]=r;
322         ((uint32_t*)block)[1]=l;
323 }
324
325
326 /*********************************************************************************************************/
327 /*********************************************************************************************************/
328 /*********************************************************************************************************/
329
330 #if 0
331
332 void cast5_old_init(cast5_ctx_t* s, uint8_t* key, uint8_t keylength){
333          /* we migth return if the key is valid and if setup was sucessfull */
334         uint32_t x[4], z[4], t;
335         #define BPX ((uint8_t*)&(x[0]))
336         #define BPZ ((uint8_t*)&(z[0]))
337         s->shortkey = (keylength<=80);
338         /* littel endian only! */
339         memset(&(x[0]), 0 ,16); /* set x to zero */
340         memcpy(&(x[0]), key, keylength/8);
341         
342
343         /* todo: merge a and b and compress the whole stuff */
344         /***** A *****/
345         z[0] = x[0] ^ S_5X(0xD) ^ S_6X(0xF) ^ S_7X(0xC) ^ S_8X(0xE) ^ S_7X(0x8);        
346         z[1] = x[2] ^ S_5Z(0x0) ^ S_6Z(0x2) ^ S_7Z(0x1) ^ S_8Z(0x3) ^ S_8X(0xA);
347         z[2] = x[3] ^ S_5Z(0x7) ^ S_6Z(0x6) ^ S_7Z(0x5) ^ S_8Z(0x4) ^ S_5X(0x9);
348         z[3] = x[1] ^ S_5Z(0xA) ^ S_6Z(0x9) ^ S_7Z(0xB) ^ S_8Z(0x8) ^ S_6X(0xB);
349         /***** M *****/
350         s->mask[0] = S_5Z(0x8) ^ S_6Z(0x9) ^ S_7Z(0x7) ^ S_8Z(0x6) ^ S_5Z(0x2);
351         s->mask[1] = S_5Z(0xA) ^ S_6Z(0xB) ^ S_7Z(0x5) ^ S_8Z(0x4) ^ S_6Z(0x6);
352         s->mask[2] = S_5Z(0xC) ^ S_6Z(0xD) ^ S_7Z(0x3) ^ S_8Z(0x2) ^ S_7Z(0x9);
353         s->mask[3] = S_5Z(0xE) ^ S_6Z(0xF) ^ S_7Z(0x1) ^ S_8Z(0x0) ^ S_8Z(0xC);
354         /***** B *****/
355         x[0] = z[2] ^ S_5Z(0x5) ^ S_6Z(0x7) ^ S_7Z(0x4) ^ S_8Z(0x6) ^ S_7Z(0x0);
356         x[1] = z[0] ^ S_5X(0x0) ^ S_6X(0x2) ^ S_7X(0x1) ^ S_8X(0x3) ^ S_8Z(0x2);
357         x[2] = z[1] ^ S_5X(0x7) ^ S_6X(0x6) ^ S_7X(0x5) ^ S_8X(0x4) ^ S_5Z(0x1);
358         x[3] = z[3] ^ S_5X(0xA) ^ S_6X(0x9) ^ S_7X(0xB) ^ S_8X(0x8) ^ S_6Z(0x3);
359         /***** N *****/
360         s->mask[4] = S_5X(0x3) ^ S_6X(0x2) ^ S_7X(0xC) ^ S_8X(0xD) ^ S_5X(0x8);
361         s->mask[5] = S_5X(0x1) ^ S_6X(0x0) ^ S_7X(0xE) ^ S_8X(0xF) ^ S_6X(0xD);
362         s->mask[6] = S_5X(0x7) ^ S_6X(0x6) ^ S_7X(0x8) ^ S_8X(0x9) ^ S_7X(0x3);
363         s->mask[7] = S_5X(0x5) ^ S_6X(0x4) ^ S_7X(0xA) ^ S_8X(0xB) ^ S_8X(0x7);
364         /***** A *****/
365         z[0] = x[0] ^ S_5X(0xD) ^ S_6X(0xF) ^ S_7X(0xC) ^ S_8X(0xE) ^ S_7X(0x8);
366         z[1] = x[2] ^ S_5Z(0x0) ^ S_6Z(0x2) ^ S_7Z(0x1) ^ S_8Z(0x3) ^ S_8X(0xA);
367         z[2] = x[3] ^ S_5Z(0x7) ^ S_6Z(0x6) ^ S_7Z(0x5) ^ S_8Z(0x4) ^ S_5X(0x9);
368         z[3] = x[1] ^ S_5Z(0xA) ^ S_6Z(0x9) ^ S_7Z(0xB) ^ S_8Z(0x8) ^ S_6X(0xB);
369         /***** N' *****/
370         s->mask[8] = S_5Z(0x3) ^ S_6Z(0x2) ^ S_7Z(0xC) ^ S_8Z(0xD) ^ S_5Z(0x9);
371         s->mask[9] = S_5Z(0x1) ^ S_6Z(0x0) ^ S_7Z(0xE) ^ S_8Z(0xF) ^ S_6Z(0xC);
372         s->mask[10] = S_5Z(0x7) ^ S_6Z(0x6) ^ S_7Z(0x8) ^ S_8Z(0x9) ^ S_7Z(0x2);
373         s->mask[11] = S_5Z(0x5) ^ S_6Z(0x4) ^ S_7Z(0xA) ^ S_8Z(0xB) ^ S_8Z(0x6);
374         /***** B *****/
375         x[0] = z[2] ^ S_5Z(0x5) ^ S_6Z(0x7) ^ S_7Z(0x4) ^ S_8Z(0x6) ^ S_7Z(0x0);
376         x[1] = z[0] ^ S_5X(0x0) ^ S_6X(0x2) ^ S_7X(0x1) ^ S_8X(0x3) ^ S_8Z(0x2);
377         x[2] = z[1] ^ S_5X(0x7) ^ S_6X(0x6) ^ S_7X(0x5) ^ S_8X(0x4) ^ S_5Z(0x1);
378         x[3] = z[3] ^ S_5X(0xA) ^ S_6X(0x9) ^ S_7X(0xB) ^ S_8X(0x8) ^ S_6Z(0x3);
379         /***** M' *****/
380         s->mask[12] = S_5X(0x8) ^ S_6X(0x9) ^ S_7X(0x7) ^ S_8X(0x6) ^ S_5X(0x3);
381         s->mask[13] = S_5X(0xA) ^ S_6X(0xB) ^ S_7X(0x5) ^ S_8X(0x4) ^ S_6X(0x7);
382         s->mask[14] = S_5X(0xC) ^ S_6X(0xD) ^ S_7X(0x3) ^ S_8X(0x2) ^ S_7X(0x8);
383         s->mask[15] = S_5X(0xE) ^ S_6X(0xF) ^ S_7X(0x1) ^ S_8X(0x0) ^ S_8X(0xD);
384
385         /* that were the masking keys, now the rotation keys */
386         /* set the keys to zero */
387         memset(&(s->rotl[0]),0,8);
388         s->roth[0]=s->roth[1]=0;
389         /***** A *****/
390         z[0] = x[0] ^ S_5X(0xD) ^ S_6X(0xF) ^ S_7X(0xC) ^ S_8X(0xE) ^ S_7X(0x8);
391         z[1] = x[2] ^ S_5Z(0x0) ^ S_6Z(0x2) ^ S_7Z(0x1) ^ S_8Z(0x3) ^ S_8X(0xA);
392         z[2] = x[3] ^ S_5Z(0x7) ^ S_6Z(0x6) ^ S_7Z(0x5) ^ S_8Z(0x4) ^ S_5X(0x9);
393         z[3] = x[1] ^ S_5Z(0xA) ^ S_6Z(0x9) ^ S_7Z(0xB) ^ S_8Z(0x8) ^ S_6X(0xB);
394         /***** M *****/
395         t = S_5Z(0x8) ^ S_6Z(0x9) ^ S_7Z(0x7) ^ S_8Z(0x6) ^ S_5Z(0x2);
396         t >>= 24;
397         s->rotl[0] |= t & 0x0f;         
398         s->roth[0] |= (t >> 4) & (1<<0);
399         t = S_5Z(0xA) ^ S_6Z(0xB) ^ S_7Z(0x5) ^ S_8Z(0x4) ^ S_6Z(0x6);
400         t >>= 24;
401         s->rotl[0] |= (t<<4) & 0xf0;
402         s->roth[0] |= (t >> 3) & (1<<1);
403         t = S_5Z(0xC) ^ S_6Z(0xD) ^ S_7Z(0x3) ^ S_8Z(0x2) ^ S_7Z(0x9);
404         t >>= 24;
405         s->rotl[1] |= t & 0x0f;         
406         s->roth[0] |= (t >> 2) & (1<<2);
407         t = S_5Z(0xE) ^ S_6Z(0xF) ^ S_7Z(0x1) ^ S_8Z(0x0) ^ S_8Z(0xC);
408         t >>= 24;
409         s->rotl[1] |= (t<<4) & 0xf0;
410         s->roth[0] |= (t >> 1) & (1<<3);
411         /***** B *****/
412         x[0] = z[2] ^ S_5Z(0x5) ^ S_6Z(0x7) ^ S_7Z(0x4) ^ S_8Z(0x6) ^ S_7Z(0x0);
413         x[1] = z[0] ^ S_5X(0x0) ^ S_6X(0x2) ^ S_7X(0x1) ^ S_8X(0x3) ^ S_8Z(0x2);
414         x[2] = z[1] ^ S_5X(0x7) ^ S_6X(0x6) ^ S_7X(0x5) ^ S_8X(0x4) ^ S_5Z(0x1);
415         x[3] = z[3] ^ S_5X(0xA) ^ S_6X(0x9) ^ S_7X(0xB) ^ S_8X(0x8) ^ S_6Z(0x3);
416         /***** N *****/
417         t = S_5X(0x3) ^ S_6X(0x2) ^ S_7X(0xC) ^ S_8X(0xD) ^ S_5X(0x8);
418         t >>= 24;
419         s->rotl[2] |= t & 0x0f;         
420         s->roth[0] |= t & (1<<4);
421         t = S_5X(0x1) ^ S_6X(0x0) ^ S_7X(0xE) ^ S_8X(0xF) ^ S_6X(0xD);
422         t >>= 24;
423         s->rotl[2] |= (t<<4) & 0xf0;            
424         s->roth[0] |= (t<<1) & (1<<5);
425         t = S_5X(0x7) ^ S_6X(0x6) ^ S_7X(0x8) ^ S_8X(0x9) ^ S_7X(0x3);
426         t >>= 24;
427         s->rotl[3] |= t & 0x0f;         
428         s->roth[0] |= (t<<2) & (1<<6);
429         t = S_5X(0x5) ^ S_6X(0x4) ^ S_7X(0xA) ^ S_8X(0xB) ^ S_8X(0x7);
430         t >>= 24;
431         s->rotl[3] |= (t<<4) & 0xf0;            
432         s->roth[0] |= (t<<3) & (1<<7);
433         /***** A *****/
434         z[0] = x[0] ^ S_5X(0xD) ^ S_6X(0xF) ^ S_7X(0xC) ^ S_8X(0xE) ^ S_7X(0x8);
435         z[1] = x[2] ^ S_5Z(0x0) ^ S_6Z(0x2) ^ S_7Z(0x1) ^ S_8Z(0x3) ^ S_8X(0xA);
436         z[2] = x[3] ^ S_5Z(0x7) ^ S_6Z(0x6) ^ S_7Z(0x5) ^ S_8Z(0x4) ^ S_5X(0x9);
437         z[3] = x[1] ^ S_5Z(0xA) ^ S_6Z(0x9) ^ S_7Z(0xB) ^ S_8Z(0x8) ^ S_6X(0xB);
438         /***** N' *****/
439         t = S_5Z(0x3) ^ S_6Z(0x2) ^ S_7Z(0xC) ^ S_8Z(0xD) ^ S_5Z(0x9);
440         t >>= 24;
441         s->rotl[4] |= t & 0x0f;         
442         s->roth[1] |= (t>>4) & (1<<0);
443         t = S_5Z(0x1) ^ S_6Z(0x0) ^ S_7Z(0xE) ^ S_8Z(0xF) ^ S_6Z(0xC);
444         t >>= 24;
445         s->rotl[4] |= (t<<4) & 0xf0;            
446         s->roth[1] |= (t>>3) & (1<<1);
447         t = S_5Z(0x7) ^ S_6Z(0x6) ^ S_7Z(0x8) ^ S_8Z(0x9) ^ S_7Z(0x2);
448         t >>= 24;
449         s->rotl[5] |= t & 0x0f;         
450         s->roth[1] |= (t>>2) & (1<<2);
451         t = S_5Z(0x5) ^ S_6Z(0x4) ^ S_7Z(0xA) ^ S_8Z(0xB) ^ S_8Z(0x6);
452         t >>= 24;
453         s->rotl[5] |= (t<<4) & 0xf0;            
454         s->roth[1] |= (t>>1) & (1<<3);
455         /***** B *****/
456         x[0] = z[2] ^ S_5Z(0x5) ^ S_6Z(0x7) ^ S_7Z(0x4) ^ S_8Z(0x6) ^ S_7Z(0x0);
457         x[1] = z[0] ^ S_5X(0x0) ^ S_6X(0x2) ^ S_7X(0x1) ^ S_8X(0x3) ^ S_8Z(0x2);
458         x[2] = z[1] ^ S_5X(0x7) ^ S_6X(0x6) ^ S_7X(0x5) ^ S_8X(0x4) ^ S_5Z(0x1);
459         x[3] = z[3] ^ S_5X(0xA) ^ S_6X(0x9) ^ S_7X(0xB) ^ S_8X(0x8) ^ S_6Z(0x3);
460         /***** M' *****/
461         t = S_5X(0x8) ^ S_6X(0x9) ^ S_7X(0x7) ^ S_8X(0x6) ^ S_5X(0x3);
462         t >>= 24;
463         s->rotl[6] |= t & 0x0f;         
464         s->roth[1] |= t & (1<<4);
465         t = S_5X(0xA) ^ S_6X(0xB) ^ S_7X(0x5) ^ S_8X(0x4) ^ S_6X(0x7);
466         t >>= 24;
467         s->rotl[6] |= (t<<4) & 0xf0;            
468         s->roth[1] |= (t<<1) & (1<<5);
469         t = S_5X(0xC) ^ S_6X(0xD) ^ S_7X(0x3) ^ S_8X(0x2) ^ S_7X(0x8);
470         t >>= 24;
471         s->rotl[7] |= t & 0x0f;         
472         s->roth[1] |= (t<<2) & (1<<6);
473         t = S_5X(0xE) ^ S_6X(0xF) ^ S_7X(0x1) ^ S_8X(0x0) ^ S_8X(0xD);
474         t >>= 24;
475         s->rotl[7] |= (t<<4) & 0xf0;            
476         s->roth[1] |= (t<<3) & (1<<7);
477         
478         /* done ;-) */
479 }
480
481 #endif
482
483
484
485