7 #ifndef BITCOIN_BIGNUM_H
8 #define BITCOIN_BIGNUM_H
12 #include <openssl/bn.h>
37 throw bignum_error(
"CAutoBN_CTX : BN_CTX_new() returned NULL");
46 operator BN_CTX*() {
return pctx; }
73 if (!BN_copy(
bn,
b.bn))
76 throw bignum_error(
"CBigNum::CBigNum(const CBigNum&) : BN_copy failed");
82 if (!BN_copy(
bn,
b.bn))
83 throw bignum_error(
"CBigNum::operator= : BN_copy failed");
107 explicit CBigNum(
const std::vector<unsigned char>& vch)
120 if(!BN_rand_range(ret.
bn, range.
bn)){
121 throw bignum_error(
"CBigNum:rand element : BN_rand_range failed");
132 if(!BN_rand(ret.
bn, k, -1, 0)){
133 throw bignum_error(
"CBigNum:rand element : BN_rand failed");
143 return BN_num_bits(
bn);
148 if (!BN_set_word(
bn, n))
149 throw bignum_error(
"CBigNum conversion from unsigned long : BN_set_word failed");
154 return BN_get_word(
bn);
159 return BN_get_word(
bn);
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);
168 return (n > (
unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::min() : -(
int)n);
173 unsigned char pch[
sizeof(sn) + 6];
174 unsigned char* p = pch + 4;
191 bool fLeadingZeroes =
true;
192 for (
int i = 0; i < 8; i++)
194 unsigned char c = (n >> 56) & 0xff;
201 *p++ = (fNegative ? 0x80 : 0);
204 fLeadingZeroes =
false;
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);
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++)
223 unsigned char c = (n >> 56) & 0xff;
231 fLeadingZeroes =
false;
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);
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)
252 unsigned char c = *(--psrc);
259 fLeadingZeroes =
false;
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);
273 unsigned int nSize = BN_bn2mpi(
bn, NULL);
276 std::vector<unsigned char> vch(nSize);
277 BN_bn2mpi(
bn, &vch[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];
286 void setvch(
const std::vector<unsigned char>& vch)
288 std::vector<unsigned char> vch2(vch.size() + 4);
289 unsigned int nSize = vch.size();
292 vch2[0] = (nSize >> 24) & 0xff;
293 vch2[1] = (nSize >> 16) & 0xff;
294 vch2[2] = (nSize >> 8) & 0xff;
295 vch2[3] = (nSize >> 0) & 0xff;
297 reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4);
298 BN_mpi2bn(&vch2[0], vch2.size(),
bn);
301 std::vector<unsigned char>
getvch()
const
303 unsigned int nSize = BN_bn2mpi(
bn, NULL);
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());
337 unsigned int nSize = nCompact >> 24;
338 bool fNegative =(nCompact & 0x00800000) != 0;
339 unsigned int nWord = nCompact & 0x007fffff;
342 nWord >>= 8*(3-nSize);
343 BN_set_word(
bn, nWord);
347 BN_set_word(
bn, nWord);
348 BN_lshift(
bn,
bn, 8*(nSize-3));
350 BN_set_negative(
bn, fNegative);
356 unsigned int nSize = BN_num_bytes(
bn);
357 unsigned int nCompact = 0;
359 nCompact = BN_get_word(
bn) << 8*(3-nSize);
363 BN_rshift(cbn.
bn,
bn, 8*(nSize-3));
364 nCompact = BN_get_word(
bn);
368 if (nCompact & 0x00800000)
373 nCompact |= nSize << 24;
374 nCompact |= (BN_is_negative(
bn) ? 0x00800000 : 0);
381 const char* psz = str.c_str();
382 while (isspace(*psz))
384 bool fNegative =
false;
390 if (psz[0] ==
'0' && tolower(psz[1]) ==
'x')
392 while (isspace(*psz))
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 };
398 while (isxdigit(*psz))
401 int n = phexdigit[(
unsigned char)*psz++];
411 const char* psz = str.c_str();
412 while (isspace(*psz))
414 bool fNegative =
false;
420 if (psz[0] ==
'0' && tolower(psz[1]) ==
'x')
422 while (isspace(*psz))
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 };
428 while (isxdigit(*psz))
431 int n = phexdigit[(
unsigned char)*psz++];
448 BN_set_negative(locBn.
bn,
false);
451 if (BN_cmp(locBn.
bn, bn0.
bn) == 0)
453 while (BN_cmp(locBn.
bn, bn0.
bn) > 0)
455 if (!BN_div(dv.
bn, rem.
bn, locBn.
bn, bnBase.
bn, pctx))
456 throw bignum_error(
"CBigNum::ToString() : BN_div failed");
459 str +=
"0123456789abcdef"[c];
461 if (BN_is_negative(
bn))
463 reverse(str.begin(), str.end());
477 template<
typename Stream>
478 void Serialize(Stream& s,
int nType=0,
int nVersion=PROTOCOL_VERSION)
const
483 template<
typename Stream>
484 void Unserialize(Stream& s,
int nType=0,
int nVersion=PROTOCOL_VERSION)
486 std::vector<unsigned char> vch;
508 if (!BN_exp(ret.
bn,
bn, e.
bn, pctx))
521 if (!BN_mod_mul(ret.
bn,
bn,
b.bn, m.
bn, pctx))
522 throw bignum_error(
"CBigNum::mul_mod : BN_mod_mul failed");
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");
542 if (!BN_mod_exp(ret.
bn,
bn, e.
bn, m.
bn, pctx))
543 throw bignum_error(
"CBigNum::pow_mod : BN_mod_exp failed");
557 if (!BN_mod_inverse(ret.
bn,
bn, m.
bn, pctx))
558 throw bignum_error(
"CBigNum::inverse*= :BN_mod_inverse");
570 if(!BN_generate_prime_ex(ret.
bn, numBits, (safe ==
true), NULL, NULL, NULL))
571 throw bignum_error(
"CBigNum::generatePrime*= :BN_generate_prime_ex");
583 if (!BN_gcd(ret.
bn,
bn,
b.bn, pctx))
594 bool isPrime(
const int checks=BN_prime_checks)
const {
596 int ret = BN_is_prime_ex(
bn, checks, pctx, NULL);
604 return BN_is_one(
bn);
611 return BN_is_zero(
bn);
616 if (!BN_add(
bn,
bn,
b.bn))
617 throw bignum_error(
"CBigNum::operator+= : BN_add failed");
623 if (!BN_sub(
bn,
bn,
b.bn))
624 throw bignum_error(
"CBigNum::operator-= : BN_sub failed");
631 if (!BN_mul(
bn,
bn,
b.bn, pctx))
632 throw bignum_error(
"CBigNum::operator*= : BN_mul failed");
639 if (!BN_div(
bn, NULL,
bn,
b.bn, pctx))
640 throw bignum_error(
"CBigNum::operator/= : BN_div failed");
647 if (!BN_mod(
bn,
b.bn,
bn, pctx))
648 throw bignum_error(
"CBigNum::operator%= : BN_mod failed");
654 if (!BN_lshift(
bn,
bn, shift))
655 throw bignum_error(
"CBigNum:operator<<= : BN_lshift failed");
665 if (BN_cmp(a.
bn,
bn) > 0)
671 if (!BN_rshift(
bn,
bn, shift))
672 throw bignum_error(
"CBigNum:operator>>= : BN_rshift failed");
680 if (!BN_add(
bn,
bn, BN_value_one()))
681 throw bignum_error(
"CBigNum::operator++ : BN_add failed");
697 if (!BN_sub(
r.bn,
bn, BN_value_one()))
698 throw bignum_error(
"CBigNum::operator-- : BN_sub failed");
731 if (!BN_add(
r.bn, a.
bn,
b.bn))
732 throw bignum_error(
"CBigNum::operator+ : BN_add failed");
739 if (!BN_sub(
r.bn, a.
bn,
b.bn))
740 throw bignum_error(
"CBigNum::operator- : BN_sub failed");
747 BN_set_negative(
r.bn, !BN_is_negative(
r.bn));
755 if (!BN_mul(
r.bn, a.
bn,
b.bn, pctx))
756 throw bignum_error(
"CBigNum::operator* : BN_mul failed");
764 if (!BN_div(
r.bn, NULL, a.
bn,
b.bn, pctx))
765 throw bignum_error(
"CBigNum::operator/ : BN_div failed");
773 if (!BN_nnmod(
r.bn, a.
bn,
b.bn, pctx))
774 throw bignum_error(
"CBigNum::operator% : BN_div failed");
781 if (!BN_lshift(
r.bn, a.
bn, shift))
782 throw bignum_error(
"CBigNum:operator<< : BN_lshift failed");