1 /* Modified for SILC. -Pekka */
\r
3 /* This is an independent implementation of the encryption algorithm: */
\r
5 /* CRYPTON by Chae Hoon Lim of Future Systms Inc */
\r
7 /* which is a candidate algorithm in the Advanced Encryption Standard */
\r
8 /* programme of the US National Institute of Standards and Technology. */
\r
10 /* Copyright in this implementation is held by Dr B R Gladman but I */
\r
11 /* hereby give permission for its free direct or derivative use subject */
\r
12 /* to acknowledgment of its origin and compliance with any conditions */
\r
13 /* that the originators of the algorithm place on its exploitation. */
\r
15 /* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999 */
\r
17 /* Timing data for CRYPTON (crypton.c)
\r
20 Key Setup: 531/1369 cycles (encrypt/decrypt)
\r
21 Encrypt: 474 cycles = 54.0 mbits/sec
\r
22 Decrypt: 474 cycles = 54.0 mbits/sec
\r
23 Mean: 474 cycles = 54.0 mbits/sec
\r
26 Key Setup: 539/1381 cycles (encrypt/decrypt)
\r
27 Encrypt: 473 cycles = 54.1 mbits/sec
\r
28 Decrypt: 470 cycles = 54.5 mbits/sec
\r
29 Mean: 472 cycles = 54.3 mbits/sec
\r
32 Key Setup: 552/1392 cycles (encrypt/decrypt)
\r
33 Encrypt: 469 cycles = 54.6 mbits/sec
\r
34 Decrypt: 483 cycles = 53.0 mbits/sec
\r
35 Mean: 476 cycles = 53.8 mbits/sec
\r
39 #include "silcincludes.h"
\r
40 #include "crypton.h"
\r
42 #define gamma_tau(x,b,m,p,q) \
\r
43 (x) = (((u4byte)s_box[p][byte(b[0],m)] ) | \
\r
44 ((u4byte)s_box[q][byte(b[1],m)] << 8) | \
\r
45 ((u4byte)s_box[p][byte(b[2],m)] << 16) | \
\r
46 ((u4byte)s_box[q][byte(b[3],m)] << 24))
\r
48 #define ma_0 0x3fcff3fc
\r
49 #define ma_1 0xfc3fcff3
\r
50 #define ma_2 0xf3fc3fcf
\r
51 #define ma_3 0xcff3fc3f
\r
53 #define mb_0 0xcffccffc
\r
54 #define mb_1 0xf33ff33f
\r
55 #define mb_2 0xfccffccf
\r
56 #define mb_3 0x3ff33ff3
\r
58 #define pi(b,n0,n1,n2,n3) \
\r
59 (((b)[0] & ma_##n0) ^ \
\r
60 ((b)[1] & ma_##n1) ^ \
\r
61 ((b)[2] & ma_##n2) ^ \
\r
64 #define phi_n(x,n0,n1,n2,n3) \
\r
65 ( (x) & mb_##n0) ^ \
\r
66 (rotl((x), 8) & mb_##n1) ^ \
\r
67 (rotl((x), 16) & mb_##n2) ^ \
\r
68 (rotl((x), 24) & mb_##n3)
\r
70 #define phi_00(x) phi_n(x,0,1,2,3)
\r
71 #define phi_01(x) phi_n(x,3,0,1,2)
\r
72 #define phi_02(x) phi_n(x,2,3,0,1)
\r
73 #define phi_03(x) phi_n(x,1,2,3,0)
\r
75 #define phi_10(x) phi_n(x,3,0,1,2)
\r
76 #define phi_11(x) phi_n(x,2,3,0,1)
\r
77 #define phi_12(x) phi_n(x,1,2,3,0)
\r
78 #define phi_13(x) phi_n(x,0,1,2,3)
\r
81 (y)[0] = phi_00((x)[0]); \
\r
82 (y)[1] = phi_01((x)[1]); \
\r
83 (y)[2] = phi_02((x)[2]); \
\r
84 (y)[3] = phi_03((x)[3])
\r
87 (y)[0] = phi_10((x)[0]); \
\r
88 (y)[1] = phi_11((x)[1]); \
\r
89 (y)[2] = phi_12((x)[2]); \
\r
90 (y)[3] = phi_13((x)[3])
\r
92 u1byte p_box[3][16] =
\r
93 { { 15, 9, 6, 8, 9, 9, 4, 12, 6, 2, 6, 10, 1, 3, 5, 15 },
\r
94 { 10, 15, 4, 7, 5, 2, 14, 6, 9, 3, 12, 8, 13, 1, 11, 0 },
\r
95 { 0, 4, 8, 4, 2, 15, 8, 13, 1, 1, 15, 7, 2, 11, 14, 15 }
\r
99 u1byte s_box[2][256];
\r
100 u4byte s_tab[4][256];
\r
103 { u4byte i, xl, xr, yl, yr;
\r
105 for(i = 0; i < 256; ++i)
\r
107 xl = (i & 0xf0) >> 4; xr = i & 15;
\r
109 yr = xr ^ p_box[1][xl ^ p_box[0][xr]];
\r
110 yl = xl ^ p_box[0][xr] ^ p_box[2][yr];
\r
112 yr |= (yl << 4); s_box[0][i] = (u1byte)yr; s_box[1][yr] = (u1byte)i;
\r
114 xr = yr * 0x01010101; xl = i * 0x01010101;
\r
116 s_tab[0][ i] = xr & 0x3fcff3fc;
\r
117 s_tab[1][yr] = xl & 0xfc3fcff3;
\r
118 s_tab[2][ i] = xr & 0xf3fc3fcf;
\r
119 s_tab[3][yr] = xl & 0xcff3fc3f;
\r
123 /* initialise the key schedule from the user supplied key */
\r
125 u4byte kp[4] = { 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f };
\r
126 u4byte kq[4] = { 0x9b05688c, 0x1f83d9ab, 0x5be0cd19, 0xcbbb9d5d };
\r
128 #define h0_block(n,r0,r1) \
\r
129 e_key[4 * n + 8] = rotl(e_key[4 * n + 0], r0); \
\r
130 e_key[4 * n + 9] = rc ^ e_key[4 * n + 1]; \
\r
131 e_key[4 * n + 10] = rotl(e_key[4 * n + 2], r1); \
\r
132 e_key[4 * n + 11] = rc ^ e_key[4 * n + 3]
\r
134 #define h1_block(n,r0,r1) \
\r
135 e_key[4 * n + 8] = rc ^ e_key[4 * n + 0]; \
\r
136 e_key[4 * n + 9] = rotl(e_key[4 * n + 1], r0); \
\r
137 e_key[4 * n + 10] = rc ^ e_key[4 * n + 2]; \
\r
138 e_key[4 * n + 11] = rotl(e_key[4 * n + 3], r1)
\r
140 u4byte *crypton_set_key(CryptonContext *ctx,
\r
141 const u4byte in_key[], const u4byte key_len)
\r
143 u4byte i, rc, t0, t1, tmp[4];
\r
144 u4byte *e_key = ctx->l_key + 52;
\r
145 u4byte *d_key = ctx->l_key;
\r
149 gen_tab(); tab_gen = 1;
\r
152 e_key[2] = e_key[3] = e_key[6] = e_key[7] = 0;
\r
154 switch((key_len + 63) / 64)
\r
156 case 4: e_key[3] = in_key[6]; e_key[7] = in_key[7];
\r
157 case 3: e_key[2] = in_key[4]; e_key[6] = in_key[5];
\r
158 case 2: e_key[0] = in_key[0]; e_key[4] = in_key[1];
\r
159 e_key[1] = in_key[2]; e_key[5] = in_key[3];
\r
162 tmp[0] = pi(e_key, 0, 1, 2, 3) ^ kp[0];
\r
163 tmp[1] = pi(e_key, 1, 2, 3, 0) ^ kp[1];
\r
164 tmp[2] = pi(e_key, 2, 3, 0, 1) ^ kp[2];
\r
165 tmp[3] = pi(e_key, 3, 0, 1, 2) ^ kp[3];
\r
167 gamma_tau(e_key[0], tmp, 0, 0, 1);
\r
168 gamma_tau(e_key[1], tmp, 1, 1, 0);
\r
169 gamma_tau(e_key[2], tmp, 2, 0, 1);
\r
170 gamma_tau(e_key[3], tmp, 3, 1, 0);
\r
172 tmp[0] = pi(e_key + 4, 1, 2, 3, 0) ^ kq[0];
\r
173 tmp[1] = pi(e_key + 4, 2, 3, 0, 1) ^ kq[1];
\r
174 tmp[2] = pi(e_key + 4, 3, 0, 1, 2) ^ kq[2];
\r
175 tmp[3] = pi(e_key + 4, 0, 1, 2, 3) ^ kq[3];
\r
177 gamma_tau(e_key[4], tmp, 0, 1, 0);
\r
178 gamma_tau(e_key[5], tmp, 1, 0, 1);
\r
179 gamma_tau(e_key[6], tmp, 2, 1, 0);
\r
180 gamma_tau(e_key[7], tmp, 3, 0, 1);
\r
182 t0 = e_key[0] ^ e_key[1] ^ e_key[2] ^ e_key[3];
\r
183 t1 = e_key[4] ^ e_key[5] ^ e_key[6] ^ e_key[7];
\r
185 e_key[0] ^= t1; e_key[1] ^= t1;
\r
186 e_key[2] ^= t1; e_key[3] ^= t1;
\r
187 e_key[4] ^= t0; e_key[5] ^= t0;
\r
188 e_key[6] ^= t0; e_key[7] ^= t0;
\r
191 h0_block( 0, 8, 16); h1_block(1, 16, 24); rc <<= 1;
\r
192 h1_block( 2, 24, 8); h0_block(3, 8, 16); rc <<= 1;
\r
193 h0_block( 4, 16, 24); h1_block(5, 24, 8); rc <<= 1;
\r
194 h1_block( 6, 8, 16); h0_block(7, 16, 24); rc <<= 1;
\r
195 h0_block( 8, 24, 8); h1_block(9, 8, 16); rc <<= 1;
\r
196 h1_block(10, 16, 24);
\r
198 for(i = 0; i < 13; ++i)
\r
202 phi0(e_key + 4 * i, d_key + 48 - 4 * i);
\r
206 phi1(e_key + 4 * i, d_key + 48 - 4 * i);
\r
210 phi1(d_key + 48, d_key + 48);
\r
211 phi1(e_key + 48, e_key + 48);
\r
216 /* encrypt a block of text */
\r
219 b1[i] = s_tab[ (i) ][byte(b0[0],i)] ^ \
\r
220 s_tab[((i) + 1) & 3][byte(b0[1],i)] ^ \
\r
221 s_tab[((i) + 2) & 3][byte(b0[2],i)] ^ \
\r
222 s_tab[((i) + 3) & 3][byte(b0[3],i)] ^ (k)
\r
225 b0[i] = s_tab[((i) + 1) & 3][byte(b1[0],i)] ^ \
\r
226 s_tab[((i) + 2) & 3][byte(b1[1],i)] ^ \
\r
227 s_tab[((i) + 3) & 3][byte(b1[2],i)] ^ \
\r
228 s_tab[(i) ][byte(b1[3],i)] ^ (k)
\r
230 #define f0_rnd(kp) \
\r
231 fr0(0,(kp)[0]); fr0(1,(kp)[1]); \
\r
232 fr0(2,(kp)[2]); fr0(3,(kp)[3])
\r
234 #define f1_rnd(kp) \
\r
235 fr1(0,(kp)[0]); fr1(1,(kp)[1]); \
\r
236 fr1(2,(kp)[2]); fr1(3,(kp)[3])
\r
238 void crypton_encrypt(CryptonContext *ctx,
\r
239 const u4byte in_blk[4], u4byte out_blk[4])
\r
241 u4byte b0[4], b1[4];
\r
242 u4byte *e_key = ctx->l_key + 52;
\r
243 u4byte *d_key = ctx->l_key;
\r
245 b0[0] = in_blk[0] ^ e_key[0];
\r
246 b0[1] = in_blk[1] ^ e_key[1];
\r
247 b0[2] = in_blk[2] ^ e_key[2];
\r
248 b0[3] = in_blk[3] ^ e_key[3];
\r
250 f0_rnd(e_key + 4); f1_rnd(e_key + 8);
\r
251 f0_rnd(e_key + 12); f1_rnd(e_key + 16);
\r
252 f0_rnd(e_key + 20); f1_rnd(e_key + 24);
\r
253 f0_rnd(e_key + 28); f1_rnd(e_key + 32);
\r
254 f0_rnd(e_key + 36); f1_rnd(e_key + 40);
\r
255 f0_rnd(e_key + 44);
\r
257 gamma_tau(b0[0], b1, 0, 1, 0);
\r
258 gamma_tau(b0[1], b1, 1, 0, 1);
\r
259 gamma_tau(b0[2], b1, 2, 1, 0);
\r
260 gamma_tau(b0[3], b1, 3, 0, 1);
\r
262 out_blk[0] = b0[0] ^ e_key[48];
\r
263 out_blk[1] = b0[1] ^ e_key[49];
\r
264 out_blk[2] = b0[2] ^ e_key[50];
\r
265 out_blk[3] = b0[3] ^ e_key[51];
\r
268 /* decrypt a block of text */
\r
270 void crypton_decrypt(CryptonContext *ctx,
\r
271 const u4byte in_blk[4], u4byte out_blk[4])
\r
273 u4byte b0[4], b1[4];
\r
274 u4byte *e_key = ctx->l_key + 52;
\r
275 u4byte *d_key = ctx->l_key;
\r
277 b0[0] = in_blk[0] ^ d_key[0];
\r
278 b0[1] = in_blk[1] ^ d_key[1];
\r
279 b0[2] = in_blk[2] ^ d_key[2];
\r
280 b0[3] = in_blk[3] ^ d_key[3];
\r
282 f0_rnd(d_key + 4); f1_rnd(d_key + 8);
\r
283 f0_rnd(d_key + 12); f1_rnd(d_key + 16);
\r
284 f0_rnd(d_key + 20); f1_rnd(d_key + 24);
\r
285 f0_rnd(d_key + 28); f1_rnd(d_key + 32);
\r
286 f0_rnd(d_key + 36); f1_rnd(d_key + 40);
\r
287 f0_rnd(d_key + 44);
\r
289 gamma_tau(b0[0], b1, 0, 1, 0);
\r
290 gamma_tau(b0[1], b1, 1, 0, 1);
\r
291 gamma_tau(b0[2], b1, 2, 1, 0);
\r
292 gamma_tau(b0[3], b1, 3, 0, 1);
\r
294 out_blk[0] = b0[0] ^ d_key[48];
\r
295 out_blk[1] = b0[1] ^ d_key[49];
\r
296 out_blk[2] = b0[2] ^ d_key[50];
\r
297 out_blk[3] = b0[3] ^ d_key[51];
\r