Merge #11726: Cleanups + nit fixes for walletdir PR
[bitcoinplatinum.git] / src / crypto / sha256.cpp
blob9a21aec20e9d4e5e19a1f82b71cb42651ef195ca
1 // Copyright (c) 2014 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 #include <crypto/sha256.h>
6 #include <crypto/common.h>
8 #include <assert.h>
9 #include <string.h>
10 #include <atomic>
12 #if defined(__x86_64__) || defined(__amd64__)
13 #if defined(USE_ASM)
14 #include <cpuid.h>
15 namespace sha256_sse4
17 void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks);
19 #endif
20 #endif
22 // Internal implementation code.
23 namespace
25 /// Internal SHA-256 implementation.
26 namespace sha256
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); }
35 /** One round of SHA-256. */
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;
39 uint32_t t2 = Sigma0(a) + Maj(a, b, c);
40 d += t1;
41 h = t1 + t2;
44 /** Initialize SHA-256 state. */
45 void inline Initialize(uint32_t* s)
47 s[0] = 0x6a09e667ul;
48 s[1] = 0xbb67ae85ul;
49 s[2] = 0x3c6ef372ul;
50 s[3] = 0xa54ff53aul;
51 s[4] = 0x510e527ful;
52 s[5] = 0x9b05688cul;
53 s[6] = 0x1f83d9abul;
54 s[7] = 0x5be0cd19ul;
57 /** Perform a number of SHA-256 transformations, processing 64-byte chunks. */
58 void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks)
60 while (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));
81 Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0(w1));
82 Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0(w2));
83 Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += sigma1(w0) + w11 + sigma0(w3));
84 Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += sigma1(w1) + w12 + sigma0(w4));
85 Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += sigma1(w2) + w13 + sigma0(w5));
86 Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += sigma1(w3) + w14 + sigma0(w6));
87 Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += sigma1(w4) + w15 + sigma0(w7));
88 Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += sigma1(w5) + w0 + sigma0(w8));
89 Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += sigma1(w6) + w1 + sigma0(w9));
90 Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += sigma1(w7) + w2 + sigma0(w10));
91 Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += sigma1(w8) + w3 + sigma0(w11));
92 Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += sigma1(w9) + w4 + sigma0(w12));
93 Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13));
94 Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14));
95 Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15));
96 Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0(w0));
98 Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0(w1));
99 Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0(w2));
100 Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += sigma1(w0) + w11 + sigma0(w3));
101 Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += sigma1(w1) + w12 + sigma0(w4));
102 Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += sigma1(w2) + w13 + sigma0(w5));
103 Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += sigma1(w3) + w14 + sigma0(w6));
104 Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += sigma1(w4) + w15 + sigma0(w7));
105 Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += sigma1(w5) + w0 + sigma0(w8));
106 Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += sigma1(w6) + w1 + sigma0(w9));
107 Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += sigma1(w7) + w2 + sigma0(w10));
108 Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += sigma1(w8) + w3 + sigma0(w11));
109 Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += sigma1(w9) + w4 + sigma0(w12));
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));
113 Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0(w0));
115 Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0(w1));
116 Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0(w2));
117 Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += sigma1(w0) + w11 + sigma0(w3));
118 Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += sigma1(w1) + w12 + sigma0(w4));
119 Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += sigma1(w2) + w13 + sigma0(w5));
120 Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += sigma1(w3) + w14 + sigma0(w6));
121 Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += sigma1(w4) + w15 + sigma0(w7));
122 Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += sigma1(w5) + w0 + sigma0(w8));
123 Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += sigma1(w6) + w1 + sigma0(w9));
124 Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += sigma1(w7) + w2 + sigma0(w10));
125 Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += sigma1(w8) + w3 + sigma0(w11));
126 Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += sigma1(w9) + w4 + sigma0(w12));
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));
129 Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15));
130 Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0(w0));
132 s[0] += a;
133 s[1] += b;
134 s[2] += c;
135 s[3] += d;
136 s[4] += e;
137 s[5] += f;
138 s[6] += g;
139 s[7] += h;
140 chunk += 64;
144 } // namespace sha256
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};
160 uint32_t buf[8];
161 memcpy(buf, init, sizeof(buf));
162 // Process nothing, and check we remain in the initial state.
163 tr(buf, nullptr, 0);
164 if (memcmp(buf, init, sizeof(buf))) return false;
165 // Process the padded empty string (unaligned)
166 tr(buf, in1 + 1, 1);
167 if (memcmp(buf, out1, sizeof(buf))) return false;
168 // Process 64 spaces (unaligned)
169 memcpy(buf, init, sizeof(buf));
170 tr(buf, in2 + 1, 2);
171 if (memcmp(buf, out2, sizeof(buf))) return false;
172 return true;
175 TransformType Transform = sha256::Transform;
177 } // namespace
179 std::string SHA256AutoDetect()
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));
186 return "sse4";
188 #endif
190 assert(SelfTest(Transform));
191 return "standard";
194 ////// SHA-256
196 CSHA256::CSHA256() : bytes(0)
198 sha256::Initialize(s);
201 CSHA256& CSHA256::Write(const unsigned char* data, size_t len)
203 const unsigned char* end = data + len;
204 size_t bufsize = bytes % 64;
205 if (bufsize && bufsize + len >= 64) {
206 // Fill the buffer, and process it.
207 memcpy(buf + bufsize, data, 64 - bufsize);
208 bytes += 64 - bufsize;
209 data += 64 - bufsize;
210 Transform(s, buf, 1);
211 bufsize = 0;
213 if (end - data >= 64) {
214 size_t blocks = (end - data) / 64;
215 Transform(s, data, blocks);
216 data += 64 * blocks;
217 bytes += 64 * blocks;
219 if (end > data) {
220 // Fill the buffer with what remains.
221 memcpy(buf + bufsize, data, end - data);
222 bytes += end - data;
224 return *this;
227 void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
229 static const unsigned char pad[64] = {0x80};
230 unsigned char sizedesc[8];
231 WriteBE64(sizedesc, bytes << 3);
232 Write(pad, 1 + ((119 - (bytes % 64)) % 64));
233 Write(sizedesc, 8);
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]);
244 CSHA256& CSHA256::Reset()
246 bytes = 0;
247 sha256::Initialize(s);
248 return *this;