Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2014 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 : #include "uint256.h"
7 :
8 : #include "utilstrencodings.h"
9 :
10 : #include <stdio.h>
11 : #include <string.h>
12 :
13 : template <unsigned int BITS>
14 17681 : base_blob<BITS>::base_blob(const std::vector<unsigned char>& vch)
15 : {
16 35362 : assert(vch.size() == sizeof(data));
17 17681 : memcpy(data, &vch[0], sizeof(data));
18 17681 : }
19 :
20 : template <unsigned int BITS>
21 60486 : std::string base_blob<BITS>::GetHex() const
22 : {
23 : char psz[sizeof(data) * 2 + 1];
24 1995731 : for (unsigned int i = 0; i < sizeof(data); i++)
25 1935245 : sprintf(psz + i * 2, "%02x", data[sizeof(data) - i - 1]);
26 120972 : return std::string(psz, psz + sizeof(data) * 2);
27 : }
28 :
29 : template <unsigned int BITS>
30 3071 : void base_blob<BITS>::SetHex(const char* psz)
31 : {
32 3071 : memset(data, 0, sizeof(data));
33 :
34 : // skip leading spaces
35 3080 : while (isspace(*psz))
36 9 : psz++;
37 :
38 : // skip 0x
39 3071 : if (psz[0] == '0' && tolower(psz[1]) == 'x')
40 2138 : psz += 2;
41 :
42 : // hex string to uint
43 3071 : const char* pbegin = psz;
44 202056 : while (::HexDigit(*psz) != -1)
45 195914 : psz++;
46 3071 : psz--;
47 3071 : unsigned char* p1 = (unsigned char*)data;
48 3071 : unsigned char* pend = p1 + WIDTH;
49 104088 : while (psz >= pbegin && p1 < pend) {
50 97946 : *p1 = ::HexDigit(*psz--);
51 97946 : if (psz >= pbegin) {
52 97944 : *p1 |= ((unsigned char)::HexDigit(*psz--) << 4);
53 97944 : p1++;
54 : }
55 : }
56 3071 : }
57 :
58 : template <unsigned int BITS>
59 316 : void base_blob<BITS>::SetHex(const std::string& str)
60 : {
61 316 : SetHex(str.c_str());
62 316 : }
63 :
64 : template <unsigned int BITS>
65 57797 : std::string base_blob<BITS>::ToString() const
66 : {
67 57797 : return (GetHex());
68 : }
69 :
70 : // Explicit instantiations for base_blob<160>
71 : template base_blob<160>::base_blob(const std::vector<unsigned char>&);
72 : template std::string base_blob<160>::GetHex() const;
73 : template std::string base_blob<160>::ToString() const;
74 : template void base_blob<160>::SetHex(const char*);
75 : template void base_blob<160>::SetHex(const std::string&);
76 :
77 : // Explicit instantiations for base_blob<256>
78 : template base_blob<256>::base_blob(const std::vector<unsigned char>&);
79 : template std::string base_blob<256>::GetHex() const;
80 : template std::string base_blob<256>::ToString() const;
81 : template void base_blob<256>::SetHex(const char*);
82 : template void base_blob<256>::SetHex(const std::string&);
83 :
84 1694860 : static void inline HashMix(uint32_t& a, uint32_t& b, uint32_t& c)
85 : {
86 : // Taken from lookup3, by Bob Jenkins.
87 1694860 : a -= c;
88 1694860 : a ^= ((c << 4) | (c >> 28));
89 1694860 : c += b;
90 1694860 : b -= a;
91 1694860 : b ^= ((a << 6) | (a >> 26));
92 1694860 : a += c;
93 1694860 : c -= b;
94 1694860 : c ^= ((b << 8) | (b >> 24));
95 1694860 : b += a;
96 1694860 : a -= c;
97 1694860 : a ^= ((c << 16) | (c >> 16));
98 1694860 : c += b;
99 1694860 : b -= a;
100 1694860 : b ^= ((a << 19) | (a >> 13));
101 1694860 : a += c;
102 1694860 : c -= b;
103 1694860 : c ^= ((b << 4) | (b >> 28));
104 1694860 : b += a;
105 1694860 : }
106 :
107 847430 : static void inline HashFinal(uint32_t& a, uint32_t& b, uint32_t& c)
108 : {
109 : // Taken from lookup3, by Bob Jenkins.
110 847430 : c ^= b;
111 847430 : c -= ((b << 14) | (b >> 18));
112 847430 : a ^= c;
113 847430 : a -= ((c << 11) | (c >> 21));
114 847430 : b ^= a;
115 847430 : b -= ((a << 25) | (a >> 7));
116 847430 : c ^= b;
117 847430 : c -= ((b << 16) | (b >> 16));
118 847430 : a ^= c;
119 847430 : a -= ((c << 4) | (c >> 28));
120 847430 : b ^= a;
121 847430 : b -= ((a << 14) | (a >> 18));
122 847430 : c ^= b;
123 847430 : c -= ((b << 24) | (b >> 8));
124 847430 : }
125 :
126 847430 : uint64_t uint256::GetHash(const uint256& salt) const
127 : {
128 : uint32_t a, b, c;
129 847430 : const uint32_t *pn = (const uint32_t*)data;
130 847430 : const uint32_t *salt_pn = (const uint32_t*)salt.data;
131 847430 : a = b = c = 0xdeadbeef + WIDTH;
132 :
133 847430 : a += pn[0] ^ salt_pn[0];
134 847430 : b += pn[1] ^ salt_pn[1];
135 847430 : c += pn[2] ^ salt_pn[2];
136 847430 : HashMix(a, b, c);
137 847430 : a += pn[3] ^ salt_pn[3];
138 847430 : b += pn[4] ^ salt_pn[4];
139 847430 : c += pn[5] ^ salt_pn[5];
140 847430 : HashMix(a, b, c);
141 847430 : a += pn[6] ^ salt_pn[6];
142 847430 : b += pn[7] ^ salt_pn[7];
143 847430 : HashFinal(a, b, c);
144 :
145 847430 : return ((((uint64_t)b) << 32) | c);
146 : }
|