experimental-genesis    1 
experimental-genesis    2 
experimental-genesis    3 
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 
experimental-genesis   33 
experimental-genesis   34 
experimental-genesis   35 
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         
experimental-genesis  264         
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         
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         
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         
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         
experimental-genesis  440         
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         
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         
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         
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         
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