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

# dkcSHA256.c

説明を見る。

    00001
    00008 #define DKUTIL_C_SHA256_C
    00009 #include "dkcSHA256.h"
    00010 #include "dkcStdio.h"
    00011
    00012
    00013 #   define  SHA256_BUFFER_SIZE (SHA256_BLOCK * 4)
    00014
    00015
    00016 const static DWORD c_dwInitH[SHA256_HASH] = {
    00017     0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
    00018 };
    00019
    00020 const static DWORD c_dwK[SHA256_WORK] = {
    00021     0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
    00022     0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
    00023     0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
    00024     0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
    00025     0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
    00026     0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
    00027     0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
    00028     0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
    00029 };
    00030
    00031
    00032 static DKC_INLINE DWORD ReverseEndian(DWORD x) {
    00033     return dkcReverseEndian32(x);
    00034     //return (x << 24) | ((x & 0x0000ff00) << 8) | ((x & 0x00ff0000) >> 8) | (x >> 24);
    00035 }
    00036 static DKC_INLINE DWORD Rotate(DWORD x, DWORD n) {return (x >> n) | (x << (32 - n));}
    00037 static DKC_INLINE DWORD Ch(DWORD x, DWORD y, DWORD z) {return (x & (y ^ z)) ^ z;}
    00038 static DKC_INLINE DWORD Maj(DWORD x, DWORD y, DWORD z) {return (x & (y | z)) | (y & z);}
    00039 static DKC_INLINE DWORD S0(DWORD x) {return Rotate(x,  2) ^ Rotate(x, 13) ^ Rotate(x, 22);}
    00040 static DKC_INLINE DWORD S1(DWORD x) {return Rotate(x,  6) ^ Rotate(x, 11) ^ Rotate(x, 25);}
    00041 static DKC_INLINE DWORD s0(DWORD x) {return Rotate(x,  7) ^ Rotate(x, 18) ^ (x >> 3);}
    00042 static DKC_INLINE DWORD s1(DWORD x) {return Rotate(x, 17) ^ Rotate(x, 19) ^ (x >> 10);}
    00043
    00044
    00045 static void Generate(DKC_SHA256 *p){
    00046     int i;
    00047     DWORD W[SHA256_WORK];
    00048     DWORD Hash[SHA256_WORK + SHA256_HASH];
    00049     DWORD *pHash;
    00050     DWORD dwT1, dwT2;
    00051
    00052
    00053     for(i = 0; i < SHA256_BLOCK; i++) W[i] = ReverseEndian(p->m_aBlock[i]);
    00054     for(i = SHA256_BLOCK; i < SHA256_WORK; i++) W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
    00055
    00056     for(i = 0; i < SHA256_HASH; i++) Hash[SHA256_WORK + i] = p->m_dwH[i];
    00057     pHash = &Hash[SHA256_WORK];
    00058
    00059     for(i = 0; i < SHA256_WORK; i++){
    00060         pHash--;
    00061         dwT1 = pHash[8] + S1(pHash[5]) + Ch(pHash[5], pHash[6], pHash[7]) + c_dwK[i] + W[i];
    00062         dwT2 = S0(pHash[1]) + Maj(pHash[1], pHash[2], pHash[3]);
    00063         pHash[0] = dwT1 + dwT2;
    00064         pHash[4] += dwT1;
    00065     }
    00066     for(i = 0; i < SHA256_HASH; i++) p->m_dwH[i] += pHash[i];
    00067 }
    00068
    00069 DKC_SHA256 *WINAPI dkcAllocSHA256(){
    00070     DKC_SHA256 *p = dkcAllocate(sizeof(DKC_SHA256));
    00071     if(NULL==p){
    00072         return NULL;
    00073     }
    00074     dkcSHA256Init(p);
    00075     return p;
    00076 }
    00077
    00078 void WINAPI dkcSHA256Init(DKC_SHA256 *p){
    00079     int i;
    00080     for(i = 0; i < SHA256_HASH; i++){
    00081         p->m_dwH[i] = c_dwInitH[i];
    00082     }
    00083     p->m_dwLNumBits = 0;
    00084     p->m_dwHNumBits = 0;
    00085     p->m_nNumChr = 0;
    00086     p->mFinalized = FALSE;
    00087 }
    00088
    00089 void WINAPI dkcSHA256Load(DKC_SHA256 *p,const BYTE *pBuffer,DWORD dwSize){
    00090     DWORD dwReadSize;
    00091     DWORD dwLNumBits;
    00092     BYTE *pBlock;
    00093
    00094     if(dwSize == 0) return;
    00095     if(p->mFinalized){
    00096         return;
    00097     }
    00098     dwLNumBits = (p->m_dwLNumBits + (dwSize << 3));
    00099     if(dwLNumBits < p->m_dwLNumBits) p->m_dwHNumBits++;
    00100     p->m_dwHNumBits += dwSize >> 29;
    00101     p->m_dwLNumBits = dwLNumBits;
    00102
    00103     pBlock = (BYTE *)p->m_aBlock;
    00104
    00105     while(dwSize){
    00106         //dwReadSize = (dwSize < SHA256_BUFFER_SIZE - p->m_nNumChr) ?
    00107         dwReadSize = (dwSize < SHA256_BUFFER_SIZE - (DWORD)p->m_nNumChr) ?
    00108             dwSize :
    00109             (SHA256_BUFFER_SIZE - p->m_nNumChr);
    00110
    00111         memcpy(pBlock + p->m_nNumChr, pBuffer, dwReadSize);
    00112
    00113         p->m_nNumChr += dwReadSize;
    00114         pBuffer += dwReadSize;
    00115         dwSize -= dwReadSize;
    00116
    00117         if(p->m_nNumChr == SHA256_BUFFER_SIZE){
    00118             Generate(p);
    00119             p->m_nNumChr = 0;
    00120         }
    00121     }
    00122 }
    00123
    00124 void WINAPI dkcSHA256Final(DKC_SHA256 *p){
    00125
    00126     BYTE cZero = 0x00;
    00127     BYTE cOne  = 0x80;
    00128     DWORD dwHNumBits;
    00129     DWORD dwLNumBits;
    00130
    00131     if(p->mFinalized){
    00132         return;
    00133     }
    00134
    00135     dwHNumBits = ReverseEndian(p->m_dwHNumBits);
    00136     dwLNumBits = ReverseEndian(p->m_dwLNumBits);
    00137
    00138     dkcSHA256Load(p,&cOne, 1);
    00139     while(p->m_nNumChr != SHA256_BUFFER_SIZE - 8) dkcSHA256Load(p,&cZero, 1);
    00140
    00141     dkcSHA256Load(p,(BYTE *)&dwHNumBits, 4);
    00142     dkcSHA256Load(p,(BYTE *)&dwLNumBits, 4);
    00143
    00144     //ファイナル処理した。
    00145     p->mFinalized = TRUE;
    00146 }
    00147
    00148 int WINAPI dkcSHA256DigestStr(DKC_SHA256 *p,char *buff,size_t size){
    00149     //char s[SHA256_HASH * 8 + 1];
    00150     char s[SHA256_STR_BUFFER_SIZE];
    00151     int i;
    00152
    00153     s[SHA256_HASH * 8]='\0';
    00154     if(SHA256_STR_BUFFER_SIZE > size){
    00155         return edk_BufferOverFlow;
    00156     }
    00157     if(FALSE==p->mFinalized){
    00158         //まだFinalやってないっつーの
    00159         return edk_LogicError;
    00160     }
    00161
    00162     for(i = 0; i < SHA256_HASH; i++){
    00163         sprintf(s + i * 8, "%08x", p->m_dwH[i]);
    00164     }
    00165     //std::string strDigest = s;
    00166     //return strDigest;
    00167     return dkc_strcpy(buff,size,s,strlen(s));
    00168 }
    00169 int WINAPI dkcSHA256FinalDigestStr(DKC_SHA256 *p,char *buff,size_t size){
    00170     dkcSHA256Final(p);
    00171     return dkcSHA256DigestStr(p,buff,size);
    00172 }
    00173
    00174
    00175
    00176 int WINAPI dkcSHA256Digest(DKC_SHA256 *p,BYTE *buff,size_t size){
    00177     size_t i;
    00178     if(SHA256_BIN_BUFFER_SIZE > size){
    00179         return edk_BufferOverFlow;
    00180     }
    00181     if(FALSE==p->mFinalized){
    00182         //まだFinalやってないっつーの
    00183         return edk_LogicError;
    00184     }
    00185     for(i = 0; i < SHA256_BIN_BUFFER_SIZE; ++i){
    00186         buff[i] = (BYTE)(p->m_dwH[i >> 2] >> (8 * (~i & 3)));
    00187     }
    00188     return edk_SUCCEEDED;
    00189     //return dkc_memcpy(buff,size,(const void *)p->m_dwH,sizeof(p->m_dwH));
    00190 }
    00191
    00192 int WINAPI dkcSHA256FinalDigest(DKC_SHA256 *p,BYTE *buff,size_t size){
    00193     dkcSHA256Final(p);
    00194     return dkcSHA256Digest(p,buff,size);
    00195 }
    00196
    00197
    00198 int WINAPI dkcFreeSHA256(DKC_SHA256 **p){
    00199     if(NULL==p){
    00200         return edk_FAILED;
    00201     }
    00202     return dkcFree((void **)p);
    00203 }