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
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 #include "utils/sha256.h"
00072
00073 #include <memory.h>
00074
00075 #ifdef HAS_STDINT
00076 #include <stdint.h>
00077 #endif
00078 #ifndef HAS_STDINT
00079 typedef unsigned int uint32_t;
00080 #endif
00081
00082 #define SHA256_BLOCK_SIZE (512 / 8)
00083
00085 class SHA256Context
00086 {
00087 public:
00088 unsigned int tot_len;
00089 unsigned int len;
00090 unsigned char block[2 * SHA256_BLOCK_SIZE];
00091 uint32_t h[8];
00092 };
00093
00094 #define SHA256_DIGEST_SIZE (256 / 8)
00095
00096 #define SHFR(x, n) (x >> n)
00097 #define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n)))
00098 #define ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n)))
00099 #define CH(x, y, z) ((x & y) ^ (~x & z))
00100 #define MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
00101
00102 #define SHA256_F1(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
00103 #define SHA256_F2(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
00104 #define SHA256_F3(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHFR(x, 3))
00105 #define SHA256_F4(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHFR(x, 10))
00106
00107 #define UNPACK32(x, str) \
00108 { \
00109 *((str) + 3) = (uint8_t) ((x) ); \
00110 *((str) + 2) = (uint8_t) ((x) >> 8); \
00111 *((str) + 1) = (uint8_t) ((x) >> 16); \
00112 *((str) + 0) = (uint8_t) ((x) >> 24); \
00113 }
00114
00115 #define PACK32(str, x) \
00116 { \
00117 *(x) = ((uint32_t) *((str) + 3) ) \
00118 | ((uint32_t) *((str) + 2) << 8) \
00119 | ((uint32_t) *((str) + 1) << 16) \
00120 | ((uint32_t) *((str) + 0) << 24); \
00121 }
00122
00123
00124
00125 #define SHA256_SCR(i) \
00126 { \
00127 w[i] = SHA256_F4(w[i - 2]) + w[i - 7] \
00128 + SHA256_F3(w[i - 15]) + w[i - 16]; \
00129 }
00130
00131 const unsigned int sha256_h0[8] =
00132 {
00133 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
00134 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
00135 };
00136
00137 uint32_t sha256_k[64] =
00138 {
00139 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
00140 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
00141 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
00142 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
00143 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
00144 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
00145 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
00146 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
00147 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
00148 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
00149 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
00150 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
00151 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
00152 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
00153 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
00154 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
00155 };
00156
00157 void SHA256Init(SHA256Context *ctx)
00158 {
00159 for (int i = 0; i < 8; i++)
00160 ctx->h[i] = sha256_h0[i];
00161 ctx->len = 0;
00162 ctx->tot_len = 0;
00163 }
00164
00165 void SHA256Transform(SHA256Context *ctx,
00166 unsigned char *message,
00167 unsigned int block_nb)
00168 {
00169 uint32_t w[64];
00170 uint32_t wv[8];
00171 unsigned char *sub_block;
00172 for (unsigned int i = 1; i <= block_nb; i++)
00173 {
00174 int j;
00175 sub_block = message + ((i - 1) << 6);
00176
00177 for (j = 0; j < 16; j++)
00178 PACK32(&sub_block[j << 2], &w[j]);
00179 for (j = 16; j < 64; j++)
00180 SHA256_SCR(j);
00181 for (j = 0; j < 8; j++)
00182 wv[j] = ctx->h[j];
00183 for (j = 0; j < 64; j++)
00184 {
00185 uint32_t t1 = wv[7] + SHA256_F2(wv[4]) + CH(wv[4], wv[5], wv[6]) + sha256_k[j] + w[j];
00186 uint32_t t2 = SHA256_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]);
00187 wv[7] = wv[6];
00188 wv[6] = wv[5];
00189 wv[5] = wv[4];
00190 wv[4] = wv[3] + t1;
00191 wv[3] = wv[2];
00192 wv[2] = wv[1];
00193 wv[1] = wv[0];
00194 wv[0] = t1 + t2;
00195 }
00196 for (j = 0; j < 8; j++)
00197 ctx->h[j] += wv[j];
00198 }
00199 }
00200
00201 void SHA256Update(SHA256Context *ctx,
00202 unsigned char *message,
00203 unsigned int len)
00204 {
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 unsigned int tmp_len = SHA256_BLOCK_SIZE - ctx->len;
00222 unsigned int rem_len = len < tmp_len ? len : tmp_len;
00223
00224 memcpy(&ctx->block[ctx->len], message, rem_len);
00225 if (ctx->len + len < SHA256_BLOCK_SIZE)
00226 {
00227 ctx->len += len;
00228 return;
00229 }
00230 unsigned int new_len = len - rem_len;
00231 unsigned int block_nb = new_len / SHA256_BLOCK_SIZE;
00232 unsigned char *shifted_message = message + rem_len;
00233 SHA256Transform(ctx, ctx->block, 1);
00234 SHA256Transform(ctx, shifted_message, block_nb);
00235 rem_len = new_len % SHA256_BLOCK_SIZE;
00236 memcpy(ctx->block, &shifted_message[block_nb << 6],rem_len);
00237 ctx->len = rem_len;
00238 ctx->tot_len += (block_nb + 1) << 6;
00239 }
00240
00241 void SHA256Final(SHA256Context *ctx, unsigned char *digest)
00242 {
00243 unsigned int block_nb = (1 + ((SHA256_BLOCK_SIZE - 9) < (ctx->len % SHA256_BLOCK_SIZE)));
00244 unsigned int len_b = (ctx->tot_len + ctx->len) << 3;
00245 unsigned int pm_len = block_nb << 6;
00246 memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
00247 ctx->block[ctx->len] = 0x80;
00248 UNPACK32(len_b, ctx->block + pm_len - 4);
00249 SHA256Transform(ctx, ctx->block, block_nb);
00250 for (int i = 0 ; i < 8; i++)
00251 UNPACK32(ctx->h[i], &digest[i << 2]);
00252 }
00253
00254 std::string SHA256Hash(const char *src, int len)
00255 {
00256
00257 unsigned char bytehash[SHA256_DIGEST_SIZE];
00258 SHA256Context ctx;
00259 SHA256Init(&ctx);
00260 SHA256Update(&ctx, (unsigned char *)src, (unsigned int)len);
00261 SHA256Final(&ctx, bytehash);
00262
00263 const char* hxc = "0123456789abcdef";
00264 std::string hash = "";
00265 for (int i = 0; i < SHA256_DIGEST_SIZE; i++)
00266 {
00267 hash += hxc[bytehash[i] / 16];
00268 hash += hxc[bytehash[i] % 16];
00269 }
00270 return hash;
00271 }
00272
00273 std::string sha256(const std::string &string)
00274 {
00275 return SHA256Hash(string.c_str(), string.length());
00276 }