5 #ifndef BITCOIN_BIGNUM_H
6 #define BITCOIN_BIGNUM_H
10 #include <openssl/bn.h>
27 BN_CTX*
operator=(BN_CTX* pnew) {
return pctx = pnew; }
34 throw bignum_error(
"CAutoBN_CTX : BN_CTX_new() returned NULL");
43 operator BN_CTX*() {
return pctx; }
62 if (!BN_copy(
this, &b))
65 throw bignum_error(
"CBigNum::CBigNum(const CBigNum&) : BN_copy failed");
71 if (!BN_copy(
this, &b))
72 throw bignum_error(
"CBigNum::operator= : BN_copy failed");
94 explicit CBigNum(
const std::vector<unsigned char>& vch)
102 if (!BN_set_word(
this, n))
103 throw bignum_error(
"CBigNum conversion from unsigned long : BN_set_word failed");
108 return BN_get_word(
this);
113 return BN_get_word(
this);
118 unsigned long n = BN_get_word(
this);
119 if (!BN_is_negative(
this))
120 return (n > (
unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : n);
122 return (n > (
unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::min() : -(
int)n);
127 unsigned char pch[
sizeof(sn) + 6];
128 unsigned char* p = pch + 4;
145 bool fLeadingZeroes =
true;
146 for (
int i = 0; i < 8; i++)
148 unsigned char c = (n >> 56) & 0xff;
155 *p++ = (fNegative ? 0x80 : 0);
158 fLeadingZeroes =
false;
162 unsigned int nSize = p - (pch + 4);
163 pch[0] = (nSize >> 24) & 0xff;
164 pch[1] = (nSize >> 16) & 0xff;
165 pch[2] = (nSize >> 8) & 0xff;
166 pch[3] = (nSize) & 0xff;
167 BN_mpi2bn(pch, p - pch,
this);
172 unsigned char pch[
sizeof(n) + 6];
173 unsigned char* p = pch + 4;
174 bool fLeadingZeroes =
true;
175 for (
int i = 0; i < 8; i++)
177 unsigned char c = (n >> 56) & 0xff;
185 fLeadingZeroes =
false;
189 unsigned int nSize = p - (pch + 4);
190 pch[0] = (nSize >> 24) & 0xff;
191 pch[1] = (nSize >> 16) & 0xff;
192 pch[2] = (nSize >> 8) & 0xff;
193 pch[3] = (nSize) & 0xff;
194 BN_mpi2bn(pch, p - pch,
this);
199 unsigned char pch[
sizeof(n) + 6];
200 unsigned char* p = pch + 4;
201 bool fLeadingZeroes =
true;
202 unsigned char* pbegin = (
unsigned char*)&n;
203 unsigned char* psrc = pbegin +
sizeof(n);
204 while (psrc != pbegin)
206 unsigned char c = *(--psrc);
213 fLeadingZeroes =
false;
217 unsigned int nSize = p - (pch + 4);
218 pch[0] = (nSize >> 24) & 0xff;
219 pch[1] = (nSize >> 16) & 0xff;
220 pch[2] = (nSize >> 8) & 0xff;
221 pch[3] = (nSize >> 0) & 0xff;
222 BN_mpi2bn(pch, p - pch,
this);
227 unsigned int nSize = BN_bn2mpi(
this, NULL);
230 std::vector<unsigned char> vch(nSize);
231 BN_bn2mpi(
this, &vch[0]);
235 for (
unsigned int i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--)
236 ((
unsigned char*)&n)[i] = vch[j];
240 void setvch(
const std::vector<unsigned char>& vch)
242 std::vector<unsigned char> vch2(vch.size() + 4);
243 unsigned int nSize = vch.size();
246 vch2[0] = (nSize >> 24) & 0xff;
247 vch2[1] = (nSize >> 16) & 0xff;
248 vch2[2] = (nSize >> 8) & 0xff;
249 vch2[3] = (nSize >> 0) & 0xff;
251 reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4);
252 BN_mpi2bn(&vch2[0], vch2.size(),
this);
255 std::vector<unsigned char>
getvch()
const
257 unsigned int nSize = BN_bn2mpi(
this, NULL);
259 return std::vector<unsigned char>();
260 std::vector<unsigned char> vch(nSize);
261 BN_bn2mpi(
this, &vch[0]);
262 vch.erase(vch.begin(), vch.begin() + 4);
263 reverse(vch.begin(), vch.end());
291 unsigned int nSize = nCompact >> 24;
292 bool fNegative =(nCompact & 0x00800000) != 0;
293 unsigned int nWord = nCompact & 0x007fffff;
296 nWord >>= 8*(3-nSize);
297 BN_set_word(
this, nWord);
301 BN_set_word(
this, nWord);
302 BN_lshift(
this,
this, 8*(nSize-3));
304 BN_set_negative(
this, fNegative);
310 unsigned int nSize = BN_num_bytes(
this);
311 unsigned int nCompact = 0;
313 nCompact = BN_get_word(
this) << 8*(3-nSize);
317 BN_rshift(&bn,
this, 8*(nSize-3));
318 nCompact = BN_get_word(&bn);
322 if (nCompact & 0x00800000)
327 nCompact |= nSize << 24;
328 nCompact |= (BN_is_negative(
this) ? 0x00800000 : 0);
335 const char* psz = str.c_str();
336 while (isspace(*psz))
338 bool fNegative =
false;
344 if (psz[0] ==
'0' && tolower(psz[1]) ==
'x')
346 while (isspace(*psz))
350 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 };
352 while (isxdigit(*psz))
355 int n = phexdigit[(
unsigned char)*psz++];
369 BN_set_negative(&bn,
false);
372 if (BN_cmp(&bn, &bn0) == 0)
374 while (BN_cmp(&bn, &bn0) > 0)
376 if (!BN_div(&dv, &rem, &bn, &bnBase, pctx))
377 throw bignum_error(
"CBigNum::ToString() : BN_div failed");
380 str +=
"0123456789abcdef"[c];
382 if (BN_is_negative(
this))
384 reverse(str.begin(), str.end());
398 template<
typename Stream>
399 void Serialize(Stream& s,
int nType=0,
int nVersion=PROTOCOL_VERSION)
const
404 template<
typename Stream>
405 void Unserialize(Stream& s,
int nType=0,
int nVersion=PROTOCOL_VERSION)
407 std::vector<unsigned char> vch;
415 return BN_is_zero(
this);
420 if (!BN_add(
this,
this, &b))
421 throw bignum_error(
"CBigNum::operator+= : BN_add failed");
434 if (!BN_mul(
this,
this, &b, pctx))
435 throw bignum_error(
"CBigNum::operator*= : BN_mul failed");
453 if (!BN_lshift(
this,
this, shift))
454 throw bignum_error(
"CBigNum:operator<<= : BN_lshift failed");
464 if (BN_cmp(&a,
this) > 0)
470 if (!BN_rshift(
this,
this, shift))
471 throw bignum_error(
"CBigNum:operator>>= : BN_rshift failed");
479 if (!BN_add(
this,
this, BN_value_one()))
480 throw bignum_error(
"CBigNum::operator++ : BN_add failed");
496 if (!BN_sub(&r,
this, BN_value_one()))
497 throw bignum_error(
"CBigNum::operator-- : BN_sub failed");
521 if (!BN_add(&r, &a, &b))
522 throw bignum_error(
"CBigNum::operator+ : BN_add failed");
529 if (!BN_sub(&r, &a, &b))
530 throw bignum_error(
"CBigNum::operator- : BN_sub failed");
537 BN_set_negative(&r, !BN_is_negative(&r));
545 if (!BN_mul(&r, &a, &b, pctx))
546 throw bignum_error(
"CBigNum::operator* : BN_mul failed");
554 if (!BN_div(&r, NULL, &a, &b, pctx))
555 throw bignum_error(
"CBigNum::operator/ : BN_div failed");
563 if (!BN_mod(&r, &a, &b, pctx))
564 throw bignum_error(
"CBigNum::operator% : BN_div failed");
571 if (!BN_lshift(&r, &a, shift))
572 throw bignum_error(
"CBigNum:operator<< : BN_lshift failed");
const CBigNum operator-(const CBigNum &a, const CBigNum &b)
bool operator!=(const CBigNum &a, const CBigNum &b)
bool operator==(const CBigNum &a, const CBigNum &b)
uint256 getuint256() const
bool operator<(const CBigNum &a, const CBigNum &b)
bignum_error(const std::string &str)
CBigNum & operator>>=(unsigned int shift)
std::string GetHex() const
CBigNum & operator/=(const CBigNum &b)
const CBigNum operator%(const CBigNum &a, const CBigNum &b)
void setuint256(uint256 n)
CBigNum & operator<<=(unsigned int shift)
unsigned long getulong() const
RAII encapsulated BN_CTX (OpenSSL bignum context)
unsigned long long uint64
void setulong(unsigned long n)
CBigNum & operator%=(const CBigNum &b)
const CBigNum operator/(const CBigNum &a, const CBigNum &b)
const CBigNum operator<<(const CBigNum &a, unsigned int shift)
BN_CTX * operator=(BN_CTX *pnew)
const CBigNum operator*(const CBigNum &a, const CBigNum &b)
void Unserialize(Stream &s, int nType=0, int nVersion=PROTOCOL_VERSION)
CBigNum & SetCompact(unsigned int nCompact)
bool operator>(const CBigNum &a, const CBigNum &b)
CBigNum(const std::vector< unsigned char > &vch)
unsigned int GetSerializeSize(char a, int, int=0)
const CBigNum operator>>(const CBigNum &a, unsigned int shift)
const CBigNum operator--(int)
CBigNum & operator*=(const CBigNum &b)
bool operator<=(const CBigNum &a, const CBigNum &b)
const CBigNum operator+(const CBigNum &a, const CBigNum &b)
unsigned int getuint() const
C++ wrapper for BIGNUM (OpenSSL bignum)
std::vector< unsigned char > getvch() const
friend const CBigNum operator%(const CBigNum &a, const CBigNum &b)
Errors thrown by the bignum class.
unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const
bool operator>=(const CBigNum &a, const CBigNum &b)
CBigNum & operator-=(const CBigNum &b)
void SetHex(const std::string &str)
void setvch(const std::vector< unsigned char > &vch)
CBigNum(unsigned short n)
CBigNum & operator=(const CBigNum &b)
unsigned int GetCompact() const
CBigNum & operator+=(const CBigNum &b)
const CBigNum operator++(int)
friend const CBigNum operator-(const CBigNum &a, const CBigNum &b)
std::string ToString(int nBase=10) const
CBigNum(const CBigNum &b)
friend const CBigNum operator/(const CBigNum &a, const CBigNum &b)
void Serialize(Stream &s, int nType=0, int nVersion=PROTOCOL_VERSION) const