]>
Commit | Line | Data |
---|---|---|
de79aaa7 | 1 | // Copyright (c) 2009-2010 Satoshi Nakamoto |
f914f1a7 | 2 | // Copyright (c) 2009-2014 The Bitcoin Core developers |
78253fcb | 3 | // Distributed under the MIT software license, see the accompanying |
de79aaa7 PW |
4 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
5 | ||
6 | #include "uint256.h" | |
ad49c256 WL |
7 | |
8 | #include "utilstrencodings.h" | |
de79aaa7 PW |
9 | |
10 | #include <stdio.h> | |
11 | #include <string.h> | |
12 | ||
20e01b1a | 13 | template <unsigned int BITS> |
bfc60703 | 14 | base_blob<BITS>::base_blob(const std::vector<unsigned char>& vch) |
de79aaa7 | 15 | { |
bfc60703 WL |
16 | assert(vch.size() == sizeof(data)); |
17 | memcpy(data, &vch[0], sizeof(data)); | |
de79aaa7 PW |
18 | } |
19 | ||
20e01b1a | 20 | template <unsigned int BITS> |
bfc60703 | 21 | std::string base_blob<BITS>::GetHex() const |
de79aaa7 | 22 | { |
bfc60703 WL |
23 | char psz[sizeof(data) * 2 + 1]; |
24 | for (unsigned int i = 0; i < sizeof(data); i++) | |
25 | sprintf(psz + i * 2, "%02x", data[sizeof(data) - i - 1]); | |
26 | return std::string(psz, psz + sizeof(data) * 2); | |
de79aaa7 PW |
27 | } |
28 | ||
20e01b1a | 29 | template <unsigned int BITS> |
bfc60703 | 30 | void base_blob<BITS>::SetHex(const char* psz) |
de79aaa7 | 31 | { |
bfc60703 | 32 | memset(data, 0, sizeof(data)); |
de79aaa7 PW |
33 | |
34 | // skip leading spaces | |
35 | while (isspace(*psz)) | |
36 | psz++; | |
37 | ||
38 | // skip 0x | |
39 | if (psz[0] == '0' && tolower(psz[1]) == 'x') | |
40 | psz += 2; | |
41 | ||
42 | // hex string to uint | |
43 | const char* pbegin = psz; | |
44 | while (::HexDigit(*psz) != -1) | |
45 | psz++; | |
46 | psz--; | |
bfc60703 | 47 | unsigned char* p1 = (unsigned char*)data; |
e96c5184 | 48 | unsigned char* pend = p1 + WIDTH; |
de79aaa7 PW |
49 | while (psz >= pbegin && p1 < pend) { |
50 | *p1 = ::HexDigit(*psz--); | |
51 | if (psz >= pbegin) { | |
52 | *p1 |= ((unsigned char)::HexDigit(*psz--) << 4); | |
53 | p1++; | |
54 | } | |
55 | } | |
56 | } | |
57 | ||
20e01b1a | 58 | template <unsigned int BITS> |
bfc60703 | 59 | void base_blob<BITS>::SetHex(const std::string& str) |
de79aaa7 PW |
60 | { |
61 | SetHex(str.c_str()); | |
62 | } | |
63 | ||
20e01b1a | 64 | template <unsigned int BITS> |
bfc60703 | 65 | std::string base_blob<BITS>::ToString() const |
de79aaa7 PW |
66 | { |
67 | return (GetHex()); | |
68 | } | |
69 | ||
bfc60703 WL |
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&); | |
de79aaa7 | 76 | |
bfc60703 WL |
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&); | |
bc42503f PW |
83 | |
84 | static void inline HashMix(uint32_t& a, uint32_t& b, uint32_t& c) | |
85 | { | |
86 | // Taken from lookup3, by Bob Jenkins. | |
20e01b1a PW |
87 | a -= c; |
88 | a ^= ((c << 4) | (c >> 28)); | |
89 | c += b; | |
90 | b -= a; | |
91 | b ^= ((a << 6) | (a >> 26)); | |
92 | a += c; | |
93 | c -= b; | |
94 | c ^= ((b << 8) | (b >> 24)); | |
95 | b += a; | |
96 | a -= c; | |
97 | a ^= ((c << 16) | (c >> 16)); | |
98 | c += b; | |
99 | b -= a; | |
100 | b ^= ((a << 19) | (a >> 13)); | |
101 | a += c; | |
102 | c -= b; | |
103 | c ^= ((b << 4) | (b >> 28)); | |
104 | b += a; | |
bc42503f PW |
105 | } |
106 | ||
107 | static void inline HashFinal(uint32_t& a, uint32_t& b, uint32_t& c) | |
108 | { | |
109 | // Taken from lookup3, by Bob Jenkins. | |
20e01b1a PW |
110 | c ^= b; |
111 | c -= ((b << 14) | (b >> 18)); | |
112 | a ^= c; | |
113 | a -= ((c << 11) | (c >> 21)); | |
114 | b ^= a; | |
115 | b -= ((a << 25) | (a >> 7)); | |
116 | c ^= b; | |
117 | c -= ((b << 16) | (b >> 16)); | |
118 | a ^= c; | |
119 | a -= ((c << 4) | (c >> 28)); | |
120 | b ^= a; | |
121 | b -= ((a << 14) | (a >> 18)); | |
122 | c ^= b; | |
123 | c -= ((b << 24) | (b >> 8)); | |
bc42503f PW |
124 | } |
125 | ||
20e01b1a | 126 | uint64_t uint256::GetHash(const uint256& salt) const |
bc42503f PW |
127 | { |
128 | uint32_t a, b, c; | |
bfc60703 WL |
129 | const uint32_t *pn = (const uint32_t*)data; |
130 | const uint32_t *salt_pn = (const uint32_t*)salt.data; | |
e96c5184 | 131 | a = b = c = 0xdeadbeef + WIDTH; |
bc42503f | 132 | |
bfc60703 WL |
133 | a += pn[0] ^ salt_pn[0]; |
134 | b += pn[1] ^ salt_pn[1]; | |
135 | c += pn[2] ^ salt_pn[2]; | |
bc42503f | 136 | HashMix(a, b, c); |
bfc60703 WL |
137 | a += pn[3] ^ salt_pn[3]; |
138 | b += pn[4] ^ salt_pn[4]; | |
139 | c += pn[5] ^ salt_pn[5]; | |
bc42503f | 140 | HashMix(a, b, c); |
bfc60703 WL |
141 | a += pn[6] ^ salt_pn[6]; |
142 | b += pn[7] ^ salt_pn[7]; | |
bc42503f PW |
143 | HashFinal(a, b, c); |
144 | ||
145 | return ((((uint64_t)b) << 32) | c); | |
146 | } |