sha.cpp

来自「此压缩包内有cast、blowfish、simple、des、cryptlib、」· C++ 代码 · 共 554 行 · 第 1/2 页

CPP
554
字号
	W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65),
	W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483),
	W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5),
	W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210),
	W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4),
	W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725),
	W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70),
	W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926),
	W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df),
	W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8),
	W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b),
	W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001),
	W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30),
	W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910),
	W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8),
	W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53),
	W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8),
	W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb),
	W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3),
	W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60),
	W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec),
	W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9),
	W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b),
	W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207),
	W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178),
	W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6),
	W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b),
	W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493),
	W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c),
	W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a),
	W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817)
};

#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86
// put assembly version in separate function, otherwise MSVC 2005 SP1 doesn't generate correct code for the non-assembly version
CRYPTOPP_NAKED static void CRYPTOPP_FASTCALL SHA512_SSE2_Transform(word64 *state, const word64 *data)
{
#ifdef __GNUC__
	__asm__ __volatile__
	(
		".intel_syntax noprefix;"
	AS1(	push	ebx)
	AS2(	mov		ebx, eax)
#else
	AS1(	push	ebx)
	AS1(	push	esi)
	AS1(	push	edi)
	AS2(	lea		ebx, SHA512_K)
#endif

	AS2(	mov		eax, esp)
	AS2(	and		esp, 0xfffffff0)
	AS2(	sub		esp, 27*16)				// 17*16 for expanded data, 20*8 for state
	AS1(	push	eax)
	AS2(	xor		eax, eax)
	AS2(	lea		edi, [esp+4+8*8])		// start at middle of state buffer. will decrement pointer each round to avoid copying
	AS2(	lea		esi, [esp+4+20*8+8])	// 16-byte alignment, then add 8

	AS2(	movq	mm4, [ecx+0*8])
	AS2(	movq	[edi+0*8], mm4)
	AS2(	movq	mm0, [ecx+1*8])
	AS2(	movq	[edi+1*8], mm0)
	AS2(	movq	mm0, [ecx+2*8])
	AS2(	movq	[edi+2*8], mm0)
	AS2(	movq	mm0, [ecx+3*8])
	AS2(	movq	[edi+3*8], mm0)
	AS2(	movq	mm5, [ecx+4*8])
	AS2(	movq	[edi+4*8], mm5)
	AS2(	movq	mm0, [ecx+5*8])
	AS2(	movq	[edi+5*8], mm0)
	AS2(	movq	mm0, [ecx+6*8])
	AS2(	movq	[edi+6*8], mm0)
	AS2(	movq	mm0, [ecx+7*8])
	AS2(	movq	[edi+7*8], mm0)
	ASJ(	jmp,	0, f)

#define SSE2_S0_S1(r, a, b, c)	\
	AS2(	movq	mm6, r)\
	AS2(	psrlq	r, a)\
	AS2(	movq	mm7, r)\
	AS2(	psllq	mm6, 64-c)\
	AS2(	pxor	mm7, mm6)\
	AS2(	psrlq	r, b-a)\
	AS2(	pxor	mm7, r)\
	AS2(	psllq	mm6, c-b)\
	AS2(	pxor	mm7, mm6)\
	AS2(	psrlq	r, c-b)\
	AS2(	pxor	r, mm7)\
	AS2(	psllq	mm6, b-a)\
	AS2(	pxor	r, mm6)

#define SSE2_s0(r, a, b, c)	\
	AS2(	movdqa	xmm6, r)\
	AS2(	psrlq	r, a)\
	AS2(	movdqa	xmm7, r)\
	AS2(	psllq	xmm6, 64-c)\
	AS2(	pxor	xmm7, xmm6)\
	AS2(	psrlq	r, b-a)\
	AS2(	pxor	xmm7, r)\
	AS2(	psrlq	r, c-b)\
	AS2(	pxor	r, xmm7)\
	AS2(	psllq	xmm6, c-a)\
	AS2(	pxor	r, xmm6)

#define SSE2_s1(r, a, b, c)	\
	AS2(	movdqa	xmm6, r)\
	AS2(	psrlq	r, a)\
	AS2(	movdqa	xmm7, r)\
	AS2(	psllq	xmm6, 64-c)\
	AS2(	pxor	xmm7, xmm6)\
	AS2(	psrlq	r, b-a)\
	AS2(	pxor	xmm7, r)\
	AS2(	psllq	xmm6, c-b)\
	AS2(	pxor	xmm7, xmm6)\
	AS2(	psrlq	r, c-b)\
	AS2(	pxor	r, xmm7)

	ASL(SHA512_Round)
	// k + w is in mm0, a is in mm4, e is in mm5
	AS2(	paddq	mm0, [edi+7*8])		// h
	AS2(	movq	mm2, [edi+5*8])		// f
	AS2(	movq	mm3, [edi+6*8])		// g
	AS2(	pxor	mm2, mm3)
	AS2(	pand	mm2, mm5)
	SSE2_S0_S1(mm5,14,18,41)
	AS2(	pxor	mm2, mm3)
	AS2(	paddq	mm0, mm2)			// h += Ch(e,f,g)
	AS2(	paddq	mm5, mm0)			// h += S1(e)
	AS2(	movq	mm2, [edi+1*8])		// b
	AS2(	movq	mm1, mm2)
	AS2(	por		mm2, mm4)
	AS2(	pand	mm2, [edi+2*8])		// c
	AS2(	pand	mm1, mm4)
	AS2(	por		mm1, mm2)
	AS2(	paddq	mm1, mm5)			// temp = h + Maj(a,b,c)
	AS2(	paddq	mm5, [edi+3*8])		// e = d + h
	AS2(	movq	[edi+3*8], mm5)
	AS2(	movq	[edi+11*8], mm5)
	SSE2_S0_S1(mm4,28,34,39)			// S0(a)
	AS2(	paddq	mm4, mm1)			// a = temp + S0(a)
	AS2(	movq	[edi-8], mm4)
	AS2(	movq	[edi+7*8], mm4)
	AS1(	ret)

	// first 16 rounds
	ASL(0)
	AS2(	movq	mm0, [edx+eax*8])
	AS2(	movq	[esi+eax*8], mm0)
	AS2(	movq	[esi+eax*8+16*8], mm0)
	AS2(	paddq	mm0, [ebx+eax*8])
	ASC(	call,	SHA512_Round)
	AS1(	inc		eax)
	AS2(	sub		edi, 8)
	AS2(	test	eax, 7)
	ASJ(	jnz,	0, b)
	AS2(	add		edi, 8*8)
	AS2(	cmp		eax, 16)
	ASJ(	jne,	0, b)

	// rest of the rounds
	AS2(	movdqu	xmm0, [esi+(16-2)*8])
	ASL(1)
	// data expansion, W[i-2] already in xmm0
	AS2(	movdqu	xmm3, [esi])
	AS2(	paddq	xmm3, [esi+(16-7)*8])
	AS2(	movdqa	xmm2, [esi+(16-15)*8])
	SSE2_s1(xmm0, 6, 19, 61)
	AS2(	paddq	xmm0, xmm3)
	SSE2_s0(xmm2, 1, 7, 8)
	AS2(	paddq	xmm0, xmm2)
	AS2(	movdq2q	mm0, xmm0)
	AS2(	movhlps	xmm1, xmm0)
	AS2(	paddq	mm0, [ebx+eax*8])
	AS2(	movlps	[esi], xmm0)
	AS2(	movlps	[esi+8], xmm1)
	AS2(	movlps	[esi+8*16], xmm0)
	AS2(	movlps	[esi+8*17], xmm1)
	// 2 rounds
	ASC(	call,	SHA512_Round)
	AS2(	sub		edi, 8)
	AS2(	movdq2q	mm0, xmm1)
	AS2(	paddq	mm0, [ebx+eax*8+8])
	ASC(	call,	SHA512_Round)
	// update indices and loop
	AS2(	add		esi, 16)
	AS2(	add		eax, 2)
	AS2(	sub		edi, 8)
	AS2(	test	eax, 7)
	ASJ(	jnz,	1, b)
	// do housekeeping every 8 rounds
	AS2(	mov		esi, 0xf)
	AS2(	and		esi, eax)
	AS2(	lea		esi, [esp+4+20*8+8+esi*8])
	AS2(	add		edi, 8*8)
	AS2(	cmp		eax, 80)
	ASJ(	jne,	1, b)

#define SSE2_CombineState(i)	\
	AS2(	movq	mm0, [edi+i*8])\
	AS2(	paddq	mm0, [ecx+i*8])\
	AS2(	movq	[ecx+i*8], mm0)

	SSE2_CombineState(0)
	SSE2_CombineState(1)
	SSE2_CombineState(2)
	SSE2_CombineState(3)
	SSE2_CombineState(4)
	SSE2_CombineState(5)
	SSE2_CombineState(6)
	SSE2_CombineState(7)

	AS1(	pop		esp)
	AS1(	emms)

#if defined(__GNUC__)
	AS1(	pop		ebx)
	".att_syntax prefix;"
		:
		: "a" (SHA512_K), "c" (state), "d" (data)
		: "%esi", "%edi", "memory", "cc"
	);
#else
	AS1(	pop		edi)
	AS1(	pop		esi)
	AS1(	pop		ebx)
	AS1(	ret)
#endif
}
#endif	// #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE

