📄 sha.cpp
字号:
{ X86_SHA256_HashBlocks(m_state, input, (length&(size_t(0)-BLOCKSIZE)) - !HasSSE2()); return length % BLOCKSIZE;}size_t SHA224::HashMultipleBlocks(const word32 *input, size_t length){ X86_SHA256_HashBlocks(m_state, input, (length&(size_t(0)-BLOCKSIZE)) - !HasSSE2()); return length % BLOCKSIZE;}#endif#define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15]))#define Ch(x,y,z) (z^(x&(y^z)))#define Maj(x,y,z) (y^((x^y)&(y^z)))#define a(i) T[(0-i)&7]#define b(i) T[(1-i)&7]#define c(i) T[(2-i)&7]#define d(i) T[(3-i)&7]#define e(i) T[(4-i)&7]#define f(i) T[(5-i)&7]#define g(i) T[(6-i)&7]#define h(i) T[(7-i)&7]#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA256_K[i+j]+(j?blk2(i):blk0(i));\ d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i))// for SHA256#define S0(x) (rotrFixed(x,2)^rotrFixed(x,13)^rotrFixed(x,22))#define S1(x) (rotrFixed(x,6)^rotrFixed(x,11)^rotrFixed(x,25))#define s0(x) (rotrFixed(x,7)^rotrFixed(x,18)^(x>>3))#define s1(x) (rotrFixed(x,17)^rotrFixed(x,19)^(x>>10))void SHA256::Transform(word32 *state, const word32 *data){ word32 W[16];#if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_X64_MASM_AVAILABLE) // this byte reverse is a waste of time, but this function is only called by MDC ByteReverse(W, data, BLOCKSIZE); X86_SHA256_HashBlocks(state, W, BLOCKSIZE - !HasSSE2());#else word32 T[8]; /* Copy context->state[] to working vars */ memcpy(T, state, sizeof(T)); /* 64 operations, partially loop unrolled */ for (unsigned int j=0; j<64; 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}/* // smaller but slowervoid SHA256::Transform(word32 *state, const word32 *data){ word32 T[20]; word32 W[32]; unsigned int i = 0, j = 0; word32 *t = T+8; memcpy(t, state, 8*4); word32 e = t[4], a = t[0]; do { word32 w = data[j]; W[j] = w; w += SHA256_K[j]; w += t[7]; w += S1(e); w += Ch(e, t[5], t[6]); e = t[3] + w; t[3] = t[3+8] = e; w += S0(t[0]); a = w + Maj(a, t[1], t[2]); t[-1] = t[7] = a; --t; ++j; if (j%8 == 0) t += 8; } while (j<16); do { i = j&0xf; word32 w = s1(W[i+16-2]) + s0(W[i+16-15]) + W[i] + W[i+16-7]; W[i+16] = W[i] = w; w += SHA256_K[j]; w += t[7]; w += S1(e); w += Ch(e, t[5], t[6]); e = t[3] + w; t[3] = t[3+8] = e; w += S0(t[0]); a = w + Maj(a, t[1], t[2]); t[-1] = t[7] = a; w = s1(W[(i+1)+16-2]) + s0(W[(i+1)+16-15]) + W[(i+1)] + W[(i+1)+16-7]; W[(i+1)+16] = W[(i+1)] = w; w += SHA256_K[j+1]; w += (t-1)[7]; w += S1(e); w += Ch(e, (t-1)[5], (t-1)[6]); e = (t-1)[3] + w; (t-1)[3] = (t-1)[3+8] = e; w += S0((t-1)[0]); a = w + Maj(a, (t-1)[1], (t-1)[2]); (t-1)[-1] = (t-1)[7] = a; t-=2; j+=2; if (j%8 == 0) t += 8; } while (j<64); state[0] += a; state[1] += t[1]; state[2] += t[2]; state[3] += t[3]; state[4] += e; state[5] += t[5]; state[6] += t[6]; state[7] += t[7];}*/#undef S0#undef S1#undef s0#undef s1#undef R// *************************************************************void SHA384::InitState(HashWordType *state){ static const word64 s[8] = { W64LIT(0xcbbb9d5dc1059ed8), W64LIT(0x629a292a367cd507), W64LIT(0x9159015a3070dd17), W64LIT(0x152fecd8f70e5939), W64LIT(0x67332667ffc00b31), W64LIT(0x8eb44a8768581511), W64LIT(0xdb0c2e0d64f98fa7), W64LIT(0x47b5481dbefa4fa4)}; memcpy(state, s, sizeof(s));}void SHA512::InitState(HashWordType *state){ static const word64 s[8] = { W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b), W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1), W64LIT(0x510e527fade682d1), W64LIT(0x9b05688c2b3e6c1f), W64LIT(0x1f83d9abfb41bd6b), W64LIT(0x5be0cd19137e2179)}; memcpy(state, s, sizeof(s));}#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86CRYPTOPP_ALIGN_DATA(16) static const word64 SHA512_K[80] CRYPTOPP_SECTION_ALIGN16 = {#elsestatic const word64 SHA512_K[80] = {#endif W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd), W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc), W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019), W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118), W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe), W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2), W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1), W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694), W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3), 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 versionCRYPTOPP_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( movdqa xmm0, [ecx+0*16]) AS2( movdq2q mm4, xmm0) AS2( movdqa [edi+0*16], xmm0) AS2( movdqa xmm0, [ecx+1*16]) AS2( movdqa [edi+1*16], xmm0) AS2( movdqa xmm0, [ecx+2*16]) AS2( movdq2q mm5, xmm0) AS2( movdqa [edi+2*16], xmm0) AS2( movdqa xmm0, [ecx+3*16]) AS2( movdqa [edi+3*16], xmm0) 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( movdqa xmm0, [edi+i*16])\ AS2( paddq xmm0, [ecx+i*16])\ AS2( movdqa [ecx+i*16], xmm0) SSE2_CombineState(0) SSE2_CombineState(1) SSE2_CombineState(2) SSE2_CombineState(3) 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_AVAILABLEvoid 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);}NAMESPACE_END#endif // #ifndef CRYPTOPP_GENERATE_X64_MASM#endif // #ifndef CRYPTOPP_IMPORTS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -