]> Git Repo - VerusCoin.git/blob - src/hash.h
mining performance boost
[VerusCoin.git] / src / hash.h
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2013 The Bitcoin 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 #ifndef BITCOIN_HASH_H
7 #define BITCOIN_HASH_H
8
9 #include "crypto/ripemd160.h"
10 #include "crypto/sha256.h"
11 #include "crypto/verus_hash.h"
12 #include "serialize.h"
13 #include "uint256.h"
14 #include "version.h"
15
16 #include "sodium.h"
17
18 #include <vector>
19
20 typedef uint256 ChainCode;
21
22 /** A hasher class for Bitcoin's 256-bit hash (double SHA-256). */
23 class CHash256 {
24 private:
25     CSHA256 sha;
26 public:
27     static const size_t OUTPUT_SIZE = CSHA256::OUTPUT_SIZE;
28
29     void Finalize(unsigned char hash[OUTPUT_SIZE]) {
30         unsigned char buf[sha.OUTPUT_SIZE];
31         sha.Finalize(buf);
32         sha.Reset().Write(buf, sha.OUTPUT_SIZE).Finalize(hash);
33     }
34
35     CHash256& Write(const unsigned char *data, size_t len) {
36         sha.Write(data, len);
37         return *this;
38     }
39
40     CHash256& Reset() {
41         sha.Reset();
42         return *this;
43     }
44 };
45
46 /** A hasher class for Bitcoin's 160-bit hash (SHA-256 + RIPEMD-160). */
47 class CHash160 {
48 private:
49     CSHA256 sha;
50 public:
51     static const size_t OUTPUT_SIZE = CRIPEMD160::OUTPUT_SIZE;
52
53     void Finalize(unsigned char hash[OUTPUT_SIZE]) {
54         unsigned char buf[sha.OUTPUT_SIZE];
55         sha.Finalize(buf);
56         CRIPEMD160().Write(buf, sha.OUTPUT_SIZE).Finalize(hash);
57     }
58
59     CHash160& Write(const unsigned char *data, size_t len) {
60         sha.Write(data, len);
61         return *this;
62     }
63
64     CHash160& Reset() {
65         sha.Reset();
66         return *this;
67     }
68 };
69
70 /** Compute the 256-bit hash of an object. */
71 template<typename T1>
72 inline uint256 Hash(const T1 pbegin, const T1 pend)
73 {
74     static const unsigned char pblank[1] = {};
75     uint256 result;
76     CHash256().Write(pbegin == pend ? pblank : (const unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0]))
77               .Finalize((unsigned char*)&result);
78     return result;
79 }
80
81 /** Compute the 256-bit hash of the concatenation of two objects. */
82 template<typename T1, typename T2>
83 inline uint256 Hash(const T1 p1begin, const T1 p1end,
84                     const T2 p2begin, const T2 p2end) {
85     static const unsigned char pblank[1] = {};
86     uint256 result;
87     CHash256().Write(p1begin == p1end ? pblank : (const unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0]))
88               .Write(p2begin == p2end ? pblank : (const unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0]))
89               .Finalize((unsigned char*)&result);
90     return result;
91 }
92
93 /** Compute the 256-bit hash of the concatenation of three objects. */
94 template<typename T1, typename T2, typename T3>
95 inline uint256 Hash(const T1 p1begin, const T1 p1end,
96                     const T2 p2begin, const T2 p2end,
97                     const T3 p3begin, const T3 p3end) {
98     static const unsigned char pblank[1] = {};
99     uint256 result;
100     CHash256().Write(p1begin == p1end ? pblank : (const unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0]))
101               .Write(p2begin == p2end ? pblank : (const unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0]))
102               .Write(p3begin == p3end ? pblank : (const unsigned char*)&p3begin[0], (p3end - p3begin) * sizeof(p3begin[0]))
103               .Finalize((unsigned char*)&result);
104     return result;
105 }
106
107 /** Compute the 160-bit hash an object. */
108 template<typename T1>
109 inline uint160 Hash160(const T1 pbegin, const T1 pend)
110 {
111     static unsigned char pblank[1] = {};
112     uint160 result;
113     CHash160().Write(pbegin == pend ? pblank : (const unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0]))
114               .Finalize((unsigned char*)&result);
115     return result;
116 }
117
118 /** Compute the 160-bit hash of a vector. */
119 inline uint160 Hash160(const std::vector<unsigned char>& vch)
120 {
121     return Hash160(vch.begin(), vch.end());
122 }
123
124 /** A writer stream (for serialization) that computes a 256-bit hash. */
125 class CHashWriter
126 {
127 private:
128     CHash256 ctx;
129
130 public:
131     int nType;
132     int nVersion;
133
134     CHashWriter(int nTypeIn, int nVersionIn) : nType(nTypeIn), nVersion(nVersionIn) {}
135
136     CHashWriter& write(const char *pch, size_t size) {
137         ctx.Write((const unsigned char*)pch, size);
138         return (*this);
139     }
140
141     // invalidates the object
142     uint256 GetHash() {
143         uint256 result;
144         ctx.Finalize((unsigned char*)&result);
145         return result;
146     }
147
148     template<typename T>
149     CHashWriter& operator<<(const T& obj) {
150         // Serialize to this stream
151         ::Serialize(*this, obj, nType, nVersion);
152         return (*this);
153     }
154 };
155
156
157 /** A writer stream (for serialization) that computes a 256-bit BLAKE2b hash. */
158 class CBLAKE2bWriter
159 {
160 private:
161     crypto_generichash_blake2b_state state;
162
163 public:
164     int nType;
165     int nVersion;
166
167     CBLAKE2bWriter(int nTypeIn, int nVersionIn, const unsigned char* personal) : nType(nTypeIn), nVersion(nVersionIn) {
168         assert(crypto_generichash_blake2b_init_salt_personal(
169             &state,
170             NULL, 0, // No key.
171             32,
172             NULL,    // No salt.
173             personal) == 0);
174     }
175
176     CBLAKE2bWriter& write(const char *pch, size_t size) {
177         crypto_generichash_blake2b_update(&state, (const unsigned char*)pch, size);
178         return (*this);
179     }
180
181     // invalidates the object
182     uint256 GetHash() {
183         uint256 result;
184         crypto_generichash_blake2b_final(&state, (unsigned char*)&result, 32);
185         return result;
186     }
187
188     template<typename T>
189     CBLAKE2bWriter& operator<<(const T& obj) {
190         // Serialize to this stream
191         ::Serialize(*this, obj, nType, nVersion);
192         return (*this);
193     }
194 };
195
196 /** A writer stream (for serialization) that computes a 256-bit Verus hash. */
197 class CVerusHashWriter
198 {
199 private:
200     CVerusHash state;
201
202 public:
203     int nType;
204     int nVersion;
205
206     CVerusHashWriter(int nTypeIn, int nVersionIn) : nType(nTypeIn), nVersion(nVersionIn), state() {}
207
208     CVerusHashWriter& write(const char *pch, size_t size) {
209         state.Write((const unsigned char*)pch, size);
210         return (*this);
211     }
212
213     // invalidates the object for further writing
214     uint256 GetHash() {
215         uint256 result;
216         state.Finalize((unsigned char*)&result);
217         return result;
218     }
219
220     template<typename T>
221     CVerusHashWriter& operator<<(const T& obj) {
222         // Serialize to this stream
223         ::Serialize(*this, obj, nType, nVersion);
224         return (*this);
225     }
226 };
227
228 /** An optimized and dangerous writer stream (for serialization) that computes a 256-bit Verus hash without the normal
229  * safety checks. Do not try to write more than 1488 bytes to this hash writer. */
230 class CVerusMiningHashWriter
231 {
232 public:
233     union hwBuf {
234         unsigned char charBuf[1488];
235         int32_t i32a[522];
236         hwBuf()
237         {
238             memset(charBuf, 0, sizeof(charBuf));
239         }
240     };
241     hwBuf buf;
242     int nPos;
243     int nType;
244     int nVersion;
245
246     CVerusMiningHashWriter(int nTypeIn, int nVersionIn, int pos = 0) : buf()
247     {
248         nPos = pos;
249         nType = nTypeIn;
250         nVersion = nVersionIn;
251     }
252
253     CVerusMiningHashWriter& write(const char *pch, size_t size) {
254         if ((nPos + size) <= sizeof(buf.charBuf))
255         {
256             memcpy(&(buf.charBuf[nPos]), pch, size);
257             nPos += size;
258         }
259         return (*this);
260     }
261
262     // does not invalidate the object for modification and further hashing
263     uint256 GetHash() {
264         uint256 result;
265         CVerusHash::Hash((unsigned char*)&result, buf.charBuf, nPos);
266         return result;
267     }
268
269     template<typename T>
270     CVerusMiningHashWriter& operator<<(const T& obj) {
271         // Serialize to this stream
272         ::Serialize(*this, obj, nType, nVersion);
273         return (*this);
274     }
275 };
276
277 /** Compute the 256-bit hash of an object's serialization. */
278 template<typename T>
279 uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
280 {
281     CHashWriter ss(nType, nVersion);
282     ss << obj;
283     return ss.GetHash();
284 }
285
286 /** Compute the 256-bit Verus hash of an object's serialization. */
287 template<typename T>
288 uint256 SerializeVerusHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
289 {
290     CVerusHashWriter ss(nType, nVersion);
291     ss << obj;
292     return ss.GetHash();
293 }
294
295 /** Compute the 256-bit Verus hash of an object's serialization. */
296 template<typename T>
297 uint256 SerializeVerusMiningHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
298 {
299     CVerusMiningHashWriter ss = CVerusMiningHashWriter(nType, nVersion);
300     ss << obj;
301     return ss.GetHash();
302 }
303
304 unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char>& vDataToHash);
305
306 void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64]);
307
308 #endif // BITCOIN_HASH_H
This page took 0.040843 seconds and 4 git commands to generate.