PRCYCoin  2.0.0.7rc1
P2P Digital Currency
arith_uint256.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin 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 "arith_uint256.h"
7 
8 #include "crypto/common.h"
9 #include "utilstrencodings.h"
10 
11 #include <stdio.h>
12 #include <string.h>
13 
14 template <unsigned int BITS>
15 base_uint<BITS>::base_uint(const std::string& str)
16 {
17  SetHex(str);
18 }
19 
20 template <unsigned int BITS>
21 base_uint<BITS>::base_uint(const std::vector<unsigned char>& vch)
22 {
23  if (vch.size() != sizeof(pn))
24  throw uint_error("Converting vector of wrong size to base_uint");
25  memcpy(pn, &vch[0], sizeof(pn));
26 }
27 
28 template <unsigned int BITS>
30 {
31  base_uint<BITS> a(*this);
32  for (int i = 0; i < WIDTH; i++)
33  pn[i] = 0;
34  int k = shift / 32;
35  shift = shift % 32;
36  for (int i = 0; i < WIDTH; i++) {
37  if (i + k + 1 < WIDTH && shift != 0)
38  pn[i + k + 1] |= (a.pn[i] >> (32 - shift));
39  if (i + k < WIDTH)
40  pn[i + k] |= (a.pn[i] << shift);
41  }
42  return *this;
43 }
44 
45 template <unsigned int BITS>
47 {
48  base_uint<BITS> a(*this);
49  for (int i = 0; i < WIDTH; i++)
50  pn[i] = 0;
51  int k = shift / 32;
52  shift = shift % 32;
53  for (int i = 0; i < WIDTH; i++) {
54  if (i - k - 1 >= 0 && shift != 0)
55  pn[i - k - 1] |= (a.pn[i] << (32 - shift));
56  if (i - k >= 0)
57  pn[i - k] |= (a.pn[i] >> shift);
58  }
59  return *this;
60 }
61 
62 template <unsigned int BITS>
64 {
65  uint64_t carry = 0;
66  for (int i = 0; i < WIDTH; i++) {
67  uint64_t n = carry + (uint64_t)b32 * pn[i];
68  pn[i] = n & 0xffffffff;
69  carry = n >> 32;
70  }
71  return *this;
72 }
73 
74 template <unsigned int BITS>
76 {
77  base_uint<BITS> a = *this;
78  *this = 0;
79  for (int j = 0; j < WIDTH; j++) {
80  uint64_t carry = 0;
81  for (int i = 0; i + j < WIDTH; i++) {
82  uint64_t n = carry + pn[i + j] + (uint64_t)a.pn[j] * b.pn[i];
83  pn[i + j] = n & 0xffffffff;
84  carry = n >> 32;
85  }
86  }
87  return *this;
88 }
89 
90 template <unsigned int BITS>
92 {
93  base_uint<BITS> div = b; // make a copy, so we can shift.
94  base_uint<BITS> num = *this; // make a copy, so we can subtract.
95  *this = 0; // the quotient.
96  int num_bits = num.bits();
97  int div_bits = div.bits();
98  if (div_bits == 0)
99  throw uint_error("Division by zero");
100  if (div_bits > num_bits) // the result is certainly 0.
101  return *this;
102  int shift = num_bits - div_bits;
103  div <<= shift; // shift so that div and num align.
104  while (shift >= 0) {
105  if (num >= div) {
106  num -= div;
107  pn[shift / 32] |= (1 << (shift & 31)); // set a bit of the result.
108  }
109  div >>= 1; // shift back.
110  shift--;
111  }
112  // num now contains the remainder of the division.
113  return *this;
114 }
115 
116 template <unsigned int BITS>
118 {
119  for (int i = WIDTH - 1; i >= 0; i--) {
120  if (pn[i] < b.pn[i])
121  return -1;
122  if (pn[i] > b.pn[i])
123  return 1;
124  }
125  return 0;
126 }
127 
128 template <unsigned int BITS>
129 bool base_uint<BITS>::EqualTo(uint64_t b) const
130 {
131  for (int i = WIDTH - 1; i >= 2; i--) {
132  if (pn[i])
133  return false;
134  }
135  if (pn[1] != (b >> 32))
136  return false;
137  if (pn[0] != (b & 0xfffffffful))
138  return false;
139  return true;
140 }
141 
142 template <unsigned int BITS>
144 {
145  double ret = 0.0;
146  double fact = 1.0;
147  for (int i = 0; i < WIDTH; i++) {
148  ret += fact * pn[i];
149  fact *= 4294967296.0;
150  }
151  return ret;
152 }
153 
154 template <unsigned int BITS>
155 std::string base_uint<BITS>::GetHex() const
156 {
157  char psz[sizeof(pn) * 2 + 1];
158  for (unsigned int i = 0; i < sizeof(pn); i++)
159  sprintf(psz + i * 2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]);
160  return std::string(psz, psz + sizeof(pn) * 2);
161 }
162 
163 template <unsigned int BITS>
164 void base_uint<BITS>::SetHex(const char* psz)
165 {
166  memset(pn, 0, sizeof(pn));
167 
168  // skip leading spaces
169  while (isspace(*psz))
170  psz++;
171 
172  // skip 0x
173  if (psz[0] == '0' && tolower(psz[1]) == 'x')
174  psz += 2;
175 
176  // hex string to uint
177  const char* pbegin = psz;
178  while (::HexDigit(*psz) != -1)
179  psz++;
180  psz--;
181  unsigned char* p1 = (unsigned char*)pn;
182  unsigned char* pend = p1 + WIDTH * 4;
183  while (psz >= pbegin && p1 < pend) {
184  *p1 = ::HexDigit(*psz--);
185  if (psz >= pbegin) {
186  *p1 |= ((unsigned char)::HexDigit(*psz--) << 4);
187  p1++;
188  }
189  }
190 }
191 
192 template <unsigned int BITS>
193 void base_uint<BITS>::SetHex(const std::string& str)
194 {
195  SetHex(str.c_str());
196 }
197 
198 template <unsigned int BITS>
199 std::string base_uint<BITS>::ToString() const
200 {
201  return (GetHex());
202 }
203 
204 template <unsigned int BITS>
206 {
207  char psz[sizeof(pn) * 2 + 1];
208  for (unsigned int i = 0; i < sizeof(pn); i++)
209  sprintf(psz + i * 2, "%02x", ((unsigned char*)pn)[i]);
210  return std::string(psz, psz + sizeof(pn) * 2);
211 }
212 
213 template <unsigned int BITS>
214 unsigned int base_uint<BITS>::bits() const
215 {
216  for (int pos = WIDTH - 1; pos >= 0; pos--) {
217  if (pn[pos]) {
218  for (int bits = 31; bits > 0; bits--) {
219  if (pn[pos] & 1 << bits)
220  return 32 * pos + bits + 1;
221  }
222  return 32 * pos + 1;
223  }
224  }
225  return 0;
226 }
227 
228 // Explicit instantiations for base_uint<160>
229 template base_uint<160>::base_uint(const std::string&);
230 template base_uint<160>::base_uint(const std::vector<unsigned char>&);
231 template base_uint<160>& base_uint<160>::operator<<=(unsigned int);
232 template base_uint<160>& base_uint<160>::operator>>=(unsigned int);
233 template base_uint<160>& base_uint<160>::operator*=(uint32_t b32);
236 template int base_uint<160>::CompareTo(const base_uint<160>&) const;
237 template bool base_uint<160>::EqualTo(uint64_t) const;
238 template double base_uint<160>::getdouble() const;
239 template std::string base_uint<160>::GetHex() const;
240 template std::string base_uint<160>::ToString() const;
241 template void base_uint<160>::SetHex(const char*);
242 template void base_uint<160>::SetHex(const std::string&);
243 template unsigned int base_uint<160>::bits() const;
244 
245 // Explicit instantiations for base_uint<256>
246 template base_uint<256>::base_uint(const std::string&);
247 template base_uint<256>::base_uint(const std::vector<unsigned char>&);
248 template base_uint<256>& base_uint<256>::operator<<=(unsigned int);
249 template base_uint<256>& base_uint<256>::operator>>=(unsigned int);
250 template base_uint<256>& base_uint<256>::operator*=(uint32_t b32);
253 template int base_uint<256>::CompareTo(const base_uint<256>&) const;
254 template bool base_uint<256>::EqualTo(uint64_t) const;
255 template double base_uint<256>::getdouble() const;
256 template std::string base_uint<256>::GetHex() const;
257 template std::string base_uint<256>::ToString() const;
258 template void base_uint<256>::SetHex(const char*);
259 template void base_uint<256>::SetHex(const std::string&);
260 template unsigned int base_uint<256>::bits() const;
261 template std::string base_uint<256>::ToStringReverseEndian() const;
262 
263 // Explicit instantiations for base_uint<512>
264 template base_uint<512>::base_uint(const std::string&);
265 template base_uint<512>& base_uint<512>::operator<<=(unsigned int);
266 template base_uint<512>& base_uint<512>::operator>>=(unsigned int);
267 template std::string base_uint<512>::GetHex() const;
268 template std::string base_uint<512>::ToString() const;
269 template std::string base_uint<512>::ToStringReverseEndian() const;
270 
271 // This implementation directly uses shifts instead of going
272 // through an intermediate MPI representation.
273 arith_uint256& arith_uint256::SetCompact(uint32_t nCompact, bool* pfNegative, bool* pfOverflow)
274 {
275  int nSize = nCompact >> 24;
276  uint32_t nWord = nCompact & 0x007fffff;
277  if (nSize <= 3) {
278  nWord >>= 8 * (3 - nSize);
279  *this = nWord;
280  } else {
281  *this = nWord;
282  *this <<= 8 * (nSize - 3);
283  }
284  if (pfNegative)
285  *pfNegative = nWord != 0 && (nCompact & 0x00800000) != 0;
286  if (pfOverflow)
287  *pfOverflow = nWord != 0 && ((nSize > 34) ||
288  (nWord > 0xff && nSize > 33) ||
289  (nWord > 0xffff && nSize > 32));
290  return *this;
291 }
292 
293 uint32_t arith_uint256::GetCompact(bool fNegative) const
294 {
295  int nSize = (bits() + 7) / 8;
296  uint32_t nCompact = 0;
297  if (nSize <= 3) {
298  nCompact = GetLow64() << 8 * (3 - nSize);
299  } else {
300  arith_uint256 bn = *this >> 8 * (nSize - 3);
301  nCompact = bn.GetLow64();
302  }
303  // The 0x00800000 bit denotes the sign.
304  // Thus, if it is already set, divide the mantissa by 256 and increase the exponent.
305  if (nCompact & 0x00800000) {
306  nCompact >>= 8;
307  nSize++;
308  }
309  assert((nCompact & ~0x007fffff) == 0);
310  assert(nSize < 256);
311  nCompact |= nSize << 24;
312  nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0);
313  return nCompact;
314 }
315 
316 static void inline HashMix(uint32_t& a, uint32_t& b, uint32_t& c)
317 {
318  // Taken from lookup3, by Bob Jenkins.
319  a -= c;
320  a ^= ((c << 4) | (c >> 28));
321  c += b;
322  b -= a;
323  b ^= ((a << 6) | (a >> 26));
324  a += c;
325  c -= b;
326  c ^= ((b << 8) | (b >> 24));
327  b += a;
328  a -= c;
329  a ^= ((c << 16) | (c >> 16));
330  c += b;
331  b -= a;
332  b ^= ((a << 19) | (a >> 13));
333  a += c;
334  c -= b;
335  c ^= ((b << 4) | (b >> 28));
336  b += a;
337 }
338 
339 static void inline HashFinal(uint32_t& a, uint32_t& b, uint32_t& c)
340 {
341  // Taken from lookup3, by Bob Jenkins.
342  c ^= b;
343  c -= ((b << 14) | (b >> 18));
344  a ^= c;
345  a -= ((c << 11) | (c >> 21));
346  b ^= a;
347  b -= ((a << 25) | (a >> 7));
348  c ^= b;
349  c -= ((b << 16) | (b >> 16));
350  a ^= c;
351  a -= ((c << 4) | (c >> 28));
352  b ^= a;
353  b -= ((a << 14) | (a >> 18));
354  c ^= b;
355  c -= ((b << 24) | (b >> 8));
356 }
357 
358 uint64_t arith_uint256::GetHash(const arith_uint256& salt) const
359 {
360  uint32_t a, b, c;
361  a = b = c = 0xdeadbeef + (WIDTH << 2);
362 
363  a += pn[0] ^ salt.pn[0];
364  b += pn[1] ^ salt.pn[1];
365  c += pn[2] ^ salt.pn[2];
366  HashMix(a, b, c);
367  a += pn[3] ^ salt.pn[3];
368  b += pn[4] ^ salt.pn[4];
369  c += pn[5] ^ salt.pn[5];
370  HashMix(a, b, c);
371  a += pn[6] ^ salt.pn[6];
372  b += pn[7] ^ salt.pn[7];
373  HashFinal(a, b, c);
374 
375  return ((((uint64_t)b) << 32) | c);
376 }
arith_uint256.h
arith_uint256::SetCompact
arith_uint256 & SetCompact(uint32_t nCompact, bool *pfNegative=NULL, bool *pfOverflow=NULL)
The "compact" format is a representation of a whole number N using an unsigned 32bit number similar t...
Definition: arith_uint256.cpp:273
b
void const uint64_t * b
Definition: field_5x52_asm_impl.h:10
base_uint::GetHex
std::string GetHex() const
Definition: arith_uint256.cpp:155
base_uint::operator<<=
base_uint & operator<<=(unsigned int shift)
Definition: arith_uint256.cpp:29
arith_uint256
256-bit unsigned big integer.
Definition: arith_uint256.h:340
base_uint::bits
unsigned int bits() const
Returns the position of the highest bit set plus one, or zero if the value is zero.
Definition: arith_uint256.cpp:214
memcpy
void * memcpy(void *a, const void *b, size_t c)
Definition: glibc_compat.cpp:15
arith_uint256::GetHash
uint64_t GetHash(const arith_uint256 &salt) const
Definition: arith_uint256.cpp:358
base_uint::operator*=
base_uint & operator*=(uint32_t b32)
Definition: arith_uint256.cpp:63
base_uint::EqualTo
bool EqualTo(uint64_t b) const
Definition: arith_uint256.cpp:129
base_uint< 256 >::GetLow64
uint64_t GetLow64() const
Definition: arith_uint256.h:280
arith_uint256::GetCompact
uint32_t GetCompact(bool fNegative=false) const
Definition: arith_uint256.cpp:293
base_uint::SetHex
void SetHex(const char *psz)
Definition: arith_uint256.cpp:164
GetHex
std::string GetHex(const unsigned char *vch, int sz)
Definition: rpcwallet.cpp:2940
base_uint
Template base class for unsigned big integers.
Definition: arith_uint256.h:30
common.h
base_uint< 256 >::WIDTH
@ WIDTH
Definition: arith_uint256.h:33
HexDigit
signed char HexDigit(char c)
Definition: utilstrencodings.cpp:63
base_uint::operator>>=
base_uint & operator>>=(unsigned int shift)
Definition: arith_uint256.cpp:46
base_uint::ToStringReverseEndian
std::string ToStringReverseEndian() const
Definition: arith_uint256.cpp:205
base_uint::CompareTo
int CompareTo(const base_uint &b) const
Definition: arith_uint256.cpp:117
utilstrencodings.h
uint_error
Definition: arith_uint256.h:23
base_uint::base_uint
base_uint()
Definition: arith_uint256.h:36
base_uint::getdouble
double getdouble() const
Definition: arith_uint256.cpp:143
base_uint::operator/=
base_uint & operator/=(const base_uint &b)
Definition: arith_uint256.cpp:91
base_uint::pn
uint32_t pn[WIDTH]
Definition: arith_uint256.h:34
base_uint::ToString
std::string ToString() const
Definition: arith_uint256.cpp:199