00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #ifndef __SHA2C_H__
00045 #define __SHA2C_H__
00046
00047 #include <string>
00048 #include <stdexcept>
00049
00050
00051 typedef unsigned char sha_byte;
00052 typedef unsigned int sha_word32;
00053 #ifdef WIN32
00054 #include <windows.h>
00055 typedef ULONG64 sha_word64;
00056 #else
00057 typedef unsigned long long sha_word64;
00058 #endif
00059
00060
00061 const sha_word32 SHA1_DIGESTC_LENGTH = 20;
00062 const sha_word32 SHA1_DIGESTC_STRING_LENGTH = (SHA1_DIGESTC_LENGTH * 2 + 1);
00063 const sha_word32 SHA224_DIGESTC_LENGTH = 28;
00064 const sha_word32 SHA224_DIGESTC_STRING_LENGTH = (SHA224_DIGESTC_LENGTH * 2 + 1);
00065 const sha_word32 SHA256_DIGESTC_LENGTH = 32;
00066 const sha_word32 SHA256_DIGESTC_STRING_LENGTH = (SHA256_DIGESTC_LENGTH * 2 + 1);
00067 const sha_word32 SHA384_DIGESTC_LENGTH = 48;
00068 const sha_word32 SHA384_DIGESTC_STRING_LENGTH = (SHA384_DIGESTC_LENGTH * 2 + 1);
00069 const sha_word32 SHA512_DIGESTC_LENGTH = 64;
00070 const sha_word32 SHA512_DIGESTC_STRING_LENGTH = (SHA512_DIGESTC_LENGTH * 2 + 1);
00071
00072 class sha2{
00073 public:
00074 enum SHA_TYPE{
00075 enuSHA_NONE,
00076 enuSHA1,
00077 enuSHA160 = enuSHA1,
00078 enuSHA224,
00079 enuSHA256,
00080 enuSHA384,
00081 enuSHA512,
00082 enuSHA_LAST
00083 };
00084
00085 sha2(){
00086 m_Type = enuSHA_NONE;
00087 m_boolIsBigEndian = true;
00088 m_boolEnded = false;
00089
00090
00091 unsigned int test = 1;
00092 unsigned char *ptr = (unsigned char *)&test;
00093 if (ptr[0]) m_boolIsBigEndian = false;
00094
00095
00096
00097 if (sizeof(sha_byte) != 1) throw std::runtime_error("sha_byte != 1!");
00098 if (sizeof(sha_word32) != 4) throw std::runtime_error("sha_word32 != 4!");
00099 if (sizeof(sha_word64) != 8) throw std::runtime_error("sha_word64 != 8!");
00100
00101 memset(m_chrRawHash, 0, SHA512_DIGESTC_LENGTH);
00102 memset(m_chrHexHash, 0, SHA512_DIGESTC_STRING_LENGTH);
00103 memset(m_digest, 0, SHA512_DIGESTC_LENGTH);
00104 };
00105
00106 SHA_TYPE GetEnumType(){return m_Type;};
00107 bool IsBigEndian(){return m_boolIsBigEndian;};
00108 const char * GetTypeString(){
00109 switch (m_Type){
00110 case sha2::enuSHA1 : return "SHA160";
00111 case sha2::enuSHA224 : return "SHA224";
00112 case sha2::enuSHA256 : return "SHA256";
00113 case sha2::enuSHA384 : return "SHA384";
00114 case sha2::enuSHA512 : return "SHA512";
00115 default : return "Unknown!";
00116 }
00117 };
00118
00119
00120 void Init(SHA_TYPE type);
00121
00122 void Update(const sha_byte *data, size_t len);
00123 void End();
00124
00125
00126 const std::string &GetHash(SHA_TYPE type, const sha_byte* data, size_t len);
00127
00128
00129
00130 const char *HexHash();
00131 const std::string &StringHash();
00132 const char *RawHash(int &length);
00133
00134
00135 private:
00136 SHA_TYPE m_Type;
00137 std::string m_strHash;
00138 bool m_boolEnded, m_boolIsBigEndian;
00139 char m_chrRawHash[SHA512_DIGESTC_LENGTH], m_chrHexHash[SHA512_DIGESTC_STRING_LENGTH];
00140 sha_byte m_digest[SHA512_DIGESTC_LENGTH];
00141
00142
00143 struct SHA_CTX{
00144 sha_byte state[sizeof(sha_word64) * 8];
00145 sha_word64 bitcount[2];
00146 sha_byte buffer[128];
00147 }ctx;
00148
00149
00150
00151 void SHA256_Internal_Last(bool isSha1 = false);
00152 void SHA512_Internal_Last();
00153
00154 void SHA1_Internal_Transform(const sha_word32 *data);
00155 void SHA256_Internal_Transform(const sha_word32* data);
00156 void SHA512_Internal_Transform(const sha_word64*);
00157
00158 void SHA32bit_Update(const sha_byte *data, size_t len, bool isSha1=false);
00159 void SHA64bit_Update(const sha_byte *data, size_t len);
00160
00161
00162 inline void MEMSET_BZERO(void *p, size_t l){memset(p, 0, l);};
00163 inline void MEMCPY_BCOPY(void *d,const void *s, size_t l) {memcpy(d, s, l);};
00164
00165
00166
00167
00168 inline void ADDINC128(sha_word64 *w, sha_word32 n) {
00169 w[0] += (sha_word64)(n);
00170 if (w[0] < (n)) w[1]++;
00171 }
00172
00173
00174 inline sha_word32 SHR(sha_word32 b,sha_word32 x){return (x >> b);};
00175 inline sha_word64 SHR(sha_word64 b,sha_word64 x){return (x >> b);};
00176
00177 inline sha_word32 ROTR32(sha_word32 b,sha_word32 x){return ((x >> b) | (x << (32 - b)));};
00178
00179 inline sha_word64 ROTR64(sha_word64 b,sha_word64 x){return ((x >> b) | (x << (64 - b)));};
00180
00181 inline sha_word32 ROTL32(sha_word32 b,sha_word32 x){return ((x << b) | (x >> (32 - b)));};
00182
00183
00184 inline sha_word32 Ch(sha_word32 x,sha_word32 y,sha_word32 z){return ((x & y) ^ ((~x) & z));};
00185 inline sha_word64 Ch(sha_word64 x,sha_word64 y,sha_word64 z){return ((x & y) ^ ((~x) & z));};
00186 inline sha_word32 Maj(sha_word32 x,sha_word32 y,sha_word32 z){return ((x & y) ^ (x & z) ^ (y & z));};
00187 inline sha_word64 Maj(sha_word64 x,sha_word64 y,sha_word64 z){return ((x & y) ^ (x & z) ^ (y & z));};
00188
00189
00190 inline sha_word32 Parity(sha_word32 x,sha_word32 y,sha_word32 z){return (x ^ y ^ z);};
00191
00192
00193 inline sha_word32 Sigma0_256(sha_word32 x){return (ROTR32(2, x) ^ ROTR32(13, x) ^ ROTR32(22, x));};
00194 inline sha_word32 Sigma1_256(sha_word32 x){return (ROTR32(6, x) ^ ROTR32(11, x) ^ ROTR32(25, x));};
00195 inline sha_word32 sigma0_256(sha_word32 x){return (ROTR32(7, x) ^ ROTR32(18, x) ^ SHR( 3 , x));};
00196 inline sha_word32 sigma1_256(sha_word32 x){return (ROTR32(17,x) ^ ROTR32(19, x) ^ SHR( 10, x));};
00197
00198
00199 inline sha_word64 Sigma0_512(sha_word64 x){return (ROTR64(28, x) ^ ROTR64(34, x) ^ ROTR64(39, x));};
00200 inline sha_word64 Sigma1_512(sha_word64 x){return (ROTR64(14, x) ^ ROTR64(18, x) ^ ROTR64(41, x));};
00201 inline sha_word64 sigma0_512(sha_word64 x){return (ROTR64( 1, x) ^ ROTR64( 8, x) ^ SHR( 7, x));};
00202 inline sha_word64 sigma1_512(sha_word64 x){return (ROTR64(19, x) ^ ROTR64(61, x) ^ SHR( 6, x));};
00203
00204 inline void REVERSE32(sha_word32 w, sha_word32 &x) {
00205 w = (w >> 16) | (w << 16);
00206 x = ((w & 0xff00ff00UL) >> 8) | ((w & 0x00ff00ffUL) << 8);
00207 }
00208 #ifdef _VC6
00209 inline void REVERSE64(sha_word64 w, sha_word64 &x) {
00210 w = (w >> 32) | (w << 32);
00211 w = ((w & 0xff00ff00ff00ff00ui64) >> 8) |
00212 ((w & 0x00ff00ff00ff00ffui64) << 8);
00213 (x) = ((w & 0xffff0000ffff0000ui64) >> 16) |
00214 ((w & 0x0000ffff0000ffffui64) << 16);
00215 }
00216 #else
00217 inline void REVERSE64(sha_word64 w, sha_word64 &x) {
00218 w = (w >> 32) | (w << 32);
00219 w = ((w & 0xff00ff00ff00ff00ULL) >> 8) |
00220 ((w & 0x00ff00ff00ff00ffULL) << 8);
00221 (x) = ((w & 0xffff0000ffff0000ULL) >> 16) |
00222 ((w & 0x0000ffff0000ffffULL) << 16);
00223 }
00224 #endif
00225
00226 };
00227 #endif // __SHA2C_H__