Use CBigNum for temporary variables to prevent overflow. Which is unlikely to happen...
[novacoin.git] / src / bignum.h
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 #ifndef BITCOIN_BIGNUM_H
6 #define BITCOIN_BIGNUM_H
7
8 #include <stdexcept>
9 #include <vector>
10 #include <openssl/bn.h>
11 #include "util.h"
12
13 /** Errors thrown by the bignum class */
14 class bignum_error : public std::runtime_error
15 {
16 public:
17     explicit bignum_error(const std::string& str) : std::runtime_error(str) {}
18 };
19
20
21 /** RAII encapsulated BN_CTX (OpenSSL bignum context) */
22 class CAutoBN_CTX
23 {
24 protected:
25     BN_CTX* pctx;
26     BN_CTX* operator=(BN_CTX* pnew) { return pctx = pnew; }
27
28 public:
29     CAutoBN_CTX()
30     {
31         pctx = BN_CTX_new();
32         if (pctx == NULL)
33             throw bignum_error("CAutoBN_CTX : BN_CTX_new() returned NULL");
34     }
35
36     ~CAutoBN_CTX()
37     {
38         if (pctx != NULL)
39             BN_CTX_free(pctx);
40     }
41
42     operator BN_CTX*() { return pctx; }
43     BN_CTX& operator*() { return *pctx; }
44     BN_CTX** operator&() { return &pctx; }
45     bool operator!() { return (pctx == NULL); }
46 };
47
48
49 /** C++ wrapper for BIGNUM (OpenSSL bignum) */
50 class CBigNum : public BIGNUM
51 {
52 public:
53     CBigNum()
54     {
55         BN_init(this);
56     }
57
58     CBigNum(const CBigNum& b)
59     {
60         BN_init(this);
61         if (!BN_copy(this, &b))
62         {
63             BN_clear_free(this);
64             throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed");
65         }
66     }
67
68     CBigNum& operator=(const CBigNum& b)
69     {
70         if (!BN_copy(this, &b))
71             throw bignum_error("CBigNum::operator= : BN_copy failed");
72         return (*this);
73     }
74
75     ~CBigNum()
76     {
77         BN_clear_free(this);
78     }
79
80     CBigNum(int8_t  n)  { BN_init(this); if (n >= 0) setuint32(n); else setint64(n); }
81     CBigNum(int16_t n)  { BN_init(this); if (n >= 0) setuint32(n); else setint64(n); }
82     CBigNum(int32_t n)  { BN_init(this); if (n >= 0) setuint32(n); else setint64(n); }
83     CBigNum(int64_t n)  { BN_init(this); if (n >= 0) setuint64(n); else setint64(n); }
84
85     CBigNum(uint8_t  n) { BN_init(this); setuint32(n); }
86     CBigNum(uint16_t n) { BN_init(this); setuint32(n); }
87     CBigNum(uint32_t n) { BN_init(this); setuint32(n); }
88     CBigNum(uint64_t n) { BN_init(this); setuint64(n); }
89
90     explicit CBigNum(uint256 n) { BN_init(this); setuint256(n); }
91     explicit CBigNum(const std::vector<uint8_t>& vch)
92     {
93         BN_init(this);
94         setvch(vch);
95     }
96
97     /** Generates a cryptographically secure random number between zero and range exclusive
98     * i.e. 0 < returned number < range
99     * @param range The upper bound on the number.
100     * @return
101     */
102     static CBigNum  randBignum(const CBigNum& range) {
103         CBigNum ret;
104         if(!BN_rand_range(&ret, &range)){
105             throw bignum_error("CBigNum:rand element : BN_rand_range failed");
106         }
107         return ret;
108     }
109
110     /** Generates a cryptographically secure random k-bit number
111     * @param k The bit length of the number.
112     * @return
113     */
114     static CBigNum RandKBitBigum(const uint32_t k){
115         CBigNum ret;
116         if(!BN_rand(&ret, k, -1, 0)){
117             throw bignum_error("CBigNum:rand element : BN_rand failed");
118         }
119         return ret;
120     }
121
122     /**Returns the size in bits of the underlying bignum.
123      *
124      * @return the size
125      */
126     int bitSize() const{
127         return  BN_num_bits(this);
128     }
129
130
131     void setuint32(uint32_t n)
132     {
133         if (!BN_set_word(this, n))
134             throw bignum_error("CBigNum conversion from uint32_t : BN_set_word failed");
135     }
136
137     uint32_t getuint32() const
138     {
139         return BN_get_word(this);
140     }
141
142     int32_t getint32() const
143     {
144         uint64_t n = BN_get_word(this);
145         if (!BN_is_negative(this))
146             return (n > (uint64_t)std::numeric_limits<int32_t>::max() ? std::numeric_limits<int32_t>::max() : (int32_t)n);
147         else
148             return (n > (uint64_t)std::numeric_limits<int32_t>::max() ? std::numeric_limits<int32_t>::min() : -(int32_t)n);
149     }
150
151     void setint64(int64_t sn)
152     {
153         uint8_t pch[sizeof(sn) + 6];
154         uint8_t* p = pch + 4;
155         bool fNegative;
156         uint64_t n;
157
158         if (sn < (int64_t)0)
159         {
160             // Since the minimum signed integer cannot be represented as positive so long as its type is signed, and it's not well-defined what happens if you make it unsigned before negating it, we instead increment the negative integer by 1, convert it, then increment the (now positive) unsigned integer by 1 to compensate
161             n = -(sn + 1);
162             ++n;
163             fNegative = true;
164         } else {
165             n = sn;
166             fNegative = false;
167         }
168
169         bool fLeadingZeroes = true;
170         for (int i = 0; i < 8; i++)
171         {
172             uint8_t c = (n >> 56) & 0xff;
173             n <<= 8;
174             if (fLeadingZeroes)
175             {
176                 if (c == 0)
177                     continue;
178                 if (c & 0x80)
179                     *p++ = (fNegative ? 0x80 : 0);
180                 else if (fNegative)
181                     c |= 0x80;
182                 fLeadingZeroes = false;
183             }
184             *p++ = c;
185         }
186         uint32_t nSize = (uint32_t) (p - (pch + 4));
187         pch[0] = (nSize >> 24) & 0xff;
188         pch[1] = (nSize >> 16) & 0xff;
189         pch[2] = (nSize >> 8) & 0xff;
190         pch[3] = (nSize) & 0xff;
191         BN_mpi2bn(pch, (int)(p - pch), this);
192     }
193
194     int64_t getint64()
195     {
196         return (int64_t) getuint64();
197     }
198
199     uint64_t getuint64()
200     {
201         size_t nSize = BN_bn2mpi(this, NULL);
202         if (nSize < 4)
203             return 0;
204         std::vector<uint8_t> vch(nSize);
205         BN_bn2mpi(this, &vch[0]);
206         if (vch.size() > 4)
207             vch[4] &= 0x7f;
208         uint64_t n = 0;
209         for (size_t i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--)
210             ((uint8_t*)&n)[i] = vch[j];
211         return n;
212     }
213
214     //supress msvc C4127: conditional expression is constant
215     inline bool check(bool value) {return value;}
216
217     void setuint64(uint64_t n)
218     {
219         // Use BN_set_word if word size is sufficient for uint64_t
220         if (check(sizeof(n) <= sizeof(BN_ULONG)))
221         {
222             if (!BN_set_word(this, (BN_ULONG)n))
223                 throw bignum_error("CBigNum conversion from uint64_t : BN_set_word failed");
224             return;
225         }
226
227         uint8_t pch[sizeof(n) + 6];
228         uint8_t* p = pch + 4;
229         bool fLeadingZeroes = true;
230         for (int i = 0; i < 8; i++)
231         {
232             uint8_t c = (n >> 56) & 0xff;
233             n <<= 8;
234             if (fLeadingZeroes)
235             {
236                 if (c == 0)
237                     continue;
238                 if (c & 0x80)
239                     *p++ = 0;
240                 fLeadingZeroes = false;
241             }
242             *p++ = c;
243         }
244         uint32_t nSize = (uint32_t) (p - (pch + 4));
245         pch[0] = (nSize >> 24) & 0xff;
246         pch[1] = (nSize >> 16) & 0xff;
247         pch[2] = (nSize >> 8) & 0xff;
248         pch[3] = (nSize) & 0xff;
249         BN_mpi2bn(pch, (int)(p - pch), this);
250     }
251
252     void setuint160(uint160 n)
253     {
254         uint8_t pch[sizeof(n) + 6];
255         uint8_t* p = pch + 4;
256         bool fLeadingZeroes = true;
257         uint8_t* pbegin = (uint8_t*)&n;
258         uint8_t* psrc = pbegin + sizeof(n);
259         while (psrc != pbegin)
260         {
261             uint8_t c = *(--psrc);
262             if (fLeadingZeroes)
263             {
264                 if (c == 0)
265                     continue;
266                 if (c & 0x80)
267                     *p++ = 0;
268                 fLeadingZeroes = false;
269             }
270             *p++ = c;
271         }
272         uint32_t nSize = (uint32_t) (p - (pch + 4));
273         pch[0] = (nSize >> 24) & 0xff;
274         pch[1] = (nSize >> 16) & 0xff;
275         pch[2] = (nSize >> 8) & 0xff;
276         pch[3] = (nSize >> 0) & 0xff;
277         BN_mpi2bn(pch, (int) (p - pch), this);
278     }
279
280     uint160 getuint160() const
281     {
282         unsigned int nSize = BN_bn2mpi(this, NULL);
283         if (nSize < 4)
284             return 0;
285         std::vector<uint8_t> vch(nSize);
286         BN_bn2mpi(this, &vch[0]);
287         if (vch.size() > 4)
288             vch[4] &= 0x7f;
289         uint160 n = 0;
290         for (size_t i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--)
291             ((uint8_t*)&n)[i] = vch[j];
292         return n;
293     }
294
295     void setuint256(uint256 n)
296     {
297         uint8_t pch[sizeof(n) + 6];
298         uint8_t* p = pch + 4;
299         bool fLeadingZeroes = true;
300         uint8_t* pbegin = (uint8_t*)&n;
301         uint8_t* psrc = pbegin + sizeof(n);
302         while (psrc != pbegin)
303         {
304             uint8_t c = *(--psrc);
305             if (fLeadingZeroes)
306             {
307                 if (c == 0)
308                     continue;
309                 if (c & 0x80)
310                     *p++ = 0;
311                 fLeadingZeroes = false;
312             }
313             *p++ = c;
314         }
315         uint32_t nSize = (uint32_t) (p - (pch + 4));
316         pch[0] = (nSize >> 24) & 0xff;
317         pch[1] = (nSize >> 16) & 0xff;
318         pch[2] = (nSize >> 8) & 0xff;
319         pch[3] = (nSize >> 0) & 0xff;
320         BN_mpi2bn(pch, (int) (p - pch), this);
321     }
322
323     uint256 getuint256() const
324     {
325         unsigned int nSize = BN_bn2mpi(this, NULL);
326         if (nSize < 4)
327             return 0;
328         std::vector<uint8_t> vch(nSize);
329         BN_bn2mpi(this, &vch[0]);
330         if (vch.size() > 4)
331             vch[4] &= 0x7f;
332         uint256 n = 0;
333         for (size_t i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--)
334             ((uint8_t*)&n)[i] = vch[j];
335         return n;
336     }
337
338     void setBytes(const std::vector<uint8_t>& vchBytes)
339     {
340         BN_bin2bn(&vchBytes[0], (int) vchBytes.size(), this);
341     }
342
343     std::vector<uint8_t> getBytes() const
344     {
345         int nBytes = BN_num_bytes(this);
346
347         std::vector<uint8_t> vchBytes(nBytes);
348
349         int n = BN_bn2bin(this, &vchBytes[0]);
350         if (n != nBytes) {
351             throw bignum_error("CBigNum::getBytes : BN_bn2bin failed");
352         }
353
354         return vchBytes;
355     }
356
357     void setvch(const std::vector<uint8_t>& vch)
358     {
359         std::vector<uint8_t> vch2(vch.size() + 4);
360         uint32_t nSize = (uint32_t) vch.size();
361         // BIGNUM's byte stream format expects 4 bytes of
362         // big endian size data info at the front
363         vch2[0] = (nSize >> 24) & 0xff;
364         vch2[1] = (nSize >> 16) & 0xff;
365         vch2[2] = (nSize >> 8) & 0xff;
366         vch2[3] = (nSize >> 0) & 0xff;
367         // swap data to big endian
368         reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4);
369         BN_mpi2bn(&vch2[0], (int) vch2.size(), this);
370     }
371
372     std::vector<uint8_t> getvch() const
373     {
374         unsigned int nSize = BN_bn2mpi(this, NULL);
375         if (nSize <= 4)
376             return std::vector<uint8_t>();
377         std::vector<uint8_t> vch(nSize);
378         BN_bn2mpi(this, &vch[0]);
379         vch.erase(vch.begin(), vch.begin() + 4);
380         reverse(vch.begin(), vch.end());
381         return vch;
382     }
383
384     CBigNum& SetCompact(uint32_t nCompact)
385     {
386         uint32_t nSize = nCompact >> 24;
387         std::vector<uint8_t> vch(4 + nSize);
388         vch[3] = nSize;
389         if (nSize >= 1) vch[4] = (nCompact >> 16) & 0xff;
390         if (nSize >= 2) vch[5] = (nCompact >> 8) & 0xff;
391         if (nSize >= 3) vch[6] = (nCompact >> 0) & 0xff;
392         BN_mpi2bn(&vch[0], (int) vch.size(), this);
393         return *this;
394     }
395
396     uint32_t GetCompact() const
397     {
398         uint32_t nSize = BN_bn2mpi(this, NULL);
399         std::vector<uint8_t> vch(nSize);
400         nSize -= 4;
401         BN_bn2mpi(this, &vch[0]);
402         uint32_t nCompact = nSize << 24;
403         if (nSize >= 1) nCompact |= (vch[4] << 16);
404         if (nSize >= 2) nCompact |= (vch[5] << 8);
405         if (nSize >= 3) nCompact |= (vch[6] << 0);
406         return nCompact;
407     }
408
409     void SetHex(const std::string& str)
410     {
411         // skip 0x
412         const char* psz = str.c_str();
413         while (isspace(*psz))
414             psz++;
415         bool fNegative = false;
416         if (*psz == '-')
417         {
418             fNegative = true;
419             psz++;
420         }
421         if (psz[0] == '0' && tolower(psz[1]) == 'x')
422             psz += 2;
423         while (isspace(*psz))
424             psz++;
425
426         // hex string to bignum
427         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         *this = 0;
429         while (isxdigit(*psz))
430         {
431             *this <<= 4;
432             int n = phexdigit[(uint8_t)*psz++];
433             *this += n;
434         }
435         if (fNegative)
436             *this = 0 - *this;
437     }
438
439     std::string ToString(int nBase=10) const
440     {
441         CAutoBN_CTX pctx;
442         CBigNum bnBase = nBase;
443         CBigNum bn0 = 0;
444         std::string str;
445         CBigNum bn = *this;
446         BN_set_negative(&bn, false);
447         CBigNum dv;
448         CBigNum rem;
449         if (BN_cmp(&bn, &bn0) == 0)
450             return "0";
451         while (BN_cmp(&bn, &bn0) > 0)
452         {
453             if (!BN_div(&dv, &rem, &bn, &bnBase, pctx))
454                 throw bignum_error("CBigNum::ToString() : BN_div failed");
455             bn = dv;
456             uint32_t c = rem.getuint32();
457             str += "0123456789abcdef"[c];
458         }
459         if (BN_is_negative(this))
460             str += "-";
461         reverse(str.begin(), str.end());
462         return str;
463     }
464
465     std::string GetHex() const
466     {
467         return ToString(16);
468     }
469
470     unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const
471     {
472         return ::GetSerializeSize(getvch(), nType, nVersion);
473     }
474
475     template<typename Stream>
476     void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const
477     {
478         ::Serialize(s, getvch(), nType, nVersion);
479     }
480
481     template<typename Stream>
482     void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION)
483     {
484         std::vector<uint8_t> vch;
485         ::Unserialize(s, vch, nType, nVersion);
486         setvch(vch);
487     }
488
489     /**
490     * exponentiation with an int. this^e
491     * @param e the exponent as an int
492     * @return
493     */
494     CBigNum pow(const int e) const {
495         return this->pow(CBigNum(e));
496     }
497
498     /**
499      * exponentiation this^e
500      * @param e the exponent
501      * @return
502      */
503     CBigNum pow(const CBigNum& e) const {
504         CAutoBN_CTX pctx;
505         CBigNum ret;
506         if (!BN_exp(&ret, this, &e, pctx))
507             throw bignum_error("CBigNum::pow : BN_exp failed");
508         return ret;
509     }
510
511     /**
512      * modular multiplication: (this * b) mod m
513      * @param b operand
514      * @param m modulus
515      */
516     CBigNum mul_mod(const CBigNum& b, const CBigNum& m) const {
517         CAutoBN_CTX pctx;
518         CBigNum ret;
519         if (!BN_mod_mul(&ret, this, &b, &m, pctx))
520             throw bignum_error("CBigNum::mul_mod : BN_mod_mul failed");
521
522         return ret;
523     }
524
525     /**
526      * modular exponentiation: this^e mod n
527      * @param e exponent
528      * @param m modulus
529      */
530     CBigNum pow_mod(const CBigNum& e, const CBigNum& m) const {
531         CAutoBN_CTX pctx;
532         CBigNum ret;
533         if( e < 0){
534             // g^-x = (g^-1)^x
535             CBigNum inv = this->inverse(m);
536             CBigNum posE = e * -1;
537             if (!BN_mod_exp(&ret, &inv, &posE, &m, pctx))
538                 throw bignum_error("CBigNum::pow_mod: BN_mod_exp failed on negative exponent");
539         }else
540             if (!BN_mod_exp(&ret, this, &e, &m, pctx))
541                 throw bignum_error("CBigNum::pow_mod : BN_mod_exp failed");
542
543         return ret;
544     }
545
546     /**
547     * Calculates the inverse of this element mod m.
548     * i.e. i such this*i = 1 mod m
549     * @param m the modu
550     * @return the inverse
551     */
552     CBigNum inverse(const CBigNum& m) const {
553         CAutoBN_CTX pctx;
554         CBigNum ret;
555         if (!BN_mod_inverse(&ret, this, &m, pctx))
556             throw bignum_error("CBigNum::inverse*= :BN_mod_inverse");
557         return ret;
558     }
559
560     /**
561      * Generates a random (safe) prime of numBits bits
562      * @param numBits the number of bits
563      * @param safe true for a safe prime
564      * @return the prime
565      */
566     static CBigNum generatePrime(const unsigned int numBits, bool safe = false) {
567         CBigNum ret;
568         if(!BN_generate_prime_ex(&ret, numBits, (safe == true), NULL, NULL, NULL))
569             throw bignum_error("CBigNum::generatePrime*= :BN_generate_prime_ex");
570         return ret;
571     }
572
573     /**
574      * Calculates the greatest common divisor (GCD) of two numbers.
575      * @param m the second element
576      * @return the GCD
577      */
578     CBigNum gcd( const CBigNum& b) const{
579         CAutoBN_CTX pctx;
580         CBigNum ret;
581         if (!BN_gcd(&ret, this, &b, pctx))
582             throw bignum_error("CBigNum::gcd*= :BN_gcd");
583         return ret;
584     }
585
586     /**
587     * Miller-Rabin primality test on this element
588     * @param checks: optional, the number of Miller-Rabin tests to run
589     * default causes error rate of 2^-80.
590     * @return true if prime
591     */
592     bool isPrime(const int checks=BN_prime_checks) const {
593         CAutoBN_CTX pctx;
594         int ret = BN_is_prime(this, checks, NULL, pctx, NULL);
595         if(ret < 0){
596             throw bignum_error("CBigNum::isPrime :BN_is_prime");
597         }
598         return ret != 0;
599     }
600
601     bool isOne() const {
602         return BN_is_one(this);
603     }
604
605
606     bool operator!() const
607     {
608         return BN_is_zero(this);
609     }
610
611     CBigNum& operator+=(const CBigNum& b)
612     {
613         if (!BN_add(this, this, &b))
614             throw bignum_error("CBigNum::operator+= : BN_add failed");
615         return *this;
616     }
617
618     CBigNum& operator-=(const CBigNum& b)
619     {
620         *this = *this - b;
621         return *this;
622     }
623
624     CBigNum& operator*=(const CBigNum& b)
625     {
626         CAutoBN_CTX pctx;
627         if (!BN_mul(this, this, &b, pctx))
628             throw bignum_error("CBigNum::operator*= : BN_mul failed");
629         return *this;
630     }
631
632     CBigNum& operator/=(const CBigNum& b)
633     {
634         *this = *this / b;
635         return *this;
636     }
637
638     CBigNum& operator%=(const CBigNum& b)
639     {
640         *this = *this % b;
641         return *this;
642     }
643
644     CBigNum& operator<<=(unsigned int shift)
645     {
646         if (!BN_lshift(this, this, shift))
647             throw bignum_error("CBigNum:operator<<= : BN_lshift failed");
648         return *this;
649     }
650
651     CBigNum& operator>>=(unsigned int shift)
652     {
653         // Note: BN_rshift segfaults on 64-bit if 2^shift is greater than the number
654         //   if built on ubuntu 9.04 or 9.10, probably depends on version of OpenSSL
655         CBigNum a = 1;
656         a <<= shift;
657         if (BN_cmp(&a, this) > 0)
658         {
659             *this = 0;
660             return *this;
661         }
662
663         if (!BN_rshift(this, this, shift))
664             throw bignum_error("CBigNum:operator>>= : BN_rshift failed");
665         return *this;
666     }
667
668
669     CBigNum& operator++()
670     {
671         // prefix operator
672         if (!BN_add(this, this, BN_value_one()))
673             throw bignum_error("CBigNum::operator++ : BN_add failed");
674         return *this;
675     }
676
677     const CBigNum operator++(int)
678     {
679         // postfix operator
680         const CBigNum ret = *this;
681         ++(*this);
682         return ret;
683     }
684
685     CBigNum& operator--()
686     {
687         // prefix operator
688         CBigNum r;
689         if (!BN_sub(&r, this, BN_value_one()))
690             throw bignum_error("CBigNum::operator-- : BN_sub failed");
691         *this = r;
692         return *this;
693     }
694
695     const CBigNum operator--(int)
696     {
697         // postfix operator
698         const CBigNum ret = *this;
699         --(*this);
700         return ret;
701     }
702
703
704     friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b);
705     friend inline const CBigNum operator/(const CBigNum& a, const CBigNum& b);
706     friend inline const CBigNum operator%(const CBigNum& a, const CBigNum& b);
707     friend inline const CBigNum operator*(const CBigNum& a, const CBigNum& b);
708     friend inline bool operator<(const CBigNum& a, const CBigNum& b);
709 };
710
711
712
713 inline const CBigNum operator+(const CBigNum& a, const CBigNum& b)
714 {
715     CBigNum r;
716     if (!BN_add(&r, &a, &b))
717         throw bignum_error("CBigNum::operator+ : BN_add failed");
718     return r;
719 }
720
721 inline const CBigNum operator-(const CBigNum& a, const CBigNum& b)
722 {
723     CBigNum r;
724     if (!BN_sub(&r, &a, &b))
725         throw bignum_error("CBigNum::operator- : BN_sub failed");
726     return r;
727 }
728
729 inline const CBigNum operator-(const CBigNum& a)
730 {
731     CBigNum r(a);
732     BN_set_negative(&r, !BN_is_negative(&r));
733     return r;
734 }
735
736 inline const CBigNum operator*(const CBigNum& a, const CBigNum& b)
737 {
738     CAutoBN_CTX pctx;
739     CBigNum r;
740     if (!BN_mul(&r, &a, &b, pctx))
741         throw bignum_error("CBigNum::operator* : BN_mul failed");
742     return r;
743 }
744
745 inline const CBigNum operator/(const CBigNum& a, const CBigNum& b)
746 {
747     CAutoBN_CTX pctx;
748     CBigNum r;
749     if (!BN_div(&r, NULL, &a, &b, pctx))
750         throw bignum_error("CBigNum::operator/ : BN_div failed");
751     return r;
752 }
753
754 inline const CBigNum operator%(const CBigNum& a, const CBigNum& b)
755 {
756     CAutoBN_CTX pctx;
757     CBigNum r;
758     if (!BN_nnmod(&r, &a, &b, pctx))
759         throw bignum_error("CBigNum::operator% : BN_div failed");
760     return r;
761 }
762
763 inline const CBigNum operator<<(const CBigNum& a, unsigned int shift)
764 {
765     CBigNum r;
766     if (!BN_lshift(&r, &a, shift))
767         throw bignum_error("CBigNum:operator<< : BN_lshift failed");
768     return r;
769 }
770
771 inline const CBigNum operator>>(const CBigNum& a, unsigned int shift)
772 {
773     CBigNum r = a;
774     r >>= shift;
775     return r;
776 }
777
778 inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) == 0); }
779 inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) != 0); }
780 inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) <= 0); }
781 inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) >= 0); }
782 inline bool operator<(const CBigNum& a, const CBigNum& b)  { return (BN_cmp(&a, &b) < 0); }
783 inline bool operator>(const CBigNum& a, const CBigNum& b)  { return (BN_cmp(&a, &b) > 0); }
784
785 inline std::ostream& operator<<(std::ostream &strm, const CBigNum &b) { return strm << b.ToString(10); }
786
787 typedef  CBigNum Bignum;
788
789 #endif