Fabcoin Core  0.16.2
P2P Digital Currency
picosha2.h
Go to the documentation of this file.
1 /*
2 The MIT License (MIT)
3 
4 Copyright (C) 2014 okdshin
5 
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12 
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15 
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 THE SOFTWARE.
23 */
24 #ifndef PICOSHA2_H
25 #define PICOSHA2_H
26 //picosha2:20140213
27 #include <cstdint>
28 #include <iostream>
29 #include <vector>
30 #include <iterator>
31 #include <cassert>
32 #include <sstream>
33 #include <algorithm>
34 
35 namespace picosha2
36 {
37 
38 namespace detail
39 {
40 
41 inline uint8_t mask_8bit(uint8_t x){
42  return x&0xff;
43 }
44 
45 inline uint32_t mask_32bit(uint32_t x){
46  return x&0xffffffff;
47 }
48 
49 static const uint32_t add_constant[64] = {
50  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
51  0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
52  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
53  0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
54  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
55  0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
56  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
57  0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
58  0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
59  0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
60  0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
61  0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
62  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
63  0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
64  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
65  0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
66 };
67 
68 static const uint32_t initial_message_digest[8] = {
69  0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
70  0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
71 };
72 
73 inline uint32_t ch(uint32_t x, uint32_t y, uint32_t z){
74  return (x&y)^((~x)&z);
75 }
76 
77 inline uint32_t maj(uint32_t x, uint32_t y, uint32_t z){
78  return (x&y)^(x&z)^(y&z);
79 }
80 
81 inline uint32_t rotr(uint32_t x, std::size_t n){
82  assert(n < 32);
83  return mask_32bit((x>>n)|(x<<(32-n)));
84 }
85 
86 inline uint32_t bsig0(uint32_t x){
87  return rotr(x, 2)^rotr(x, 13)^rotr(x, 22);
88 }
89 
90 inline uint32_t bsig1(uint32_t x){
91  return rotr(x, 6)^rotr(x, 11)^rotr(x, 25);
92 }
93 
94 inline uint32_t shr(uint32_t x, std::size_t n){
95  assert(n < 32);
96  return x >> n;
97 }
98 
99 inline uint32_t ssig0(uint32_t x){
100  return rotr(x, 7)^rotr(x, 18)^shr(x, 3);
101 }
102 
103 inline uint32_t ssig1(uint32_t x){
104  return rotr(x, 17)^rotr(x, 19)^shr(x, 10);
105 }
106 
107 template<typename RaIter1, typename RaIter2>
108 void hash256_block(RaIter1 message_digest, RaIter2 first, RaIter2 last){
109  (void)last; // FIXME: check this is valid
110  uint32_t w[64];
111  std::fill(w, w+64, 0);
112  for(std::size_t i = 0; i < 16; ++i){
113  w[i] = (static_cast<uint32_t>(mask_8bit(*(first+i*4)))<<24)
114  |(static_cast<uint32_t>(mask_8bit(*(first+i*4+1)))<<16)
115  |(static_cast<uint32_t>(mask_8bit(*(first+i*4+2)))<<8)
116  |(static_cast<uint32_t>(mask_8bit(*(first+i*4+3))));
117  }
118  for(std::size_t i = 16; i < 64; ++i){
119  w[i] = mask_32bit(ssig1(w[i-2])+w[i-7]+ssig0(w[i-15])+w[i-16]);
120  }
121 
122  uint32_t a = *message_digest;
123  uint32_t b = *(message_digest+1);
124  uint32_t c = *(message_digest+2);
125  uint32_t d = *(message_digest+3);
126  uint32_t e = *(message_digest+4);
127  uint32_t f = *(message_digest+5);
128  uint32_t g = *(message_digest+6);
129  uint32_t h = *(message_digest+7);
130 
131  for(std::size_t i = 0; i < 64; ++i){
132  uint32_t temp1 = h+bsig1(e)+ch(e,f,g)+add_constant[i]+w[i];
133  uint32_t temp2 = bsig0(a)+maj(a,b,c);
134  h = g;
135  g = f;
136  f = e;
137  e = mask_32bit(d+temp1);
138  d = c;
139  c = b;
140  b = a;
141  a = mask_32bit(temp1+temp2);
142  }
143  *message_digest += a;
144  *(message_digest+1) += b;
145  *(message_digest+2) += c;
146  *(message_digest+3) += d;
147  *(message_digest+4) += e;
148  *(message_digest+5) += f;
149  *(message_digest+6) += g;
150  *(message_digest+7) += h;
151  for(std::size_t i = 0; i < 8; ++i){
152  *(message_digest+i) = mask_32bit(*(message_digest+i));
153  }
154 }
155 
156 }//namespace detail
157 
158 template<typename InIter>
159 void output_hex(InIter first, InIter last, std::ostream& os){
160  os.setf(std::ios::hex, std::ios::basefield);
161  while(first != last){
162  os.width(2);
163  os.fill('0');
164  os << static_cast<unsigned int>(*first);
165  ++first;
166  }
167  os.setf(std::ios::dec, std::ios::basefield);
168 }
169 
170 template<typename InIter>
171 void bytes_to_hex_string(InIter first, InIter last, std::string& hex_str){
172  std::ostringstream oss;
173  output_hex(first, last, oss);
174  hex_str.assign(oss.str());
175 }
176 
177 template<typename InContainer>
178 void bytes_to_hex_string(const InContainer& bytes, std::string& hex_str){
179  bytes_to_hex_string(bytes.begin(), bytes.end(), hex_str);
180 }
181 
182 template<typename InIter>
183 std::string bytes_to_hex_string(InIter first, InIter last){
184  std::string hex_str;
185  bytes_to_hex_string(first, last, hex_str);
186  return hex_str;
187 }
188 
189 template<typename InContainer>
190 std::string bytes_to_hex_string(const InContainer& bytes){
191  std::string hex_str;
192  bytes_to_hex_string(bytes, hex_str);
193  return hex_str;
194 }
195 
197 public:
199  init();
200  }
201 
202  void init(){
203  buffer_.clear();
204  std::fill(data_length_digits_, data_length_digits_+4, 0);
205  std::copy(detail::initial_message_digest, detail::initial_message_digest+8, h_);
206  }
207 
208  template<typename RaIter>
209  void process(RaIter first, RaIter last){
210  add_to_data_length(std::distance(first, last));
211  std::copy(first, last, std::back_inserter(buffer_));
212  std::size_t i = 0;
213  for(;i+64 <= buffer_.size(); i+=64){
214  detail::hash256_block(h_, buffer_.begin()+i, buffer_.begin()+i+64);
215  }
216  buffer_.erase(buffer_.begin(), buffer_.begin()+i);
217  }
218 
219  void finish(){
220  uint8_t temp[64];
221  std::fill(temp, temp+64, 0);
222  std::size_t remains = buffer_.size();
223  std::copy(buffer_.begin(), buffer_.end(), temp);
224  temp[remains] = 0x80;
225 
226  if(remains > 55){
227  std::fill(temp+remains+1, temp+64, 0);
228  detail::hash256_block(h_, temp, temp+64);
229  std::fill(temp, temp+64-4, 0);
230  }
231  else {
232  std::fill(temp+remains+1, temp+64-4, 0);
233  }
234 
235  write_data_bit_length(&(temp[56]));
236  detail::hash256_block(h_, temp, temp+64);
237  }
238 
239  template<typename OutIter>
240  void get_hash_bytes(OutIter first, OutIter last)const{
241  for(const uint32_t* iter = h_; iter != h_+8; ++iter){
242  for(std::size_t i = 0; i < 4 && first != last; ++i){
243  *(first++) = detail::mask_8bit(static_cast<uint8_t>((*iter >> (24-8*i))));
244  }
245  }
246  }
247 
248 private:
249  void add_to_data_length(uint32_t n) {
250  uint32_t carry = 0;
251  data_length_digits_[0] += n;
252  for(std::size_t i = 0; i < 4; ++i) {
253  data_length_digits_[i] += carry;
254  if(data_length_digits_[i] >= 65536u) {
255  data_length_digits_[i] -= 65536u;
256  carry = 1;
257  }
258  else {
259  break;
260  }
261  }
262  }
263  void write_data_bit_length(uint8_t* begin) {
264  uint32_t data_bit_length_digits[4];
265  std::copy(
266  data_length_digits_, data_length_digits_+4,
267  data_bit_length_digits
268  );
269 
270  // convert byte length to bit length (multiply 8 or shift 3 times left)
271  uint32_t carry = 0;
272  for(std::size_t i = 0; i < 4; ++i) {
273  uint32_t before_val = data_bit_length_digits[i];
274  data_bit_length_digits[i] <<= 3;
275  data_bit_length_digits[i] |= carry;
276  data_bit_length_digits[i] &= 65535u;
277  carry = (before_val >> (16-3)) & 65535u;
278  }
279 
280  // write data_bit_length
281  for(int i = 3; i >= 0; --i) {
282  (*begin++) = static_cast<uint8_t>(data_bit_length_digits[i] >> 8);
283  (*begin++) = static_cast<uint8_t>(data_bit_length_digits[i]);
284  }
285  }
286  std::vector<uint8_t> buffer_;
287  uint32_t data_length_digits_[4]; //as 64bit integer (16bit x 4 integer)
288  uint32_t h_[8];
289 };
290 
291 inline void get_hash_hex_string(const hash256_one_by_one& hasher, std::string& hex_str){
292  uint8_t hash[32];
293  hasher.get_hash_bytes(hash, hash+32);
294  return bytes_to_hex_string(hash, hash+32, hex_str);
295 }
296 
297 inline std::string get_hash_hex_string(const hash256_one_by_one& hasher){
298  std::string hex_str;
299  get_hash_hex_string(hasher, hex_str);
300  return hex_str;
301 }
302 
303 template<typename RaIter, typename OutIter>
304 void hash256(RaIter first, RaIter last, OutIter first2, OutIter last2){
305  hash256_one_by_one hasher;
306  //hasher.init();
307  hasher.process(first, last);
308  hasher.finish();
309  hasher.get_hash_bytes(first2, last2);
310 }
311 
312 template<typename RaIter, typename OutContainer>
313 void hash256(RaIter first, RaIter last, OutContainer& dst){
314  hash256(first, last, dst.begin(), dst.end());
315 }
316 
317 template<typename RaContainer, typename OutIter>
318 void hash256(const RaContainer& src, OutIter first, OutIter last){
319  hash256(src.begin(), src.end(), first, last);
320 }
321 
322 template<typename RaContainer, typename OutContainer>
323 void hash256(const RaContainer& src, OutContainer& dst){
324  hash256(src.begin(), src.end(), dst.begin(), dst.end());
325 }
326 
327 
328 template<typename RaIter>
329 void hash256_hex_string(RaIter first, RaIter last, std::string& hex_str){
330  uint8_t hashed[32];
331  hash256(first, last, hashed, hashed+32);
332  std::ostringstream oss;
333  output_hex(hashed, hashed+32, oss);
334  hex_str.assign(oss.str());
335 }
336 
337 template<typename RaIter>
338 std::string hash256_hex_string(RaIter first, RaIter last){
339  std::string hex_str;
340  hash256_hex_string(first, last, hex_str);
341  return hex_str;
342 }
343 
344 inline void hash256_hex_string(const std::string& src, std::string& hex_str){
345  hash256_hex_string(src.begin(), src.end(), hex_str);
346 }
347 
348 template<typename RaContainer>
349 void hash256_hex_string(const RaContainer& src, std::string& hex_str){
350  hash256_hex_string(src.begin(), src.end(), hex_str);
351 }
352 
353 template<typename RaContainer>
354 std::string hash256_hex_string(const RaContainer& src){
355  return hash256_hex_string(src.begin(), src.end());
356 }
357 
358 }//namespace picosha2
359 
360 #endif //PICOSHA2_H
void bytes_to_hex_string(InIter first, InIter last, std::string &hex_str)
Definition: picosha2.h:171
uint32_t maj(uint32_t x, uint32_t y, uint32_t z)
Definition: picosha2.h:77
uint8_t mask_8bit(uint8_t x)
Definition: picosha2.h:41
void hash256(RaIter first, RaIter last, OutIter first2, OutIter last2)
Definition: picosha2.h:304
#define h(i)
Definition: sha.cpp:736
#define g(i)
Definition: sha.cpp:735
void hash256_hex_string(RaIter first, RaIter last, std::string &hex_str)
Definition: picosha2.h:329
#define c(i)
void get_hash_bytes(OutIter first, OutIter last) const
Definition: picosha2.h:240
assert(len-trim+(2 *lenIndices)<=WIDTH)
void add_to_data_length(uint32_t n)
Definition: picosha2.h:249
void process(RaIter first, RaIter last)
Definition: picosha2.h:209
uint32_t mask_32bit(uint32_t x)
Definition: picosha2.h:45
std::vector< uint8_t > buffer_
Definition: picosha2.h:286
void output_hex(InIter first, InIter last, std::ostream &os)
Definition: picosha2.h:159
#define a(i)
#define x(i)
void get_hash_hex_string(const hash256_one_by_one &hasher, std::string &hex_str)
Definition: picosha2.h:291
uint32_t shr(uint32_t x, std::size_t n)
Definition: picosha2.h:94
std::vector< byte > bytes
Definition: Common.h:75
#define b(i, j)
#define f(x)
Definition: gost.cpp:57
uint32_t rotr(uint32_t x, std::size_t n)
Definition: picosha2.h:81
uint32_t ssig1(uint32_t x)
Definition: picosha2.h:103
#define e(i)
Definition: sha.cpp:733
void hash256_block(RaIter1 message_digest, RaIter2 first, RaIter2 last)
Definition: picosha2.h:108
uint32_t bsig1(uint32_t x)
Definition: picosha2.h:90
#define d(i)
Definition: sha.cpp:732
#define z(i)
uint32_t ch(uint32_t x, uint32_t y, uint32_t z)
Definition: picosha2.h:73
void write_data_bit_length(uint8_t *begin)
Definition: picosha2.h:263
uint32_t ssig0(uint32_t x)
Definition: picosha2.h:99
uint32_t bsig0(uint32_t x)
Definition: picosha2.h:86