メインページ | 構成 | ファイル一覧 | 構成メンバ | ファイルメンバ | 関連ページ

dkcSHA512.c

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

dkutil_cに対してSun Jul 18 22:45:21 2004に生成されました。 doxygen 1.3.6