⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tigerhash.cpp

📁 软件是使用VC70
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/* 
 * 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 + -