メインページ | アルファベット順一覧 | 構成 | ファイル一覧 | 構成メンバ | ファイルメンバ | 関連ページ

dkcSHA512.c

説明を見る。
00001 
00008 #define DKUTIL_C_SHA512_C
00009 
00010 #include "dkcSHA512.h"
00011 #include "dkcStdio.h"
00012 
00013 #define SHA512_BUFFER_SIZE (SHA512_BLOCK * 8)
00014 
00015 
00016 
00017 
00018 const static QWORD c_qwInitH[SHA512_HASH] = {
00019     0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
00020     0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,
00021 };
00022 
00023 const static QWORD c_qwK[SHA512_WORK] = {
00024     0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,
00025     0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
00026     0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
00027     0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694,
00028     0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
00029     0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
00030     0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4,
00031     0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70,
00032     0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
00033     0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
00034     0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30,
00035     0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
00036     0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8,
00037     0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,
00038     0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
00039     0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b,
00040     0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178,
00041     0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
00042     0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,
00043     0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817,
00044 };
00045 
00046 
00047 
00048 #define cpuid __asm __emit 0fh __asm __emit 0a2h
00049 
00050 static DKC_INLINE BOOL CheckMMX(void)
00051 {
00052     return dkcIsMMX();
00053 }
00054 
00055 
00056 static DKC_INLINE DWORD ReverseEndianDWORD(DWORD x) {
00057     return dkcReverseEndian32(x);
00058 }
00059 static DKC_INLINE QWORD ReverseEndianQWORD(QWORD x) {
00060     return dkcReverseEndian64(x);
00061 }
00062 static DKC_INLINE QWORD Rotate(QWORD x, DWORD n) {return (x >> n) | (x << (64 - n));}
00063 static DKC_INLINE QWORD Ch(QWORD x, QWORD y, QWORD z) {return (x & (y ^ z)) ^ z;}
00064 static DKC_INLINE QWORD Maj(QWORD x, QWORD y, QWORD z) {return (x & (y | z)) | (y & z);}
00065 static DKC_INLINE QWORD S0(QWORD x) {return Rotate(x, 28) ^ Rotate(x, 34) ^ Rotate(x, 39);}
00066 static DKC_INLINE QWORD S1(QWORD x) {return Rotate(x, 14) ^ Rotate(x, 18) ^ Rotate(x, 41);}
00067 static DKC_INLINE QWORD s0(QWORD x) {return Rotate(x,  1) ^ Rotate(x,  8) ^ (x >> 7);}
00068 static DKC_INLINE QWORD s1(QWORD x) {return Rotate(x, 19) ^ Rotate(x, 61) ^ (x >> 6);}
00069 
00070 //プロトタイプ宣言
00071 static DKC_INLINE void Generate(DKC_SHA512 *);
00072 static DKC_INLINE void MMX_Generate(DKC_SHA512 *);
00073 
00074 static DKC_INLINE void Default_Generate(DKC_SHA512 *p){
00075     int i;
00076     QWORD W[SHA512_WORK];
00077     QWORD Hash[SHA512_WORK + SHA512_HASH];
00078     QWORD *pHash = &Hash[SHA512_WORK];
00079     QWORD qwT1, qwT2;
00080     for(i = 0; i < SHA512_HASH; i++) Hash[SHA512_WORK + i] = p->m_qwH[i];
00081     for(i = 0; i < SHA512_BLOCK; i++) W[i] = ReverseEndianQWORD(p->m_aBlock[i]);
00082     for(i = SHA512_BLOCK; i < SHA512_WORK; i++) W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
00083     for(i = 0; i < SHA512_WORK; i++){
00084         pHash--;
00085         qwT1 = pHash[8] + S1(pHash[5]) + Ch(pHash[5], pHash[6], pHash[7]) + c_qwK[i] + W[i];
00086         qwT2 = S0(pHash[1]) + Maj(pHash[1], pHash[2], pHash[3]);
00087         pHash[4] += qwT1;
00088         pHash[0] = qwT1 + qwT2;
00089     }
00090     for(i = 0; i < SHA512_HASH; i++) p->m_qwH[i] += Hash[i];
00091 }
00092 
00093 #ifdef _MSC_VER
00094 
00095 static DKC_INLINE void MMX_Generate(DKC_SHA512 *p)
00096 {
00097     int i;
00098     QWORD W[SHA512_WORK];
00099     QWORD Hash[SHA512_WORK + SHA512_HASH];
00100     QWORD *pBlock;
00101     for(i = 0; i < SHA512_HASH; i++) Hash[SHA512_WORK + i] = p->m_qwH[i];
00102 
00103     pBlock = &(p->m_aBlock[0]);
00104 
00105     __asm{
00107         // ReverseEndian
00109         mov     esi, pBlock
00110         add     esi, SHA512_BLOCK*8
00111         lea     edi, W
00112         add     edi, SHA512_BLOCK*8
00113         mov     ecx, -SHA512_BLOCK
00114     loopR:
00115         mov     eax, [esi+ecx*8]
00116         mov     ebx, [esi+ecx*8+4]
00117         bswap   eax
00118         bswap   ebx
00119         mov     [edi+ecx*8],   ebx
00120         mov     [edi+ecx*8+4], eax
00121         inc     ecx
00122         jnz     loopR
00123         
00125         // W
00127         lea     esi, W
00128         add     esi, SHA512_BLOCK*8
00129         add     esi, (SHA512_WORK - SHA512_BLOCK)*8
00130         mov     ecx, -(SHA512_WORK - SHA512_BLOCK)
00131     loop0:
00133         // W7+W16
00135         movq    mm0, [esi+ecx*8-7*8]
00136         nop
00137         movq    mm1, [esi+ecx*8-16*8]
00138         movq    mm2, mm0
00139         movq    mm3, mm0
00140         pxor    mm2, mm1
00141         pand    mm3, mm1
00142         psrld   mm2, 1
00143         paddd   mm3, mm2
00144         paddd   mm0, mm1
00146                                         // s1
00148                                         movq    mm5, [esi+ecx*8-2*8]
00149         psrld   mm3, 31
00150         psllq   mm3, 32
00151                                         movq    mm4, mm5
00152         paddd   mm0, mm3
00153                                         psllq   mm4, 3
00154                                         movq    mm6, mm4
00155                                         psllq   mm4, (45-3)
00156                                         pxor    mm6, mm4
00157                                         psrlq   mm5, 6
00158                                         pxor    mm6, mm5
00159                                         psrlq   mm5, (19-6)
00161         // s0
00163         movq    mm1, [esi+ecx*8-15*8]
00164                                         pxor    mm6, mm5
00165                                         psrlq   mm5, (61-19)
00166         movq    mm4, mm1
00167                                         pxor    mm6, mm5 // mm6 = s1
00168         psllq   mm4, 56
00169         movq    mm7, mm4
00170         psllq   mm4, (63-56)
00171         pxor    mm7, mm4
00172         psrlq   mm1, 1
00173         pxor    mm7, mm1
00175                                         // +s1
00177                                         movq    mm2, mm6
00178                                         movq    mm3, mm6
00179                                         pxor    mm2, mm0
00180                                         pand    mm3, mm0
00181                                         psrld   mm2, 1
00182                                         paddd   mm3, mm2
00183         psrlq   mm1, (7-1)
00184         pxor    mm7, mm1
00185                                         psrld   mm3, 31
00186                                         paddd   mm0, mm6
00187         psrlq   mm1, (8-7)
00188         pxor    mm7, mm1 // mm7 = s0
00189                                         psllq   mm3, 32
00191         // +s0
00193         movq    mm4, mm7
00194                                         paddd   mm0, mm3
00195         movq    mm5, mm7
00196         pxor    mm4, mm0
00197         pand    mm5, mm0
00198         psrld   mm4, 1
00199         paddd   mm5, mm4
00200         paddd   mm0, mm7
00201         psrld   mm5, 31
00202         psllq   mm5, 32
00203         paddd   mm0, mm5
00204         movq    [esi+ecx*8], mm0
00205         inc     ecx
00206         jnz     loop0
00207 
00208 
00210         // H
00212         lea     ebx, c_qwK
00213         add     ebx, SHA512_WORK*8
00214         lea     esi, W
00215         add     esi, SHA512_WORK*8
00216         lea     edi, Hash
00217         add     edi, -8
00218         mov     ecx, -SHA512_WORK
00219         mov     edx, SHA512_WORK
00220     loop1:
00222         // H8+K
00224         movq    mm0, [edi+edx*8+8*8] // H8
00225         nop
00226         movq    mm1, [ebx+ecx*8]     // K
00227         movq    mm2, mm0
00228         movq    mm3, mm0
00229         pxor    mm2, mm1
00230         pand    mm3, mm1
00231         psrld   mm2, 1
00232         paddd   mm0, mm1
00233         paddd   mm3, mm2
00235                                         // Ch
00237                                         movq    mm5, [edi+edx*8+5*8]
00238         psrld   mm3, 31
00239                                         movq    mm6, [edi+edx*8+6*8]
00240         psllq   mm3, 32
00241                                         movq    mm7, [edi+edx*8+7*8]
00242         paddd   mm0, mm3
00244         // +W
00246         movq    mm1, [esi+ecx*8]     // W
00247                                         pxor    mm6, mm7
00248         movq    mm2, mm1
00249                                         pand    mm6, mm5
00250         movq    mm3, mm1
00251         pxor    mm2, mm0
00252         pand    mm3, mm0
00253         psrld   mm2, 1
00254         paddd   mm0, mm1
00255         paddd   mm3, mm2
00256         psrld   mm3, 31
00257                                         pxor    mm7, mm6 // mm7 = Ch
00258         psllq   mm3, 32
00260                                         // S1
00262                                         movq    mm4, mm5
00263                                         psllq   mm4, 23
00264         paddd   mm0, mm3
00265                                         movq    mm6, mm4
00266                                         psllq   mm4, (46-23)
00267                                         pxor    mm6, mm4
00268                                         psllq   mm4, (50-46)
00269                                         pxor    mm6, mm4
00270                                         psrlq   mm5, 14
00271                                         pxor    mm6, mm5
00272                                         psrlq   mm5, (18-14)
00273                                         pxor    mm6, mm5
00274                                         psrlq   mm5, (41-18)
00275                                         pxor    mm6, mm5 // mm6 = S1
00277         // +Ch
00279         movq    mm2, mm7
00280         movq    mm3, mm7
00281         pxor    mm2, mm0
00282         pand    mm3, mm0
00283         psrld   mm2, 1
00285                                         // Maj
00287                                         movq    mm4, [edi+edx*8+1*8]
00288         paddd   mm0, mm7
00289                                         movq    mm1, [edi+edx*8+2*8]
00290         paddd   mm3, mm2
00291                                         movq    mm5, [edi+edx*8+3*8]
00292         psrld   mm3, 31
00293                                         movq    mm7, mm5
00294         psllq   mm3, 32
00295                                         por     mm7, mm1 // y | z
00296         paddd   mm0, mm3
00298         // +S1
00300         movq    mm2, mm6
00301         movq    mm3, mm6
00302         pxor    mm2, mm0
00303         pand    mm3, mm0
00304         psrld   mm2, 1
00305         paddd   mm0, mm6
00306         paddd   mm3, mm2
00307                                         pand    mm1, mm5 // y & z
00308         psrld   mm3, 31
00309                                         pand    mm7, mm4 // & x
00310         psllq   mm3, 32
00311                                         por     mm7, mm1 // mm7 = Maj
00313                                         // S0
00315                                         movq    mm5, mm4
00316         paddd   mm0, mm3
00317                                         psllq   mm4, 25
00318         movq    mm1, mm0 //T2=mm0, T1=mm1
00319                                         movq    mm6, mm4
00320                                         psllq   mm4, (30-25)
00321                                         pxor    mm6, mm4
00322                                         psllq   mm4, (36-30)
00323                                         pxor    mm6, mm4
00324                                         psrlq   mm5, 28
00325                                         pxor    mm6, mm5
00326                                         psrlq   mm5, (34-28)
00327                                         pxor    mm6, mm5
00328                                         psrlq   mm5, (39-34)
00329                                         pxor    mm6, mm5 //mm6 = S0
00331         // +Maj
00333         movq    mm2, mm7
00334         movq    mm3, mm7
00335         pxor    mm2, mm0
00336         pand    mm3, mm0
00337         psrld   mm2, 1
00338         paddd   mm0, mm7
00339         paddd   mm3, mm2
00341                                         // H4+T1
00343                                         movq    mm7, [edi+edx*8+4*8]
00344         psrld   mm3, 31
00345                                         movq    mm4, mm7
00346         psllq   mm3, 32
00347         paddd   mm0, mm3
00348                                         movq    mm5, mm7
00349                                         pxor    mm4, mm1
00350                                         pand    mm5, mm1
00351                                         paddd   mm1, mm7
00352                                         psrld   mm4, 1
00354         // +S0
00356         movq    mm2, mm6
00357         movq    mm3, mm6
00358         pxor    mm2, mm0
00359         pand    mm3, mm0
00360                                         paddd   mm5, mm4
00361         psrld   mm2, 1
00362                                         psrld   mm5, 31
00363         paddd   mm3, mm2
00364                                         psllq   mm5, 32
00365         paddd   mm0, mm6
00366         psrld   mm3, 31
00367                                         paddd   mm1, mm5
00368         psllq   mm3, 32
00369         dec     edx // 先にデクリメントのため以下+8
00370         paddd   mm0, mm3
00371         inc     ecx
00372                                         movq    [edi+edx*8+4*8+8], mm1 // H4
00373         nop
00374         movq    [edi+edx*8+8], mm0
00375         jnz     loop1
00376         emms
00377     }
00378     for(i = 0; i < SHA512_HASH; i++) p->m_qwH[i] += Hash[i];
00379 }
00380 
00381 #else
00382 
00383 static DKC_INLINE void MMX_Generate(DKC_SHA512 *p){
00384     Default_Generate(p);
00385 }
00386 
00387 #endif
00388 
00389 static DKC_INLINE void Generate(DKC_SHA512 *p)
00390 {
00391     if(p->m_bMMX){
00392         MMX_Generate(p);
00393         return;
00394     }
00395     Default_Generate(p);
00396 }
00397 
00398 DKC_SHA512 *WINAPI dkcAllocSHA512(){
00399     DKC_SHA512 *p = dkcAllocate(sizeof(DKC_SHA512));
00400     if(NULL==p){
00401         return NULL;
00402     }
00403     p->m_bMMX = CheckMMX();
00404     dkcSHA512Init(p);
00405     return p;
00406 }
00407 
00408 void WINAPI dkcSHA512Init(DKC_SHA512 *p){
00409     int i;
00410     for(i = 0; i < SHA512_HASH; i++){
00411         p->m_qwH[i] = c_qwInitH[i];
00412     }
00413     p->m_qwLNumBits = 0;
00414     p->m_qwHNumBits = 0;
00415     p->m_nNumChr = 0;
00416     p->mFinalized = FALSE;
00417 }
00418 
00419 void WINAPI dkcSHA512Load(DKC_SHA512 *p,const BYTE *pBuffer,DWORD dwSize){
00420     QWORD qwSize;
00421     QWORD qwLNumBits;
00422     BYTE *pBlock;
00423     DWORD dwReadSize;
00424 
00425     if(dwSize == 0) return;
00426     if(p->mFinalized){
00427         return;
00428     }
00429 
00430     qwSize = dwSize;
00431     qwLNumBits = (p->m_qwLNumBits + (qwSize << 3));
00432     if(qwLNumBits < p->m_qwLNumBits) p->m_qwHNumBits++;
00433 //  p->m_qwHNumBits += qwSize >> 61;
00434     p->m_qwLNumBits = qwLNumBits;
00435 
00436     pBlock = (BYTE *)p->m_aBlock;
00437     while(dwSize){
00438         //dwReadSize = (dwSize < SHA512_BUFFER_SIZE - p->m_nNumChr) ?
00439         dwReadSize = (dwSize < SHA512_BUFFER_SIZE - (DWORD)p->m_nNumChr) ?
00440              dwSize :
00441             (SHA512_BUFFER_SIZE - p->m_nNumChr);
00442         
00443         memcpy(pBlock + p->m_nNumChr, pBuffer, dwReadSize);
00444         
00445         p->m_nNumChr += dwReadSize;
00446         pBuffer += dwReadSize;
00447         dwSize -= dwReadSize;
00448         
00449         if(p->m_nNumChr == SHA512_BUFFER_SIZE){
00450             Generate(p);
00451             p->m_nNumChr = 0;
00452         }
00453     }
00454 }
00455 
00456 void WINAPI dkcSHA512Final(DKC_SHA512 *p){
00457 
00458     BYTE cZero = 0x00;
00459     BYTE cOne  = 0x80;
00460     QWORD qwHNumBits;
00461     QWORD qwLNumBits;
00462     if(p->mFinalized){
00463         return;
00464     }
00465     qwHNumBits = ReverseEndianQWORD(p->m_qwHNumBits);
00466     qwLNumBits = ReverseEndianQWORD(p->m_qwLNumBits);
00467 
00468     dkcSHA512Load(p,&cOne, 1);
00469     while(p->m_nNumChr != SHA512_BUFFER_SIZE - 16) dkcSHA512Load(p,&cZero, 1);
00470 
00471     dkcSHA512Load(p,(BYTE *)&qwHNumBits, 8);
00472     dkcSHA512Load(p,(BYTE *)&qwLNumBits, 8);
00473 
00474     p->mFinalized = TRUE;
00475 }
00476 
00477 int WINAPI dkcSHA512DigestStr(DKC_SHA512 *p,char *buff,size_t size){
00478     //char s[SHA512_HASH * 16 + 1];
00479     char s[ SHA512_STR_BUFFER_SIZE ];
00480     int i;
00481 
00482     s[SHA512_HASH * 16 ] = '\0';
00483     //if(size <= sizeof(s)){
00484     if(SHA512_STR_BUFFER_SIZE > size){
00485         return edk_BufferOverFlow;
00486     }
00487     if(FALSE==p->mFinalized){
00488         //まだFinalやってないっつーの
00489         return edk_LogicError;
00490     }
00491 
00492     for(i = 0; i < SHA512_HASH; i++){
00493         sprintf(s + i * 16,     "%08x", (DWORD)(p->m_qwH[i] >> 32));
00494         sprintf(s + i * 16 + 8, "%08x", (DWORD)(p->m_qwH[i] & 0x00000000ffffffff));
00495     }
00496     //std::string strDigest = s;
00497     //return strDigest;
00498     return dkc_strcpy(buff,size,s,strlen(s));
00499 }
00500 
00501 
00502 int WINAPI dkcSHA512FinalDigestStr(DKC_SHA512 *p,char *buff,size_t size){
00503     dkcSHA512Final(p);
00504     return dkcSHA512DigestStr(p,buff,size);
00505 }
00506 
00507 
00508 
00509 int WINAPI dkcSHA512Digest(DKC_SHA512 *p,BYTE *buff,size_t size){   
00510     //if(sizeof(QWORD) * SHA512_HASH > size){
00511     size_t i;
00512     if(SHA512_BIN_BUFFER_SIZE > size){
00513         return edk_BufferOverFlow;
00514     }
00515     if(FALSE==p->mFinalized){
00516         //まだFinalやってないっつーの
00517         return edk_LogicError;
00518     }
00519     for(i = 0; i < SHA512_BIN_BUFFER_SIZE; ++i){
00520         buff[i] = (BYTE)(p->m_qwH[i >> 3] >> (8 * (~i & 7)));
00521     }
00522     return edk_SUCCEEDED;
00523     //return dkc_memcpy(buff,size,(const void *)p->m_qwH,sizeof(p->m_qwH));
00524 }
00525 
00526 
00527 int WINAPI dkcSHA512FinalDigest(DKC_SHA512 *p,BYTE *buff,size_t size){
00528     dkcSHA512Final(p);
00529     return dkcSHA512Digest(p,buff,size);
00530 }
00531 
00532 
00533 int WINAPI dkcFreeSHA512(DKC_SHA512 **p){
00534     if(NULL==p){
00535         return edk_FAILED;
00536     }
00537     return dkcFree((void **)p);
00538 }
00539 
00540 #undef cpuid

dkutil_cに対してTue Dec 7 01:09:57 2004に生成されました。 doxygen 1.3.6