Line data Source code
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 : #ifndef PIVX_LIBZEROCOIN_BIGNUM_H
8 : #define PIVX_LIBZEROCOIN_BIGNUM_H
9 :
10 : #if defined HAVE_CONFIG_H
11 : #include "config/pivx-config.h"
12 : #endif
13 :
14 : #include <gmp.h>
15 :
16 : #include <stdexcept>
17 : #include <vector>
18 : #include <limits.h>
19 :
20 : #include "arith_uint256.h"
21 : #include "serialize.h"
22 : #include "uint256.h"
23 : #include "version.h"
24 : #include "random.h"
25 :
26 : /** Errors thrown by the bignum class */
27 : class bignum_error : public std::runtime_error
28 : {
29 : public:
30 : explicit bignum_error(const std::string& str) : std::runtime_error(str) {}
31 : };
32 :
33 : /** C++ wrapper for BIGNUM */
34 : class CBigNum
35 : {
36 : mpz_t bn;
37 : public:
38 : CBigNum();
39 : CBigNum(const CBigNum& b);
40 : CBigNum& operator=(const CBigNum& b);
41 : ~CBigNum();
42 :
43 : //CBigNum(char n) is not portable. Use 'signed char' or 'unsigned char'.
44 : CBigNum(signed char n);
45 : CBigNum(short n);
46 : CBigNum(int n);
47 : CBigNum(long n);
48 : CBigNum(long long n);
49 : CBigNum(unsigned char n);
50 : CBigNum(unsigned short n);
51 : CBigNum(unsigned int n);
52 : CBigNum(unsigned long n);
53 : CBigNum(unsigned long long n);
54 : explicit CBigNum(uint256 n);
55 : explicit CBigNum(const std::vector<unsigned char>& vch);
56 :
57 : /** Generates a cryptographically secure random number between zero and range exclusive
58 : * i.e. 0 < returned number < range
59 : * @param range The upper bound on the number.
60 : * @return
61 : */
62 : static CBigNum randBignum(const CBigNum& range);
63 :
64 : /**Returns the size in bits of the underlying bignum.
65 : *
66 : * @return the size
67 : */
68 : int bitSize() const;
69 : void setulong(unsigned long n);
70 : unsigned long getulong() const;
71 : unsigned int getuint() const;
72 : int getint() const;
73 : void setint64(int64_t sn);
74 : void setuint64(uint64_t n);
75 : void setuint256(uint256 n);
76 : arith_uint256 getuint256() const;
77 : void setvch(const std::vector<unsigned char>& vch);
78 : std::vector<unsigned char> getvch() const;
79 : void SetDec(const std::string& str);
80 : void SetHex(const std::string& str);
81 : bool SetHexBool(const std::string& str);
82 : std::string ToString(int nBase=10) const;
83 : std::string GetHex() const;
84 : std::string GetDec() const;
85 :
86 : template<typename Stream>
87 580 : void Serialize(Stream& s) const
88 : {
89 580 : ::Serialize(s, getvch());
90 580 : }
91 :
92 : template<typename Stream>
93 0 : void Unserialize(Stream& s)
94 : {
95 0 : std::vector<unsigned char> vch;
96 0 : ::Unserialize(s, vch);
97 0 : setvch(vch);
98 0 : }
99 :
100 : /**
101 : * exponentiation with an int. this^e
102 : * @param e the exponent as an int
103 : * @return
104 : */
105 : CBigNum pow(const int e) const;
106 :
107 : /**
108 : * exponentiation this^e
109 : * @param e the exponent
110 : * @return
111 : */
112 : CBigNum pow(const CBigNum& e) const;
113 :
114 : /**
115 : * modular multiplication: (this * b) mod m
116 : * @param b operand
117 : * @param m modulus
118 : */
119 : CBigNum mul_mod(const CBigNum& b, const CBigNum& m) const;
120 :
121 : /**
122 : * modular exponentiation: this^e mod n
123 : * @param e exponent
124 : * @param m modulus
125 : */
126 : CBigNum pow_mod(const CBigNum& e, const CBigNum& m) const;
127 :
128 : /**
129 : * Calculates the inverse of this element mod m.
130 : * i.e. i such this*i = 1 mod m
131 : * @param m the modu
132 : * @return the inverse
133 : */
134 : CBigNum inverse(const CBigNum& m) const;
135 :
136 : /**
137 : * Calculates the greatest common divisor (GCD) of two numbers.
138 : * @param m the second element
139 : * @return the GCD
140 : */
141 : CBigNum gcd( const CBigNum& b) const;
142 :
143 : /**
144 : * Miller-Rabin primality test on this element
145 : * @param checks: optional, the number of Miller-Rabin tests to run
146 : * default causes error rate of 2^-80.
147 : * @return true if prime
148 : */
149 : bool isPrime(const int checks=15) const;
150 :
151 : bool isOne() const;
152 : bool operator!() const;
153 : CBigNum& operator+=(const CBigNum& b);
154 : CBigNum& operator-=(const CBigNum& b);
155 : CBigNum& operator*=(const CBigNum& b);
156 : CBigNum& operator/=(const CBigNum& b);
157 : CBigNum& operator%=(const CBigNum& b);
158 : CBigNum& operator<<=(unsigned int shift);
159 : CBigNum& operator>>=(unsigned int shift);
160 : CBigNum& operator++();
161 : const CBigNum operator++(int);
162 : CBigNum& operator--();
163 : const CBigNum operator--(int);
164 :
165 : friend inline const CBigNum operator+(const CBigNum& a, const CBigNum& b);
166 : friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b);
167 : friend inline const CBigNum operator/(const CBigNum& a, const CBigNum& b);
168 : friend inline const CBigNum operator%(const CBigNum& a, const CBigNum& b);
169 : friend inline const CBigNum operator*(const CBigNum& a, const CBigNum& b);
170 : friend inline const CBigNum operator<<(const CBigNum& a, unsigned int shift);
171 : friend inline const CBigNum operator-(const CBigNum& a);
172 : friend inline bool operator==(const CBigNum& a, const CBigNum& b);
173 : friend inline bool operator!=(const CBigNum& a, const CBigNum& b);
174 : friend inline bool operator<=(const CBigNum& a, const CBigNum& b);
175 : friend inline bool operator>=(const CBigNum& a, const CBigNum& b);
176 : friend inline bool operator<(const CBigNum& a, const CBigNum& b);
177 : friend inline bool operator>(const CBigNum& a, const CBigNum& b);
178 : };
179 :
180 645692 : inline const CBigNum operator+(const CBigNum& a, const CBigNum& b) {
181 645692 : CBigNum r;
182 645692 : mpz_add(r.bn, a.bn, b.bn);
183 645692 : return r;
184 : }
185 297472 : inline const CBigNum operator-(const CBigNum& a, const CBigNum& b) {
186 297472 : CBigNum r;
187 297472 : mpz_sub(r.bn, a.bn, b.bn);
188 297472 : return r;
189 : }
190 1404 : inline const CBigNum operator-(const CBigNum& a) {
191 1404 : CBigNum r;
192 1404 : mpz_neg(r.bn, a.bn);
193 1404 : return r;
194 : }
195 1223862 : inline const CBigNum operator*(const CBigNum& a, const CBigNum& b) {
196 1223862 : CBigNum r;
197 1223862 : mpz_mul(r.bn, a.bn, b.bn);
198 1223862 : return r;
199 : }
200 2900 : inline const CBigNum operator/(const CBigNum& a, const CBigNum& b) {
201 2900 : CBigNum r;
202 2900 : mpz_tdiv_q(r.bn, a.bn, b.bn);
203 2900 : return r;
204 : }
205 296439 : inline const CBigNum operator%(const CBigNum& a, const CBigNum& b) {
206 296439 : CBigNum r;
207 296439 : mpz_mmod(r.bn, a.bn, b.bn);
208 296439 : return r;
209 : }
210 : inline const CBigNum operator<<(const CBigNum& a, unsigned int shift) {
211 : CBigNum r;
212 : mpz_mul_2exp(r.bn, a.bn, shift);
213 : return r;
214 : }
215 : inline const CBigNum operator>>(const CBigNum& a, unsigned int shift) {
216 : CBigNum r = a;
217 : r >>= shift;
218 : return r;
219 : }
220 5964 : inline bool operator==(const CBigNum& a, const CBigNum& b) { return (mpz_cmp(a.bn, b.bn) == 0); }
221 5616 : inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (mpz_cmp(a.bn, b.bn) != 0); }
222 5616 : inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (mpz_cmp(a.bn, b.bn) <= 0); }
223 5616 : inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (mpz_cmp(a.bn, b.bn) >= 0); }
224 5618 : inline bool operator<(const CBigNum& a, const CBigNum& b) { return (mpz_cmp(a.bn, b.bn) < 0); }
225 377918 : inline bool operator>(const CBigNum& a, const CBigNum& b) { return (mpz_cmp(a.bn, b.bn) > 0); }
226 :
227 0 : inline std::ostream& operator<<(std::ostream &strm, const CBigNum &b) { return strm << b.ToString(10); }
228 :
229 : typedef CBigNum Bignum;
230 :
231 : /** constant bignum instances */
232 : const CBigNum BN_ZERO = CBigNum(0);
233 : const CBigNum BN_ONE = CBigNum(1);
234 : const CBigNum BN_TWO = CBigNum(2);
235 : const CBigNum BN_THREE = CBigNum(3);
236 :
237 : #endif // PIVX_LIBZEROCOIN_BIGNUM_H
|