12 #if defined(__x86_64__) || defined(__amd64__) 17 void Transform(uint32_t* s,
const unsigned char* chunk,
size_t blocks);
28 uint32_t
inline Ch(uint32_t
x, uint32_t y, uint32_t
z) {
return z ^ (x & (y ^
z)); }
29 uint32_t
inline Maj(uint32_t x, uint32_t y, uint32_t z) {
return (x & y) | (z & (x | y)); }
30 uint32_t
inline Sigma0(uint32_t x) {
return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10); }
31 uint32_t
inline Sigma1(uint32_t x) {
return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7); }
32 uint32_t
inline sigma0(uint32_t x) {
return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3); }
33 uint32_t
inline sigma1(uint32_t x) {
return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10); }
36 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)
38 uint32_t
t1 = h +
Sigma1(e) +
Ch(e, f, g) + k + w;
45 void inline Initialize(uint32_t* s)
58 void Transform(uint32_t* s,
const unsigned char* chunk,
size_t blocks)
61 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];
62 uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
64 Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = ReadBE32(chunk + 0));
65 Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = ReadBE32(chunk + 4));
66 Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = ReadBE32(chunk + 8));
67 Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = ReadBE32(chunk + 12));
68 Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = ReadBE32(chunk + 16));
69 Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = ReadBE32(chunk + 20));
70 Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = ReadBE32(chunk + 24));
71 Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = ReadBE32(chunk + 28));
72 Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = ReadBE32(chunk + 32));
73 Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = ReadBE32(chunk + 36));
74 Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = ReadBE32(chunk + 40));
75 Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = ReadBE32(chunk + 44));
76 Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = ReadBE32(chunk + 48));
77 Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = ReadBE32(chunk + 52));
78 Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = ReadBE32(chunk + 56));
79 Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = ReadBE32(chunk + 60));
110 Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 +=
sigma1(w10) + w5 +
sigma0(w13));
111 Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 +=
sigma1(w11) + w6 +
sigma0(w14));
112 Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 +=
sigma1(w12) + w7 +
sigma0(w15));
127 Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 +=
sigma1(w10) + w5 +
sigma0(w13));
128 Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 +=
sigma1(w11) + w6 +
sigma0(w14));
146 typedef void (*TransformType)(uint32_t*,
const unsigned char*, size_t);
148 bool SelfTest(TransformType tr) {
149 static const unsigned char in1[65] = {0, 0x80};
150 static const unsigned char in2[129] = {
152 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,
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 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,
155 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
157 static const uint32_t init[8] = {0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, 0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul};
158 static const uint32_t out1[8] = {0xe3b0c442ul, 0x98fc1c14ul, 0x9afbf4c8ul, 0x996fb924ul, 0x27ae41e4ul, 0x649b934cul, 0xa495991bul, 0x7852b855ul};
159 static const uint32_t out2[8] = {0xce4153b0ul, 0x147c2a86ul, 0x3ed4298eul, 0xe0676bc8ul, 0x79fc77a1ul, 0x2abe1f49ul, 0xb2b055dful, 0x1069523eul};
161 memcpy(buf, init,
sizeof(buf));
164 if (memcmp(buf, init,
sizeof(buf)))
return false;
167 if (memcmp(buf, out1,
sizeof(buf)))
return false;
169 memcpy(buf, init,
sizeof(buf));
171 if (memcmp(buf, out2,
sizeof(buf)))
return false;
175 TransformType Transform = sha256::Transform;
181 #if defined(USE_ASM) && (defined(__x86_64__) || defined(__amd64__)) 182 uint32_t eax, ebx, ecx, edx;
183 if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) && (ecx >> 19) & 1) {
184 Transform = sha256_sse4::Transform;
185 assert(SelfTest(Transform));
190 assert(SelfTest(Transform));
198 sha256::Initialize(
s);
203 const unsigned char* end = data + len;
204 size_t bufsize =
bytes % 64;
205 if (bufsize && bufsize + len >= 64) {
207 memcpy(
buf + bufsize, data, 64 - bufsize);
208 bytes += 64 - bufsize;
209 data += 64 - bufsize;
210 Transform(
s,
buf, 1);
213 if (end - data >= 64) {
214 size_t blocks = (end -
data) / 64;
215 Transform(
s, data, blocks);
217 bytes += 64 * blocks;
229 static const unsigned char pad[64] = {0x80};
230 unsigned char sizedesc[8];
231 WriteBE64(sizedesc,
bytes << 3);
234 WriteBE32(hash,
s[0]);
235 WriteBE32(hash + 4,
s[1]);
236 WriteBE32(hash + 8,
s[2]);
237 WriteBE32(hash + 12,
s[3]);
238 WriteBE32(hash + 16,
s[4]);
239 WriteBE32(hash + 20,
s[5]);
240 WriteBE32(hash + 24,
s[6]);
241 WriteBE32(hash + 28,
s[7]);
247 sha256::Initialize(
s);
CSHA256 & Write(const unsigned char *data, size_t len)
#define Round(a, b, c, d, e, f, g, h, k, w)
assert(len-trim+(2 *lenIndices)<=WIDTH)
std::string SHA256AutoDetect()
Autodetect the best available SHA256 implementation.
void Finalize(unsigned char hash[OUTPUT_SIZE])
std::vector< byte > bytes
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.