void SHA512::Transform(word64 *state, const word64 *data)
{
#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86
	if (HasSSE2())
	{
		SHA512_SSE2_Transform(state, data);
		return;
	}
#endif

#define S0(x) (rotrFixed(x,28)^rotrFixed(x,34)^rotrFixed(x,39))
#define S1(x) (rotrFixed(x,14)^rotrFixed(x,18)^rotrFixed(x,41))
#define s0(x) (rotrFixed(x,1)^rotrFixed(x,8)^(x>>7))
#define s1(x) (rotrFixed(x,19)^rotrFixed(x,61)^(x>>6))

#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA512_K[i+j]+(j?blk2(i):blk0(i));\
	d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i))

	word64 W[16];
	word64 T[8];
    /* Copy context->state[] to working vars */
	memcpy(T, state, sizeof(T));
    /* 80 operations, partially loop unrolled */
	for (unsigned int j=0; j<80; j+=16)
	{
		R( 0); R( 1); R( 2); R( 3);
		R( 4); R( 5); R( 6); R( 7);
		R( 8); R( 9); R(10); R(11);
		R(12); R(13); R(14); R(15);
	}
    /* Add the working vars back into context.state[] */
    state[0] += a(0);
    state[1] += b(0);
    state[2] += c(0);
    state[3] += d(0);
    state[4] += e(0);
    state[5] += f(0);
    state[6] += g(0);
    state[7] += h(0);
}

#endif

NAMESPACE_END

#endif	// #ifndef CRYPTOPP_IMPORTS

⌨️ 快捷键说明

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