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

📄 tigertree.cpp

📁 p2p软件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			nRowCount *= 2;
			nRowPos = 0;
		}
	}
	
	if ( m_nHeight == 0 || m_nHeight > nHeight )
	{
		Clear();
		return FALSE;
	}
	
	SetupParameters( nLength );

	if ( ! CheckIntegrity() )
	{
		Clear();
		return FALSE;
	}
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CTigerTree integrity check

BOOL CTigerTree::CheckIntegrity()
{
	if ( m_pNode == NULL ) return FALSE;
	
	m_nNodeBase = ( m_nNodeCount + 1 ) / 2;
	CTigerNode* pBase = m_pNode + m_nNodeCount - m_nNodeBase;
	
	for ( DWORD nCombine = m_nNodeBase ; nCombine > 1 ; nCombine /= 2 )
	{
		CTigerNode* pIn		= pBase;
		CTigerNode* pOut	= pBase - nCombine / 2;
		
		if ( nCombine == 2 && pOut->bValid == FALSE ) return FALSE;
		
		for ( DWORD nIterate = nCombine / 2 ; nIterate ; nIterate--, pIn += 2, pOut++ )
		{
			if ( pIn[0].bValid && pIn[1].bValid )
			{
				TIGEROOT pTemp;
				Tiger( NULL, TIGER_SIZE * 2, pTemp.w, pIn[0].value, pIn[1].value );
				if ( memcmp( pTemp.w, pOut->value, TIGER_SIZE ) ) return FALSE;
			}
			else if ( pIn[0].bValid )
			{
				if ( memcmp( pIn[0].value, pOut->value, TIGER_SIZE ) ) return FALSE;
			}
			else
			{
				// pOut is bValid=FALSE
			}
		}
		
		pBase -= nCombine / 2;
	}
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CTigerTree dump to file

void CTigerTree::Dump()
{
#ifdef _DEBUG
	CString strOutput, strLine;

	DWORD nRowPos = 0, nRowCount = 1;
	m_nHeight = 0;
	
	for ( DWORD nStep = 0 ; nStep < m_nNodeCount ; nStep++ )
	{
		if ( m_pNode[ nStep ].bValid )
			strLine += CTigerNode::HashToString( (TIGEROOT*)m_pNode[ nStep ].value );
		else
			strLine += _T("_______________________________________");
		strLine += ' ';
		
		if ( ++nRowPos == nRowCount )
		{
			strOutput += strLine;
			strOutput += _T("\r\n");
			strLine.Empty();
			
			m_nHeight ++;
			nRowCount *= 2;
			nRowPos = 0;
		}
	}
	
	CFile pFile;
	
	if ( pFile.Open( _T("\\Shareaza.log"), CFile::modeReadWrite ) )
	{
		pFile.Seek( 0, CFile::end );
	}
	else
	{
		if ( ! pFile.Open( _T("\\Shareaza.log"), CFile::modeWrite|CFile::modeCreate ) )
			return;
	}

	strOutput += _T("\r\n");
	
	USES_CONVERSION;
	LPCSTR pszOutput = T2A(strOutput);
	pFile.Write( pszOutput, strlen(pszOutput) );
	pFile.Close();
#endif
}


//////////////////////////////////////////////////////////////////////
// CTigerNode to string

CString CTigerNode::ToString()
{
	return HashToString( (TIGEROOT*)&value );
}

CString CTigerNode::HashToString(const TIGEROOT* pInHash, BOOL bURN)
{
	static LPCTSTR pszBase64 = _T("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567");
	
	CString strHash;
	LPTSTR pszHash	= strHash.GetBuffer( bURN ? 16 + 39 : 39 );
	
	if ( bURN )
	{
		*pszHash++ = 'u'; *pszHash++ = 'r'; *pszHash++ = 'n'; *pszHash++ = ':'; 
		*pszHash++ = 't'; *pszHash++ = 'r'; *pszHash++ = 'e'; *pszHash++ = 'e'; *pszHash++ = ':'; 
		*pszHash++ = 't'; *pszHash++ = 'i'; *pszHash++ = 'g'; *pszHash++ = 'e'; *pszHash++ = 'r'; *pszHash++ = '/'; *pszHash++ = ':'; 
	}
	
	LPBYTE pHash	= (LPBYTE)pInHash;
	BYTE pZero		= 0;
	int nShift		= 7;
	int nHash		= 0;
	
	for ( int nChar = 39 ; nChar ; nChar-- )
	{
		BYTE nBits = 0;
		
		for ( int nBit = 0 ; nBit < 5 ; nBit++ )
		{
			if ( nBit ) nBits <<= 1;
			nBits |= ( *pHash >> nShift ) & 1;
			
			if ( ! nShift-- )
			{
				nShift = 7;
				if ( ++nHash < TIGER_SIZE )
					pHash++;
				else
					pHash = &pZero;
			}
		}
		
		*pszHash++ = pszBase64[ nBits ];
	}
	
	strHash.ReleaseBuffer( bURN ? 16 + 39 : 39 );
	
	return strHash;
}

//////////////////////////////////////////////////////////////////////
// CTigerNode parse from string

BOOL CTigerNode::HashFromString(LPCTSTR pszHash, TIGEROOT* pTiger)
{
	if ( ! pszHash || _tcslen( pszHash ) < 39 ) return FALSE;

	LPBYTE pHash = (LPBYTE)pTiger;
	DWORD nBits	= 0;
	int nCount	= 0;

	for ( int nChars = 39 ; nChars-- ; pszHash++ )
	{
		if ( *pszHash >= 'A' && *pszHash <= 'Z' )
			nBits |= ( *pszHash - 'A' );
		else if ( *pszHash >= 'a' && *pszHash <= 'z' )
			nBits |= ( *pszHash - 'a' );
		else if ( *pszHash >= '2' && *pszHash <= '7' )
			nBits |= ( *pszHash - '2' + 26 );
		else
			return FALSE;
		
		nCount += 5;

		if ( nCount >= 8 )
		{
			*pHash++ = (BYTE)( nBits >> ( nCount - 8 ) );
			nCount -= 8;
		}

		nBits <<= 5;
	}

	return TRUE;
}

BOOL CTigerNode::HashFromURN(LPCTSTR pszHash, TIGEROOT* pTiger)
{
	if ( pszHash == NULL ) return FALSE;

	int nLen = _tcslen( pszHash );

	if ( nLen >= 16+39 && _tcsncmp( pszHash, _T("urn:tree:tiger/:"), 16 ) == 0 )
	{
		return HashFromString( pszHash + 16, pTiger );
	}
	else if ( nLen >= 12+39 && _tcsncmp( pszHash, _T("tree:tiger/:"), 12 ) == 0 )
	{
		return HashFromString( pszHash + 12, pTiger );
	}
	else if ( nLen >= 15+39 && _tcsncmp( pszHash, _T("urn:tree:tiger:"), 15 ) == 0 )
	{
		return HashFromString( pszHash + 15, pTiger );
	}
	else if ( nLen >= 11+39 && _tcsncmp( pszHash, _T("tree:tiger:"), 11 ) == 0 )
	{
		return HashFromString( pszHash + 11, pTiger );
	}
	else if ( nLen >= 85 && _tcsncmp( pszHash, _T("urn:bitprint:"), 13 ) == 0 )
	{
		return HashFromString( pszHash + 46, pTiger );
	}
	else if ( nLen >= 81 && _tcsncmp( pszHash, _T("bitprint:"), 9 ) == 0 )
	{
		return HashFromString( pszHash + 42, pTiger );
	}
	
	return FALSE;
}


//////////////////////////////////////////////////////////////////////
// CTigerTree tiger hash implementation
//
// Portions created and released into the public domain by Eli Biham
//

void CTigerTree::Tiger(LPCVOID pInput, WORD64 nInput, WORD64* pOutput, WORD64* pInput1, WORD64* pInput2)
{
	register WORD64 i, j;
	BYTE pTemp[64];
	
	pOutput[0] = 0x0123456789ABCDEF;
	pOutput[1] = 0xFEDCBA9876543210;
	pOutput[2] = 0xF096A5B4C3B2E187;
	
	if ( pInput != NULL )
	{
#ifdef NEW_TIGER_ALG
		if ( nInput < 63 )
		{
			pTemp[0] = 0x00;
			const BYTE* pBytes = (const BYTE*)pInput;
			for ( j = 1 ; j < nInput + 1 ; j++ ) pTemp[j] = *pBytes++;
		}
		else
		{
			pTemp[0] = 0x00;
			CopyMemory( pTemp + 1, pInput, 63 );
			Tiger( (const WORD64*)pTemp, pOutput );
			
			const WORD64* pWords = (const WORD64*)( (const BYTE*)pInput + 63 );
			
			for ( i = nInput - 63 ; i >= 64 ; i -= 64 )
			{
				Tiger( pWords, pOutput );
				pWords += 8;
			}
			
			for ( j = 0 ; j < i ; j++ ) pTemp[j] = ((BYTE*)pWords)[j];
		}
		nInput++;
#else
		const WORD64* pWords = (const WORD64*)pInput;
		
		for ( i = nInput ; i >= 64 ; i -= 64 )
		{
			Tiger( pWords, pOutput );
			pWords += 8;
		}
		
		for ( j = 0 ; j < i ; j++ ) pTemp[j] = ((BYTE*)pWords)[j];
#endif
	}
	else if ( pInput1 != NULL && pInput2 != NULL )
	{
#ifdef NEW_TIGER_ALG
		pTemp[0] = 0x01;
		CopyMemory( pTemp + 1, pInput1, TIGER_SIZE );
		CopyMemory( pTemp + TIGER_SIZE + 1, pInput2, TIGER_SIZE );
		j = TIGER_SIZE * 2 + 1;
		nInput = j;
#else
		CopyMemory( pTemp, pInput1, TIGER_SIZE );
		CopyMemory( pTemp + TIGER_SIZE, pInput2, TIGER_SIZE );
		nInput = j = TIGER_SIZE * 2;
#endif
	}
	else
	{
		ASSERT( FALSE );
	}
	
	pTemp[j++] = 0x01;
	
	for ( ; j & 7 ; j++ ) pTemp[j] = 0;
	
	if ( j > 56 )
	{
		for ( ; j < 64 ; j++ ) pTemp[j] = 0;
		Tiger( ((WORD64*)pTemp), pOutput );
		j = 0;
	}
	
	for ( ; j < 56 ; j++ ) pTemp[j] = 0;
	
	((WORD64*)(&(pTemp[56])))[0] = ((WORD64)nInput) << 3;
	
	Tiger( ((WORD64*)pTemp), pOutput );
}

#define PASSES 3

#define t1 (m_pTable)
#define t2 (m_pTable+256)
#define t3 (m_pTable+256*2)
#define t4 (m_pTable+256*3)

#define save_abc \
      aa = a; \
      bb = b; \
      cc = c;

#define round(a,b,c,x,mul) \
      c ^= x; \
      a -= t1[(BYTE)(c)] ^ \
           t2[(BYTE)(((DWORD)(c))>>(2*8))] ^ \
	   t3[(BYTE)((c)>>(4*8))] ^ \
           t4[(BYTE)(((DWORD)((c)>>(4*8)))>>(2*8))] ; \
      b += t4[(BYTE)(((DWORD)(c))>>(1*8))] ^ \
           t3[(BYTE)(((DWORD)(c))>>(3*8))] ^ \
	   t2[(BYTE)(((DWORD)((c)>>(4*8)))>>(1*8))] ^ \
           t1[(BYTE)(((DWORD)((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 ^ 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 ^ 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

void CTigerTree::Tiger(const WORD64* str, WORD64* state)
{
	register WORD64 x0, x1, x2, x3, x4, x5, x6, x7;
	register WORD64 a, b, c, tmpa;
	WORD64 aa, bb, cc;
	// register DWORD i;
	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;
}

//////////////////////////////////////////////////////////////////////
// CTigerTree collapse stack

void CTigerTree::Collapse()
{
	ASSERT( m_pStackTop - m_pStackBase >= 2 );

	Tiger( NULL, TIGER_SIZE * 2, m_pStackTop->value, m_pStackTop[-2].value, m_pStackTop[-1].value );

	m_pStackTop -= 2;
	m_pStackTop[0] = m_pStackTop[2];
	m_pStackTop ++;
}

//////////////////////////////////////////////////////////////////////
// CTigerTree convert a block sequence to a node

void CTigerTree::BlocksToNode()
{
	if ( m_pStackTop == m_pStackBase ) return;
	
	while ( m_pStackTop - 1 > m_pStackBase ) Collapse();
	
	CTigerNode* pNode = m_pNode + m_nNodeCount - m_nNodeBase + m_nNodePos++;
	
	pNode->v1		= m_pStackBase->v1;
	pNode->v2		= m_pStackBase->v2;
	pNode->v3		= m_pStackBase->v3;
	pNode->bValid	= TRUE;
	
	m_nBlockPos		= 0;
	m_pStackTop		= m_pStackBase;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -