2 /* This is an independent implementation of the encryption algorithm: */
\r
4 /* SAFER+ by Cylink */
\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
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
14 /* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999 */
\r
16 /* Timing data for SAFER+ (safer.c)
\r
18 Core timing without I/O endian conversion:
\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
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
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
38 Full timing with I/O endian conversion:
\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
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
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
61 #include <sys/types.h>
\r
62 #include "safer_internal.h"
\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
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
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
120 u4byte *safer_set_key(SaferContext *ctx,
\r
121 const u4byte in_key[], const u4byte key_len)
\r
124 u4byte i, j, k, l, m;
\r
125 u1byte *l_key = ctx->l_key;
\r
127 get_key(lk, key_len);
\r
129 ctx->k_bytes = k_bytes = key_len / 8; lk[k_bytes] = 0;
\r
131 for(i = 0; i < k_bytes; ++i)
\r
133 lk[k_bytes] ^= lk[i]; l_key[i] = lk[i];
\r
136 for(i = 0; i < k_bytes; ++i)
\r
138 for(j = 0; j <= k_bytes; ++j)
\r
140 by = lk[j]; lk[j] = by << 3 | by >> 5;
\r
143 k = 17 * i + 35; l = 16 * i + 16; m = i + 1;
\r
147 for(j = 0; j < 16; ++j)
\r
149 l_key[l + j] = lk[m] + expf[expf[(k + j) & 255]];
\r
151 m = (m == k_bytes ? 0 : m + 1);
\r
156 for(j = 0; j < 16; ++j)
\r
158 l_key[l + j] = lk[m] + expf[(k + j) & 255];
\r
160 m = (m == k_bytes ? 0 : m + 1);
\r
164 return (u4byte*)l_key;
\r
167 void do_fr(u1byte x[16], u1byte *kp)
\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
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
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
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
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
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
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
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
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
229 t = x[1]; x[1] = x[7]; x[7] = x[11]; x[11] = x[5]; x[5] = x[13]; x[13] = t;
\r
231 t = x[15]; x[15] = x[3]; x[3] = t;
\r
234 void do_ir(u1byte x[16], u1byte *kp)
\r
237 t = x[3]; x[3] = x[15]; x[15] = t;
\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
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
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
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
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
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
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
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
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
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
301 void safer_encrypt(SaferContext *ctx,
\r
302 const u4byte in_blk[4], u4byte out_blk[4])
\r
304 u1byte blk[16], *kp;
\r
305 u1byte *l_key = ctx->l_key;
\r
306 u4byte k_bytes = ctx->k_bytes;
\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
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
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
327 kp = l_key + 16 * k_bytes;
\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
341 void safer_decrypt(SaferContext *ctx,
\r
342 const u4byte in_blk[4], u4byte out_blk[4])
\r
344 u1byte blk[16], *kp;
\r
345 u1byte *l_key = ctx->l_key;
\r
346 u4byte k_bytes = ctx->k_bytes;
\r
350 kp = l_key + 16 * k_bytes;
\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
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
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
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