13 #if defined(__x86_64__) || defined(__amd64__) 18 void Transform(uint32_t* s,
const unsigned char* chunk,
size_t blocks);
29 uint32_t
inline Ch(uint32_t x, uint32_t y, uint32_t z) {
return z ^ (x & (y ^ z)); }
30 uint32_t
inline Maj(uint32_t x, uint32_t y, uint32_t z) {
return (x & y) | (z & (x | y)); }
31 uint32_t
inline Sigma0(uint32_t x) {
return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10); }
32 uint32_t
inline Sigma1(uint32_t x) {
return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7); }
33 uint32_t
inline sigma0(uint32_t x) {
return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3); }
34 uint32_t
inline sigma1(uint32_t x) {
return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10); }
37 void inline Round(uint32_t a, uint32_t b, uint32_t c, uint32_t& d, uint32_t e, uint32_t f, uint32_t g, uint32_t& h, uint32_t k, uint32_t w)
39 uint32_t t1 = h +
Sigma1(e) +
Ch(e, f, g) + k + w;
46 void inline Initialize(uint32_t* s)
59 void Transform(uint32_t* s,
const unsigned char* chunk,
size_t blocks)
62 uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
63 uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
65 Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = ReadBE32(chunk + 0));
66 Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = ReadBE32(chunk + 4));
67 Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = ReadBE32(chunk + 8));
68 Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = ReadBE32(chunk + 12));
69 Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = ReadBE32(chunk + 16));
70 Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = ReadBE32(chunk + 20));
71 Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = ReadBE32(chunk + 24));
72 Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = ReadBE32(chunk + 28));
73 Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = ReadBE32(chunk + 32));
74 Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = ReadBE32(chunk + 36));
75 Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = ReadBE32(chunk + 40));
76 Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = ReadBE32(chunk + 44));
77 Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = ReadBE32(chunk + 48));
78 Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = ReadBE32(chunk + 52));
79 Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = ReadBE32(chunk + 56));
80 Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = ReadBE32(chunk + 60));
111 Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 +=
sigma1(w10) + w5 +
sigma0(w13));
112 Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 +=
sigma1(w11) + w6 +
sigma0(w14));
113 Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 +=
sigma1(w12) + w7 +
sigma0(w15));
128 Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 +=
sigma1(w10) + w5 +
sigma0(w13));
129 Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 +=
sigma1(w11) + w6 +
sigma0(w14));
147 typedef void (*TransformType)(uint32_t*,
const unsigned char*, size_t);
149 bool SelfTest(TransformType tr) {
150 static const unsigned char in1[65] = {0, 0x80};
151 static const unsigned char in2[129] = {
153 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
154 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
155 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
156 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0
158 static const uint32_t init[8] = {0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, 0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul};
159 static const uint32_t out1[8] = {0xe3b0c442ul, 0x98fc1c14ul, 0x9afbf4c8ul, 0x996fb924ul, 0x27ae41e4ul, 0x649b934cul, 0xa495991bul, 0x7852b855ul};
160 static const uint32_t out2[8] = {0xce4153b0ul, 0x147c2a86ul, 0x3ed4298eul, 0xe0676bc8ul, 0x79fc77a1ul, 0x2abe1f49ul, 0xb2b055dful, 0x1069523eul};
162 memcpy(buf, init,
sizeof(buf));
165 if (memcmp(buf, init,
sizeof(buf)))
return false;
168 if (memcmp(buf, out1,
sizeof(buf)))
return false;
170 memcpy(buf, init,
sizeof(buf));
172 if (memcmp(buf, out2,
sizeof(buf)))
return false;
176 TransformType Transform = sha256::Transform;
182 #if defined(USE_ASM) && (defined(__x86_64__) || defined(__amd64__)) 183 uint32_t eax, ebx, ecx, edx;
184 if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) && (ecx >> 19) & 1) {
185 Transform = sha256_sse4::Transform;
186 assert(SelfTest(Transform));
191 assert(SelfTest(Transform));
199 sha256::Initialize(
s);
204 const unsigned char* end = data + len;
205 size_t bufsize =
bytes % 64;
206 if (bufsize && bufsize + len >= 64) {
208 memcpy(
buf + bufsize, data, 64 - bufsize);
209 bytes += 64 - bufsize;
210 data += 64 - bufsize;
211 Transform(
s,
buf, 1);
214 if (end - data >= 64) {
215 size_t blocks = (end - data) / 64;
216 Transform(
s, data, blocks);
218 bytes += 64 * blocks;
230 static const unsigned char pad[64] = {0x80};
231 unsigned char sizedesc[8];
232 WriteBE64(sizedesc,
bytes << 3);
235 WriteBE32(hash,
s[0]);
236 WriteBE32(hash + 4,
s[1]);
237 WriteBE32(hash + 8,
s[2]);
238 WriteBE32(hash + 12,
s[3]);
239 WriteBE32(hash + 16,
s[4]);
240 WriteBE32(hash + 20,
s[5]);
241 WriteBE32(hash + 24,
s[6]);
242 WriteBE32(hash + 28,
s[7]);
248 sha256::Initialize(
s);
CSHA256 & Write(const unsigned char *data, size_t len)
#define Round(a, b, c, d, e, f, g, h, k, w)
std::string SHA256AutoDetect()
Autodetect the best available SHA256 implementation.
void Finalize(unsigned char hash[OUTPUT_SIZE])
void * memcpy(void *a, const void *b, size_t c)
Internal SHA-256 implementation.
static const size_t OUTPUT_SIZE
A hasher class for SHA-256.