📄 tigerhash.cpp
字号:
/*
* Copyright (C) 2001-2005 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"
#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;
#define round(a,b,c,x,mul) \
c ^= x; \
a -= t1[(u_int8_t)(c)] ^ \
t2[(u_int8_t)(((u_int32_t)(c))>>(2*8))] ^ \
t3[(u_int8_t)((c)>>(4*8))] ^ \
t4[(u_int8_t)(((u_int32_t)((c)>>(4*8)))>>(2*8))] ; \
b += t4[(u_int8_t)(((u_int32_t)(c))>>(1*8))] ^ \
t3[(u_int8_t)(((u_int32_t)(c))>>(3*8))] ^ \
t2[(u_int8_t)(((u_int32_t)((c)>>(4*8)))>>(1*8))] ^ \
t1[(u_int8_t)(((u_int32_t)((c)>>(4*8)))>>(3*8))]; \
b *= mul;
#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;
#define compress \
save_abc \
for(pass_no=0; pass_no<PASSES; pass_no++) { \
if(pass_no != 0) {key_schedule} \
pass(a,b,c,(pass_no==0?5:pass_no==1?7:9)); \
tmpa=a; a=c; c=b; b=tmpa;} \
feedforward
#define tiger_compress_macro(str, state) \
{ \
register u_int64_t a, b, c, tmpa; \
u_int64_t aa, bb, cc; \
register u_int64_t x0, x1, x2, x3, x4, x5, x6, x7; \
int pass_no; \
\
a = state[0]; \
b = state[1]; \
c = state[2]; \
\
x0=str[0]; x1=str[1]; x2=str[2]; x3=str[3]; \
x4=str[4]; x5=str[5]; x6=str[6]; x7=str[7]; \
\
compress; \
\
state[0] = a; \
state[1] = b; \
state[2] = c; \
}
/* The compress function is a function. Requires smaller cache? */
void TigerHash::tigerCompress(const u_int64_t *str, u_int64_t state[3]) {
tiger_compress_macro(((const u_int64_t*)str), ((u_int64_t*)state));
}
void TigerHash::update(const void* data, size_t length) {
size_t tmppos = (u_int32_t)(pos & BLOCK_SIZE-1);
const u_int8_t* str = (const u_int8_t*)data;
// First empty tmp buffer if possible
if(tmppos > 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) {
tigerCompress((u_int64_t*)tmp, res);
tmppos = 0;
}
}
// So, now either tmp is empty or all data has been consumed...
dcassert(length == 0 || tmppos == 0);
// Process the bulk of data
while(length>=BLOCK_SIZE) {
tigerCompress((u_int64_t*)str, res);
str += BLOCK_SIZE;
pos += BLOCK_SIZE;
length -= BLOCK_SIZE;
}
// Copy the rest to the tmp buffer
memcpy(tmp, str, length);
pos += length;
}
u_int8_t* TigerHash::finalize() {
size_t tmppos = (size_t)(pos & BLOCK_SIZE-1);
// Tmp buffer always has at least one pos, otherwise it would have
// been processed in update()
tmp[tmppos++] = 0x01;
if(tmppos > (BLOCK_SIZE - sizeof(u_int64_t))) {
memset(tmp + tmppos, 0, BLOCK_SIZE - tmppos);
tigerCompress(((u_int64_t*)tmp), res);
memset(tmp, 0, BLOCK_SIZE);
} else {
memset(tmp + tmppos, 0, BLOCK_SIZE - tmppos - sizeof(u_int64_t));
}
((u_int64_t*)(&(tmp[56])))[0] = pos<<3;
tigerCompress((u_int64_t*)tmp, res);
return getResult();
}
u_int64_t TigerHash::table[4*256] = {
_ULL(0x02AAB17CF7E90C5E) /* 0 */, _ULL(0xAC424B03E243A8EC) /* 1 */,
_ULL(0x72CD5BE30DD5FCD3) /* 2 */, _ULL(0x6D019B93F6F97F3A) /* 3 */,
_ULL(0xCD9978FFD21F9193) /* 4 */, _ULL(0x7573A1C9708029E2) /* 5 */,
_ULL(0xB164326B922A83C3) /* 6 */, _ULL(0x46883EEE04915870) /* 7 */,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -