1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
| typedef unsigned char uint8; typedef unsigned int uint32; typedef unsigned long long uint64;
#define SHA256_BLOCK_SIZE 32 #define SHA256_CHUNK_SIZE 64
typedef struct { uint8 data[SHA256_CHUNK_SIZE]; uint32 datalen; uint64 bitlen; uint32 state[8]; } SHA256_CTX;
static const uint32 k[64] = { 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5, 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174, 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da, 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967, 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85, 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070, 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3, 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 };
static uint32 rotr(uint32 x, uint32 n) { return (x >> n) | (x << (32 - n)); }
static uint32 ch(uint32 x, uint32 y, uint32 z) { return (x & y) ^ (~x & z); }
static uint32 maj(uint32 x, uint32 y, uint32 z) { return (x & y) ^ (x & z) ^ (y & z); }
static uint32 sigma0(uint32 x) { return rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22); }
static uint32 sigma1(uint32 x) { return rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25); }
static uint32 gamma0(uint32 x) { return rotr(x, 7) ^ rotr(x, 18) ^ (x >> 3); }
static uint32 gamma1(uint32 x) { return rotr(x, 17) ^ rotr(x, 19) ^ (x >> 10); }
static void sha256_init(SHA256_CTX* ctx) { ctx->datalen = 0; ctx->bitlen = 0; ctx->state[0] = 0x6a09e667; ctx->state[1] = 0xbb67ae85; ctx->state[2] = 0x3c6ef372; ctx->state[3] = 0xa54ff53a; ctx->state[4] = 0x510e527f; ctx->state[5] = 0x9b05688c; ctx->state[6] = 0x1f83d9ab; ctx->state[7] = 0x5be0cd19; }
static void sha256_update(SHA256_CTX* ctx, const uint8 data[], size_t len) { for (size_t i = 0; i < len; i++) { ctx->data[ctx->datalen] = data[i]; ctx->datalen++; if (ctx->datalen == SHA256_CHUNK_SIZE) { uint32 m[16], w[64]; for (int j = 0; j < SHA256_CHUNK_SIZE; j++) { m[j / 4] |= (uint32)ctx->data[j] << (24 - (j % 4) * 8); } for (int j = 0; j < 16; j++) w[j] = m[j]; for (int j = 16; j < 64; j++) { w[j] = gamma1(w[j - 2]) + w[j - 7] + gamma0(w[j - 15]) + w[j - 16]; } uint32 a = ctx->state[0], b = ctx->state[1], c = ctx->state[2], d = ctx->state[3]; uint32 e = ctx->state[4], f = ctx->state[5], g = ctx->state[6], h = ctx->state[7]; for (int j = 0; j < 64; j++) { uint32 t1 = h + sigma1(e) + ch(e, f, g) + k[j] + w[j]; uint32 t2 = sigma0(a) + maj(a, b, c); h = g; g = f; f = e; e = d + t1; d = c; c = b; b = a; a = t1 + t2; } ctx->state[0] += a; ctx->state[1] += b; ctx->state[2] += c; ctx->state[3] += d; ctx->state[4] += e; ctx->state[5] += f; ctx->state[6] += g; ctx->state[7] += h; ctx->datalen = 0; } ctx->bitlen += 8; } }
static void sha256_final(SHA256_CTX* ctx, uint8 hash[]) { size_t i = ctx->datalen; if (ctx->datalen < 56) { ctx->data[i++] = 0x80; while (i < 56) ctx->data[i++] = 0x00; } else { ctx->data[i++] = 0x80; while (i < 64) ctx->data[i++] = 0x00; sha256_update(ctx, ctx->data, 64); memset(ctx->data, 0, 56); } uint64 bits = ctx->bitlen; for (i = 0; i < 8; i++) { ctx->data[56 + i] = (uint8)((bits >> (56 - i * 8)) & 0xFF); } sha256_update(ctx, ctx->data, 64); for (i = 0; i < 8; i++) { for (int j = 0; j < 4; j++) { hash[i * 4 + j] = (uint8)((ctx->state[i] >> (24 - j * 8)) & 0xFF); } } }
|