1 /* Crypto/Sha256.c -- SHA-256 Hash 2 2015-11-14 : Igor Pavlov : Public domain 3 This code is based on public domain code from Wei Dai's Crypto++ library. */ 4 5 #include "Precomp.h" 6 7 #include <string.h> 8 9 #include "CpuArch.h" 10 #include "RotateDefs.h" 11 #include "Sha256.h" 12 13 /* define it for speed optimization */ 14 #ifndef _SFX 15 #define _SHA256_UNROLL 16 #define _SHA256_UNROLL2 17 #endif 18 19 /* #define _SHA256_UNROLL2 */ 20 21 void Sha256_Init(CSha256 *p) 22 { 23 p->state[0] = 0x6a09e667; 24 p->state[1] = 0xbb67ae85; 25 p->state[2] = 0x3c6ef372; 26 p->state[3] = 0xa54ff53a; 27 p->state[4] = 0x510e527f; 28 p->state[5] = 0x9b05688c; 29 p->state[6] = 0x1f83d9ab; 30 p->state[7] = 0x5be0cd19; 31 p->count = 0; 32 } 33 34 #define S0(x) (rotrFixed(x, 2) ^ rotrFixed(x,13) ^ rotrFixed(x, 22)) 35 #define S1(x) (rotrFixed(x, 6) ^ rotrFixed(x,11) ^ rotrFixed(x, 25)) 36 #define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3)) 37 #define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10)) 38 39 #define blk0(i) (W[i]) 40 #define blk2(i) (W[i] += s1(W[((i)-2)&15]) + W[((i)-7)&15] + s0(W[((i)-15)&15])) 41 42 #define Ch(x,y,z) (z^(x&(y^z))) 43 #define Maj(x,y,z) ((x&y)|(z&(x|y))) 44 45 #ifdef _SHA256_UNROLL2 46 47 #define R(a,b,c,d,e,f,g,h, i) \ 48 h += S1(e) + Ch(e,f,g) + K[(i)+(j)] + (j ? blk2(i) : blk0(i)); \ 49 d += h; \ 50 h += S0(a) + Maj(a, b, c) 51 52 #define RX_8(i) \ 53 R(a,b,c,d,e,f,g,h, i); \ 54 R(h,a,b,c,d,e,f,g, i+1); \ 55 R(g,h,a,b,c,d,e,f, i+2); \ 56 R(f,g,h,a,b,c,d,e, i+3); \ 57 R(e,f,g,h,a,b,c,d, i+4); \ 58 R(d,e,f,g,h,a,b,c, i+5); \ 59 R(c,d,e,f,g,h,a,b, i+6); \ 60 R(b,c,d,e,f,g,h,a, i+7) 61 62 #define RX_16 RX_8(0); RX_8(8); 63 64 #else 65 66 #define a(i) T[(0-(i))&7] 67 #define b(i) T[(1-(i))&7] 68 #define c(i) T[(2-(i))&7] 69 #define d(i) T[(3-(i))&7] 70 #define e(i) T[(4-(i))&7] 71 #define f(i) T[(5-(i))&7] 72 #define g(i) T[(6-(i))&7] 73 #define h(i) T[(7-(i))&7] 74 75 #define R(i) \ 76 h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[(i)+(j)] + (j ? blk2(i) : blk0(i)); \ 77 d(i) += h(i); \ 78 h(i) += S0(a(i)) + Maj(a(i), b(i), c(i)) \ 79 80 #ifdef _SHA256_UNROLL 81 82 #define RX_8(i) R(i+0); R(i+1); R(i+2); R(i+3); R(i+4); R(i+5); R(i+6); R(i+7); 83 #define RX_16 RX_8(0); RX_8(8); 84 85 #else 86 87 #define RX_16 unsigned i; for (i = 0; i < 16; i++) { R(i); } 88 89 #endif 90 91 #endif 92 93 static const UInt32 K[64] = { 94 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 95 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 96 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 97 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 98 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 99 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 100 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 101 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 102 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 103 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 104 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 105 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 106 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 107 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 108 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 109 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 110 }; 111 112 static void Sha256_WriteByteBlock(CSha256 *p) 113 { 114 UInt32 W[16]; 115 unsigned j; 116 UInt32 *state; 117 118 #ifdef _SHA256_UNROLL2 119 UInt32 a,b,c,d,e,f,g,h; 120 #else 121 UInt32 T[8]; 122 #endif 123 124 for (j = 0; j < 16; j += 4) 125 { 126 const Byte *ccc = p->buffer + j * 4; 127 W[j ] = GetBe32(ccc); 128 W[j + 1] = GetBe32(ccc + 4); 129 W[j + 2] = GetBe32(ccc + 8); 130 W[j + 3] = GetBe32(ccc + 12); 131 } 132 133 state = p->state; 134 135 #ifdef _SHA256_UNROLL2 136 a = state[0]; 137 b = state[1]; 138 c = state[2]; 139 d = state[3]; 140 e = state[4]; 141 f = state[5]; 142 g = state[6]; 143 h = state[7]; 144 #else 145 for (j = 0; j < 8; j++) 146 T[j] = state[j]; 147 #endif 148 149 for (j = 0; j < 64; j += 16) 150 { 151 RX_16 152 } 153 154 #ifdef _SHA256_UNROLL2 155 state[0] += a; 156 state[1] += b; 157 state[2] += c; 158 state[3] += d; 159 state[4] += e; 160 state[5] += f; 161 state[6] += g; 162 state[7] += h; 163 #else 164 for (j = 0; j < 8; j++) 165 state[j] += T[j]; 166 #endif 167 168 /* Wipe variables */ 169 /* memset(W, 0, sizeof(W)); */ 170 /* memset(T, 0, sizeof(T)); */ 171 } 172 173 #undef S0 174 #undef S1 175 #undef s0 176 #undef s1 177 178 void Sha256_Update(CSha256 *p, const Byte *data, size_t size) 179 { 180 if (size == 0) 181 return; 182 183 { 184 unsigned pos = (unsigned)p->count & 0x3F; 185 unsigned num; 186 187 p->count += size; 188 189 num = 64 - pos; 190 if (num > size) 191 { 192 memcpy(p->buffer + pos, data, size); 193 return; 194 } 195 196 size -= num; 197 memcpy(p->buffer + pos, data, num); 198 data += num; 199 } 200 201 for (;;) 202 { 203 Sha256_WriteByteBlock(p); 204 if (size < 64) 205 break; 206 size -= 64; 207 memcpy(p->buffer, data, 64); 208 data += 64; 209 } 210 211 if (size != 0) 212 memcpy(p->buffer, data, size); 213 } 214 215 void Sha256_Final(CSha256 *p, Byte *digest) 216 { 217 unsigned pos = (unsigned)p->count & 0x3F; 218 unsigned i; 219 220 p->buffer[pos++] = 0x80; 221 222 while (pos != (64 - 8)) 223 { 224 pos &= 0x3F; 225 if (pos == 0) 226 Sha256_WriteByteBlock(p); 227 p->buffer[pos++] = 0; 228 } 229 230 { 231 UInt64 numBits = (p->count << 3); 232 SetBe32(p->buffer + 64 - 8, (UInt32)(numBits >> 32)); 233 SetBe32(p->buffer + 64 - 4, (UInt32)(numBits)); 234 } 235 236 Sha256_WriteByteBlock(p); 237 238 for (i = 0; i < 8; i += 2) 239 { 240 UInt32 v0 = p->state[i]; 241 UInt32 v1 = p->state[i + 1]; 242 SetBe32(digest , v0); 243 SetBe32(digest + 4, v1); 244 digest += 8; 245 } 246 247 Sha256_Init(p); 248 } 249