source: trunk/src/sh_tiger1.c@ 92

Last change on this file since 92 was 18, checked in by rainer, 19 years ago

Optimized version of tiger algorithm, and basic ingredients for unit testing (part 2)

File size: 9.4 KB
Line 
1/* Do not include ANY system headers here. The implementation is */
2/* somehow flawed - maybe something gets overlayed by definitions */
3/* in the system headers. Results will become incorrect. */
4
5#include "config_xor.h"
6
7/* we already inline in the function used for file checksums */
8/* #define UNROLL_COMPRESS */
9#undef UNROLL_COMPRESS
10
11#if !defined(TIGER_64_BIT)
12
13/* Tiger: A Fast New Hash Function
14 *
15 * Ross Anderson and Eli Biham
16 *
17 * From the homepage (http://www.cs.technion.ac.il/~biham/Reports/Tiger/):
18 *
19 * Tiger has no usage restrictions nor patents. It can be used freely,
20 * with the reference implementation, with other implementations or with
21 * a modification to the reference implementation (as long as it still
22 * implements Tiger). We only ask you to let us know about your
23 * implementation and to cite the origin of Tiger and of the reference
24 * implementation.
25 *
26 *
27 * The authors' home pages can be found both in
28 * http://www.cs.technion.ac.il/~biham/ and in
29 * http://www.cl.cam.ac.uk/users/rja14/.
30 * The authors' email addresses are biham@cs.technion.ac.il
31 * and rja14@cl.cam.ac.uk.
32 */
33
34
35#if defined(HAVE_INT_32)
36typedef unsigned int sh_word32;
37#elif defined(HAVE_LONG_32)
38typedef unsigned long sh_word32;
39#elif defined(HAVE_SHORT_32)
40typedef unsigned short sh_word32;
41#else
42#error No 32 bit type found !
43#endif
44
45typedef unsigned char sh_byte;
46
47/* Big endian: */
48#ifdef WORDS_BIGENDIAN
49#define BIG_ENDIAN
50#endif
51
52/* The number of passes of the hash function. */
53/* Three passes are recommended. */
54/* Use four passes when you need extra security. */
55/* Must be at least three. */
56#define PASSES 3
57
58extern sh_word32 tiger_table[4*256][2];
59
60#define t1 (tiger_table)
61#define t2 (tiger_table+256)
62#define t3 (tiger_table+256*2)
63#define t4 (tiger_table+256*3)
64
65#define sub64(s0, s1, p0, p1) \
66 temps0 = (p0); \
67 tcarry = s0 < temps0; \
68 s0 -= temps0; \
69 s1 -= (p1) + tcarry;
70
71#define add64(s0, s1, p0, p1) \
72 temps0 = (p0); \
73 s0 += temps0; \
74 tcarry = s0 < temps0; \
75 s1 += (p1) + tcarry;
76
77#define xor64(s0, s1, p0, p1) \
78 s0 ^= (p0); \
79 s1 ^= (p1);
80
81#define mul5(s0, s1) \
82 tempt0 = s0<<2; \
83 tempt1 = (s1<<2)|(s0>>30); \
84 add64(s0, s1, tempt0, tempt1);
85
86#define mul7(s0, s1) \
87 tempt0 = s0<<3; \
88 tempt1 = (s1<<3)|(s0>>29); \
89 sub64(tempt0, tempt1, s0, s1); \
90 s0 = tempt0; \
91 s1 = tempt1;
92
93#define mul9(s0, s1) \
94 tempt0 = s0<<3; \
95 tempt1 = (s1<<3)|(s0>>29); \
96 add64(s0, s1, tempt0, tempt1);
97
98#define save_abc \
99 aa0 = a0; \
100 aa1 = a1; \
101 bb0 = b0; \
102 bb1 = b1; \
103 cc0 = c0; \
104 cc1 = c1;
105
106#define roundX(a0,a1,b0,b1,c0,c1,x0,x1) \
107 xor64(c0, c1, x0, x1); \
108 temp0 = t1[((c0)>>(0*8))&0xFF][0] ; \
109 temp1 = t1[((c0)>>(0*8))&0xFF][1] ; \
110 temp0 ^= t2[((c0)>>(2*8))&0xFF][0] ; \
111 temp1 ^= t2[((c0)>>(2*8))&0xFF][1] ; \
112 temp0 ^= t3[((c1)>>(0*8))&0xFF][0] ; \
113 temp1 ^= t3[((c1)>>(0*8))&0xFF][1] ; \
114 temp0 ^= t4[((c1)>>(2*8))&0xFF][0] ; \
115 temp1 ^= t4[((c1)>>(2*8))&0xFF][1] ; \
116 sub64(a0, a1, temp0, temp1); \
117 temp0 = t4[((c0)>>(1*8))&0xFF][0] ; \
118 temp1 = t4[((c0)>>(1*8))&0xFF][1] ; \
119 temp0 ^= t3[((c0)>>(3*8))&0xFF][0] ; \
120 temp1 ^= t3[((c0)>>(3*8))&0xFF][1] ; \
121 temp0 ^= t2[((c1)>>(1*8))&0xFF][0] ; \
122 temp1 ^= t2[((c1)>>(1*8))&0xFF][1] ; \
123 temp0 ^= t1[((c1)>>(3*8))&0xFF][0] ; \
124 temp1 ^= t1[((c1)>>(3*8))&0xFF][1] ; \
125 add64(b0, b1, temp0, temp1);
126
127
128#define round5(a0,a1,b0,b1,c0,c1,x0,x1) \
129 roundX(a0,a1,b0,b1,c0,c1,x0,x1); \
130 mul5(b0, b1);
131
132#define round7(a0,a1,b0,b1,c0,c1,x0,x1) \
133 roundX(a0,a1,b0,b1,c0,c1,x0,x1); \
134 mul7(b0, b1);
135
136#define round9(a0,a1,b0,b1,c0,c1,x0,x1) \
137 roundX(a0,a1,b0,b1,c0,c1,x0,x1); \
138 mul9(b0, b1);
139
140
141/* mixed with key_schedule
142 */
143#define pass5(a0,a1,b0,b1,c0,c1) \
144 round5(a0,a1,b0,b1,c0,c1,x00,x01); \
145 sub64(x00, x01, x70^0xA5A5A5A5, x71^0xA5A5A5A5); \
146 round5(b0,b1,c0,c1,a0,a1,x10,x11); \
147 xor64(x10, x11, x00, x01); \
148 round5(c0,c1,a0,a1,b0,b1,x20,x21); \
149 add64(x20, x21, x10, x11); \
150 round5(a0,a1,b0,b1,c0,c1,x30,x31); \
151 sub64(x30, x31, x20^((~x10)<<19), ~x21^(((x11)<<19)|((x10)>>13))); \
152 round5(b0,b1,c0,c1,a0,a1,x40,x41); \
153 xor64(x40, x41, x30, x31); \
154 round5(c0,c1,a0,a1,b0,b1,x50,x51); \
155 add64(x50, x51, x40, x41); \
156 round5(a0,a1,b0,b1,c0,c1,x60,x61); \
157 sub64(x60, x61, ~x50^(((x40)>>23)|((x41)<<9)), x51^((~x41)>>23)); \
158 round5(b0,b1,c0,c1,a0,a1,x70,x71);
159
160/* mixed with key_schedule
161 */
162#define pass7(a0,a1,b0,b1,c0,c1) \
163 round7(a0,a1,b0,b1,c0,c1,x00,x01); \
164 sub64(x00, x01, x70^0xA5A5A5A5, x71^0xA5A5A5A5); \
165 round7(b0,b1,c0,c1,a0,a1,x10,x11); \
166 xor64(x10, x11, x00, x01); \
167 round7(c0,c1,a0,a1,b0,b1,x20,x21); \
168 add64(x20, x21, x10, x11); \
169 round7(a0,a1,b0,b1,c0,c1,x30,x31); \
170 sub64(x30, x31, x20^((~x10)<<19), ~x21^(((x11)<<19)|((x10)>>13))); \
171 round7(b0,b1,c0,c1,a0,a1,x40,x41); \
172 xor64(x40, x41, x30, x31); \
173 round7(c0,c1,a0,a1,b0,b1,x50,x51); \
174 add64(x50, x51, x40, x41); \
175 round7(a0,a1,b0,b1,c0,c1,x60,x61); \
176 sub64(x60, x61, ~x50^(((x40)>>23)|((x41)<<9)), x51^((~x41)>>23)); \
177 round7(b0,b1,c0,c1,a0,a1,x70,x71);
178
179/* mixed with key_schedule
180 */
181#define pass9(a0,a1,b0,b1,c0,c1) \
182 round9(a0,a1,b0,b1,c0,c1,x00,x01); \
183 sub64(x00, x01, x70^0xA5A5A5A5, x71^0xA5A5A5A5); \
184 round9(b0,b1,c0,c1,a0,a1,x10,x11); \
185 xor64(x10, x11, x00, x01); \
186 round9(c0,c1,a0,a1,b0,b1,x20,x21); \
187 add64(x20, x21, x10, x11); \
188 round9(a0,a1,b0,b1,c0,c1,x30,x31); \
189 sub64(x30, x31, x20^((~x10)<<19), ~x21^(((x11)<<19)|((x10)>>13))); \
190 round9(b0,b1,c0,c1,a0,a1,x40,x41); \
191 xor64(x40, x41, x30, x31); \
192 round9(c0,c1,a0,a1,b0,b1,x50,x51); \
193 add64(x50, x51, x40, x41); \
194 round9(a0,a1,b0,b1,c0,c1,x60,x61); \
195 sub64(x60, x61, ~x50^(((x40)>>23)|((x41)<<9)), x51^((~x41)>>23)); \
196 round9(b0,b1,c0,c1,a0,a1,x70,x71);
197
198#define key_schedule \
199 xor64(x70, x71, x60, x61); \
200 add64(x00, x01, x70, x71); \
201 sub64(x10, x11, x00^((~x70)<<19), ~x01^(((x71)<<19)|((x70)>>13))); \
202 xor64(x20, x21, x10, x11); \
203 add64(x30, x31, x20, x21); \
204 sub64(x40, x41, ~x30^(((x20)>>23)|((x21)<<9)), x31^((~x21)>>23)); \
205 xor64(x50, x51, x40, x41); \
206 add64(x60, x61, x50, x51); \
207 sub64(x70, x71, x60^0x89ABCDEF, x61^0x01234567);
208
209#define feedforward \
210 xor64(a0, a1, aa0, aa1); \
211 sub64(b0, b1, bb0, bb1); \
212 add64(c0, c1, cc0, cc1);
213
214#define compress \
215 pass5(a0,a1,b0,b1,c0,c1); \
216 key_schedule; \
217 pass7(c0,c1,a0,a1,b0,b1); \
218 key_schedule; \
219 pass9(b0,b1,c0,c1,a0,a1); \
220 feedforward
221
222#define tiger_compress_macro(str, state) \
223{ \
224 register sh_word32 a0, a1, b0, b1, c0, c1; \
225 sh_word32 aa0, aa1, bb0, bb1, cc0, cc1; \
226 sh_word32 x00, x01, x10, x11, x20, x21, x30, x31, \
227 x40, x41, x50, x51, x60, x61, x70, x71; \
228 sh_word32 temp0, temp1, tempt0, tempt1, temps0, tcarry; \
229\
230 a0 = state[0]; \
231 a1 = state[1]; \
232 b0 = state[2]; \
233 b1 = state[3]; \
234 c0 = state[4]; \
235 c1 = state[5]; \
236\
237 save_abc \
238\
239 x00=str[0*2]; x01=str[0*2+1]; x10=str[1*2]; x11=str[1*2+1]; \
240 x20=str[2*2]; x21=str[2*2+1]; x30=str[3*2]; x31=str[3*2+1]; \
241 x40=str[4*2]; x41=str[4*2+1]; x50=str[5*2]; x51=str[5*2+1]; \
242 x60=str[6*2]; x61=str[6*2+1]; x70=str[7*2]; x71=str[7*2+1]; \
243\
244 compress; \
245\
246 state[0] = a0; \
247 state[1] = a1; \
248 state[2] = b0; \
249 state[3] = b1; \
250 state[4] = c0; \
251 state[5] = c1; \
252}
253
254#if defined(UNROLL_COMPRESS)
255/* The compress function is inlined */
256#define tiger_compress(str, state) \
257 tiger_compress_macro(((sh_word32*)str), ((sh_word32*)state))
258
259#else
260
261void
262tiger_compress(sh_word32 *str, sh_word32 state[6])
263{
264 tiger_compress_macro(((sh_word32*)str), ((sh_word32*)state));
265}
266#endif
267
268void
269tiger_t(sh_word32 *str, sh_word32 length, sh_word32 res[6])
270{
271 register sh_word32 i;
272#ifdef BIG_ENDIAN
273 register sh_word32 j;
274 sh_byte temp[64];
275#endif
276
277 for(i=length; i>=64; i-=64)
278 {
279#ifdef BIG_ENDIAN
280 for(j=0; j<64; j++)
281 temp[j^3] = ((sh_byte*)str)[j];
282 tiger_compress_macro(((sh_word32*)temp), res);
283#else
284 tiger_compress_macro(str, res);
285#endif
286 str += 16;
287 }
288}
289
290
291void tiger(sh_word32 *str, sh_word32 length, sh_word32 res[6])
292{
293 register sh_word32 i, j;
294 sh_byte temp[64];
295
296 /*
297 * res[0]=0x89ABCDEF;
298 * res[1]=0x01234567;
299 * res[2]=0x76543210;
300 * res[3]=0xFEDCBA98;
301 * res[4]=0xC3B2E187;
302 * res[5]=0xF096A5B4;
303 */
304
305 for(i=length; i>=64; i-=64)
306 {
307#ifdef BIG_ENDIAN
308 for(j=0; j<64; j++)
309 temp[j^3] = ((sh_byte*)str)[j];
310 tiger_compress(((sh_word32*)temp), res);
311#else
312 tiger_compress(str, res);
313#endif
314 str += 16;
315 }
316
317#ifdef BIG_ENDIAN
318 for(j=0; j<i; j++)
319 temp[j^3] = ((sh_byte*)str)[j];
320
321 temp[j^3] = 0x01;
322 j++;
323 for(; j&7; j++)
324 temp[j^3] = 0;
325#else
326 for(j=0; j<i; j++)
327 temp[j] = ((sh_byte*)str)[j];
328
329 temp[j++] = 0x01;
330 for(; j&7; j++)
331 temp[j] = 0;
332#endif
333 if(j>56)
334 {
335 for(; j<64; j++)
336 temp[j] = 0;
337 tiger_compress(((sh_word32*)temp), res);
338 j=0;
339 }
340
341 for(; j<56; j++)
342 temp[j] = 0;
343 ((sh_word32*)(&(temp[56])))[0] = ((sh_word32)length)<<3;
344 ((sh_word32*)(&(temp[56])))[1] = 0;
345 tiger_compress(((sh_word32*)temp), res);
346}
347
348#endif
349
Note: See TracBrowser for help on using the repository browser.