PIVX Core  5.6.99
P2P Digital Currency
bignum.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Copyright (c) 2017-2021 The PIVX Core developers
4 // Distributed under the MIT/X11 software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 #include "bignum.h"
8 
11 {
12  mpz_init(bn);
13 }
14 
16 {
17  mpz_init(bn);
18  mpz_set(bn, b.bn);
19 }
20 
22 {
23  mpz_set(bn, b.bn);
24  return (*this);
25 }
26 
28 {
29  mpz_clear(bn);
30 }
31 
32 //CBigNum(char n) is not portable. Use 'signed char' or 'unsigned char'.
33 CBigNum::CBigNum(signed char n) { mpz_init(bn); if (n >= 0) mpz_set_ui(bn, n); else mpz_set_si(bn, n); }
34 CBigNum::CBigNum(short n) { mpz_init(bn); if (n >= 0) mpz_set_ui(bn, n); else mpz_set_si(bn, n); }
35 CBigNum::CBigNum(int n) { mpz_init(bn); if (n >= 0) mpz_set_ui(bn, n); else mpz_set_si(bn, n); }
36 CBigNum::CBigNum(long n) { mpz_init(bn); if (n >= 0) mpz_set_ui(bn, n); else mpz_set_si(bn, n); }
37 CBigNum::CBigNum(long long n) { mpz_init(bn); mpz_set_si(bn, n); }
38 CBigNum::CBigNum(unsigned char n) { mpz_init(bn); mpz_set_ui(bn, n); }
39 CBigNum::CBigNum(unsigned short n) { mpz_init(bn); mpz_set_ui(bn, n); }
40 CBigNum::CBigNum(unsigned int n) { mpz_init(bn); mpz_set_ui(bn, n); }
41 CBigNum::CBigNum(unsigned long n) { mpz_init(bn); mpz_set_ui(bn, n); }
42 
43 CBigNum::CBigNum(uint256 n) { mpz_init(bn); setuint256(n); }
44 
45 CBigNum::CBigNum(const std::vector<unsigned char>& vch)
46 {
47  mpz_init(bn);
48  setvch(vch);
49 }
50 
59 {
60  if (range < 2)
61  return 0;
62 
63  size_t size = (mpz_sizeinbase (range.bn, 2) + CHAR_BIT-1) / CHAR_BIT;
64  std::vector<unsigned char> buf(size);
65 
66  GetStrongRandBytes(buf.data(), size);
67 
68  CBigNum ret(buf);
69  if (ret < 0)
70  mpz_neg(ret.bn, ret.bn);
71  return (ret % range);
72 }
73 
78 int CBigNum::bitSize() const
79 {
80  return mpz_sizeinbase(bn, 2);
81 }
82 
83 void CBigNum::setulong(unsigned long n)
84 {
85  mpz_set_ui(bn, n);
86 }
87 
88 unsigned long CBigNum::getulong() const
89 {
90  return mpz_get_ui(bn);
91 }
92 
93 unsigned int CBigNum::getuint() const
94 {
95  return mpz_get_ui(bn);
96 }
97 
98 int CBigNum::getint() const
99 {
100  unsigned long n = getulong();
101  if (mpz_cmp(bn, BN_ZERO.bn) >= 0) {
102  return (n > (unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : n);
103  } else {
104  return (n > (unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::min() : -(int)n);
105  }
106 }
107 
109 {
110  mpz_import(bn, n.size(), -1, 1, 0, 0, (unsigned char*)&n);
111 }
112 
114 {
115  if(bitSize() > 256) {
116  throw std::range_error("cannot convert to uint256, bignum longer than 256 bits");
117  }
118  uint256 n = UINT256_ZERO;
119  mpz_export((unsigned char*)&n, nullptr, -1, 1, 0, 0, bn);
120  return UintToArith256(n);
121 }
122 
123 void CBigNum::setvch(const std::vector<unsigned char>& vch)
124 {
125  std::vector<unsigned char> vch2 = vch;
126  unsigned char sign = 0;
127  if (vch2.size() > 0) {
128  sign = vch2[vch2.size()-1] & 0x80;
129  vch2[vch2.size()-1] = vch2[vch2.size()-1] & 0x7f;
130  mpz_import(bn, vch2.size(), -1, 1, 0, 0, vch2.data());
131  if (sign)
132  mpz_neg(bn, bn);
133  }
134  else {
135  mpz_set_si(bn, 0);
136  }
137 }
138 
139 std::vector<unsigned char> CBigNum::getvch() const
140 {
141  if (mpz_cmp(bn, BN_ZERO.bn) == 0) {
142  return std::vector<unsigned char>(0);
143  }
144  size_t size = (mpz_sizeinbase (bn, 2) + CHAR_BIT-1) / CHAR_BIT;
145  if (size <= 0)
146  return std::vector<unsigned char>();
147  std::vector<unsigned char> v(size + 1);
148  mpz_export(v.data(), &size, -1, 1, 0, 0, bn);
149  if (v[v.size()-2] & 0x80) {
150  if (mpz_sgn(bn)<0) {
151  v[v.size()-1] = 0x80;
152  } else {
153  v[v.size()-1] = 0x00;
154  }
155  } else {
156  v.pop_back();
157  if (mpz_sgn(bn)<0) {
158  v[v.size()-1] |= 0x80;
159  }
160  }
161  return v;
162 }
163 
164 void CBigNum::SetDec(const std::string& str)
165 {
166  const char* psz = str.c_str();
167  mpz_set_str(bn, psz, 10);
168 }
169 
170 bool CBigNum::SetHexBool(const std::string& str)
171 {
172  const char* psz = str.c_str();
173  int ret = 1 + mpz_set_str(bn, psz, 16);
174  return (bool) ret;
175 }
176 
177 std::string CBigNum::ToString(int nBase) const
178 {
179  char* c_str = mpz_get_str(nullptr, nBase, bn);
180  std::string str(c_str);
181  // Free c_str with the right free function:
182  void (*freefunc)(void *, size_t);
183  mp_get_memory_functions (nullptr, nullptr, &freefunc);
184  freefunc(c_str, strlen(c_str) + 1);
185 
186  return str;
187 }
188 
194 CBigNum CBigNum::pow(const CBigNum& e) const
195 {
196  CBigNum ret;
197  long unsigned int ei = mpz_get_ui (e.bn);
198  mpz_pow_ui(ret.bn, bn, ei);
199  return ret;
200 }
201 
207 CBigNum CBigNum::mul_mod(const CBigNum& b, const CBigNum& m) const
208 {
209  CBigNum ret;
210  mpz_mul (ret.bn, bn, b.bn);
211  mpz_mod (ret.bn, ret.bn, m.bn);
212  return ret;
213 }
214 
220 CBigNum CBigNum::pow_mod(const CBigNum& e, const CBigNum& m) const
221 {
222  CBigNum ret;
223  if (e > BN_ZERO && mpz_odd_p(m.bn))
224  mpz_powm_sec (ret.bn, bn, e.bn, m.bn);
225  else
226  mpz_powm (ret.bn, bn, e.bn, m.bn);
227  return ret;
228 }
229 
237 {
238  CBigNum ret;
239  mpz_invert(ret.bn, bn, m.bn);
240  return ret;
241 }
242 
248 CBigNum CBigNum::gcd( const CBigNum& b) const
249 {
250  CBigNum ret;
251  mpz_gcd(ret.bn, bn, b.bn);
252  return ret;
253 }
254 
261 bool CBigNum::isPrime(const int checks) const
262 {
263  int ret = mpz_probab_prime_p(bn, checks);
264  return ret;
265 }
266 
267 bool CBigNum::isOne() const
268 {
269  return mpz_cmp(bn, BN_ONE.bn) == 0;
270 }
271 
272 bool CBigNum::operator!() const
273 {
274  return mpz_cmp(bn, BN_ZERO.bn) == 0;
275 }
276 
278 {
279  mpz_add(bn, bn, b.bn);
280  return *this;
281 }
282 
284 {
285  mpz_sub(bn, bn, b.bn);
286  return *this;
287 }
288 
290 {
291  mpz_mul(bn, bn, b.bn);
292  return *this;
293 }
294 
295 CBigNum& CBigNum::operator<<=(unsigned int shift)
296 {
297  mpz_mul_2exp(bn, bn, shift);
298  return *this;
299 }
300 
301 CBigNum& CBigNum::operator>>=(unsigned int shift)
302 {
303  mpz_div_2exp(bn, bn, shift);
304  return *this;
305 }
306 
308 {
309  // prefix operator
310  mpz_add(bn, bn, BN_ONE.bn);
311  return *this;
312 }
313 
315 {
316  // prefix operator
317  mpz_sub(bn, bn, BN_ONE.bn);
318  return *this;
319 }
320 
321 std::string CBigNum::GetHex() const
322 {
323  return ToString(16);
324 }
325 
326 std::string CBigNum::GetDec() const
327 {
328  return ToString(10);
329 }
330 
331 CBigNum CBigNum::pow(const int e) const
332 {
333  return this->pow(CBigNum(e));
334 }
335 
336 void CBigNum::SetHex(const std::string& str)
337 {
338  SetHexBool(str);
339 }
340 
342 {
343  *this = *this / b;
344  return *this;
345 }
346 
348 {
349  *this = *this % b;
350  return *this;
351 }
352 
354 {
355  // postfix operator
356  const CBigNum ret = *this;
357  ++(*this);
358  return ret;
359 }
360 
362 {
363  // postfix operator
364  const CBigNum ret = *this;
365  --(*this);
366  return ret;
367 }
arith_uint256 UintToArith256(const uint256 &a)
const CBigNum BN_ZERO
constant bignum instances
Definition: bignum.h:232
const CBigNum BN_ONE
Definition: bignum.h:233
C++ wrapper for BIGNUM.
Definition: bignum.h:35
std::vector< unsigned char > getvch() const
Definition: bignum.cpp:139
unsigned long getulong() const
Definition: bignum.cpp:88
~CBigNum()
Definition: bignum.cpp:27
bool isOne() const
Definition: bignum.cpp:267
std::string ToString(int nBase=10) const
Definition: bignum.cpp:177
mpz_t bn
Definition: bignum.h:36
void SetDec(const std::string &str)
Definition: bignum.cpp:164
CBigNum & operator*=(const CBigNum &b)
Definition: bignum.cpp:289
CBigNum & operator+=(const CBigNum &b)
Definition: bignum.cpp:277
CBigNum()
C++ wrapper for BIGNUM (Gmp bignum)
Definition: bignum.cpp:10
bool SetHexBool(const std::string &str)
Definition: bignum.cpp:170
CBigNum & operator/=(const CBigNum &b)
Definition: bignum.cpp:341
CBigNum & operator<<=(unsigned int shift)
Definition: bignum.cpp:295
CBigNum gcd(const CBigNum &b) const
Calculates the greatest common divisor (GCD) of two numbers.
Definition: bignum.cpp:248
unsigned int getuint() const
Definition: bignum.cpp:93
CBigNum & operator%=(const CBigNum &b)
Definition: bignum.cpp:347
bool isPrime(const int checks=15) const
Miller-Rabin primality test on this element.
Definition: bignum.cpp:261
std::string GetHex() const
Definition: bignum.cpp:321
arith_uint256 getuint256() const
Definition: bignum.cpp:113
CBigNum & operator--()
Definition: bignum.cpp:314
bool operator!() const
Definition: bignum.cpp:272
CBigNum pow_mod(const CBigNum &e, const CBigNum &m) const
modular exponentiation: this^e mod n
Definition: bignum.cpp:220
std::string GetDec() const
Definition: bignum.cpp:326
void SetHex(const std::string &str)
Definition: bignum.cpp:336
CBigNum & operator=(const CBigNum &b)
Definition: bignum.cpp:21
static CBigNum randBignum(const CBigNum &range)
Generates a cryptographically secure random number between zero and range exclusive i....
Definition: bignum.cpp:58
CBigNum pow(const int e) const
exponentiation with an int.
Definition: bignum.cpp:331
void setvch(const std::vector< unsigned char > &vch)
Definition: bignum.cpp:123
int bitSize() const
Returns the size in bits of the underlying bignum.
Definition: bignum.cpp:78
CBigNum mul_mod(const CBigNum &b, const CBigNum &m) const
modular multiplication: (this * b) mod m
Definition: bignum.cpp:207
CBigNum & operator-=(const CBigNum &b)
Definition: bignum.cpp:283
CBigNum & operator++()
Definition: bignum.cpp:307
void setulong(unsigned long n)
Definition: bignum.cpp:83
CBigNum inverse(const CBigNum &m) const
Calculates the inverse of this element mod m.
Definition: bignum.cpp:236
void setuint256(uint256 n)
Definition: bignum.cpp:108
CBigNum & operator>>=(unsigned int shift)
Definition: bignum.cpp:301
int getint() const
Definition: bignum.cpp:98
256-bit unsigned big integer.
unsigned int size() const
Definition: uint256.h:83
256-bit opaque blob.
Definition: uint256.h:138
void GetStrongRandBytes(unsigned char *buf, int num) noexcept
Gather entropy from various sources, feed it into the internal PRNG, and generate random data using i...
Definition: random.cpp:580
const uint256 UINT256_ZERO
constant uint256 instances
Definition: uint256.h:175