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