PRCYCoin  2.0.0.7rc1
P2P Digital Currency
bignum.h
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) 2015-2018 The PIVX developers
4 // Copyright (c) 2018-2020 The DAPS Project developers
5 // Distributed under the MIT/X11 software license, see the accompanying
6 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
7 #ifndef BITCOIN_BIGNUM_H
8 #define BITCOIN_BIGNUM_H
9 
10 #include <stdexcept>
11 #include <vector>
12 #include <openssl/bn.h>
13 #include "serialize.h"
14 #include "uint256.h"
15 #include "version.h"
16 
18 class bignum_error : public std::runtime_error
19 {
20 public:
21  explicit bignum_error(const std::string& str) : std::runtime_error(str) {}
22 };
23 
24 
27 {
28 protected:
29  BN_CTX* pctx;
30  BN_CTX* operator=(BN_CTX* pnew) { return pctx = pnew; }
31 
32 public:
34  {
35  pctx = BN_CTX_new();
36  if (pctx == NULL)
37  throw bignum_error("CAutoBN_CTX : BN_CTX_new() returned NULL");
38  }
39 
41  {
42  if (pctx != NULL)
43  BN_CTX_free(pctx);
44  }
45 
46  operator BN_CTX*() { return pctx; }
47  BN_CTX& operator*() { return *pctx; }
48  BN_CTX** operator&() { return &pctx; }
49  bool operator!() { return (pctx == NULL); }
50 };
51 
52 
54 class CBigNum
55 {
56  BIGNUM* bn;
57 public:
59  {
60  bn = BN_new();
61  }
62 
63  // Initialize from a Hex String
64  CBigNum(const std::string& str) {
65  bn = BN_new();
66  SetHexBool(str);
67  }
68 
69 
70  CBigNum(const CBigNum& b)
71  {
72  bn = BN_new();
73  if (!BN_copy(bn, b.bn))
74  {
75  BN_clear_free(bn);
76  throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed");
77  }
78  }
79 
81  {
82  if (!BN_copy(bn, b.bn))
83  throw bignum_error("CBigNum::operator= : BN_copy failed");
84  return (*this);
85  }
86 
88  {
89  BN_clear_free(bn);
90  }
91 
92  //CBigNum(char n) is not portable. Use 'signed char' or 'unsigned char'.
93  CBigNum(signed char n) { bn = BN_new(); if (n >= 0) setulong(n); else setint64(n); }
94  CBigNum(short n) { bn = BN_new(); if (n >= 0) setulong(n); else setint64(n); }
95  CBigNum(int n) { bn = BN_new(); if (n >= 0) setulong(n); else setint64(n); }
96  CBigNum(long n) { bn = BN_new(); if (n >= 0) setulong(n); else setint64(n); }
97 #ifdef __APPLE__
98  CBigNum(int64_t n) { bn = BN_new(); setint64(n); }
99 #endif
100  CBigNum(unsigned char n) { bn = BN_new(); setulong(n); }
101  CBigNum(unsigned short n) { bn = BN_new(); setulong(n); }
102  CBigNum(unsigned int n) { bn = BN_new(); setulong(n); }
103  CBigNum(unsigned long n) { bn = BN_new(); setulong(n); }
104  // CBigNum(uint64_t n) { bn = BN_new(); setuint64(n); }
105  explicit CBigNum(uint256 n) { bn = BN_new(); setuint256(n); }
106 
107  explicit CBigNum(const std::vector<unsigned char>& vch)
108  {
109  bn = BN_new();
110  setvch(vch);
111  }
112 
118  static CBigNum randBignum(const CBigNum& range) {
119  CBigNum ret;
120  if(!BN_rand_range(ret.bn, range.bn)){
121  throw bignum_error("CBigNum:rand element : BN_rand_range failed");
122  }
123  return ret;
124  }
125 
130  static CBigNum RandKBitBigum(const uint32_t k){
131  CBigNum ret;
132  if(!BN_rand(ret.bn, k, -1, 0)){
133  throw bignum_error("CBigNum:rand element : BN_rand failed");
134  }
135  return ret;
136  }
137 
142  int bitSize() const{
143  return BN_num_bits(bn);
144  }
145 
146  void setulong(unsigned long n)
147  {
148  if (!BN_set_word(bn, n))
149  throw bignum_error("CBigNum conversion from unsigned long : BN_set_word failed");
150  }
151 
152  unsigned long getulong() const
153  {
154  return BN_get_word(bn);
155  }
156 
157  unsigned int getuint() const
158  {
159  return BN_get_word(bn);
160  }
161 
162  int getint() const
163  {
164  unsigned long n = BN_get_word(bn);
165  if (!BN_is_negative(bn))
166  return (n > (unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : n);
167  else
168  return (n > (unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::min() : -(int)n);
169  }
170 
171  void setint64(int64_t sn)
172  {
173  unsigned char pch[sizeof(sn) + 6];
174  unsigned char* p = pch + 4;
175  bool fNegative;
176  uint64_t n;
177 
178  if (sn < (int64_t)0)
179  {
180  // Since the minimum signed integer cannot be represented as positive so long as its type is signed,
181  // and it's not well-defined what happens if you make it unsigned before negating it,
182  // we instead increment the negative integer by 1, convert it, then increment the (now positive) unsigned integer by 1 to compensate
183  n = -(sn + 1);
184  ++n;
185  fNegative = true;
186  } else {
187  n = sn;
188  fNegative = false;
189  }
190 
191  bool fLeadingZeroes = true;
192  for (int i = 0; i < 8; i++)
193  {
194  unsigned char c = (n >> 56) & 0xff;
195  n <<= 8;
196  if (fLeadingZeroes)
197  {
198  if (c == 0)
199  continue;
200  if (c & 0x80)
201  *p++ = (fNegative ? 0x80 : 0);
202  else if (fNegative)
203  c |= 0x80;
204  fLeadingZeroes = false;
205  }
206  *p++ = c;
207  }
208  unsigned int nSize = p - (pch + 4);
209  pch[0] = (nSize >> 24) & 0xff;
210  pch[1] = (nSize >> 16) & 0xff;
211  pch[2] = (nSize >> 8) & 0xff;
212  pch[3] = (nSize) & 0xff;
213  BN_mpi2bn(pch, p - pch, bn);
214  }
215 
216  void setuint64(uint64_t n)
217  {
218  unsigned char pch[sizeof(n) + 6];
219  unsigned char* p = pch + 4;
220  bool fLeadingZeroes = true;
221  for (int i = 0; i < 8; i++)
222  {
223  unsigned char c = (n >> 56) & 0xff;
224  n <<= 8;
225  if (fLeadingZeroes)
226  {
227  if (c == 0)
228  continue;
229  if (c & 0x80)
230  *p++ = 0;
231  fLeadingZeroes = false;
232  }
233  *p++ = c;
234  }
235  unsigned int nSize = p - (pch + 4);
236  pch[0] = (nSize >> 24) & 0xff;
237  pch[1] = (nSize >> 16) & 0xff;
238  pch[2] = (nSize >> 8) & 0xff;
239  pch[3] = (nSize) & 0xff;
240  BN_mpi2bn(pch, p - pch, bn);
241  }
242 
244  {
245  unsigned char pch[sizeof(n) + 6];
246  unsigned char* p = pch + 4;
247  bool fLeadingZeroes = true;
248  unsigned char* pbegin = (unsigned char*)&n;
249  unsigned char* psrc = pbegin + sizeof(n);
250  while (psrc != pbegin)
251  {
252  unsigned char c = *(--psrc);
253  if (fLeadingZeroes)
254  {
255  if (c == 0)
256  continue;
257  if (c & 0x80)
258  *p++ = 0;
259  fLeadingZeroes = false;
260  }
261  *p++ = c;
262  }
263  unsigned int nSize = p - (pch + 4);
264  pch[0] = (nSize >> 24) & 0xff;
265  pch[1] = (nSize >> 16) & 0xff;
266  pch[2] = (nSize >> 8) & 0xff;
267  pch[3] = (nSize >> 0) & 0xff;
268  BN_mpi2bn(pch, p - pch, bn);
269  }
270 
272  {
273  unsigned int nSize = BN_bn2mpi(bn, NULL);
274  if (nSize < 4)
275  return 0;
276  std::vector<unsigned char> vch(nSize);
277  BN_bn2mpi(bn, &vch[0]);
278  if (vch.size() > 4)
279  vch[4] &= 0x7f;
280  uint256 n = 0;
281  for (unsigned int i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--)
282  ((unsigned char*)&n)[i] = vch[j];
283  return n;
284  }
285 
286  void setvch(const std::vector<unsigned char>& vch)
287  {
288  std::vector<unsigned char> vch2(vch.size() + 4);
289  unsigned int nSize = vch.size();
290  // BIGNUM's byte stream format expects 4 bytes of
291  // big endian size data info at the front
292  vch2[0] = (nSize >> 24) & 0xff;
293  vch2[1] = (nSize >> 16) & 0xff;
294  vch2[2] = (nSize >> 8) & 0xff;
295  vch2[3] = (nSize >> 0) & 0xff;
296  // swap data to big endian
297  reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4);
298  BN_mpi2bn(&vch2[0], vch2.size(), bn);
299  }
300 
301  std::vector<unsigned char> getvch() const
302  {
303  unsigned int nSize = BN_bn2mpi(bn, NULL);
304  if (nSize <= 4)
305  return std::vector<unsigned char>();
306  std::vector<unsigned char> vch(nSize);
307  BN_bn2mpi(bn, &vch[0]);
308  vch.erase(vch.begin(), vch.begin() + 4);
309  reverse(vch.begin(), vch.end());
310  return vch;
311  }
312 
313  // The "compact" format is a representation of a whole
314  // number N using an unsigned 32bit number similar to a
315  // floating point format.
316  // The most significant 8 bits are the unsigned exponent of base 256.
317  // This exponent can be thought of as "number of bytes of N".
318  // The lower 23 bits are the mantissa.
319  // Bit number 24 (0x800000) represents the sign of N.
320  // N = (-1^sign) * mantissa * 256^(exponent-3)
321  //
322  // Satoshi's original implementation used BN_bn2mpi() and BN_mpi2bn().
323  // MPI uses the most significant bit of the first byte as sign.
324  // Thus 0x1234560000 is compact (0x05123456)
325  // and 0xc0de000000 is compact (0x0600c0de)
326  // (0x05c0de00) would be -0x40de000000
327  //
328  // Bitcoin only uses this "compact" format for encoding difficulty
329  // targets, which are unsigned 256bit quantities. Thus, all the
330  // complexities of the sign bit and using base 256 are probably an
331  // implementation accident.
332  //
333  // This implementation directly uses shifts instead of going
334  // through an intermediate MPI representation.
335  CBigNum& SetCompact(unsigned int nCompact)
336  {
337  unsigned int nSize = nCompact >> 24;
338  bool fNegative =(nCompact & 0x00800000) != 0;
339  unsigned int nWord = nCompact & 0x007fffff;
340  if (nSize <= 3)
341  {
342  nWord >>= 8*(3-nSize);
343  BN_set_word(bn, nWord);
344  }
345  else
346  {
347  BN_set_word(bn, nWord);
348  BN_lshift(bn, bn, 8*(nSize-3));
349  }
350  BN_set_negative(bn, fNegative);
351  return *this;
352  }
353 
354  unsigned int GetCompact() const
355  {
356  unsigned int nSize = BN_num_bytes(bn);
357  unsigned int nCompact = 0;
358  if (nSize <= 3)
359  nCompact = BN_get_word(bn) << 8*(3-nSize);
360  else
361  {
362  CBigNum cbn;
363  BN_rshift(cbn.bn, bn, 8*(nSize-3));
364  nCompact = BN_get_word(bn);
365  }
366  // The 0x00800000 bit denotes the sign.
367  // Thus, if it is already set, divide the mantissa by 256 and increase the exponent.
368  if (nCompact & 0x00800000)
369  {
370  nCompact >>= 8;
371  nSize++;
372  }
373  nCompact |= nSize << 24;
374  nCompact |= (BN_is_negative(bn) ? 0x00800000 : 0);
375  return nCompact;
376  }
377 
378  void SetHex(const std::string& str)
379  {
380  // skip 0x
381  const char* psz = str.c_str();
382  while (isspace(*psz))
383  psz++;
384  bool fNegative = false;
385  if (*psz == '-')
386  {
387  fNegative = true;
388  psz++;
389  }
390  if (psz[0] == '0' && tolower(psz[1]) == 'x')
391  psz += 2;
392  while (isspace(*psz))
393  psz++;
394 
395  // hex string to bignum
396  static const signed char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 };
397  *this = 0;
398  while (isxdigit(*psz))
399  {
400  *this <<= 4;
401  int n = phexdigit[(unsigned char)*psz++];
402  *this += n;
403  }
404  if (fNegative)
405  *this = 0 - *this;
406  }
407 
408  bool SetHexBool(const std::string& str)
409  {
410  // skip 0x
411  const char* psz = str.c_str();
412  while (isspace(*psz))
413  psz++;
414  bool fNegative = false;
415  if (*psz == '-')
416  {
417  fNegative = true;
418  psz++;
419  }
420  if (psz[0] == '0' && tolower(psz[1]) == 'x')
421  psz += 2;
422  while (isspace(*psz))
423  psz++;
424 
425  // hex string to bignum
426  static const signed char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 };
427  *this = 0;
428  while (isxdigit(*psz))
429  {
430  *this <<= 4;
431  int n = phexdigit[(unsigned char)*psz++];
432  *this += n;
433  }
434  if (fNegative)
435  *this = 0 - *this;
436 
437  return true;
438  }
439 
440 
441  std::string ToString(int nBase=10) const
442  {
443  CAutoBN_CTX pctx;
444  CBigNum bnBase = nBase;
445  CBigNum bn0 = 0;
446  CBigNum locBn = *this;
447  std::string str;
448  BN_set_negative(locBn.bn, false);
449  CBigNum dv;
450  CBigNum rem;
451  if (BN_cmp(locBn.bn, bn0.bn) == 0)
452  return "0";
453  while (BN_cmp(locBn.bn, bn0.bn) > 0)
454  {
455  if (!BN_div(dv.bn, rem.bn, locBn.bn, bnBase.bn, pctx))
456  throw bignum_error("CBigNum::ToString() : BN_div failed");
457  locBn = dv;
458  unsigned int c = rem.getulong();
459  str += "0123456789abcdef"[c];
460  }
461  if (BN_is_negative(bn))
462  str += "-";
463  reverse(str.begin(), str.end());
464  return str;
465  }
466 
467  std::string GetHex() const
468  {
469  return ToString(16);
470  }
471 
472  unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const
473  {
474  return ::GetSerializeSize(getvch(), nType, nVersion);
475  }
476 
477  template<typename Stream>
478  void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const
479  {
480  ::Serialize(s, getvch(), nType, nVersion);
481  }
482 
483  template<typename Stream>
484  void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION)
485  {
486  std::vector<unsigned char> vch;
487  ::Unserialize(s, vch, nType, nVersion);
488  setvch(vch);
489  }
490 
496  CBigNum pow(const int e) const {
497  return this->pow(CBigNum(e));
498  }
499 
505  CBigNum pow(const CBigNum& e) const {
506  CAutoBN_CTX pctx;
507  CBigNum ret;
508  if (!BN_exp(ret.bn, bn, e.bn, pctx))
509  throw bignum_error("CBigNum::pow : BN_exp failed");
510  return ret;
511  }
512 
518  CBigNum mul_mod(const CBigNum& b, const CBigNum& m) const {
519  CAutoBN_CTX pctx;
520  CBigNum ret;
521  if (!BN_mod_mul(ret.bn, bn, b.bn, m.bn, pctx))
522  throw bignum_error("CBigNum::mul_mod : BN_mod_mul failed");
523 
524  return ret;
525  }
526 
532  CBigNum pow_mod(const CBigNum& e, const CBigNum& m) const {
533  CAutoBN_CTX pctx;
534  CBigNum ret;
535  if( e < 0){
536  // g^-x = (g^-1)^x
537  CBigNum inv = this->inverse(m);
538  CBigNum posE = e * -1;
539  if (!BN_mod_exp(ret.bn, inv.bn, posE.bn, m.bn, pctx))
540  throw bignum_error("CBigNum::pow_mod: BN_mod_exp failed on negative exponent");
541  }else
542  if (!BN_mod_exp(ret.bn, bn, e.bn, m.bn, pctx))
543  throw bignum_error("CBigNum::pow_mod : BN_mod_exp failed");
544 
545  return ret;
546  }
547 
554  CBigNum inverse(const CBigNum& m) const {
555  CAutoBN_CTX pctx;
556  CBigNum ret;
557  if (!BN_mod_inverse(ret.bn, bn, m.bn, pctx))
558  throw bignum_error("CBigNum::inverse*= :BN_mod_inverse");
559  return ret;
560  }
561 
568  static CBigNum generatePrime(const unsigned int numBits, bool safe = false) {
569  CBigNum ret;
570  if(!BN_generate_prime_ex(ret.bn, numBits, (safe == true), NULL, NULL, NULL))
571  throw bignum_error("CBigNum::generatePrime*= :BN_generate_prime_ex");
572  return ret;
573  }
574 
580  CBigNum gcd( const CBigNum& b) const{
581  CAutoBN_CTX pctx;
582  CBigNum ret;
583  if (!BN_gcd(ret.bn, bn, b.bn, pctx))
584  throw bignum_error("CBigNum::gcd*= :BN_gcd");
585  return ret;
586  }
587 
594  bool isPrime(const int checks=BN_prime_checks) const {
595  CAutoBN_CTX pctx;
596  int ret = BN_is_prime_ex(bn, checks, pctx, NULL);
597  if(ret < 0){
598  throw bignum_error("CBigNum::isPrime :BN_is_prime");
599  }
600  return ret;
601  }
602 
603  bool isOne() const {
604  return BN_is_one(bn);
605  }
606 
607 
608 
609  bool operator!() const
610  {
611  return BN_is_zero(bn);
612  }
613 
615  {
616  if (!BN_add(bn, bn, b.bn))
617  throw bignum_error("CBigNum::operator+= : BN_add failed");
618  return *this;
619  }
620 
622  {
623  if (!BN_sub(bn, bn, b.bn))
624  throw bignum_error("CBigNum::operator-= : BN_sub failed");
625  return *this;
626  }
627 
629  {
630  CAutoBN_CTX pctx;
631  if (!BN_mul(bn, bn, b.bn, pctx))
632  throw bignum_error("CBigNum::operator*= : BN_mul failed");
633  return *this;
634  }
635 
637  {
638  CAutoBN_CTX pctx;
639  if (!BN_div(bn, NULL, bn, b.bn, pctx))
640  throw bignum_error("CBigNum::operator/= : BN_div failed");
641  return *this;
642  }
643 
645  {
646  CAutoBN_CTX pctx;
647  if (!BN_mod(bn, b.bn, bn, pctx))
648  throw bignum_error("CBigNum::operator%= : BN_mod failed");
649  return *this;
650  }
651 
652  CBigNum& operator<<=(unsigned int shift)
653  {
654  if (!BN_lshift(bn, bn, shift))
655  throw bignum_error("CBigNum:operator<<= : BN_lshift failed");
656  return *this;
657  }
658 
659  CBigNum& operator>>=(unsigned int shift)
660  {
661  // Note: BN_rshift segfaults on 64-bit if 2^shift is greater than the number
662  // if built on ubuntu 9.04 or 9.10, probably depends on version of OpenSSL
663  CBigNum a = 1;
664  a <<= shift;
665  if (BN_cmp(a.bn, bn) > 0)
666  {
667  bn = 0;
668  return *this;
669  }
670 
671  if (!BN_rshift(bn, bn, shift))
672  throw bignum_error("CBigNum:operator>>= : BN_rshift failed");
673  return *this;
674  }
675 
676 
678  {
679  // prefix operator
680  if (!BN_add(bn, bn, BN_value_one()))
681  throw bignum_error("CBigNum::operator++ : BN_add failed");
682  return *this;
683  }
684 
685  const CBigNum operator++(int)
686  {
687  // postfix operator
688  const CBigNum ret = *this;
689  ++(*this);
690  return ret;
691  }
692 
694  {
695  // prefix operator
696  CBigNum r;
697  if (!BN_sub(r.bn, bn, BN_value_one()))
698  throw bignum_error("CBigNum::operator-- : BN_sub failed");
699  bn = r.bn;
700  return *this;
701  }
702 
703  const CBigNum operator--(int)
704  {
705  // postfix operator
706  const CBigNum ret = *this;
707  --(*this);
708  return ret;
709  }
710 
711  friend inline const CBigNum operator+(const CBigNum& a, const CBigNum& b);
712  friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b);
713  friend inline const CBigNum operator/(const CBigNum& a, const CBigNum& b);
714  friend inline const CBigNum operator%(const CBigNum& a, const CBigNum& b);
715  friend inline const CBigNum operator*(const CBigNum& a, const CBigNum& b);
716  friend inline const CBigNum operator<<(const CBigNum& a, unsigned int shift);
717  friend inline const CBigNum operator-(const CBigNum& a);
718  friend inline bool operator==(const CBigNum& a, const CBigNum& b);
719  friend inline bool operator!=(const CBigNum& a, const CBigNum& b);
720  friend inline bool operator<=(const CBigNum& a, const CBigNum& b);
721  friend inline bool operator>=(const CBigNum& a, const CBigNum& b);
722  friend inline bool operator<(const CBigNum& a, const CBigNum& b);
723  friend inline bool operator>(const CBigNum& a, const CBigNum& b);
724 };
725 
726 
727 
728 inline const CBigNum operator+(const CBigNum& a, const CBigNum& b)
729 {
730  CBigNum r;
731  if (!BN_add(r.bn, a.bn, b.bn))
732  throw bignum_error("CBigNum::operator+ : BN_add failed");
733  return r;
734 }
735 
736 inline const CBigNum operator-(const CBigNum& a, const CBigNum& b)
737 {
738  CBigNum r;
739  if (!BN_sub(r.bn, a.bn, b.bn))
740  throw bignum_error("CBigNum::operator- : BN_sub failed");
741  return r;
742 }
743 
744 inline const CBigNum operator-(const CBigNum& a)
745 {
746  CBigNum r(a);
747  BN_set_negative(r.bn, !BN_is_negative(r.bn));
748  return r;
749 }
750 
751 inline const CBigNum operator*(const CBigNum& a, const CBigNum& b)
752 {
753  CAutoBN_CTX pctx;
754  CBigNum r;
755  if (!BN_mul(r.bn, a.bn, b.bn, pctx))
756  throw bignum_error("CBigNum::operator* : BN_mul failed");
757  return r;
758 }
759 
760 inline const CBigNum operator/(const CBigNum& a, const CBigNum& b)
761 {
762  CAutoBN_CTX pctx;
763  CBigNum r;
764  if (!BN_div(r.bn, NULL, a.bn, b.bn, pctx))
765  throw bignum_error("CBigNum::operator/ : BN_div failed");
766  return r;
767 }
768 
769 inline const CBigNum operator%(const CBigNum& a, const CBigNum& b)
770 {
771  CAutoBN_CTX pctx;
772  CBigNum r;
773  if (!BN_nnmod(r.bn, a.bn, b.bn, pctx))
774  throw bignum_error("CBigNum::operator% : BN_div failed");
775  return r;
776 }
777 
778 inline const CBigNum operator<<(const CBigNum& a, unsigned int shift)
779 {
780  CBigNum r;
781  if (!BN_lshift(r.bn, a.bn, shift))
782  throw bignum_error("CBigNum:operator<< : BN_lshift failed");
783  return r;
784 }
785 
786 inline const CBigNum operator>>(const CBigNum& a, unsigned int shift)
787 {
788  CBigNum r = a;
789  r >>= shift;
790  return r;
791 }
792 
793 inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.bn, b.bn) == 0); }
794 inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.bn, b.bn) != 0); }
795 inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.bn, b.bn) <= 0); }
796 inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.bn, b.bn) >= 0); }
797 inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.bn, b.bn) < 0); }
798 inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.bn, b.bn) > 0); }
799 inline std::ostream& operator<<(std::ostream &strm, const CBigNum &b) { return strm << b.ToString(10); }
800 
801 typedef CBigNum Bignum;
802 
803 #endif
CBigNum::operator<<
const friend CBigNum operator<<(const CBigNum &a, unsigned int shift)
Definition: bignum.h:778
CBigNum::operator+
const friend CBigNum operator+(const CBigNum &a, const CBigNum &b)
Definition: bignum.h:728
CBigNum::operator+=
CBigNum & operator+=(const CBigNum &b)
Definition: bignum.h:614
CBigNum::isOne
bool isOne() const
Definition: bignum.h:603
CBigNum::bitSize
int bitSize() const
Returns the size in bits of the underlying bignum.
Definition: bignum.h:142
CBigNum::CBigNum
CBigNum(const CBigNum &b)
Definition: bignum.h:70
CBigNum::operator<=
friend bool operator<=(const CBigNum &a, const CBigNum &b)
Definition: bignum.h:795
CBigNum
C++ wrapper for BIGNUM (OpenSSL bignum)
Definition: bignum.h:54
CBigNum::bn
BIGNUM * bn
Definition: bignum.h:56
b
void const uint64_t * b
Definition: field_5x52_asm_impl.h:10
CBigNum::CBigNum
CBigNum(uint256 n)
Definition: bignum.h:105
CBigNum::CBigNum
CBigNum(short n)
Definition: bignum.h:94
operator==
bool operator==(const CBigNum &a, const CBigNum &b)
Definition: bignum.h:793
CAutoBN_CTX::operator!
bool operator!()
Definition: bignum.h:49
CBigNum::operator=
CBigNum & operator=(const CBigNum &b)
Definition: bignum.h:80
CBigNum::CBigNum
CBigNum(const std::vector< unsigned char > &vch)
Definition: bignum.h:107
uint256.h
operator/
const CBigNum operator/(const CBigNum &a, const CBigNum &b)
Definition: bignum.h:760
operator>>
const CBigNum operator>>(const CBigNum &a, unsigned int shift)
Definition: bignum.h:786
CBigNum::RandKBitBigum
static CBigNum RandKBitBigum(const uint32_t k)
Generates a cryptographically secure random k-bit number.
Definition: bignum.h:130
CBigNum::CBigNum
CBigNum(unsigned char n)
Definition: bignum.h:100
CAutoBN_CTX
RAII encapsulated BN_CTX (OpenSSL bignum context)
Definition: bignum.h:26
GetSerializeSize
unsigned int GetSerializeSize(char a, int, int=0)
Definition: serialize.h:194
CBigNum::CBigNum
CBigNum(unsigned int n)
Definition: bignum.h:102
CBigNum::pow_mod
CBigNum pow_mod(const CBigNum &e, const CBigNum &m) const
modular exponentiation: this^e mod n
Definition: bignum.h:532
CBigNum::SetCompact
CBigNum & SetCompact(unsigned int nCompact)
Definition: bignum.h:335
version.h
CBigNum::CBigNum
CBigNum()
Definition: bignum.h:58
CAutoBN_CTX::operator=
BN_CTX * operator=(BN_CTX *pnew)
Definition: bignum.h:30
CBigNum::ToString
std::string ToString(int nBase=10) const
Definition: bignum.h:441
CBigNum::setuint64
void setuint64(uint64_t n)
Definition: bignum.h:216
CBigNum::randBignum
static CBigNum randBignum(const CBigNum &range)
Generates a cryptographically secure random number between zero and range exclusive i....
Definition: bignum.h:118
CBigNum::getulong
unsigned long getulong() const
Definition: bignum.h:152
operator*
const CBigNum operator*(const CBigNum &a, const CBigNum &b)
Definition: bignum.h:751
r
void const uint64_t uint64_t * r
Definition: field_5x52_asm_impl.h:10
CBigNum::getvch
std::vector< unsigned char > getvch() const
Definition: bignum.h:301
CBigNum::setvch
void setvch(const std::vector< unsigned char > &vch)
Definition: bignum.h:286
CBigNum::operator>=
friend bool operator>=(const CBigNum &a, const CBigNum &b)
Definition: bignum.h:796
operator<
bool operator<(const CBigNum &a, const CBigNum &b)
Definition: bignum.h:797
CBigNum::setint64
void setint64(int64_t sn)
Definition: bignum.h:171
CBigNum::operator==
friend bool operator==(const CBigNum &a, const CBigNum &b)
Definition: bignum.h:793
CBigNum::generatePrime
static CBigNum generatePrime(const unsigned int numBits, bool safe=false)
Generates a random (safe) prime of numBits bits.
Definition: bignum.h:568
operator>
bool operator>(const CBigNum &a, const CBigNum &b)
Definition: bignum.h:798
CBigNum::SetHexBool
bool SetHexBool(const std::string &str)
Definition: bignum.h:408
CAutoBN_CTX::~CAutoBN_CTX
~CAutoBN_CTX()
Definition: bignum.h:40
operator!=
bool operator!=(const CBigNum &a, const CBigNum &b)
Definition: bignum.h:794
CBigNum::operator/=
CBigNum & operator/=(const CBigNum &b)
Definition: bignum.h:636
CBigNum::Serialize
void Serialize(Stream &s, int nType=0, int nVersion=PROTOCOL_VERSION) const
Definition: bignum.h:478
CBigNum::mul_mod
CBigNum mul_mod(const CBigNum &b, const CBigNum &m) const
modular multiplication: (this * b) mod m
Definition: bignum.h:518
CBigNum::operator!=
friend bool operator!=(const CBigNum &a, const CBigNum &b)
Definition: bignum.h:794
CBigNum::operator++
CBigNum & operator++()
Definition: bignum.h:677
uint256
256-bit unsigned big integer.
Definition: uint256.h:38
CBigNum::setuint256
void setuint256(uint256 n)
Definition: bignum.h:243
CBigNum::operator<<=
CBigNum & operator<<=(unsigned int shift)
Definition: bignum.h:652
CBigNum::operator--
const CBigNum operator--(int)
Definition: bignum.h:703
CBigNum::SetHex
void SetHex(const std::string &str)
Definition: bignum.h:378
CBigNum::operator!
bool operator!() const
Definition: bignum.h:609
CBigNum::CBigNum
CBigNum(signed char n)
Definition: bignum.h:93
CBigNum::CBigNum
CBigNum(const std::string &str)
Definition: bignum.h:64
operator+
const CBigNum operator+(const CBigNum &a, const CBigNum &b)
Definition: bignum.h:728
CBigNum::setulong
void setulong(unsigned long n)
Definition: bignum.h:146
CBigNum::operator-=
CBigNum & operator-=(const CBigNum &b)
Definition: bignum.h:621
CBigNum::operator<
friend bool operator<(const CBigNum &a, const CBigNum &b)
Definition: bignum.h:797
CAutoBN_CTX::operator&
BN_CTX ** operator&()
Definition: bignum.h:48
CAutoBN_CTX::operator*
BN_CTX & operator*()
Definition: bignum.h:47
CBigNum::operator/
const friend CBigNum operator/(const CBigNum &a, const CBigNum &b)
Definition: bignum.h:760
CAutoBN_CTX::pctx
BN_CTX * pctx
Definition: bignum.h:29
CBigNum::getuint
unsigned int getuint() const
Definition: bignum.h:157
CBigNum::operator*
const friend CBigNum operator*(const CBigNum &a, const CBigNum &b)
Definition: bignum.h:751
CBigNum::CBigNum
CBigNum(long n)
Definition: bignum.h:96
operator<<
const CBigNum operator<<(const CBigNum &a, unsigned int shift)
Definition: bignum.h:778
bignum_error
Errors thrown by the bignum class.
Definition: bignum.h:18
CBigNum::getuint256
uint256 getuint256() const
Definition: bignum.h:271
CBigNum::GetCompact
unsigned int GetCompact() const
Definition: bignum.h:354
CBigNum::operator*=
CBigNum & operator*=(const CBigNum &b)
Definition: bignum.h:628
CBigNum::Unserialize
void Unserialize(Stream &s, int nType=0, int nVersion=PROTOCOL_VERSION)
Definition: bignum.h:484
CBigNum::CBigNum
CBigNum(unsigned long n)
Definition: bignum.h:103
operator<=
bool operator<=(const CBigNum &a, const CBigNum &b)
Definition: bignum.h:795
std
Definition: adjacency_graphs.hpp:25
CBigNum::operator++
const CBigNum operator++(int)
Definition: bignum.h:685
CBigNum::~CBigNum
~CBigNum()
Definition: bignum.h:87
CBigNum::pow
CBigNum pow(const CBigNum &e) const
exponentiation this^e
Definition: bignum.h:505
CBigNum::inverse
CBigNum inverse(const CBigNum &m) const
Calculates the inverse of this element mod m.
Definition: bignum.h:554
CBigNum::CBigNum
CBigNum(int n)
Definition: bignum.h:95
serialize.h
CBigNum::GetHex
std::string GetHex() const
Definition: bignum.h:467
CBigNum::GetSerializeSize
unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const
Definition: bignum.h:472
CBigNum::operator>>=
CBigNum & operator>>=(unsigned int shift)
Definition: bignum.h:659
bignum_error::bignum_error
bignum_error(const std::string &str)
Definition: bignum.h:21
CBigNum::operator--
CBigNum & operator--()
Definition: bignum.h:693
CBigNum::getint
int getint() const
Definition: bignum.h:162
Bignum
CBigNum Bignum
Definition: bignum.h:801
operator>=
bool operator>=(const CBigNum &a, const CBigNum &b)
Definition: bignum.h:796
CBigNum::operator>
friend bool operator>(const CBigNum &a, const CBigNum &b)
Definition: bignum.h:798
CBigNum::operator%
const friend CBigNum operator%(const CBigNum &a, const CBigNum &b)
Definition: bignum.h:769
CBigNum::gcd
CBigNum gcd(const CBigNum &b) const
Calculates the greatest common divisor (GCD) of two numbers.
Definition: bignum.h:580
operator-
const CBigNum operator-(const CBigNum &a, const CBigNum &b)
Definition: bignum.h:736
CBigNum::operator%=
CBigNum & operator%=(const CBigNum &b)
Definition: bignum.h:644
operator%
const CBigNum operator%(const CBigNum &a, const CBigNum &b)
Definition: bignum.h:769
CBigNum::pow
CBigNum pow(const int e) const
exponentiation with an int.
Definition: bignum.h:496
CBigNum::operator-
const friend CBigNum operator-(const CBigNum &a, const CBigNum &b)
Definition: bignum.h:736
CBigNum::isPrime
bool isPrime(const int checks=BN_prime_checks) const
Miller-Rabin primality test on this element.
Definition: bignum.h:594
CAutoBN_CTX::CAutoBN_CTX
CAutoBN_CTX()
Definition: bignum.h:33
CBigNum::CBigNum
CBigNum(unsigned short n)
Definition: bignum.h:101