/* tigersum - a command line utility to calculate the tiger hash from input. Copyright (C) 2014 Michele "King_DuckZ" Santullo This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ 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]; union RawAccessULL4 { word64 ull[8]; unsigned char raw[64]; }; #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; } } void tiger_last_chunk(word64 *str, word64 length, word64 reallength, word64 res[3], byte pad) { const word64 i = length & 0x3f; register word64 j; union RawAccessULL4 temp; #ifdef BIG_ENDIAN for(j=0; j56) { for(; j<64; j++) temp.raw[j] = 0; tiger_compress((temp.ull), res); j=0; } for(; j<56; j++) temp.raw[j] = 0; temp.ull[7] = reallength<<3; tiger_compress((temp.ull), res); } void tiger(word64 *str, word64 length, word64 res[3], byte pad) { const word64 proc_length = length & ~0x3fULL; tiger_init(res); tiger_chunk(str, proc_length, res); tiger_last_chunk(str + (proc_length / 8), length - proc_length, length, res, pad); }