raw
experimental-genesis    1 //  /****************************\
experimental-genesis 2 // * EXPERIMENTAL BRANCH. *
experimental-genesis 3 // * FOR LABORATORY USE ONLY. *
experimental-genesis 4 // ********************************
experimental-genesis 5 // ************
experimental-genesis 6 // **************
experimental-genesis 7 // ****************
experimental-genesis 8 // **** **** ****
experimental-genesis 9 // *** *** ***
experimental-genesis 10 // *** *** ***
experimental-genesis 11 // *** * * **
experimental-genesis 12 // ******** ********
experimental-genesis 13 // ******* ******
experimental-genesis 14 // *** **
experimental-genesis 15 // * ******* **
experimental-genesis 16 // ** * * * * *
experimental-genesis 17 // ** * * ***
experimental-genesis 18 // **** * * * * ****
experimental-genesis 19 // **** *** * * ** ***
experimental-genesis 20 // **** ********* ******
experimental-genesis 21 // ******* ***** *******
experimental-genesis 22 // ********* ****** **
experimental-genesis 23 // ** ****** ******
experimental-genesis 24 // ** ******* **
experimental-genesis 25 // ** ******* ***
experimental-genesis 26 // **** ******** ************
experimental-genesis 27 // ************ ************
experimental-genesis 28 // ******** *******
experimental-genesis 29 // ****** ****
experimental-genesis 30 // *** ***
experimental-genesis 31 // ********************************
experimental-genesis 32 // Copyright (c) 2009-2010 Satoshi Nakamoto
experimental-genesis 33 // Copyright (c) 2011 The Bitcoin developers
experimental-genesis 34 // Distributed under the MIT/X11 software license, see the accompanying
experimental-genesis 35 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
experimental-genesis 36 #ifndef BITCOIN_BIGNUM_H
experimental-genesis 37 #define BITCOIN_BIGNUM_H
experimental-genesis 38
experimental-genesis 39 #include <stdexcept>
experimental-genesis 40 #include <vector>
experimental-genesis 41 #include <openssl/bn.h>
experimental-genesis 42
experimental-genesis 43 #include "util.h"
experimental-genesis 44
experimental-genesis 45 class bignum_error : public std::runtime_error
experimental-genesis 46 {
experimental-genesis 47 public:
experimental-genesis 48 explicit bignum_error(const std::string& str) : std::runtime_error(str) {}
experimental-genesis 49 };
experimental-genesis 50
experimental-genesis 51
experimental-genesis 52
experimental-genesis 53 class CAutoBN_CTX
experimental-genesis 54 {
experimental-genesis 55 protected:
experimental-genesis 56 BN_CTX* pctx;
experimental-genesis 57 BN_CTX* operator=(BN_CTX* pnew) { return pctx = pnew; }
experimental-genesis 58
experimental-genesis 59 public:
experimental-genesis 60 CAutoBN_CTX()
experimental-genesis 61 {
experimental-genesis 62 pctx = BN_CTX_new();
experimental-genesis 63 if (pctx == NULL)
experimental-genesis 64 throw bignum_error("CAutoBN_CTX : BN_CTX_new() returned NULL");
experimental-genesis 65 }
experimental-genesis 66
experimental-genesis 67 ~CAutoBN_CTX()
experimental-genesis 68 {
experimental-genesis 69 if (pctx != NULL)
experimental-genesis 70 BN_CTX_free(pctx);
experimental-genesis 71 }
experimental-genesis 72
experimental-genesis 73 operator BN_CTX*() { return pctx; }
experimental-genesis 74 BN_CTX& operator*() { return *pctx; }
experimental-genesis 75 BN_CTX** operator&() { return &pctx; }
experimental-genesis 76 bool operator!() { return (pctx == NULL); }
experimental-genesis 77 };
experimental-genesis 78
experimental-genesis 79
experimental-genesis 80
experimental-genesis 81 class CBigNum : public BIGNUM
experimental-genesis 82 {
experimental-genesis 83 public:
experimental-genesis 84 CBigNum()
experimental-genesis 85 {
experimental-genesis 86 BN_init(this);
experimental-genesis 87 }
experimental-genesis 88
experimental-genesis 89 CBigNum(const CBigNum& b)
experimental-genesis 90 {
experimental-genesis 91 BN_init(this);
experimental-genesis 92 if (!BN_copy(this, &b))
experimental-genesis 93 {
experimental-genesis 94 BN_clear_free(this);
experimental-genesis 95 throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed");
experimental-genesis 96 }
experimental-genesis 97 }
experimental-genesis 98
experimental-genesis 99 CBigNum& operator=(const CBigNum& b)
experimental-genesis 100 {
experimental-genesis 101 if (!BN_copy(this, &b))
experimental-genesis 102 throw bignum_error("CBigNum::operator= : BN_copy failed");
experimental-genesis 103 return (*this);
experimental-genesis 104 }
experimental-genesis 105
experimental-genesis 106 ~CBigNum()
experimental-genesis 107 {
experimental-genesis 108 BN_clear_free(this);
experimental-genesis 109 }
experimental-genesis 110
experimental-genesis 111 CBigNum(char n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
experimental-genesis 112 CBigNum(short n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
experimental-genesis 113 CBigNum(int n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
experimental-genesis 114 CBigNum(long n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
experimental-genesis 115 CBigNum(int64 n) { BN_init(this); setint64(n); }
experimental-genesis 116 CBigNum(unsigned char n) { BN_init(this); setulong(n); }
experimental-genesis 117 CBigNum(unsigned short n) { BN_init(this); setulong(n); }
experimental-genesis 118 CBigNum(unsigned int n) { BN_init(this); setulong(n); }
experimental-genesis 119 CBigNum(unsigned long n) { BN_init(this); setulong(n); }
experimental-genesis 120 CBigNum(uint64 n) { BN_init(this); setuint64(n); }
experimental-genesis 121 explicit CBigNum(uint256 n) { BN_init(this); setuint256(n); }
experimental-genesis 122
experimental-genesis 123 explicit CBigNum(const std::vector<unsigned char>& vch)
experimental-genesis 124 {
experimental-genesis 125 BN_init(this);
experimental-genesis 126 setvch(vch);
experimental-genesis 127 }
experimental-genesis 128
experimental-genesis 129 void setulong(unsigned long n)
experimental-genesis 130 {
experimental-genesis 131 if (!BN_set_word(this, n))
experimental-genesis 132 throw bignum_error("CBigNum conversion from unsigned long : BN_set_word failed");
experimental-genesis 133 }
experimental-genesis 134
experimental-genesis 135 unsigned long getulong() const
experimental-genesis 136 {
experimental-genesis 137 return BN_get_word(this);
experimental-genesis 138 }
experimental-genesis 139
experimental-genesis 140 unsigned int getuint() const
experimental-genesis 141 {
experimental-genesis 142 return BN_get_word(this);
experimental-genesis 143 }
experimental-genesis 144
experimental-genesis 145 int getint() const
experimental-genesis 146 {
experimental-genesis 147 unsigned long n = BN_get_word(this);
experimental-genesis 148 if (!BN_is_negative(this))
experimental-genesis 149 return (n > INT_MAX ? INT_MAX : n);
experimental-genesis 150 else
experimental-genesis 151 return (n > INT_MAX ? INT_MIN : -(int)n);
experimental-genesis 152 }
experimental-genesis 153
experimental-genesis 154 void setint64(int64 n)
experimental-genesis 155 {
experimental-genesis 156 unsigned char pch[sizeof(n) + 6];
experimental-genesis 157 unsigned char* p = pch + 4;
experimental-genesis 158 bool fNegative = false;
experimental-genesis 159 if (n < (int64)0)
experimental-genesis 160 {
experimental-genesis 161 n = -n;
experimental-genesis 162 fNegative = true;
experimental-genesis 163 }
experimental-genesis 164 bool fLeadingZeroes = true;
experimental-genesis 165 for (int i = 0; i < 8; i++)
experimental-genesis 166 {
experimental-genesis 167 unsigned char c = (n >> 56) & 0xff;
experimental-genesis 168 n <<= 8;
experimental-genesis 169 if (fLeadingZeroes)
experimental-genesis 170 {
experimental-genesis 171 if (c == 0)
experimental-genesis 172 continue;
experimental-genesis 173 if (c & 0x80)
experimental-genesis 174 *p++ = (fNegative ? 0x80 : 0);
experimental-genesis 175 else if (fNegative)
experimental-genesis 176 c |= 0x80;
experimental-genesis 177 fLeadingZeroes = false;
experimental-genesis 178 }
experimental-genesis 179 *p++ = c;
experimental-genesis 180 }
experimental-genesis 181 unsigned int nSize = p - (pch + 4);
experimental-genesis 182 pch[0] = (nSize >> 24) & 0xff;
experimental-genesis 183 pch[1] = (nSize >> 16) & 0xff;
experimental-genesis 184 pch[2] = (nSize >> 8) & 0xff;
experimental-genesis 185 pch[3] = (nSize) & 0xff;
experimental-genesis 186 BN_mpi2bn(pch, p - pch, this);
experimental-genesis 187 }
experimental-genesis 188
experimental-genesis 189 void setuint64(uint64 n)
experimental-genesis 190 {
experimental-genesis 191 unsigned char pch[sizeof(n) + 6];
experimental-genesis 192 unsigned char* p = pch + 4;
experimental-genesis 193 bool fLeadingZeroes = true;
experimental-genesis 194 for (int i = 0; i < 8; i++)
experimental-genesis 195 {
experimental-genesis 196 unsigned char c = (n >> 56) & 0xff;
experimental-genesis 197 n <<= 8;
experimental-genesis 198 if (fLeadingZeroes)
experimental-genesis 199 {
experimental-genesis 200 if (c == 0)
experimental-genesis 201 continue;
experimental-genesis 202 if (c & 0x80)
experimental-genesis 203 *p++ = 0;
experimental-genesis 204 fLeadingZeroes = false;
experimental-genesis 205 }
experimental-genesis 206 *p++ = c;
experimental-genesis 207 }
experimental-genesis 208 unsigned int nSize = p - (pch + 4);
experimental-genesis 209 pch[0] = (nSize >> 24) & 0xff;
experimental-genesis 210 pch[1] = (nSize >> 16) & 0xff;
experimental-genesis 211 pch[2] = (nSize >> 8) & 0xff;
experimental-genesis 212 pch[3] = (nSize) & 0xff;
experimental-genesis 213 BN_mpi2bn(pch, p - pch, this);
experimental-genesis 214 }
experimental-genesis 215
experimental-genesis 216 void setuint256(uint256 n)
experimental-genesis 217 {
experimental-genesis 218 unsigned char pch[sizeof(n) + 6];
experimental-genesis 219 unsigned char* p = pch + 4;
experimental-genesis 220 bool fLeadingZeroes = true;
experimental-genesis 221 unsigned char* pbegin = (unsigned char*)&n;
experimental-genesis 222 unsigned char* psrc = pbegin + sizeof(n);
experimental-genesis 223 while (psrc != pbegin)
experimental-genesis 224 {
experimental-genesis 225 unsigned char c = *(--psrc);
experimental-genesis 226 if (fLeadingZeroes)
experimental-genesis 227 {
experimental-genesis 228 if (c == 0)
experimental-genesis 229 continue;
experimental-genesis 230 if (c & 0x80)
experimental-genesis 231 *p++ = 0;
experimental-genesis 232 fLeadingZeroes = false;
experimental-genesis 233 }
experimental-genesis 234 *p++ = c;
experimental-genesis 235 }
experimental-genesis 236 unsigned int nSize = p - (pch + 4);
experimental-genesis 237 pch[0] = (nSize >> 24) & 0xff;
experimental-genesis 238 pch[1] = (nSize >> 16) & 0xff;
experimental-genesis 239 pch[2] = (nSize >> 8) & 0xff;
experimental-genesis 240 pch[3] = (nSize >> 0) & 0xff;
experimental-genesis 241 BN_mpi2bn(pch, p - pch, this);
experimental-genesis 242 }
experimental-genesis 243
experimental-genesis 244 uint256 getuint256()
experimental-genesis 245 {
experimental-genesis 246 unsigned int nSize = BN_bn2mpi(this, NULL);
experimental-genesis 247 if (nSize < 4)
experimental-genesis 248 return 0;
experimental-genesis 249 std::vector<unsigned char> vch(nSize);
experimental-genesis 250 BN_bn2mpi(this, &vch[0]);
experimental-genesis 251 if (vch.size() > 4)
experimental-genesis 252 vch[4] &= 0x7f;
experimental-genesis 253 uint256 n = 0;
experimental-genesis 254 for (int i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--)
experimental-genesis 255 ((unsigned char*)&n)[i] = vch[j];
experimental-genesis 256 return n;
experimental-genesis 257 }
experimental-genesis 258
experimental-genesis 259 void setvch(const std::vector<unsigned char>& vch)
experimental-genesis 260 {
experimental-genesis 261 std::vector<unsigned char> vch2(vch.size() + 4);
experimental-genesis 262 unsigned int nSize = vch.size();
experimental-genesis 263 // BIGNUM's byte stream format expects 4 bytes of
experimental-genesis 264 // big endian size data info at the front
experimental-genesis 265 vch2[0] = (nSize >> 24) & 0xff;
experimental-genesis 266 vch2[1] = (nSize >> 16) & 0xff;
experimental-genesis 267 vch2[2] = (nSize >> 8) & 0xff;
experimental-genesis 268 vch2[3] = (nSize >> 0) & 0xff;
experimental-genesis 269 // swap data to big endian
experimental-genesis 270 reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4);
experimental-genesis 271 BN_mpi2bn(&vch2[0], vch2.size(), this);
experimental-genesis 272 }
experimental-genesis 273
experimental-genesis 274 std::vector<unsigned char> getvch() const
experimental-genesis 275 {
experimental-genesis 276 unsigned int nSize = BN_bn2mpi(this, NULL);
experimental-genesis 277 if (nSize < 4)
experimental-genesis 278 return std::vector<unsigned char>();
experimental-genesis 279 std::vector<unsigned char> vch(nSize);
experimental-genesis 280 BN_bn2mpi(this, &vch[0]);
experimental-genesis 281 vch.erase(vch.begin(), vch.begin() + 4);
experimental-genesis 282 reverse(vch.begin(), vch.end());
experimental-genesis 283 return vch;
experimental-genesis 284 }
experimental-genesis 285
experimental-genesis 286 CBigNum& SetCompact(unsigned int nCompact)
experimental-genesis 287 {
experimental-genesis 288 unsigned int nSize = nCompact >> 24;
experimental-genesis 289 std::vector<unsigned char> vch(4 + nSize);
experimental-genesis 290 vch[3] = nSize;
experimental-genesis 291 if (nSize >= 1) vch[4] = (nCompact >> 16) & 0xff;
experimental-genesis 292 if (nSize >= 2) vch[5] = (nCompact >> 8) & 0xff;
experimental-genesis 293 if (nSize >= 3) vch[6] = (nCompact >> 0) & 0xff;
experimental-genesis 294 BN_mpi2bn(&vch[0], vch.size(), this);
experimental-genesis 295 return *this;
experimental-genesis 296 }
experimental-genesis 297
experimental-genesis 298 unsigned int GetCompact() const
experimental-genesis 299 {
experimental-genesis 300 unsigned int nSize = BN_bn2mpi(this, NULL);
experimental-genesis 301 std::vector<unsigned char> vch(nSize);
experimental-genesis 302 nSize -= 4;
experimental-genesis 303 BN_bn2mpi(this, &vch[0]);
experimental-genesis 304 unsigned int nCompact = nSize << 24;
experimental-genesis 305 if (nSize >= 1) nCompact |= (vch[4] << 16);
experimental-genesis 306 if (nSize >= 2) nCompact |= (vch[5] << 8);
experimental-genesis 307 if (nSize >= 3) nCompact |= (vch[6] << 0);
experimental-genesis 308 return nCompact;
experimental-genesis 309 }
experimental-genesis 310
experimental-genesis 311 void SetHex(const std::string& str)
experimental-genesis 312 {
experimental-genesis 313 // skip 0x
experimental-genesis 314 const char* psz = str.c_str();
experimental-genesis 315 while (isspace(*psz))
experimental-genesis 316 psz++;
experimental-genesis 317 bool fNegative = false;
experimental-genesis 318 if (*psz == '-')
experimental-genesis 319 {
experimental-genesis 320 fNegative = true;
experimental-genesis 321 psz++;
experimental-genesis 322 }
experimental-genesis 323 if (psz[0] == '0' && tolower(psz[1]) == 'x')
experimental-genesis 324 psz += 2;
experimental-genesis 325 while (isspace(*psz))
experimental-genesis 326 psz++;
experimental-genesis 327
experimental-genesis 328 // hex string to bignum
experimental-genesis 329 static 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 };
experimental-genesis 330 *this = 0;
experimental-genesis 331 while (isxdigit(*psz))
experimental-genesis 332 {
experimental-genesis 333 *this <<= 4;
experimental-genesis 334 int n = phexdigit[*psz++];
experimental-genesis 335 *this += n;
experimental-genesis 336 }
experimental-genesis 337 if (fNegative)
experimental-genesis 338 *this = 0 - *this;
experimental-genesis 339 }
experimental-genesis 340
experimental-genesis 341 std::string ToString(int nBase=10) const
experimental-genesis 342 {
experimental-genesis 343 CAutoBN_CTX pctx;
experimental-genesis 344 CBigNum bnBase = nBase;
experimental-genesis 345 CBigNum bn0 = 0;
experimental-genesis 346 std::string str;
experimental-genesis 347 CBigNum bn = *this;
experimental-genesis 348 BN_set_negative(&bn, false);
experimental-genesis 349 CBigNum dv;
experimental-genesis 350 CBigNum rem;
experimental-genesis 351 if (BN_cmp(&bn, &bn0) == 0)
experimental-genesis 352 return "0";
experimental-genesis 353 while (BN_cmp(&bn, &bn0) > 0)
experimental-genesis 354 {
experimental-genesis 355 if (!BN_div(&dv, &rem, &bn, &bnBase, pctx))
experimental-genesis 356 throw bignum_error("CBigNum::ToString() : BN_div failed");
experimental-genesis 357 bn = dv;
experimental-genesis 358 unsigned int c = rem.getulong();
experimental-genesis 359 str += "0123456789abcdef"[c];
experimental-genesis 360 }
experimental-genesis 361 if (BN_is_negative(this))
experimental-genesis 362 str += "-";
experimental-genesis 363 reverse(str.begin(), str.end());
experimental-genesis 364 return str;
experimental-genesis 365 }
experimental-genesis 366
experimental-genesis 367 std::string GetHex() const
experimental-genesis 368 {
experimental-genesis 369 return ToString(16);
experimental-genesis 370 }
experimental-genesis 371
experimental-genesis 372 unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const
experimental-genesis 373 {
experimental-genesis 374 return ::GetSerializeSize(getvch(), nType, nVersion);
experimental-genesis 375 }
experimental-genesis 376
experimental-genesis 377 template<typename Stream>
experimental-genesis 378 void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
experimental-genesis 379 {
experimental-genesis 380 ::Serialize(s, getvch(), nType, nVersion);
experimental-genesis 381 }
experimental-genesis 382
experimental-genesis 383 template<typename Stream>
experimental-genesis 384 void Unserialize(Stream& s, int nType=0, int nVersion=VERSION)
experimental-genesis 385 {
experimental-genesis 386 std::vector<unsigned char> vch;
experimental-genesis 387 ::Unserialize(s, vch, nType, nVersion);
experimental-genesis 388 setvch(vch);
experimental-genesis 389 }
experimental-genesis 390
experimental-genesis 391
experimental-genesis 392 bool operator!() const
experimental-genesis 393 {
experimental-genesis 394 return BN_is_zero(this);
experimental-genesis 395 }
experimental-genesis 396
experimental-genesis 397 CBigNum& operator+=(const CBigNum& b)
experimental-genesis 398 {
experimental-genesis 399 if (!BN_add(this, this, &b))
experimental-genesis 400 throw bignum_error("CBigNum::operator+= : BN_add failed");
experimental-genesis 401 return *this;
experimental-genesis 402 }
experimental-genesis 403
experimental-genesis 404 CBigNum& operator-=(const CBigNum& b)
experimental-genesis 405 {
experimental-genesis 406 *this = *this - b;
experimental-genesis 407 return *this;
experimental-genesis 408 }
experimental-genesis 409
experimental-genesis 410 CBigNum& operator*=(const CBigNum& b)
experimental-genesis 411 {
experimental-genesis 412 CAutoBN_CTX pctx;
experimental-genesis 413 if (!BN_mul(this, this, &b, pctx))
experimental-genesis 414 throw bignum_error("CBigNum::operator*= : BN_mul failed");
experimental-genesis 415 return *this;
experimental-genesis 416 }
experimental-genesis 417
experimental-genesis 418 CBigNum& operator/=(const CBigNum& b)
experimental-genesis 419 {
experimental-genesis 420 *this = *this / b;
experimental-genesis 421 return *this;
experimental-genesis 422 }
experimental-genesis 423
experimental-genesis 424 CBigNum& operator%=(const CBigNum& b)
experimental-genesis 425 {
experimental-genesis 426 *this = *this % b;
experimental-genesis 427 return *this;
experimental-genesis 428 }
experimental-genesis 429
experimental-genesis 430 CBigNum& operator<<=(unsigned int shift)
experimental-genesis 431 {
experimental-genesis 432 if (!BN_lshift(this, this, shift))
experimental-genesis 433 throw bignum_error("CBigNum:operator<<= : BN_lshift failed");
experimental-genesis 434 return *this;
experimental-genesis 435 }
experimental-genesis 436
experimental-genesis 437 CBigNum& operator>>=(unsigned int shift)
experimental-genesis 438 {
experimental-genesis 439 // Note: BN_rshift segfaults on 64-bit if 2^shift is greater than the number
experimental-genesis 440 // if built on ubuntu 9.04 or 9.10, probably depends on version of openssl
experimental-genesis 441 CBigNum a = 1;
experimental-genesis 442 a <<= shift;
experimental-genesis 443 if (BN_cmp(&a, this) > 0)
experimental-genesis 444 {
experimental-genesis 445 *this = 0;
experimental-genesis 446 return *this;
experimental-genesis 447 }
experimental-genesis 448
experimental-genesis 449 if (!BN_rshift(this, this, shift))
experimental-genesis 450 throw bignum_error("CBigNum:operator>>= : BN_rshift failed");
experimental-genesis 451 return *this;
experimental-genesis 452 }
experimental-genesis 453
experimental-genesis 454
experimental-genesis 455 CBigNum& operator++()
experimental-genesis 456 {
experimental-genesis 457 // prefix operator
experimental-genesis 458 if (!BN_add(this, this, BN_value_one()))
experimental-genesis 459 throw bignum_error("CBigNum::operator++ : BN_add failed");
experimental-genesis 460 return *this;
experimental-genesis 461 }
experimental-genesis 462
experimental-genesis 463 const CBigNum operator++(int)
experimental-genesis 464 {
experimental-genesis 465 // postfix operator
experimental-genesis 466 const CBigNum ret = *this;
experimental-genesis 467 ++(*this);
experimental-genesis 468 return ret;
experimental-genesis 469 }
experimental-genesis 470
experimental-genesis 471 CBigNum& operator--()
experimental-genesis 472 {
experimental-genesis 473 // prefix operator
experimental-genesis 474 CBigNum r;
experimental-genesis 475 if (!BN_sub(&r, this, BN_value_one()))
experimental-genesis 476 throw bignum_error("CBigNum::operator-- : BN_sub failed");
experimental-genesis 477 *this = r;
experimental-genesis 478 return *this;
experimental-genesis 479 }
experimental-genesis 480
experimental-genesis 481 const CBigNum operator--(int)
experimental-genesis 482 {
experimental-genesis 483 // postfix operator
experimental-genesis 484 const CBigNum ret = *this;
experimental-genesis 485 --(*this);
experimental-genesis 486 return ret;
experimental-genesis 487 }
experimental-genesis 488
experimental-genesis 489
experimental-genesis 490 friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b);
experimental-genesis 491 friend inline const CBigNum operator/(const CBigNum& a, const CBigNum& b);
experimental-genesis 492 friend inline const CBigNum operator%(const CBigNum& a, const CBigNum& b);
experimental-genesis 493 };
experimental-genesis 494
experimental-genesis 495
experimental-genesis 496
experimental-genesis 497 inline const CBigNum operator+(const CBigNum& a, const CBigNum& b)
experimental-genesis 498 {
experimental-genesis 499 CBigNum r;
experimental-genesis 500 if (!BN_add(&r, &a, &b))
experimental-genesis 501 throw bignum_error("CBigNum::operator+ : BN_add failed");
experimental-genesis 502 return r;
experimental-genesis 503 }
experimental-genesis 504
experimental-genesis 505 inline const CBigNum operator-(const CBigNum& a, const CBigNum& b)
experimental-genesis 506 {
experimental-genesis 507 CBigNum r;
experimental-genesis 508 if (!BN_sub(&r, &a, &b))
experimental-genesis 509 throw bignum_error("CBigNum::operator- : BN_sub failed");
experimental-genesis 510 return r;
experimental-genesis 511 }
experimental-genesis 512
experimental-genesis 513 inline const CBigNum operator-(const CBigNum& a)
experimental-genesis 514 {
experimental-genesis 515 CBigNum r(a);
experimental-genesis 516 BN_set_negative(&r, !BN_is_negative(&r));
experimental-genesis 517 return r;
experimental-genesis 518 }
experimental-genesis 519
experimental-genesis 520 inline const CBigNum operator*(const CBigNum& a, const CBigNum& b)
experimental-genesis 521 {
experimental-genesis 522 CAutoBN_CTX pctx;
experimental-genesis 523 CBigNum r;
experimental-genesis 524 if (!BN_mul(&r, &a, &b, pctx))
experimental-genesis 525 throw bignum_error("CBigNum::operator* : BN_mul failed");
experimental-genesis 526 return r;
experimental-genesis 527 }
experimental-genesis 528
experimental-genesis 529 inline const CBigNum operator/(const CBigNum& a, const CBigNum& b)
experimental-genesis 530 {
experimental-genesis 531 CAutoBN_CTX pctx;
experimental-genesis 532 CBigNum r;
experimental-genesis 533 if (!BN_div(&r, NULL, &a, &b, pctx))
experimental-genesis 534 throw bignum_error("CBigNum::operator/ : BN_div failed");
experimental-genesis 535 return r;
experimental-genesis 536 }
experimental-genesis 537
experimental-genesis 538 inline const CBigNum operator%(const CBigNum& a, const CBigNum& b)
experimental-genesis 539 {
experimental-genesis 540 CAutoBN_CTX pctx;
experimental-genesis 541 CBigNum r;
experimental-genesis 542 if (!BN_mod(&r, &a, &b, pctx))
experimental-genesis 543 throw bignum_error("CBigNum::operator% : BN_div failed");
experimental-genesis 544 return r;
experimental-genesis 545 }
experimental-genesis 546
experimental-genesis 547 inline const CBigNum operator<<(const CBigNum& a, unsigned int shift)
experimental-genesis 548 {
experimental-genesis 549 CBigNum r;
experimental-genesis 550 if (!BN_lshift(&r, &a, shift))
experimental-genesis 551 throw bignum_error("CBigNum:operator<< : BN_lshift failed");
experimental-genesis 552 return r;
experimental-genesis 553 }
experimental-genesis 554
experimental-genesis 555 inline const CBigNum operator>>(const CBigNum& a, unsigned int shift)
experimental-genesis 556 {
experimental-genesis 557 CBigNum r = a;
experimental-genesis 558 r >>= shift;
experimental-genesis 559 return r;
experimental-genesis 560 }
experimental-genesis 561
experimental-genesis 562 inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) == 0); }
experimental-genesis 563 inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) != 0); }
experimental-genesis 564 inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) <= 0); }
experimental-genesis 565 inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) >= 0); }
experimental-genesis 566 inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) < 0); }
experimental-genesis 567 inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) > 0); }
experimental-genesis 568
experimental-genesis 569 #endif