00001
00002
00003
00004
00005
00006
00007
00008 #include "pch.h"
00009
00010 #ifndef CRYPTOPP_IMPORTS
00011 #ifndef CRYPTOPP_GENERATE_X64_MASM
00012
00013 #include "sha.h"
00014 #include "misc.h"
00015 #include "cpu.h"
00016
00017 NAMESPACE_BEGIN(CryptoPP)
00018
00019
00020
00021 #define blk0(i) (W[i] = data[i])
00022 #define blk1(i) (W[i&15] = rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1))
00023
00024 void SHA1::InitState(HashWordType *state)
00025 {
00026 state[0] = 0x67452301L;
00027 state[1] = 0xEFCDAB89L;
00028 state[2] = 0x98BADCFEL;
00029 state[3] = 0x10325476L;
00030 state[4] = 0xC3D2E1F0L;
00031 }
00032
00033 #define f1(x,y,z) (z^(x&(y^z)))
00034 #define f2(x,y,z) (x^y^z)
00035 #define f3(x,y,z) ((x&y)|(z&(x|y)))
00036 #define f4(x,y,z) (x^y^z)
00037
00038
00039 #define R0(v,w,x,y,z,i) z+=f1(w,x,y)+blk0(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30);
00040 #define R1(v,w,x,y,z,i) z+=f1(w,x,y)+blk1(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30);
00041 #define R2(v,w,x,y,z,i) z+=f2(w,x,y)+blk1(i)+0x6ED9EBA1+rotlFixed(v,5);w=rotlFixed(w,30);
00042 #define R3(v,w,x,y,z,i) z+=f3(w,x,y)+blk1(i)+0x8F1BBCDC+rotlFixed(v,5);w=rotlFixed(w,30);
00043 #define R4(v,w,x,y,z,i) z+=f4(w,x,y)+blk1(i)+0xCA62C1D6+rotlFixed(v,5);w=rotlFixed(w,30);
00044
00045 void SHA1::Transform(word32 *state, const word32 *data)
00046 {
00047 word32 W[16];
00048
00049 word32 a = state[0];
00050 word32 b = state[1];
00051 word32 c = state[2];
00052 word32 d = state[3];
00053 word32 e = state[4];
00054
00055 R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
00056 R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
00057 R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
00058 R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
00059 R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
00060 R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
00061 R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
00062 R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
00063 R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
00064 R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
00065 R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
00066 R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
00067 R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
00068 R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
00069 R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
00070 R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
00071 R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
00072 R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
00073 R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
00074 R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
00075
00076 state[0] += a;
00077 state[1] += b;
00078 state[2] += c;
00079 state[3] += d;
00080 state[4] += e;
00081 }
00082
00083
00084
00085
00086
00087 void SHA224::InitState(HashWordType *state)
00088 {
00089 static const word32 s[8] = {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4};
00090 memcpy(state, s, sizeof(s));
00091 }
00092
00093 void SHA256::InitState(HashWordType *state)
00094 {
00095 static const word32 s[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
00096 memcpy(state, s, sizeof(s));
00097 }
00098
00099 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
00100 CRYPTOPP_ALIGN_DATA(16) extern const word32 SHA256_K[64] CRYPTOPP_SECTION_ALIGN16 = {
00101 #else
00102 extern const word32 SHA256_K[64] = {
00103 #endif
00104 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
00105 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
00106 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
00107 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
00108 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
00109 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
00110 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
00111 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
00112 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
00113 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
00114 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
00115 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
00116 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
00117 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
00118 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
00119 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
00120 };
00121
00122 #endif // #ifndef CRYPTOPP_GENERATE_X64_MASM
00123
00124 #if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_GENERATE_X64_MASM)
00125
00126 #pragma warning(disable: 4731) // frame pointer register 'ebp' modified by inline assembly code
00127
00128 static void CRYPTOPP_FASTCALL X86_SHA256_HashBlocks(word32 *state, const word32 *data, size_t len
00129 #if defined(_MSC_VER) && (_MSC_VER == 1200)
00130 , ...
00131 #endif
00132 )
00133 {
00134 #if defined(_MSC_VER) && (_MSC_VER == 1200)
00135 AS2(mov ecx, [state])
00136 AS2(mov edx, [data])
00137 #endif
00138
00139 #define LOCALS_SIZE 8*4 + 16*4 + 4*WORD_SZ
00140 #define H(i) [BASE+ASM_MOD(1024+7-(i),8)*4]
00141 #define G(i) H(i+1)
00142 #define F(i) H(i+2)
00143 #define E(i) H(i+3)
00144 #define D(i) H(i+4)
00145 #define C(i) H(i+5)
00146 #define B(i) H(i+6)
00147 #define A(i) H(i+7)
00148 #define Wt(i) BASE+8*4+ASM_MOD(1024+15-(i),16)*4
00149 #define Wt_2(i) Wt((i)-2)
00150 #define Wt_15(i) Wt((i)-15)
00151 #define Wt_7(i) Wt((i)-7)
00152 #define K_END [BASE+8*4+16*4+0*WORD_SZ]
00153 #define STATE_SAVE [BASE+8*4+16*4+1*WORD_SZ]
00154 #define DATA_SAVE [BASE+8*4+16*4+2*WORD_SZ]
00155 #define DATA_END [BASE+8*4+16*4+3*WORD_SZ]
00156 #define Kt(i) WORD_REG(si)+(i)*4
00157 #if CRYPTOPP_BOOL_X86
00158 #define BASE esp+4
00159 #elif defined(__GNUC__)
00160 #define BASE r8
00161 #else
00162 #define BASE rsp
00163 #endif
00164
00165 #define RA0(i, edx, edi) \
00166 AS2( add edx, [Kt(i)] )\
00167 AS2( add edx, [Wt(i)] )\
00168 AS2( add edx, H(i) )\
00169
00170 #define RA1(i, edx, edi)
00171
00172 #define RB0(i, edx, edi)
00173
00174 #define RB1(i, edx, edi) \
00175 AS2( mov AS_REG_7d, [Wt_2(i)] )\
00176 AS2( mov edi, [Wt_15(i)])\
00177 AS2( mov ebx, AS_REG_7d )\
00178 AS2( shr AS_REG_7d, 10 )\
00179 AS2( ror ebx, 17 )\
00180 AS2( xor AS_REG_7d, ebx )\
00181 AS2( ror ebx, 2 )\
00182 AS2( xor ebx, AS_REG_7d )\
00183 AS2( add ebx, [Wt_7(i)])\
00184 AS2( mov AS_REG_7d, edi )\
00185 AS2( shr AS_REG_7d, 3 )\
00186 AS2( ror edi, 7 )\
00187 AS2( add ebx, [Wt(i)])\
00188 AS2( xor AS_REG_7d, edi )\
00189 AS2( add edx, [Kt(i)])\
00190 AS2( ror edi, 11 )\
00191 AS2( add edx, H(i) )\
00192 AS2( xor AS_REG_7d, edi )\
00193 AS2( add AS_REG_7d, ebx )\
00194 AS2( mov [Wt(i)], AS_REG_7d)\
00195 AS2( add edx, AS_REG_7d )\
00196
00197 #define ROUND(i, r, eax, ecx, edi, edx)\
00198 \
00199 \
00200 AS2( mov edx, F(i) )\
00201 AS2( xor edx, G(i) )\
00202 AS2( and edx, edi )\
00203 AS2( xor edx, G(i) )\
00204 AS2( mov AS_REG_7d, edi )\
00205 AS2( ror edi, 6 )\
00206 AS2( ror AS_REG_7d, 25 )\
00207 RA##r(i, edx, edi )\
00208 AS2( xor AS_REG_7d, edi )\
00209 AS2( ror edi, 5 )\
00210 AS2( xor AS_REG_7d, edi )\
00211 AS2( add edx, AS_REG_7d )\
00212 RB##r(i, edx, edi )\
00213 \
00214 \
00215 AS2( mov ebx, ecx )\
00216 AS2( xor ecx, B(i) )\
00217 AS2( and eax, ecx )\
00218 AS2( xor eax, B(i) )\
00219 AS2( mov AS_REG_7d, ebx )\
00220 AS2( ror ebx, 2 )\
00221 AS2( add eax, edx )\
00222 AS2( add edx, D(i) )\
00223 AS2( mov D(i), edx )\
00224 AS2( ror AS_REG_7d, 22 )\
00225 AS2( xor AS_REG_7d, ebx )\
00226 AS2( ror ebx, 11 )\
00227 AS2( xor AS_REG_7d, ebx )\
00228 AS2( add eax, AS_REG_7d )\
00229 AS2( mov H(i), eax )\
00230
00231 #define SWAP_COPY(i) \
00232 AS2( mov WORD_REG(bx), [WORD_REG(dx)+i*WORD_SZ])\
00233 AS1( bswap WORD_REG(bx))\
00234 AS2( mov [Wt(i*(1+CRYPTOPP_BOOL_X64)+CRYPTOPP_BOOL_X64)], WORD_REG(bx))
00235
00236 #if defined(__GNUC__)
00237 #if CRYPTOPP_BOOL_X64
00238 FixedSizeAlignedSecBlock<byte, LOCALS_SIZE> workspace;
00239 #endif
00240 __asm__ __volatile__
00241 (
00242 #if CRYPTOPP_BOOL_X64
00243 "lea %4, %%r8;"
00244 #endif
00245 ".intel_syntax noprefix;"
00246 #elif defined(CRYPTOPP_GENERATE_X64_MASM)
00247 ALIGN 8
00248 X86_SHA256_HashBlocks PROC FRAME
00249 rex_push_reg rsi
00250 push_reg rdi
00251 push_reg rbx
00252 push_reg rbp
00253 alloc_stack(LOCALS_SIZE+8)
00254 .endprolog
00255 mov rdi, r8
00256 lea rsi, [?SHA256_K@CryptoPP@@3QBIB + 48*4]
00257 #endif
00258
00259 #if CRYPTOPP_BOOL_X86
00260 #ifndef __GNUC__
00261 AS2( mov edi, [len])
00262 AS2( lea WORD_REG(si), [SHA256_K+48*4])
00263 #endif
00264 #if !defined(_MSC_VER) || (_MSC_VER < 1400)
00265 AS_PUSH_IF86(bx)
00266 #endif
00267
00268 AS_PUSH_IF86(bp)
00269 AS2( mov ebx, esp)
00270 AS2( and esp, -16)
00271 AS2( sub WORD_REG(sp), LOCALS_SIZE)
00272 AS_PUSH_IF86(bx)
00273 #endif
00274 AS2( mov STATE_SAVE, WORD_REG(cx))
00275 AS2( mov DATA_SAVE, WORD_REG(dx))
00276 AS2( add WORD_REG(di), WORD_REG(dx))
00277 AS2( mov DATA_END, WORD_REG(di))
00278 AS2( mov K_END, WORD_REG(si))
00279
00280 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
00281 #if CRYPTOPP_BOOL_X86
00282 AS2( test edi, 1)
00283 ASJ( jnz, 2, f)
00284 #endif
00285 AS2( movdqa xmm0, XMMWORD_PTR [WORD_REG(cx)+0*16])
00286 AS2( movdqa xmm1, XMMWORD_PTR [WORD_REG(cx)+1*16])
00287 #endif
00288
00289 #if CRYPTOPP_BOOL_X86
00290 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
00291 ASJ( jmp, 0, f)
00292 #endif
00293 ASL(2)
00294 AS2( mov esi, ecx)
00295 AS2( lea edi, A(0))
00296 AS2( mov ecx, 8)
00297 AS1( rep movsd)
00298 AS2( mov esi, K_END)
00299 ASJ( jmp, 3, f)
00300 #endif
00301
00302 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
00303 ASL(0)
00304 AS2( movdqa E(0), xmm1)
00305 AS2( movdqa A(0), xmm0)
00306 #endif
00307 #if CRYPTOPP_BOOL_X86
00308 ASL(3)
00309 #endif
00310 AS2( sub WORD_REG(si), 48*4)
00311 SWAP_COPY(0) SWAP_COPY(1) SWAP_COPY(2) SWAP_COPY(3)
00312 SWAP_COPY(4) SWAP_COPY(5) SWAP_COPY(6) SWAP_COPY(7)
00313 #if CRYPTOPP_BOOL_X86
00314 SWAP_COPY(8) SWAP_COPY(9) SWAP_COPY(10) SWAP_COPY(11)
00315 SWAP_COPY(12) SWAP_COPY(13) SWAP_COPY(14) SWAP_COPY(15)
00316 #endif
00317 AS2( mov edi, E(0))
00318 AS2( mov eax, B(0))
00319 AS2( xor eax, C(0))
00320 AS2( mov ecx, A(0))
00321
00322 ROUND(0, 0, eax, ecx, edi, edx)
00323 ROUND(1, 0, ecx, eax, edx, edi)
00324 ROUND(2, 0, eax, ecx, edi, edx)
00325 ROUND(3, 0, ecx, eax, edx, edi)
00326 ROUND(4, 0, eax, ecx, edi, edx)
00327 ROUND(5, 0, ecx, eax, edx, edi)
00328 ROUND(6, 0, eax, ecx, edi, edx)
00329 ROUND(7, 0, ecx, eax, edx, edi)
00330 ROUND(8, 0, eax, ecx, edi, edx)
00331 ROUND(9, 0, ecx, eax, edx, edi)
00332 ROUND(10, 0, eax, ecx, edi, edx)
00333 ROUND(11, 0, ecx, eax, edx, edi)
00334 ROUND(12, 0, eax, ecx, edi, edx)
00335 ROUND(13, 0, ecx, eax, edx, edi)
00336 ROUND(14, 0, eax, ecx, edi, edx)
00337 ROUND(15, 0, ecx, eax, edx, edi)
00338
00339 ASL(1)
00340 AS2(add WORD_REG(si), 4*16)
00341 ROUND(0, 1, eax, ecx, edi, edx)
00342 ROUND(1, 1, ecx, eax, edx, edi)
00343 ROUND(2, 1, eax, ecx, edi, edx)
00344 ROUND(3, 1, ecx, eax, edx, edi)
00345 ROUND(4, 1, eax, ecx, edi, edx)
00346 ROUND(5, 1, ecx, eax, edx, edi)
00347 ROUND(6, 1, eax, ecx, edi, edx)
00348 ROUND(7, 1, ecx, eax, edx, edi)
00349 ROUND(8, 1, eax, ecx, edi, edx)
00350 ROUND(9, 1, ecx, eax, edx, edi)
00351 ROUND(10, 1, eax, ecx, edi, edx)
00352 ROUND(11, 1, ecx, eax, edx, edi)
00353 ROUND(12, 1, eax, ecx, edi, edx)
00354 ROUND(13, 1, ecx, eax, edx, edi)
00355 ROUND(14, 1, eax, ecx, edi, edx)
00356 ROUND(15, 1, ecx, eax, edx, edi)
00357 AS2( cmp WORD_REG(si), K_END)
00358 ASJ( jne, 1, b)
00359
00360 AS2( mov WORD_REG(dx), DATA_SAVE)
00361 AS2( add WORD_REG(dx), 64)
00362 AS2( mov AS_REG_7, STATE_SAVE)
00363 AS2( mov DATA_SAVE, WORD_REG(dx))
00364
00365 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
00366 #if CRYPTOPP_BOOL_X86
00367 AS2( test DWORD PTR DATA_END, 1)
00368 ASJ( jnz, 4, f)
00369 #endif
00370 AS2( movdqa xmm1, XMMWORD_PTR [AS_REG_7+1*16])
00371 AS2( movdqa xmm0, XMMWORD_PTR [AS_REG_7+0*16])
00372 AS2( paddd xmm1, E(0))
00373 AS2( paddd xmm0, A(0))
00374 AS2( movdqa [AS_REG_7+1*16], xmm1)
00375 AS2( movdqa [AS_REG_7+0*16], xmm0)
00376 AS2( cmp WORD_REG(dx), DATA_END)
00377 ASJ( jl, 0, b)
00378 #endif
00379
00380 #if CRYPTOPP_BOOL_X86
00381 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
00382 ASJ( jmp, 5, f)
00383 ASL(4)
00384 #endif
00385 AS2( add [AS_REG_7+0*4], ecx)
00386 AS2( add [AS_REG_7+4*4], edi)
00387 AS2( mov eax, B(0))
00388 AS2( mov ebx, C(0))
00389 AS2( mov ecx, D(0))
00390 AS2( add [AS_REG_7+1*4], eax)
00391 AS2( add [AS_REG_7+2*4], ebx)
00392 AS2( add [AS_REG_7+3*4], ecx)
00393 AS2( mov eax, F(0))
00394 AS2( mov ebx, G(0))
00395 AS2( mov ecx, H(0))
00396 AS2( add [AS_REG_7+5*4], eax)
00397 AS2( add [AS_REG_7+6*4], ebx)
00398 AS2( add [AS_REG_7+7*4], ecx)
00399 AS2( mov ecx, AS_REG_7d)
00400 AS2( cmp WORD_REG(dx), DATA_END)
00401 ASJ( jl, 2, b)
00402 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
00403 ASL(5)
00404 #endif
00405 #endif
00406
00407 AS_POP_IF86(sp)
00408 AS_POP_IF86(bp)
00409 #if !defined(_MSC_VER) || (_MSC_VER < 1400)
00410 AS_POP_IF86(bx)
00411 #endif
00412
00413 #ifdef CRYPTOPP_GENERATE_X64_MASM
00414 add rsp, LOCALS_SIZE+8
00415 pop rbp
00416 pop rbx
00417 pop rdi
00418 pop rsi
00419 ret
00420 X86_SHA256_HashBlocks ENDP
00421 #endif
00422
00423 #ifdef __GNUC__
00424 ".att_syntax prefix;"
00425 :
00426 : "c" (state), "d" (data), "S" (SHA256_K+48), "D" (len)
00427 #if CRYPTOPP_BOOL_X64
00428 , "m" (workspace[0])
00429 #endif
00430 : "memory", "cc", "%eax"
00431 #if CRYPTOPP_BOOL_X64
00432 , "%rbx", "%r8"
00433 #endif
00434 );
00435 #endif
00436 }
00437
00438 #endif // #if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_GENERATE_X64_MASM)
00439
00440 #ifndef CRYPTOPP_GENERATE_X64_MASM
00441
00442 #ifdef CRYPTOPP_X64_MASM_AVAILABLE
00443 extern "C" {
00444 void CRYPTOPP_FASTCALL X86_SHA256_HashBlocks(word32 *state, const word32 *data, size_t len);
00445 }
00446 #endif
00447
00448 #if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_X64_MASM_AVAILABLE)
00449
00450 size_t SHA256::HashMultipleBlocks(const word32 *input, size_t length)
00451 {
00452 X86_SHA256_HashBlocks(m_state, input, (length&(size_t(0)-BLOCKSIZE)) - !HasSSE2());
00453 return length % BLOCKSIZE;
00454 }
00455
00456 size_t SHA224::HashMultipleBlocks(const word32 *input, size_t length)
00457 {
00458 X86_SHA256_HashBlocks(m_state, input, (length&(size_t(0)-BLOCKSIZE)) - !HasSSE2());
00459 return length % BLOCKSIZE;
00460 }
00461
00462 #endif
00463
00464 #define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15]))
00465
00466 #define Ch(x,y,z) (z^(x&(y^z)))
00467 #define Maj(x,y,z) (y^((x^y)&(y^z)))
00468
00469 #define a(i) T[(0-i)&7]
00470 #define b(i) T[(1-i)&7]
00471 #define c(i) T[(2-i)&7]
00472 #define d(i) T[(3-i)&7]
00473 #define e(i) T[(4-i)&7]
00474 #define f(i) T[(5-i)&7]
00475 #define g(i) T[(6-i)&7]
00476 #define h(i) T[(7-i)&7]
00477
00478 #define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA256_K[i+j]+(j?blk2(i):blk0(i));\
00479 d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i))
00480
00481
00482 #define S0(x) (rotrFixed(x,2)^rotrFixed(x,13)^rotrFixed(x,22))
00483 #define S1(x) (rotrFixed(x,6)^rotrFixed(x,11)^rotrFixed(x,25))
00484 #define s0(x) (rotrFixed(x,7)^rotrFixed(x,18)^(x>>3))
00485 #define s1(x) (rotrFixed(x,17)^rotrFixed(x,19)^(x>>10))
00486
00487 void SHA256::Transform(word32 *state, const word32 *data)
00488 {
00489 word32 W[16];
00490 #if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_X64_MASM_AVAILABLE)
00491
00492 ByteReverse(W, data, BLOCKSIZE);
00493 X86_SHA256_HashBlocks(state, W, BLOCKSIZE - !HasSSE2());
00494 #else
00495 word32 T[8];
00496
00497 memcpy(T, state, sizeof(T));
00498
00499 for (unsigned int j=0; j<64; j+=16)
00500 {
00501 R( 0); R( 1); R( 2); R( 3);
00502 R( 4); R( 5); R( 6); R( 7);
00503 R( 8); R( 9); R(10); R(11);
00504 R(12); R(13); R(14); R(15);
00505 }
00506
00507 state[0] += a(0);
00508 state[1] += b(0);
00509 state[2] += c(0);
00510 state[3] += d(0);
00511 state[4] += e(0);
00512 state[5] += f(0);
00513 state[6] += g(0);
00514 state[7] += h(0);
00515 #endif
00516 }
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593 #undef S0
00594 #undef S1
00595 #undef s0
00596 #undef s1
00597 #undef R
00598
00599
00600
00601 void SHA384::InitState(HashWordType *state)
00602 {
00603 static const word64 s[8] = {
00604 W64LIT(0xcbbb9d5dc1059ed8), W64LIT(0x629a292a367cd507),
00605 W64LIT(0x9159015a3070dd17), W64LIT(0x152fecd8f70e5939),
00606 W64LIT(0x67332667ffc00b31), W64LIT(0x8eb44a8768581511),
00607 W64LIT(0xdb0c2e0d64f98fa7), W64LIT(0x47b5481dbefa4fa4)};
00608 memcpy(state, s, sizeof(s));
00609 }
00610
00611 void SHA512::InitState(HashWordType *state)
00612 {
00613 static const word64 s[8] = {
00614 W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b),
00615 W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1),
00616 W64LIT(0x510e527fade682d1), W64LIT(0x9b05688c2b3e6c1f),
00617 W64LIT(0x1f83d9abfb41bd6b), W64LIT(0x5be0cd19137e2179)};
00618 memcpy(state, s, sizeof(s));
00619 }
00620
00621 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86
00622 CRYPTOPP_ALIGN_DATA(16) static const word64 SHA512_K[80] CRYPTOPP_SECTION_ALIGN16 = {
00623 #else
00624 static const word64 SHA512_K[80] = {
00625 #endif
00626 W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd),
00627 W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc),
00628 W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019),
00629 W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118),
00630 W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe),
00631 W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2),
00632 W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1),
00633 W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694),
00634 W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3),
00635 W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65),
00636 W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483),
00637 W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5),
00638 W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210),
00639 W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4),
00640 W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725),
00641 W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70),
00642 W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926),
00643 W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df),
00644 W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8),
00645 W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b),
00646 W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001),
00647 W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30),
00648 W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910),
00649 W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8),
00650 W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53),
00651 W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8),
00652 W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb),
00653 W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3),
00654 W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60),
00655 W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec),
00656 W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9),
00657 W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b),
00658 W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207),
00659 W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178),
00660 W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6),
00661 W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b),
00662 W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493),
00663 W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c),
00664 W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a),
00665 W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817)
00666 };
00667
00668 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86
00669
00670 CRYPTOPP_NAKED static void CRYPTOPP_FASTCALL SHA512_SSE2_Transform(word64 *state, const word64 *data)
00671 {
00672 #ifdef __GNUC__
00673 __asm__ __volatile__
00674 (
00675 ".intel_syntax noprefix;"
00676 AS1( push ebx)
00677 AS2( mov ebx, eax)
00678 #else
00679 AS1( push ebx)
00680 AS1( push esi)
00681 AS1( push edi)
00682 AS2( lea ebx, SHA512_K)
00683 #endif
00684
00685 AS2( mov eax, esp)
00686 AS2( and esp, 0xfffffff0)
00687 AS2( sub esp, 27*16)
00688 AS1( push eax)
00689 AS2( xor eax, eax)
00690 AS2( lea edi, [esp+4+8*8])
00691 AS2( lea esi, [esp+4+20*8+8])
00692
00693 AS2( movdqa xmm0, [ecx+0*16])
00694 AS2( movdq2q mm4, xmm0)
00695 AS2( movdqa [edi+0*16], xmm0)
00696 AS2( movdqa xmm0, [ecx+1*16])
00697 AS2( movdqa [edi+1*16], xmm0)
00698 AS2( movdqa xmm0, [ecx+2*16])
00699 AS2( movdq2q mm5, xmm0)
00700 AS2( movdqa [edi+2*16], xmm0)
00701 AS2( movdqa xmm0, [ecx+3*16])
00702 AS2( movdqa [edi+3*16], xmm0)
00703 ASJ( jmp, 0, f)
00704
00705 #define SSE2_S0_S1(r, a, b, c) \
00706 AS2( movq mm6, r)\
00707 AS2( psrlq r, a)\
00708 AS2( movq mm7, r)\
00709 AS2( psllq mm6, 64-c)\
00710 AS2( pxor mm7, mm6)\
00711 AS2( psrlq r, b-a)\
00712 AS2( pxor mm7, r)\
00713 AS2( psllq mm6, c-b)\
00714 AS2( pxor mm7, mm6)\
00715 AS2( psrlq r, c-b)\
00716 AS2( pxor r, mm7)\
00717 AS2( psllq mm6, b-a)\
00718 AS2( pxor r, mm6)
00719
00720 #define SSE2_s0(r, a, b, c) \
00721 AS2( movdqa xmm6, r)\
00722 AS2( psrlq r, a)\
00723 AS2( movdqa xmm7, r)\
00724 AS2( psllq xmm6, 64-c)\
00725 AS2( pxor xmm7, xmm6)\
00726 AS2( psrlq r, b-a)\
00727 AS2( pxor xmm7, r)\
00728 AS2( psrlq r, c-b)\
00729 AS2( pxor r, xmm7)\
00730 AS2( psllq xmm6, c-a)\
00731 AS2( pxor r, xmm6)
00732
00733 #define SSE2_s1(r, a, b, c) \
00734 AS2( movdqa xmm6, r)\
00735 AS2( psrlq r, a)\
00736 AS2( movdqa xmm7, r)\
00737 AS2( psllq xmm6, 64-c)\
00738 AS2( pxor xmm7, xmm6)\
00739 AS2( psrlq r, b-a)\
00740 AS2( pxor xmm7, r)\
00741 AS2( psllq xmm6, c-b)\
00742 AS2( pxor xmm7, xmm6)\
00743 AS2( psrlq r, c-b)\
00744 AS2( pxor r, xmm7)
00745
00746 ASL(SHA512_Round)
00747
00748 AS2( paddq mm0, [edi+7*8])
00749 AS2( movq mm2, [edi+5*8])
00750 AS2( movq mm3, [edi+6*8])
00751 AS2( pxor mm2, mm3)
00752 AS2( pand mm2, mm5)
00753 SSE2_S0_S1(mm5,14,18,41)
00754 AS2( pxor mm2, mm3)
00755 AS2( paddq mm0, mm2)
00756 AS2( paddq mm5, mm0)
00757 AS2( movq mm2, [edi+1*8])
00758 AS2( movq mm1, mm2)
00759 AS2( por mm2, mm4)
00760 AS2( pand mm2, [edi+2*8])
00761 AS2( pand mm1, mm4)
00762 AS2( por mm1, mm2)
00763 AS2( paddq mm1, mm5)
00764 AS2( paddq mm5, [edi+3*8])
00765 AS2( movq [edi+3*8], mm5)
00766 AS2( movq [edi+11*8], mm5)
00767 SSE2_S0_S1(mm4,28,34,39)
00768 AS2( paddq mm4, mm1)
00769 AS2( movq [edi-8], mm4)
00770 AS2( movq [edi+7*8], mm4)
00771 AS1( ret)
00772
00773
00774 ASL(0)
00775 AS2( movq mm0, [edx+eax*8])
00776 AS2( movq [esi+eax*8], mm0)
00777 AS2( movq [esi+eax*8+16*8], mm0)
00778 AS2( paddq mm0, [ebx+eax*8])
00779 ASC( call, SHA512_Round)
00780 AS1( inc eax)
00781 AS2( sub edi, 8)
00782 AS2( test eax, 7)
00783 ASJ( jnz, 0, b)
00784 AS2( add edi, 8*8)
00785 AS2( cmp eax, 16)
00786 ASJ( jne, 0, b)
00787
00788
00789 AS2( movdqu xmm0, [esi+(16-2)*8])
00790 ASL(1)
00791
00792 AS2( movdqu xmm3, [esi])
00793 AS2( paddq xmm3, [esi+(16-7)*8])
00794 AS2( movdqa xmm2, [esi+(16-15)*8])
00795 SSE2_s1(xmm0, 6, 19, 61)
00796 AS2( paddq xmm0, xmm3)
00797 SSE2_s0(xmm2, 1, 7, 8)
00798 AS2( paddq xmm0, xmm2)
00799 AS2( movdq2q mm0, xmm0)
00800 AS2( movhlps xmm1, xmm0)
00801 AS2( paddq mm0, [ebx+eax*8])
00802 AS2( movlps [esi], xmm0)
00803 AS2( movlps [esi+8], xmm1)
00804 AS2( movlps [esi+8*16], xmm0)
00805 AS2( movlps [esi+8*17], xmm1)
00806
00807 ASC( call, SHA512_Round)
00808 AS2( sub edi, 8)
00809 AS2( movdq2q mm0, xmm1)
00810 AS2( paddq mm0, [ebx+eax*8+8])
00811 ASC( call, SHA512_Round)
00812
00813 AS2( add esi, 16)
00814 AS2( add eax, 2)
00815 AS2( sub edi, 8)
00816 AS2( test eax, 7)
00817 ASJ( jnz, 1, b)
00818
00819 AS2( mov esi, 0xf)
00820 AS2( and esi, eax)
00821 AS2( lea esi, [esp+4+20*8+8+esi*8])
00822 AS2( add edi, 8*8)
00823 AS2( cmp eax, 80)
00824 ASJ( jne, 1, b)
00825
00826 #define SSE2_CombineState(i) \
00827 AS2( movdqa xmm0, [edi+i*16])\
00828 AS2( paddq xmm0, [ecx+i*16])\
00829 AS2( movdqa [ecx+i*16], xmm0)
00830
00831 SSE2_CombineState(0)
00832 SSE2_CombineState(1)
00833 SSE2_CombineState(2)
00834 SSE2_CombineState(3)
00835
00836 AS1( pop esp)
00837 AS1( emms)
00838
00839 #if defined(__GNUC__)
00840 AS1( pop ebx)
00841 ".att_syntax prefix;"
00842 :
00843 : "a" (SHA512_K), "c" (state), "d" (data)
00844 : "%esi", "%edi", "memory", "cc"
00845 );
00846 #else
00847 AS1( pop edi)
00848 AS1( pop esi)
00849 AS1( pop ebx)
00850 AS1( ret)
00851 #endif
00852 }
00853 #endif // #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
00854
00855 void SHA512::Transform(word64 *state, const word64 *data)
00856 {
00857 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86
00858 if (HasSSE2())
00859 {
00860 SHA512_SSE2_Transform(state, data);
00861 return;
00862 }
00863 #endif
00864
00865 #define S0(x) (rotrFixed(x,28)^rotrFixed(x,34)^rotrFixed(x,39))
00866 #define S1(x) (rotrFixed(x,14)^rotrFixed(x,18)^rotrFixed(x,41))
00867 #define s0(x) (rotrFixed(x,1)^rotrFixed(x,8)^(x>>7))
00868 #define s1(x) (rotrFixed(x,19)^rotrFixed(x,61)^(x>>6))
00869
00870 #define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA512_K[i+j]+(j?blk2(i):blk0(i));\
00871 d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i))
00872
00873 word64 W[16];
00874 word64 T[8];
00875
00876 memcpy(T, state, sizeof(T));
00877
00878 for (unsigned int j=0; j<80; j+=16)
00879 {
00880 R( 0); R( 1); R( 2); R( 3);
00881 R( 4); R( 5); R( 6); R( 7);
00882 R( 8); R( 9); R(10); R(11);
00883 R(12); R(13); R(14); R(15);
00884 }
00885
00886 state[0] += a(0);
00887 state[1] += b(0);
00888 state[2] += c(0);
00889 state[3] += d(0);
00890 state[4] += e(0);
00891 state[5] += f(0);
00892 state[6] += g(0);
00893 state[7] += h(0);
00894 }
00895
00896 NAMESPACE_END
00897
00898 #endif // #ifndef CRYPTOPP_GENERATE_X64_MASM
00899 #endif // #ifndef CRYPTOPP_IMPORTS