Raven Core  3.0.0
P2P Digital Currency
hash.cpp
Go to the documentation of this file.
1 // Copyright (c) 2013-2016 The Bitcoin Core developers
2 // Copyright (c) 2017-2019 The Raven Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include "hash.h"
7 #include "crypto/common.h"
8 #include "crypto/hmac_sha512.h"
9 #include "pubkey.h"
10 
11 //TODO remove these
12 double algoHashTotal[16];
13 int algoHashHits[16];
14 
15 inline uint32_t ROTL32(uint32_t x, int8_t r)
16 {
17  return (x << r) | (x >> (32 - r));
18 }
19 
20 unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char>& vDataToHash)
21 {
22  // The following is MurmurHash3 (x86_32), see http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp
23  uint32_t h1 = nHashSeed;
24  const uint32_t c1 = 0xcc9e2d51;
25  const uint32_t c2 = 0x1b873593;
26 
27  const int nblocks = vDataToHash.size() / 4;
28 
29  //----------
30  // body
31  const uint8_t* blocks = vDataToHash.data();
32 
33  for (int i = 0; i < nblocks; ++i) {
34  uint32_t k1 = ReadLE32(blocks + i*4);
35 
36  k1 *= c1;
37  k1 = ROTL32(k1, 15);
38  k1 *= c2;
39 
40  h1 ^= k1;
41  h1 = ROTL32(h1, 13);
42  h1 = h1 * 5 + 0xe6546b64;
43  }
44 
45  //----------
46  // tail
47  const uint8_t* tail = vDataToHash.data() + nblocks * 4;
48 
49  uint32_t k1 = 0;
50 
51  switch (vDataToHash.size() & 3) {
52  case 3:
53  k1 ^= tail[2] << 16;
54  case 2:
55  k1 ^= tail[1] << 8;
56  case 1:
57  k1 ^= tail[0];
58  k1 *= c1;
59  k1 = ROTL32(k1, 15);
60  k1 *= c2;
61  h1 ^= k1;
62  }
63 
64  //----------
65  // finalization
66  h1 ^= vDataToHash.size();
67  h1 ^= h1 >> 16;
68  h1 *= 0x85ebca6b;
69  h1 ^= h1 >> 13;
70  h1 *= 0xc2b2ae35;
71  h1 ^= h1 >> 16;
72 
73  return h1;
74 }
75 
76 void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64])
77 {
78  unsigned char num[4];
79  num[0] = (nChild >> 24) & 0xFF;
80  num[1] = (nChild >> 16) & 0xFF;
81  num[2] = (nChild >> 8) & 0xFF;
82  num[3] = (nChild >> 0) & 0xFF;
83  CHMAC_SHA512(chainCode.begin(), chainCode.size()).Write(&header, 1).Write(data, 32).Write(num, 4).Finalize(output);
84 }
85 
86 #define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
87 
88 #define SIPROUND do { \
89  v0 += v1; v1 = ROTL(v1, 13); v1 ^= v0; \
90  v0 = ROTL(v0, 32); \
91  v2 += v3; v3 = ROTL(v3, 16); v3 ^= v2; \
92  v0 += v3; v3 = ROTL(v3, 21); v3 ^= v0; \
93  v2 += v1; v1 = ROTL(v1, 17); v1 ^= v2; \
94  v2 = ROTL(v2, 32); \
95 } while (0)
96 
97 CSipHasher::CSipHasher(uint64_t k0, uint64_t k1)
98 {
99  v[0] = 0x736f6d6570736575ULL ^ k0;
100  v[1] = 0x646f72616e646f6dULL ^ k1;
101  v[2] = 0x6c7967656e657261ULL ^ k0;
102  v[3] = 0x7465646279746573ULL ^ k1;
103  count = 0;
104  tmp = 0;
105 }
106 
108 {
109  uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
110 
111  assert(count % 8 == 0);
112 
113  v3 ^= data;
114  SIPROUND;
115  SIPROUND;
116  v0 ^= data;
117 
118  v[0] = v0;
119  v[1] = v1;
120  v[2] = v2;
121  v[3] = v3;
122 
123  count += 8;
124  return *this;
125 }
126 
127 CSipHasher& CSipHasher::Write(const unsigned char* data, size_t size)
128 {
129  uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
130  uint64_t t = tmp;
131  int c = count;
132 
133  while (size--) {
134  t |= ((uint64_t)(*(data++))) << (8 * (c % 8));
135  c++;
136  if ((c & 7) == 0) {
137  v3 ^= t;
138  SIPROUND;
139  SIPROUND;
140  v0 ^= t;
141  t = 0;
142  }
143  }
144 
145  v[0] = v0;
146  v[1] = v1;
147  v[2] = v2;
148  v[3] = v3;
149  count = c;
150  tmp = t;
151 
152  return *this;
153 }
154 
155 uint64_t CSipHasher::Finalize() const
156 {
157  uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
158 
159  uint64_t t = tmp | (((uint64_t)count) << 56);
160 
161  v3 ^= t;
162  SIPROUND;
163  SIPROUND;
164  v0 ^= t;
165  v2 ^= 0xFF;
166  SIPROUND;
167  SIPROUND;
168  SIPROUND;
169  SIPROUND;
170  return v0 ^ v1 ^ v2 ^ v3;
171 }
172 
173 uint64_t SipHashUint256(uint64_t k0, uint64_t k1, const uint256& val)
174 {
175  /* Specialized implementation for efficiency */
176  uint64_t d = val.GetUint64(0);
177 
178  uint64_t v0 = 0x736f6d6570736575ULL ^ k0;
179  uint64_t v1 = 0x646f72616e646f6dULL ^ k1;
180  uint64_t v2 = 0x6c7967656e657261ULL ^ k0;
181  uint64_t v3 = 0x7465646279746573ULL ^ k1 ^ d;
182 
183  SIPROUND;
184  SIPROUND;
185  v0 ^= d;
186  d = val.GetUint64(1);
187  v3 ^= d;
188  SIPROUND;
189  SIPROUND;
190  v0 ^= d;
191  d = val.GetUint64(2);
192  v3 ^= d;
193  SIPROUND;
194  SIPROUND;
195  v0 ^= d;
196  d = val.GetUint64(3);
197  v3 ^= d;
198  SIPROUND;
199  SIPROUND;
200  v0 ^= d;
201  v3 ^= ((uint64_t)4) << 59;
202  SIPROUND;
203  SIPROUND;
204  v0 ^= ((uint64_t)4) << 59;
205  v2 ^= 0xFF;
206  SIPROUND;
207  SIPROUND;
208  SIPROUND;
209  SIPROUND;
210  return v0 ^ v1 ^ v2 ^ v3;
211 }
212 
213 uint64_t SipHashUint256Extra(uint64_t k0, uint64_t k1, const uint256& val, uint32_t extra)
214 {
215  /* Specialized implementation for efficiency */
216  uint64_t d = val.GetUint64(0);
217 
218  uint64_t v0 = 0x736f6d6570736575ULL ^ k0;
219  uint64_t v1 = 0x646f72616e646f6dULL ^ k1;
220  uint64_t v2 = 0x6c7967656e657261ULL ^ k0;
221  uint64_t v3 = 0x7465646279746573ULL ^ k1 ^ d;
222 
223  SIPROUND;
224  SIPROUND;
225  v0 ^= d;
226  d = val.GetUint64(1);
227  v3 ^= d;
228  SIPROUND;
229  SIPROUND;
230  v0 ^= d;
231  d = val.GetUint64(2);
232  v3 ^= d;
233  SIPROUND;
234  SIPROUND;
235  v0 ^= d;
236  d = val.GetUint64(3);
237  v3 ^= d;
238  SIPROUND;
239  SIPROUND;
240  v0 ^= d;
241  d = (((uint64_t)36) << 56) | extra;
242  v3 ^= d;
243  SIPROUND;
244  SIPROUND;
245  v0 ^= d;
246  v2 ^= 0xFF;
247  SIPROUND;
248  SIPROUND;
249  SIPROUND;
250  SIPROUND;
251  return v0 ^ v1 ^ v2 ^ v3;
252 }
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: hmac_sha512.cpp:30
CHMAC_SHA512 & Write(const unsigned char *data, size_t len)
Definition: hmac_sha512.h:25
int algoHashHits[16]
Definition: hash.cpp:13
uint64_t v[4]
Definition: hash.h:316
CSipHasher & Write(uint64_t data)
Hash a 64-bit integer worth of data It is treated as if this was the little-endian interpretation of ...
Definition: hash.cpp:107
double algoHashTotal[16]
Definition: hash.cpp:12
CSipHasher(uint64_t k0, uint64_t k1)
Construct a SipHash calculator initialized with 128-bit key (k0, k1)
Definition: hash.cpp:97
unsigned char * begin()
Definition: uint256.h:57
unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector< unsigned char > &vDataToHash)
Definition: hash.cpp:20
int count
Definition: hash.h:318
void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64])
Definition: hash.cpp:76
uint64_t Finalize() const
Compute the 64-bit SipHash-2-4 of the data written so far.
Definition: hash.cpp:155
unsigned int size() const
Definition: uint256.h:77
uint64_t tmp
Definition: hash.h:317
256-bit opaque blob.
Definition: uint256.h:123
uint64_t SipHashUint256(uint64_t k0, uint64_t k1, const uint256 &val)
Optimized SipHash-2-4 implementation for uint256.
Definition: hash.cpp:173
SipHash-2-4.
Definition: hash.h:313
#define SIPROUND
Definition: hash.cpp:88
uint64_t GetUint64(int pos) const
Definition: uint256.h:82
uint64_t SipHashUint256Extra(uint64_t k0, uint64_t k1, const uint256 &val, uint32_t extra)
Definition: hash.cpp:213
uint32_t ROTL32(uint32_t x, int8_t r)
Definition: hash.cpp:15
A hasher class for HMAC-SHA-512.
Definition: hmac_sha512.h:15