source: trunk/src/sh_tiger1_64.c@ 4

Last change on this file since 4 was 1, checked in by katerina, 19 years ago

Initial import

File size: 7.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#if defined(HAVE_LONG_64) || defined(HAVE_LONG_LONG_64)
8
9/*@-incondefs -macroparens -macroassign -macroparams -macrostmt @*/
10/*@-fixedformalarray +charindex -type -paramuse -predboolint -exportlocal@*/
11/* Big endian: */
12#ifdef WORDS_BIGENDIAN
13#define BIG_ENDIAN
14#endif
15
16
17/* Tiger: A Fast New Hash Function
18 *
19 * Ross Anderson and Eli Biham
20 *
21 * From the homepage (http://www.cs.technion.ac.il/~biham/Reports/Tiger/):
22 *
23 * Tiger has no usage restrictions nor patents. It can be used freely,
24 * with the reference implementation, with other implementations or with
25 * a modification to the reference implementation (as long as it still
26 * implements Tiger). We only ask you to let us know about your
27 * implementation and to cite the origin of Tiger and of the reference
28 * implementation.
29 *
30 *
31 * The authors' home pages can be found both in
32 * http://www.cs.technion.ac.il/~biham/ and in
33 * http://www.cl.cam.ac.uk/users/rja14/.
34 * The authors' email addresses are biham@cs.technion.ac.il
35 * and rja14@cl.cam.ac.uk.
36 */
37
38#if defined(HAVE_LONG_64)
39typedef unsigned long int word64;
40#else
41typedef unsigned long long int word64;
42#endif
43
44#if defined(HAVE_INT_32)
45typedef unsigned int sh_word32;
46#elif defined(HAVE_LONG_32)
47typedef unsigned long sh_word32;
48#elif defined(HAVE_SHORT_32)
49typedef unsigned short sh_word32;
50#else
51#error No 32 byte type found !
52#endif
53
54typedef unsigned char sh_byte;
55
56/* Big endian:
57 #if !(defined(__alpha)||defined(__i386__)||defined(__vax__))
58 #define BIG_ENDIAN
59 #endif
60*/
61
62/* The following macro denotes that an optimization */
63/* for Alpha is required. It is used only for */
64/* optimization of time. Otherwise it does nothing. */
65#ifdef __alpha
66#define OPTIMIZE_FOR_ALPHA
67#endif
68
69/* NOTE that this code is NOT FULLY OPTIMIZED for any */
70/* machine. Assembly code might be much faster on some */
71/* machines, especially if the code is compiled with */
72/* gcc. */
73
74/* The number of passes of the hash function. */
75/* Three passes are recommended. */
76/* Use four passes when you need extra security. */
77/* Must be at least three. */
78#define PASSES 3
79
80extern word64 tiger_table[4*256];
81
82#define t1 (tiger_table)
83#define t2 (tiger_table+256)
84#define t3 (tiger_table+256*2)
85#define t4 (tiger_table+256*3)
86
87#define save_abc \
88 aa = a; \
89 bb = b; \
90 cc = c;
91
92#ifdef OPTIMIZE_FOR_ALPHA
93/* This is the official definition of round */
94#define round(a,b,c,x,mul) \
95 c ^= x; \
96 a -= t1[((c)>>(0*8))&0xFF] ^ t2[((c)>>(2*8))&0xFF] ^ \
97 t3[((c)>>(4*8))&0xFF] ^ t4[((c)>>(6*8))&0xFF] ; \
98 b += t4[((c)>>(1*8))&0xFF] ^ t3[((c)>>(3*8))&0xFF] ^ \
99 t2[((c)>>(5*8))&0xFF] ^ t1[((c)>>(7*8))&0xFF] ; \
100 b *= mul;
101#else
102/* This code works faster when compiled on 32-bit machines */
103/* (but works slower on Alpha) */
104#define round(a,b,c,x,mul) \
105 c ^= x; \
106 a -= t1[(sh_byte)(c)] ^ \
107 t2[(sh_byte)(((sh_word32)(c))>>(2*8))] ^ \
108 t3[(sh_byte)((c)>>(4*8))] ^ \
109 t4[(sh_byte)(((sh_word32)((c)>>(4*8)))>>(2*8))] ; \
110 b += t4[(sh_byte)(((sh_word32)(c))>>(1*8))] ^ \
111 t3[(sh_byte)(((sh_word32)(c))>>(3*8))] ^ \
112 t2[(sh_byte)(((sh_word32)((c)>>(4*8)))>>(1*8))] ^ \
113 t1[(sh_byte)(((sh_word32)((c)>>(4*8)))>>(3*8))]; \
114 b *= mul;
115#endif
116
117#define pass(a,b,c,mul) \
118 round(a,b,c,x0,mul) \
119 round(b,c,a,x1,mul) \
120 round(c,a,b,x2,mul) \
121 round(a,b,c,x3,mul) \
122 round(b,c,a,x4,mul) \
123 round(c,a,b,x5,mul) \
124 round(a,b,c,x6,mul) \
125 round(b,c,a,x7,mul)
126
127#define key_schedule \
128 x0 -= x7 ^ 0xA5A5A5A5A5A5A5A5LL; \
129 x1 ^= x0; \
130 x2 += x1; \
131 x3 -= x2 ^ ((~x1)<<19); \
132 x4 ^= x3; \
133 x5 += x4; \
134 x6 -= x5 ^ ((~x4)>>23); \
135 x7 ^= x6; \
136 x0 += x7; \
137 x1 -= x0 ^ ((~x7)<<19); \
138 x2 ^= x1; \
139 x3 += x2; \
140 x4 -= x3 ^ ((~x2)>>23); \
141 x5 ^= x4; \
142 x6 += x5; \
143 x7 -= x6 ^ 0x0123456789ABCDEFLL;
144
145#define feedforward \
146 a ^= aa; \
147 b -= bb; \
148 c += cc;
149
150#ifdef OPTIMIZE_FOR_ALPHA
151/* The loop is unrolled: works better on Alpha */
152#define compress \
153 save_abc \
154 pass(a,b,c,5) \
155 key_schedule \
156 pass(c,a,b,7) \
157 key_schedule \
158 pass(b,c,a,9) \
159 for(pass_no=3; pass_no<PASSES; pass_no++) { \
160 key_schedule \
161 pass(a,b,c,9) \
162 tmpa=a; a=c; c=b; b=tmpa;} \
163 feedforward
164#else
165/* loop: works better on PC and Sun (smaller cache?) */
166#define compress \
167 save_abc \
168 for(pass_no=0; pass_no<PASSES; pass_no++) { \
169 if(pass_no != 0) {key_schedule} \
170 pass(a,b,c,(pass_no==0?5:pass_no==1?7:9)); \
171 tmpa=a; a=c; c=b; b=tmpa;} \
172 feedforward
173#endif
174
175#define tiger_compress_macro(str, state) \
176{ \
177 register word64 a, b, c, tmpa; \
178 word64 aa, bb, cc; \
179 register word64 x0, x1, x2, x3, x4, x5, x6, x7; \
180 int pass_no; \
181\
182 a = state[0]; \
183 b = state[1]; \
184 c = state[2]; \
185\
186 x0=str[0]; x1=str[1]; x2=str[2]; x3=str[3]; \
187 x4=str[4]; x5=str[5]; x6=str[6]; x7=str[7]; \
188\
189 compress; \
190\
191 state[0] = a; \
192 state[1] = b; \
193 state[2] = c; \
194}
195
196/* The compress function is a function. Requires smaller cache? */
197void tiger_compress(word64 *str, word64 state[3])
198{
199#ifndef S_SPLINT_S
200 tiger_compress_macro(((word64*)str), ((word64*)state));
201#endif
202}
203
204#ifdef OPTIMIZE_FOR_ALPHA
205/* The compress function is inlined: works better on Alpha. */
206/* Still leaves the function above in the code, in case some other */
207/* module calls it directly. */
208#define tiger_compress(str, state) \
209 tiger_compress_macro(((word64*)str), ((word64*)state))
210#endif
211
212void tiger_t(word64 *str, word64 length, word64 res[3])
213{
214 register word64 i;
215
216#ifdef BIG_ENDIAN
217 register word64 j = 0;
218 unsigned char temp[64];
219#endif
220
221 /*
222 res[0]=0x0123456789ABCDEFLL;
223 res[1]=0xFEDCBA9876543210LL;
224 res[2]=0xF096A5B4C3B2E187LL;
225 */
226
227 for(i=length; i>=64; i-=64)
228 {
229#ifdef BIG_ENDIAN
230 for(j=0; j<64; j++)
231 temp[j^7] = ((sh_byte*)str)[j];
232 tiger_compress(((word64*)temp), res);
233#else
234 tiger_compress(str, res);
235#endif
236 str += 8;
237 }
238
239}
240
241void tiger(word64 *str, word64 length, word64 res[3])
242{
243 register word64 i;
244 register word64 j = 0;
245 unsigned char temp[64];
246
247 /*
248 res[0]=0x0123456789ABCDEFLL;
249 res[1]=0xFEDCBA9876543210LL;
250 res[2]=0xF096A5B4C3B2E187LL;
251 */
252
253 for(i=length; i>=64; i-=64)
254 {
255#ifdef BIG_ENDIAN
256 for(j=0; j<64; j++)
257 temp[j^7] = ((sh_byte*)str)[j];
258 tiger_compress(((word64*)temp), res);
259#else
260 tiger_compress(str, res);
261#endif
262 str += 8;
263 }
264
265#ifdef BIG_ENDIAN
266 for(j=0; j<i; j++)
267 temp[j^7] = ((sh_byte*)str)[j];
268
269 temp[j^7] = 0x01;
270 j++;
271 for(; j&7; j++)
272 temp[j^7] = 0;
273#else
274 for(j=0; j<i; j++)
275 temp[j] = ((sh_byte*)str)[j];
276
277 temp[j++] = 0x01;
278 for(; j&7; j++)
279 temp[j] = 0;
280#endif
281 if(j>56)
282 {
283 for(; j<64; j++)
284 temp[j] = 0;
285 tiger_compress(((word64*)temp), res);
286 j=0;
287 }
288
289 for(; j<56; j++)
290 temp[j] = 0;
291 ((word64*)(&(temp[56])))[0] = ((word64)length)<<3;
292 tiger_compress(((word64*)temp), res);
293}
294
295#else
296
297void dummy_1_64 (int a)
298{
299 (void) a;
300 return;
301}
302
303#endif
304
305
306
307
308
309
310
311
312
Note: See TracBrowser for help on using the repository browser.