/* * Copyright (C) 2001-2008 Jacek Sieka, arnetheduck on gmail point com * * 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 2 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, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "stdinc.h" #include "DCPlusPlus.h" #include "TigerHash.h" namespace dcpp { #ifdef _WIN32 #if defined(_M_X64) #define TIGER_ARCH64 #endif #if !(defined(_M_IX86) || defined(_M_X64)) #define TIGER_BIG_ENDIAN #endif #else // _WIN32 #if defined(__x86_64__) || defined(__alpha) #define TIGER_ARCH64 #endif #if !(defined(__i386__) || defined(__x86_64__) || defined(__alpha)) #define TIGER_BIG_ENDIAN #endif #endif // _WIN32 #define PASSES 3 #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 TIGER_ARCH64 #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 #define round(a,b,c,x,mul) \ c ^= x; \ a -= t1[(uint8_t)(c)] ^ \ t2[(uint8_t)(((uint32_t)(c))>>(2*8))] ^ \ t3[(uint8_t)((c)>>(4*8))] ^ \ t4[(uint8_t)(((uint32_t)((c)>>(4*8)))>>(2*8))] ; \ b += t4[(uint8_t)(((uint32_t)(c))>>(1*8))] ^ \ t3[(uint8_t)(((uint32_t)(c))>>(3*8))] ^ \ t2[(uint8_t)(((uint32_t)((c)>>(4*8)))>>(1*8))] ^ \ t1[(uint8_t)(((uint32_t)((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 ^ _ULL(0xA5A5A5A5A5A5A5A5); \ 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 ^ _ULL(0x0123456789ABCDEF); #define feedforward \ a ^= aa; \ b -= bb; \ c += cc; #ifdef TIGER_ARCH64 #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 0) { size_t n = min(length, BLOCK_SIZE-tmppos); memcpy(tmp + tmppos, str, n); str += n; pos += n; length -= n; if((tmppos + n) == BLOCK_SIZE) { #ifdef TIGER_BIG_ENDIAN for(j=0; j=BLOCK_SIZE) { #ifdef TIGER_BIG_ENDIAN for(j=0; j (BLOCK_SIZE - sizeof(uint64_t))) { memset(tmp + tmppos, 0, BLOCK_SIZE - tmppos); #ifdef TIGER_BIG_ENDIAN for(j=0; j