Fabcoin Core  0.16.2
P2P Digital Currency
sha256.cpp
Go to the documentation of this file.
1 // Copyright (c) 2014-2017 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.
4 
5 #include <crypto/sha256.h>
6 #include <crypto/common.h>
7 
8 #include <assert.h>
9 #include <string.h>
10 #include <atomic>
11 
12 #if defined(__x86_64__) || defined(__amd64__)
13 #if defined(USE_ASM)
14 #include <cpuid.h>
15 namespace sha256_sse4
16 {
17 void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks);
18 }
19 #endif
20 #endif
21 
22 // Internal implementation code.
23 namespace
24 {
26 namespace sha256
27 {
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); }
34 
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)
37 {
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;
42 }
43 
45 void inline Initialize(uint32_t* s)
46 {
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;
55 }
56 
58 void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks)
59 {
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;
63 
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));
80 
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));
97 
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));
114 
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));
131 
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;
141  }
142 }
143 
144 } // namespace sha256
145 
146 typedef void (*TransformType)(uint32_t*, const unsigned char*, size_t);
147 
148 bool SelfTest(TransformType tr) {
149  static const unsigned char in1[65] = {0, 0x80};
150  static const unsigned char in2[129] = {
151  0,
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
156  };
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;
173 }
174 
175 TransformType Transform = sha256::Transform;
176 
177 } // namespace
178 
179 std::string SHA256AutoDetect()
180 {
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";
187  }
188 #endif
189 
190  assert(SelfTest(Transform));
191  return "standard";
192 }
193 
195 
197 {
198  sha256::Initialize(s);
199 }
200 
201 CSHA256& CSHA256::Write(const unsigned char* data, size_t len)
202 {
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;
212  }
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;
218  }
219  if (end > data) {
220  // Fill the buffer with what remains.
221  memcpy(buf + bufsize, data, end - data);
222  bytes += end - data;
223  }
224  return *this;
225 }
226 
227 void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
228 {
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]);
242 }
243 
245 {
246  bytes = 0;
247  sha256::Initialize(s);
248  return *this;
249 }
CSHA256 & Write(const unsigned char *data, size_t len)
Definition: sha256.cpp:201
#define Round(a, b, c, d, e, f, g, h, k, w)
Definition: hash_impl.h:23
#define h(i)
Definition: sha.cpp:736
#define Ch(x, y, z)
Definition: sha256.c:63
uint32_t s[8]
Definition: sha256.h:16
#define g(i)
Definition: sha.cpp:735
#define c(i)
assert(len-trim+(2 *lenIndices)<=WIDTH)
#define sigma1(x)
Definition: hash_impl.h:21
std::string SHA256AutoDetect()
Autodetect the best available SHA256 implementation.
Definition: sha256.cpp:179
#define sigma0(x)
Definition: hash_impl.h:20
#define a(i)
#define x(i)
CSHA256 & Reset()
Definition: sha256.cpp:244
#define Sigma0(x)
Definition: hash_impl.h:18
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: sha256.cpp:227
std::vector< byte > bytes
Definition: Common.h:75
#define t1
#define b(i, j)
#define t2
#define Sigma1(x)
Definition: hash_impl.h:19
#define f(x)
Definition: gost.cpp:57
uint64_t bytes
Definition: sha256.h:18
void * memcpy(void *a, const void *b, size_t c)
#define Maj(x, y, z)
Definition: sha256.c:64
Internal SHA-256 implementation.
Definition: sha256.cpp:26
static const size_t OUTPUT_SIZE
Definition: sha256.h:21
CSHA256()
Definition: sha256.cpp:196
#define e(i)
Definition: sha.cpp:733
#define d(i)
Definition: sha.cpp:732
#define z(i)
unsigned char buf[64]
Definition: sha256.h:17
A hasher class for SHA-256.
Definition: sha256.h:13
uint8_t const * data
Definition: sha3.h:19