typedef unsigned long long int word64; typedef unsigned long word32; typedef unsigned char byte; /* Big endian: */ //#if !(defined(__alpha)||defined(__i386__)||defined(__vax__)) //#define BIG_ENDIAN //#endif /* The following macro denotes that an optimization */ /* for Alpha is required. It is used only for */ /* optimization of time. Otherwise it does nothing. */ #ifdef __alpha #define OPTIMIZE_FOR_ALPHA #endif /* NOTE that this code is NOT FULLY OPTIMIZED for any */ /* machine. Assembly code might be much faster on some */ /* machines, especially if the code is compiled with */ /* gcc. */ /* The number of passes of the hash function. */ /* Three passes are recommended. */ /* Use four passes when you need extra security. */ /* Must be at least three. */ #define PASSES 3 extern word64 table[4*256]; #define t1 (table) #define t2 (table+256) #define t3 (table+256*2) #define t4 (table+256*3) #define save_abc \ aa = a; \ bb = b; \ cc = c; #ifdef OPTIMIZE_FOR_ALPHA /* This is the official definition of round */ #define round(a,b,c,x,mul) \ c ^= x; \ a -= t1[((c)>>(0*8))&0xFF] ^ t2[((c)>>(2*8))&0xFF] ^ \ t3[((c)>>(4*8))&0xFF] ^ t4[((c)>>(6*8))&0xFF] ; \ b += t4[((c)>>(1*8))&0xFF] ^ t3[((c)>>(3*8))&0xFF] ^ \ t2[((c)>>(5*8))&0xFF] ^ t1[((c)>>(7*8))&0xFF] ; \ b *= mul; #else /* This code works faster when compiled on 32-bit machines */ /* (but works slower on Alpha) */ #define round(a,b,c,x,mul) \ c ^= x; \ a -= t1[(byte)(c)] ^ \ t2[(byte)(((word32)(c))>>(2*8))] ^ \ t3[(byte)((c)>>(4*8))] ^ \ t4[(byte)(((word32)((c)>>(4*8)))>>(2*8))] ; \ b += t4[(byte)(((word32)(c))>>(1*8))] ^ \ t3[(byte)(((word32)(c))>>(3*8))] ^ \ t2[(byte)(((word32)((c)>>(4*8)))>>(1*8))] ^ \ t1[(byte)(((word32)((c)>>(4*8)))>>(3*8))]; \ b *= mul; #endif #define pass(a,b,c,mul) \ round(a,b,c,x0,mul) \ round(b,c,a,x1,mul) \ round(c,a,b,x2,mul) \ round(a,b,c,x3,mul) \ round(b,c,a,x4,mul) \ round(c,a,b,x5,mul) \ round(a,b,c,x6,mul) \ round(b,c,a,x7,mul) #define key_schedule \ x0 -= x7 ^ 0xA5A5A5A5A5A5A5A5LL; \ x1 ^= x0; \ x2 += x1; \ x3 -= x2 ^ ((~x1)<<19); \ x4 ^= x3; \ x5 += x4; \ x6 -= x5 ^ ((~x4)>>23); \ x7 ^= x6; \ x0 += x7; \ x1 -= x0 ^ ((~x7)<<19); \ x2 ^= x1; \ x3 += x2; \ x4 -= x3 ^ ((~x2)>>23); \ x5 ^= x4; \ x6 += x5; \ x7 -= x6 ^ 0x0123456789ABCDEFLL; #define feedforward \ a ^= aa; \ b -= bb; \ c += cc; #ifdef OPTIMIZE_FOR_ALPHA /* The loop is unrolled: works better on Alpha */ #define compress \ save_abc \ pass(a,b,c,5) \ key_schedule \ pass(c,a,b,7) \ key_schedule \ pass(b,c,a,9) \ for(pass_no=3; pass_no=64; i-=64) { #ifdef BIG_ENDIAN for(j=0; j<64; j++) temp[j^7] = ((byte*)str)[j]; tiger_compress(((word64*)temp), res); #else tiger_compress(str, res); #endif str += 8; } #ifdef BIG_ENDIAN for(j=0; j56) { for(; j<64; j++) temp[j] = 0; tiger_compress(((word64*)temp), res); j=0; } for(; j<56; j++) temp[j] = 0; ((word64*)(&(temp[56])))[0] = ((word64)length)<<3; tiger_compress(((word64*)temp), res); }