关键词: tiger fastest hash
可能大家很少听说过Tiger算法。Tiger由Ross在1995年提出。Tiger号称是最快的Hash算法,专门为64位机器做了优化。Tiger和md5的添加数据的方式不同,它不是加上1个1及若干个0,而是增加一个0x01和若干个0。Tiger的输出是192位的,即24个字节。分组的大小也是和md5一样:64字节。Tiger有一个1024个元素的表。这个是其最大特点。
下面是Tiger的算法代码。
#ifndef Goodzzp_Tiger_05_10_22_19
#define Goodzzp_Tiger_05_10_22_19
//Tiger
//program by Goodzzp
//05,10,22
//referred:
//http://www.cs.technion.ac.il/~biham/Reports/Tiger/
//notice:it is said that tiger will upgrade to tiger 2.0 soon.
#include "define.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[(UI8)(c)] ^ /
t2[(UI8)(((UI32)(c))>>(2*8))] ^ /
t3[(UI8)((c)>>(4*8))] ^ /
t4[(UI8)(((UI32)((c)>>(4*8)))>>(2*8))] ; /
b += t4[(UI8)(((UI32)(c))>>(1*8))] ^ /
t3[(UI8)(((UI32)(c))>>(3*8))] ^ /
t2[(UI8)(((UI32)((c)>>(4*8)))>>(1*8))] ^ /
t1[(UI8)(((UI32)((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 ^ 0xA5A5A5A5A5A5A5A5L; /
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 ^ 0x0123456789ABCDEFL;
#define feedforward /
a ^= aa; /
b -= bb; /
c += cc;
#define compress /
save_abc /
for(pass_no=0; 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
//Tiger hash 算法
class Tiger
{
public:
//输出结果的长度(字节)
static UI32 OutDataLength()
{
return 192/8;
}
//Tiger变换函数
//out:输出,长度为24,要求事先已经分配了内存
//in:输入
//length:输入值的长度
void Hash(UI8 *out,const UI8 *in,UI32 length)
{
UI32 i = length>>6,j=(length&0x3f),k;
//对数据64 64个字节的计算
for(k=0;k {
StepTransform((UI8 *)(in + k * 64),64,length);
}
//最后计算尾数
StepTransform((UI8 *)(in + 64 * i),j,length);
//拷贝输出
memcpy(out,m_state,24);
//恢复m_state值
m_state[0]=0x0123456789ABCDEF;
m_state[1]=0xFEDCBA9876543210;
m_state[2]=0xF096A5B4C3B2E187;
}
//初始化
//这里就是3个刚开始的值
Tiger()
{
m_state[0]=0x0123456789ABCDEF;
m_state[1]=0xFEDCBA9876543210;
m_state[2]=0xF096A5B4C3B2E187;
}
private:
//每步的变换函数
//输入:
// data: 要处理的数据块(不大于64字节)
// dataBlockLen: 数据块的长度
// dataTotalLen: 要处理的所有数据块的总长度
//输出结果保存在m_state里面
void StepTransform(UI8 *data,UI32 dataBlockLen, UI32 dataTotalLen)
{
UI8 buffer[64];
UI32 len=dataTotalLen*8;
memset(buffer,0,64);//清空数据为0
memcpy(buffer,data,dataBlockLen);//拷贝数据到缓冲
if(dataBlockLen <64) //需要增加数据
{
if(dataBlockLen<56)//当前数据是最后若干个,而且不需要增加一次变换
{
//添加1和0
buffer[dataBlockLen]=0x01;
//添加长度
buffer[56]=(UI8)(len&0xff);
len>>=8;
buffer[57]=(UI8)(len&0xff);
len>>=8;
buffer[58]=(UI8)(len&0xff);
len>>=8;
buffer[59]=(UI8)(len&0xff);
//变换
FirstTransform((UI32*)buffer);
CoreTransform();
}
else if(dataBlockLen>=56)
{
//添加1和0
buffer[dataBlockLen]=0x01;
//变换
FirstTransform((UI32*)buffer);
CoreTransform();
//添加长度
memset(buffer,0,64);
buffer[56]=(UI8)(len&0xff);
len>>=8;
buffer[57]=(UI8)(len&0xff);
len>>=8;
buffer[58]=(UI8)(len&0xff);
len>>=8;
buffer[59]=(UI8)(len&0xff);
//变换
FirstTransform((UI32*)buffer);
CoreTransform();
}
}
else if(dataBlockLen == 64)
{
//变换
FirstTransform((UI32*)buffer);
CoreTransform();
}
}
//把64字节的原始数据data进行初步转化到m_data中去
void FirstTransform(UI32 *data)
{
memcpy(m_data,data,64);
}
//核心变换
void CoreTransform()
{
UI64 a, b, c, tmpa,aa, bb, cc;
UI64 x0, x1, x2, x3, x4, x5, x6, x7;
UI32 pass_no;
a = m_state[0];
b = m_state[1];
c = m_state[2];
x0=m_data[0]; x1=m_data[1]; x2=m_data[2]; x3=m_data[3];
x4=m_data[4]; x5=m_data[5]; x6=m_data[6]; x7=m_data[7];
compress;
m_state[0] = a;
m_state[1] = b;
m_state[2] = c;
}
private:
UI64 m_state[3];//保存有tiger输出值
UI64 m_data[8]; //保存有每步变换时对输入的初始化转化值
static const UI64 table[4*256]; //s-box
};
const UI64 Tiger::table[4*256] = {
0x02AAB17CF7E90C5EL /* 0 */, 0xAC424B03E243A8ECL /* 1 */,
0x72CD5BE30DD5FCD3L /* 2 */, 0x6D019B93F6F97F3AL /* 3 */,
0xCD9978FFD21F9193L /* 4 */, 0x7573A1C9708029E2L /* 5 */,
0xB164326B922A83C3L /* 6 */, 0x46883EEE04915870L /* 7 */,
0xEAACE3057103ECE6L /* 8 */, 0xC54169B808A3535CL /* 9 */,
0x4CE754918DDEC47CL /* 10 */, 0x0AA2F4DFDC0DF40CL /* 11 */,
0x10B76F18A74DBEFAL /* 12 */, 0xC6CCB6235AD1AB6AL /* 13 */,
0x13726121572FE2FFL /* 14 */, 0x1A488C6F199D921EL /* 15 */,
0x4BC9F9F4DA0007CAL /* 16 */, 0x26F5E6F6E85241C7L /* 17 */,
0x859079DBEA5947B6L /* 18 */, 0x4F1885C5C99E8C92L /* 19 */,
0xD78E761EA96F864BL /* 20 */, 0x8E36428C52B5C17DL /* 21 */,
0x69CF6827373063C1L /* 22 */, 0xB607C93D9BB4C56EL /* 23 */,
0x7D820E760E76B5EAL /* 24 */, 0x645C9CC6F07FDC42L /* 25 */,
0xBF38A078243342E0L /* 26 */, 0x5F6B343C9D2E7D04L /* 27 */,
0xF2C28AEB600B0EC6L /* 28 */, 0x6C0ED85F7254BCACL /* 29 */,
0x71592281A4DB4FE5L /* 30 */, 0x1967FA69CE0FED9FL /* 31 */,
0xFD5293F8B96545DBL /* 32 */, 0xC879E9D7F2A7600BL /* 33 */,
0x860248920193194EL /* 34 */, 0xA4F9533B2D9CC0B3L /* 35 */,
0x9053836C15957613L /* 36 */, 0xDB6DCF8AFC357BF1L /* 37 */,
0x18BEEA7A7A370F57L /* 38 */, 0x037117CA50B99066L /* 39 */,
0x6AB30A9774424A35L /* 40 */, 0xF4E92F02E325249BL /* 41 */,
0x7739DB07061CCAE1L /* 42 */, 0xD8F3B49CECA42A05L /* 43 */,
0xBD56BE3F51382F73L /* 44 */, 0x45FAED5843B0BB28L /* 45 */,
0x1C813D5C11BF1F83L /* 46 */, 0x8AF0E4B6D75FA169L /* 47 */,
0x33EE18A487AD9999L /* 48 */, 0x3C26E8EAB1C94410L /* 49 */,
0xB510102BC0A822F9L /* 50 */, 0x141EEF310CE6123BL /* 51 */,
0xFC65B90059DDB154L /* 52 */, 0xE0158640C5E0E607L /* 53 */,
0x884E079826C3A3CFL /* 54 */, 0x930D0D9523C535FDL /* 55 */,
0x35638D754E9A2B00L /* 56 */, 0x4085FCCF40469DD5L /* 57 */,
0xC4B17AD28BE23A4CL /* 58 */, 0xCAB2F0FC6A3E6A2EL /* 59 */,
0x2860971A6B943FCDL /* 60 */, 0x3DDE6EE212E30446L /* 61 */,
0x6222F32AE01765AEL /* 62 */, 0x5D550BB5478308FEL /* 63 */,
0xA9EFA98DA0EDA22AL /* 64 */, 0xC351A71686C40DA7L /* 65 */,
0x1105586D9C867C84L /* 66 */, 0xDCFFEE85FDA22853L /* 67 */,
0xCCFBD0262C5EEF76L /* 68 */, 0xBAF294CB8990D201L /* 69 */,
0xE69464F52AFAD975L /* 70 */, 0x94B013AFDF133E14L /* 71 */,
0x06A7