Initial revision
[silc.git] / lib / silccrypt / safer.c
1 \r
2 /* This is an independent implementation of the encryption algorithm:   */\r
3 /*                                                                      */\r
4 /*         SAFER+ by Cylink                                             */\r
5 /*                                                                      */\r
6 /* which is a candidate algorithm in the Advanced Encryption Standard   */\r
7 /* programme of the US National Institute of Standards and Technology.  */\r
8 /*                                                                      */\r
9 /* Copyright in this implementation is held by Dr B R Gladman but I     */\r
10 /* hereby give permission for its free direct or derivative use subject */\r
11 /* to acknowledgment of its origin and compliance with any conditions   */\r
12 /* that the originators of the algorithm place on its exploitation.     */\r
13 /*                                                                      */\r
14 /* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999     */\r
15 \r
16 /* Timing data for SAFER+ (safer.c)\r
17 \r
18 Core timing without I/O endian conversion:\r
19 \r
20 128 bit key:\r
21 Key Setup:    4278 cycles\r
22 Encrypt:      1722 cycles =    14.9 mbits/sec\r
23 Decrypt:      1709 cycles =    15.0 mbits/sec\r
24 Mean:         1716 cycles =    14.9 mbits/sec\r
25 \r
26 192 bit key:\r
27 Key Setup:    7426 cycles\r
28 Encrypt:      2555 cycles =    10.0 mbits/sec\r
29 Decrypt:      2530 cycles =    10.1 mbits/sec\r
30 Mean:         2543 cycles =    10.1 mbits/sec\r
31 \r
32 256 bit key:\r
33 Key Setup:   11313 cycles\r
34 Encrypt:      3391 cycles =     7.5 mbits/sec\r
35 Decrypt:      3338 cycles =     7.7 mbits/sec\r
36 Mean:         3365 cycles =     7.6 mbits/sec\r
37 \r
38 Full timing with I/O endian conversion:\r
39 \r
40 128 bit key:\r
41 Key Setup:    3977 cycles\r
42 Encrypt:      1751 cycles =    14.6 mbits/sec\r
43 Decrypt:      1734 cycles =    14.8 mbits/sec\r
44 Mean:         1743 cycles =    14.7 mbits/sec\r
45 \r
46 192 bit key:\r
47 Key Setup:    6490 cycles\r
48 Encrypt:      2574 cycles =     9.9 mbits/sec\r
49 Decrypt:      2549 cycles =    10.0 mbits/sec\r
50 Mean:         2562 cycles =    10.0 mbits/sec\r
51 \r
52 256 bit key:\r
53 Key Setup:    9487 cycles\r
54 Encrypt:      3412 cycles =     7.5 mbits/sec\r
55 Decrypt:      3372 cycles =     7.6 mbits/sec\r
56 Mean:         3392 cycles =     7.5 mbits/sec\r
57 \r
58 */\r
59 \r
60 #include <stdio.h>\r
61 #include <sys/types.h>\r
62 #include "safer_internal.h"\r
63 \r
64 u1byte  expf[256] =\r
65 {     1,  45, 226, 147, 190,  69,  21, 174, 120,   3, 135, 164, 184,  56, 207,  63, \r
66       8, 103,   9, 148, 235,  38, 168, 107, 189,  24,  52,  27, 187, 191, 114, 247, \r
67      64,  53,  72, 156,  81,  47,  59,  85, 227, 192, 159, 216, 211, 243, 141, 177, \r
68     255, 167,  62, 220, 134, 119, 215, 166,  17, 251, 244, 186, 146, 145, 100, 131, \r
69     241,  51, 239, 218,  44, 181, 178,  43, 136, 209, 153, 203, 140, 132,  29,  20, \r
70     129, 151, 113, 202,  95, 163, 139,  87,  60, 130, 196,  82,  92,  28, 232, 160, \r
71       4, 180, 133,  74, 246,  19,  84, 182, 223,  12,  26, 142, 222, 224,  57, 252, \r
72      32, 155,  36,  78, 169, 152, 158, 171, 242,  96, 208, 108, 234, 250, 199, 217, \r
73       0, 212,  31, 110,  67, 188, 236,  83, 137, 254, 122,  93,  73, 201,  50, 194, \r
74     249, 154, 248, 109,  22, 219,  89, 150,  68, 233, 205, 230,  70,  66, 143,  10, \r
75     193, 204, 185, 101, 176, 210, 198, 172,  30,  65,  98,  41,  46,  14, 116,  80, \r
76       2,  90, 195,  37, 123, 138,  42,  91, 240,   6,  13,  71, 111, 112, 157, 126, \r
77      16, 206,  18,  39, 213,  76,  79, 214, 121,  48, 104,  54, 117, 125, 228, 237, \r
78     128, 106, 144,  55, 162,  94, 118, 170, 197, 127,  61, 175, 165, 229,  25,  97, \r
79     253,  77, 124, 183,  11, 238, 173,  75,  34, 245, 231, 115,  35,  33, 200,   5, \r
80     225, 102, 221, 179,  88, 105,  99,  86,  15, 161,  49, 149,  23,   7,  58,  40 \r
81 };\r
82 \r
83 u1byte logf[512] = \r
84 {\r
85     128,   0, 176,   9,  96, 239, 185, 253,  16,  18, 159, 228, 105, 186, 173, 248, \r
86     192,  56, 194, 101,  79,   6, 148, 252,  25, 222, 106,  27,  93,  78, 168, 130, \r
87     112, 237, 232, 236, 114, 179,  21, 195, 255, 171, 182,  71,  68,   1, 172,  37, \r
88     201, 250, 142,  65,  26,  33, 203, 211,  13, 110, 254,  38,  88, 218,  50,  15, \r
89      32, 169, 157, 132, 152,   5, 156, 187,  34, 140,  99, 231, 197, 225, 115, 198, \r
90     175,  36,  91, 135, 102,  39, 247,  87, 244, 150, 177, 183,  92, 139, 213,  84, \r
91     121, 223, 170, 246,  62, 163, 241,  17, 202, 245, 209,  23, 123, 147, 131, 188, \r
92     189,  82,  30, 235, 174, 204, 214,  53,   8, 200, 138, 180, 226, 205, 191, 217, \r
93     208,  80,  89,  63,  77,  98,  52,  10,  72, 136, 181,  86,  76,  46, 107, 158, \r
94     210,  61,  60,   3,  19, 251, 151,  81, 117,  74, 145, 113,  35, 190, 118,  42, \r
95      95, 249, 212,  85,  11, 220,  55,  49,  22, 116, 215, 119, 167, 230,   7, 219, \r
96     164,  47,  70, 243,  97,  69, 103, 227,  12, 162,  59,  28, 133,  24,   4,  29, \r
97      41, 160, 143, 178,  90, 216, 166, 126, 238, 141,  83,  75, 161, 154, 193,  14, \r
98     122,  73, 165,  44, 129, 196, 199,  54,  43, 127,  67, 149,  51, 242, 108, 104, \r
99     109, 240,   2,  40, 206, 221, 155, 234,  94, 153, 124,  20, 134, 207, 229,  66, \r
100     184,  64, 120,  45,  58, 233, 100,  31, 146, 144, 125,  57, 111, 224, 137,  48,\r
101 \r
102     128,   0, 176,   9,  96, 239, 185, 253,  16,  18, 159, 228, 105, 186, 173, 248, \r
103     192,  56, 194, 101,  79,   6, 148, 252,  25, 222, 106,  27,  93,  78, 168, 130, \r
104     112, 237, 232, 236, 114, 179,  21, 195, 255, 171, 182,  71,  68,   1, 172,  37, \r
105     201, 250, 142,  65,  26,  33, 203, 211,  13, 110, 254,  38,  88, 218,  50,  15, \r
106      32, 169, 157, 132, 152,   5, 156, 187,  34, 140,  99, 231, 197, 225, 115, 198, \r
107     175,  36,  91, 135, 102,  39, 247,  87, 244, 150, 177, 183,  92, 139, 213,  84, \r
108     121, 223, 170, 246,  62, 163, 241,  17, 202, 245, 209,  23, 123, 147, 131, 188, \r
109     189,  82,  30, 235, 174, 204, 214,  53,   8, 200, 138, 180, 226, 205, 191, 217, \r
110     208,  80,  89,  63,  77,  98,  52,  10,  72, 136, 181,  86,  76,  46, 107, 158, \r
111     210,  61,  60,   3,  19, 251, 151,  81, 117,  74, 145, 113,  35, 190, 118,  42, \r
112      95, 249, 212,  85,  11, 220,  55,  49,  22, 116, 215, 119, 167, 230,   7, 219, \r
113     164,  47,  70, 243,  97,  69, 103, 227,  12, 162,  59,  28, 133,  24,   4,  29, \r
114      41, 160, 143, 178,  90, 216, 166, 126, 238, 141,  83,  75, 161, 154, 193,  14, \r
115     122,  73, 165,  44, 129, 196, 199,  54,  43, 127,  67, 149,  51, 242, 108, 104, \r
116     109, 240,   2,  40, 206, 221, 155, 234,  94, 153, 124,  20, 134, 207, 229,  66, \r
117     184,  64, 120,  45,  58, 233, 100,  31, 146, 144, 125,  57, 111, 224, 137,  48\r
118 };\r
119 \r
120 u4byte *safer_set_key(SaferContext *ctx,\r
121                       const u4byte in_key[], const u4byte key_len)\r
122 {   \r
123     u1byte  by, lk[33];\r
124     u4byte  i, j, k, l, m;\r
125     u1byte *l_key = ctx->l_key;\r
126 \r
127     get_key(lk, key_len);\r
128 \r
129     ctx->k_bytes = k_bytes = key_len / 8; lk[k_bytes] = 0;\r
130 \r
131     for(i = 0; i < k_bytes; ++i)\r
132     {\r
133         lk[k_bytes] ^= lk[i]; l_key[i] = lk[i];\r
134     }\r
135 \r
136     for(i = 0; i < k_bytes; ++i)\r
137     {\r
138         for(j = 0; j <= k_bytes; ++j)\r
139         {\r
140             by = lk[j]; lk[j] = by << 3 | by >> 5;\r
141         }\r
142 \r
143         k = 17 * i + 35; l = 16 * i + 16; m = i + 1;\r
144 \r
145         if(i < 16)\r
146         {\r
147             for(j = 0; j < 16; ++j)\r
148             {\r
149                 l_key[l + j] = lk[m] + expf[expf[(k + j) & 255]];\r
150 \r
151                 m = (m == k_bytes ? 0 : m + 1);\r
152             }\r
153         }\r
154         else\r
155         {\r
156             for(j = 0; j < 16; ++j)\r
157             {\r
158                 l_key[l + j] = lk[m] + expf[(k + j) & 255];\r
159 \r
160                 m = (m == k_bytes ? 0 : m + 1);\r
161             }\r
162         }\r
163     }\r
164     return (u4byte*)l_key;\r
165 };\r
166 \r
167 void do_fr(u1byte x[16], u1byte *kp)\r
168 {   u1byte  t;\r
169 \r
170     x[ 0] = expf[x[ 0] ^ kp[ 0]] + kp[16];\r
171     x[ 1] = logf[x[ 1] + kp[ 1]] ^ kp[17]; \r
172     x[ 2] = logf[x[ 2] + kp[ 2]] ^ kp[18]; \r
173     x[ 3] = expf[x[ 3] ^ kp[ 3]] + kp[19];\r
174 \r
175     x[ 4] = expf[x[ 4] ^ kp[ 4]] + kp[20];\r
176     x[ 5] = logf[x[ 5] + kp[ 5]] ^ kp[21]; \r
177     x[ 6] = logf[x[ 6] + kp[ 6]] ^ kp[22]; \r
178     x[ 7] = expf[x[ 7] ^ kp[ 7]] + kp[23];\r
179  \r
180     x[ 8] = expf[x[ 8] ^ kp[ 8]] + kp[24];\r
181     x[ 9] = logf[x[ 9] + kp[ 9]] ^ kp[25]; \r
182     x[10] = logf[x[10] + kp[10]] ^ kp[26]; \r
183     x[11] = expf[x[11] ^ kp[11]] + kp[27];\r
184 \r
185     x[12] = expf[x[12] ^ kp[12]] + kp[28];\r
186     x[13] = logf[x[13] + kp[13]] ^ kp[29]; \r
187     x[14] = logf[x[14] + kp[14]] ^ kp[30]; \r
188     x[15] = expf[x[15] ^ kp[15]] + kp[31];\r
189 \r
190     x[ 1] += x[ 0]; x[ 0] += x[ 1];\r
191     x[ 3] += x[ 2]; x[ 2] += x[ 3];\r
192     x[ 5] += x[ 4]; x[ 4] += x[ 5];\r
193     x[ 7] += x[ 6]; x[ 6] += x[ 7];\r
194     x[ 9] += x[ 8]; x[ 8] += x[ 9];\r
195     x[11] += x[10]; x[10] += x[11];\r
196     x[13] += x[12]; x[12] += x[13];\r
197     x[15] += x[14]; x[14] += x[15];\r
198 \r
199     x[ 7] += x[ 0]; x[ 0] += x[ 7];\r
200     x[ 1] += x[ 2]; x[ 2] += x[ 1];\r
201     x[ 3] += x[ 4]; x[ 4] += x[ 3];\r
202     x[ 5] += x[ 6]; x[ 6] += x[ 5];\r
203     x[11] += x[ 8]; x[ 8] += x[11];\r
204     x[ 9] += x[10]; x[10] += x[ 9];\r
205     x[15] += x[12]; x[12] += x[15];\r
206     x[13] += x[14]; x[14] += x[13];\r
207 \r
208     x[ 3] += x[ 0]; x[ 0] += x[ 3];\r
209     x[15] += x[ 2]; x[ 2] += x[15];\r
210     x[ 7] += x[ 4]; x[ 4] += x[ 7];\r
211     x[ 1] += x[ 6]; x[ 6] += x[ 1];\r
212     x[ 5] += x[ 8]; x[ 8] += x[ 5];\r
213     x[13] += x[10]; x[10] += x[13];\r
214     x[11] += x[12]; x[12] += x[11];\r
215     x[ 9] += x[14]; x[14] += x[ 9];\r
216 \r
217     x[13] += x[ 0]; x[ 0] += x[13];\r
218     x[ 5] += x[ 2]; x[ 2] += x[ 5];\r
219     x[ 9] += x[ 4]; x[ 4] += x[ 9];\r
220     x[11] += x[ 6]; x[ 6] += x[11];\r
221     x[15] += x[ 8]; x[ 8] += x[15];\r
222     x[ 1] += x[10]; x[10] += x[ 1];\r
223     x[ 3] += x[12]; x[12] += x[ 3];\r
224     x[ 7] += x[14]; x[14] += x[ 7];\r
225 \r
226     t = x[0]; x[0] = x[14]; x[14] = x[12]; x[12] = x[10]; x[10] = x[2]; \r
227     x[2] = x[8]; x[8] = x[4]; x[4] = t;\r
228 \r
229     t = x[1]; x[1] = x[7]; x[7] = x[11]; x[11] = x[5]; x[5] = x[13]; x[13] = t; \r
230     \r
231     t = x[15]; x[15] = x[3]; x[3] = t;\r
232 };\r
233 \r
234 void do_ir(u1byte x[16], u1byte *kp)\r
235 {   u1byte  t;\r
236 \r
237     t = x[3]; x[3] = x[15]; x[15] = t; \r
238 \r
239     t = x[13]; x[13] = x[5]; x[5] = x[11]; x[11] = x[7]; x[7] = x[1]; x[1] = t; \r
240 \r
241     t = x[4]; x[4] = x[8]; x[8] = x[2]; x[2] = x[10]; \r
242     x[10] = x[12]; x[12] = x[14]; x[14] = x[0]; x[0] = t; \r
243 \r
244     x[14] -= x[ 7]; x[ 7] -= x[14]; \r
245     x[12] -= x[ 3]; x[ 3] -= x[12];\r
246     x[10] -= x[ 1]; x[ 1] -= x[10];\r
247     x[ 8] -= x[15]; x[15] -= x[ 8];\r
248     x[ 6] -= x[11]; x[11] -= x[ 6]; \r
249     x[ 4] -= x[ 9]; x[ 9] -= x[ 4];\r
250     x[ 2] -= x[ 5]; x[ 5] -= x[ 2]; \r
251     x[ 0] -= x[13]; x[13] -= x[ 0]; \r
252 \r
253     x[14] -= x[ 9]; x[ 9] -= x[14]; \r
254     x[12] -= x[11]; x[11] -= x[12]; \r
255     x[10] -= x[13]; x[13] -= x[10]; \r
256     x[ 8] -= x[ 5]; x[ 5] -= x[ 8]; \r
257     x[ 6] -= x[ 1]; x[ 1] -= x[ 6]; \r
258     x[ 4] -= x[ 7]; x[ 7] -= x[ 4]; \r
259     x[ 2] -= x[15]; x[15] -= x[ 2]; \r
260     x[ 0] -= x[ 3]; x[ 3] -= x[ 0]; \r
261 \r
262     x[14] -= x[13]; x[13] -= x[14]; \r
263     x[12] -= x[15]; x[15] -= x[12]; \r
264     x[10] -= x[ 9]; x[ 9] -= x[10]; \r
265     x[ 8] -= x[11]; x[11] -= x[ 8];     \r
266     x[ 6] -= x[ 5]; x[ 5] -= x[ 6]; \r
267     x[ 4] -= x[ 3]; x[ 3] -= x[ 4]; \r
268     x[ 2] -= x[ 1]; x[ 1] -= x[ 2]; \r
269     x[ 0] -= x[ 7]; x[ 7] -= x[ 0]; \r
270 \r
271     x[14] -= x[15]; x[15] -= x[14]; \r
272     x[12] -= x[13]; x[13] -= x[12];\r
273     x[10] -= x[11]; x[11] -= x[10]; \r
274     x[ 8] -= x[ 9]; x[ 9] -= x[ 8]; \r
275     x[ 6] -= x[ 7]; x[ 7] -= x[ 6];\r
276     x[ 4] -= x[ 5]; x[ 5] -= x[ 4]; \r
277     x[ 2] -= x[ 3]; x[ 3] -= x[ 2]; \r
278     x[ 0] -= x[ 1]; x[ 1] -= x[ 0]; \r
279     \r
280     x[ 0] = logf[x[ 0] - kp[16] + 256] ^ kp[ 0];\r
281     x[ 1] = expf[x[ 1] ^ kp[17]] - kp[ 1];\r
282     x[ 2] = expf[x[ 2] ^ kp[18]] - kp[ 2];\r
283     x[ 3] = logf[x[ 3] - kp[19] + 256] ^ kp[ 3];\r
284 \r
285     x[ 4] = logf[x[ 4] - kp[20] + 256] ^ kp[ 4];\r
286     x[ 5] = expf[x[ 5] ^ kp[21]] - kp[ 5];\r
287     x[ 6] = expf[x[ 6] ^ kp[22]] - kp[ 6];\r
288     x[ 7] = logf[x[ 7] - kp[23] + 256] ^ kp[ 7];\r
289 \r
290     x[ 8] = logf[x[ 8] - kp[24] + 256] ^ kp[ 8];\r
291     x[ 9] = expf[x[ 9] ^ kp[25]] - kp[ 9];\r
292     x[10] = expf[x[10] ^ kp[26]] - kp[10];\r
293     x[11] = logf[x[11] - kp[27] + 256] ^ kp[11];\r
294 \r
295     x[12] = logf[x[12] - kp[28] + 256] ^ kp[12];\r
296     x[13] = expf[x[13] ^ kp[29]] - kp[13];\r
297     x[14] = expf[x[14] ^ kp[30]] - kp[14];\r
298     x[15] = logf[x[15] - kp[31] + 256] ^ kp[15];\r
299 };\r
300 \r
301 void safer_encrypt(SaferContext *ctx,\r
302                    const u4byte in_blk[4], u4byte out_blk[4])\r
303 {   \r
304     u1byte  blk[16], *kp;\r
305     u1byte *l_key = ctx->l_key;\r
306     u4byte k_bytes = ctx->k_bytes;\r
307 \r
308     get_block(blk);\r
309 \r
310     do_fr(blk, l_key);       do_fr(blk, l_key +  32); \r
311     do_fr(blk, l_key +  64); do_fr(blk, l_key +  96);\r
312     do_fr(blk, l_key + 128); do_fr(blk, l_key + 160);\r
313     do_fr(blk, l_key + 192); do_fr(blk, l_key + 224);\r
314     \r
315     if(k_bytes > 16)\r
316     {\r
317         do_fr(blk, l_key + 256); do_fr(blk, l_key + 288); \r
318         do_fr(blk, l_key + 320); do_fr(blk, l_key + 352);\r
319     }\r
320 \r
321     if(k_bytes > 24)\r
322     {\r
323         do_fr(blk, l_key + 384); do_fr(blk, l_key + 416); \r
324         do_fr(blk, l_key + 448); do_fr(blk, l_key + 480);\r
325     }\r
326 \r
327     kp = l_key + 16 * k_bytes;\r
328 \r
329     blk[ 0] ^= kp[ 0]; blk[ 1] += kp[ 1];\r
330     blk[ 2] += kp[ 2]; blk[ 3] ^= kp[ 3]; \r
331     blk[ 4] ^= kp[ 4]; blk[ 5] += kp[ 5];\r
332     blk[ 6] += kp[ 6]; blk[ 7] ^= kp[ 7]; \r
333     blk[ 8] ^= kp[ 8]; blk[ 9] += kp[ 9];\r
334     blk[10] += kp[10]; blk[11] ^= kp[11]; \r
335     blk[12] ^= kp[12]; blk[13] += kp[13];\r
336     blk[14] += kp[14]; blk[15] ^= kp[15]; \r
337 \r
338     put_block(blk);\r
339 };\r
340 \r
341 void safer_decrypt(SaferContext *ctx,\r
342                    const u4byte in_blk[4], u4byte out_blk[4])\r
343 {   \r
344     u1byte  blk[16], *kp;\r
345     u1byte *l_key = ctx->l_key;\r
346     u4byte k_bytes = ctx->k_bytes;\r
347 \r
348     get_block(blk);\r
349 \r
350     kp = l_key + 16 * k_bytes;\r
351 \r
352     blk[ 0] ^= kp[ 0]; blk[ 1] -= kp[ 1];\r
353     blk[ 2] -= kp[ 2]; blk[ 3] ^= kp[ 3];\r
354     blk[ 4] ^= kp[ 4]; blk[ 5] -= kp[ 5];\r
355     blk[ 6] -= kp[ 6]; blk[ 7] ^= kp[ 7];\r
356     blk[ 8] ^= kp[ 8]; blk[ 9] -= kp[ 9];\r
357     blk[10] -= kp[10]; blk[11] ^= kp[11];\r
358     blk[12] ^= kp[12]; blk[13] -= kp[13];\r
359     blk[14] -= kp[14]; blk[15] ^= kp[15];\r
360 \r
361     if(k_bytes > 24)\r
362     {\r
363         do_ir(blk, l_key + 480); do_ir(blk, l_key + 448); \r
364         do_ir(blk, l_key + 416); do_ir(blk, l_key + 384);\r
365     }\r
366 \r
367     if(k_bytes > 16)\r
368     {\r
369         do_ir(blk, l_key + 352); do_ir(blk, l_key + 320); \r
370         do_ir(blk, l_key + 288); do_ir(blk, l_key + 256);\r
371     }\r
372 \r
373     do_ir(blk, l_key + 224); do_ir(blk, l_key + 192); \r
374     do_ir(blk, l_key + 160); do_ir(blk, l_key + 128);\r
375     do_ir(blk, l_key +  96); do_ir(blk, l_key +  64); \r
376     do_ir(blk, l_key +  32); do_ir(blk, l_key);\r
377 \r
378     put_block(blk);\r
379 };\r