Remove unused includes.
[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     uint64_t getuint64()
195     {
196         size_t nSize = BN_bn2mpi(this, NULL);
197         if (nSize < 4)
198             return 0;
199         std::vector<uint8_t> vch(nSize);
200         BN_bn2mpi(this, &vch[0]);
201         if (vch.size() > 4)
202             vch[4] &= 0x7f;
203         uint64_t n = 0;
204         for (size_t i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--)
205             ((uint8_t*)&n)[i] = vch[j];
206         return n;
207     }
208
209     void setuint64(uint64_t n)
210     {
211         // Use BN_set_word if word size is sufficient for uint64_t
212         if (sizeof(n) <= sizeof(BN_ULONG))
213         {
214             if (!BN_set_word(this, (BN_ULONG)n))
215                 throw bignum_error("CBigNum conversion from uint64_t : BN_set_word failed");
216             return;
217         }
218
219         uint8_t pch[sizeof(n) + 6];
220         uint8_t* p = pch + 4;
221         bool fLeadingZeroes = true;
222         for (int i = 0; i < 8; i++)
223         {
224             uint8_t c = (n >> 56) & 0xff;
225             n <<= 8;
226             if (fLeadingZeroes)
227             {
228                 if (c == 0)
229                     continue;
230                 if (c & 0x80)
231                     *p++ = 0;
232                 fLeadingZeroes = false;
233             }
234             *p++ = c;
235         }
236         uint32_t nSize = (uint32_t) (p - (pch + 4));
237         pch[0] = (nSize >> 24) & 0xff;
238         pch[1] = (nSize >> 16) & 0xff;
239         pch[2] = (nSize >> 8) & 0xff;
240         pch[3] = (nSize) & 0xff;
241         BN_mpi2bn(pch, (int)(p - pch), this);
242     }
243
244     void setuint160(uint160 n)
245     {
246         uint8_t pch[sizeof(n) + 6];
247         uint8_t* p = pch + 4;
248         bool fLeadingZeroes = true;
249         uint8_t* pbegin = (uint8_t*)&n;
250         uint8_t* psrc = pbegin + sizeof(n);
251         while (psrc != pbegin)
252         {
253             uint8_t c = *(--psrc);
254             if (fLeadingZeroes)
255             {
256                 if (c == 0)
257                     continue;
258                 if (c & 0x80)
259                     *p++ = 0;
260                 fLeadingZeroes = false;
261             }
262             *p++ = c;
263         }
264         uint32_t nSize = (uint32_t) (p - (pch + 4));
265         pch[0] = (nSize >> 24) & 0xff;
266         pch[1] = (nSize >> 16) & 0xff;
267         pch[2] = (nSize >> 8) & 0xff;
268         pch[3] = (nSize >> 0) & 0xff;
269         BN_mpi2bn(pch, (int) (p - pch), this);
270     }
271
272     uint160 getuint160() const
273     {
274         unsigned int nSize = BN_bn2mpi(this, NULL);
275         if (nSize < 4)
276             return 0;
277         std::vector<uint8_t> vch(nSize);
278         BN_bn2mpi(this, &vch[0]);
279         if (vch.size() > 4)
280             vch[4] &= 0x7f;
281         uint160 n = 0;
282         for (size_t i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--)
283             ((uint8_t*)&n)[i] = vch[j];
284         return n;
285     }
286
287     void setuint256(uint256 n)
288     {
289         uint8_t pch[sizeof(n) + 6];
290         uint8_t* p = pch + 4;
291         bool fLeadingZeroes = true;
292         uint8_t* pbegin = (uint8_t*)&n;
293         uint8_t* psrc = pbegin + sizeof(n);
294         while (psrc != pbegin)
295         {
296             uint8_t c = *(--psrc);
297             if (fLeadingZeroes)
298             {
299                 if (c == 0)
300                     continue;
301                 if (c & 0x80)
302                     *p++ = 0;
303                 fLeadingZeroes = false;
304             }
305             *p++ = c;
306         }
307         uint32_t nSize = (uint32_t) (p - (pch + 4));
308         pch[0] = (nSize >> 24) & 0xff;
309         pch[1] = (nSize >> 16) & 0xff;
310         pch[2] = (nSize >> 8) & 0xff;
311         pch[3] = (nSize >> 0) & 0xff;
312         BN_mpi2bn(pch, (int) (p - pch), this);
313     }
314
315     uint256 getuint256() const
316     {
317         unsigned int nSize = BN_bn2mpi(this, NULL);
318         if (nSize < 4)
319             return 0;
320         std::vector<uint8_t> vch(nSize);
321         BN_bn2mpi(this, &vch[0]);
322         if (vch.size() > 4)
323             vch[4] &= 0x7f;
324         uint256 n = 0;
325         for (size_t i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--)
326             ((uint8_t*)&n)[i] = vch[j];
327         return n;
328     }
329
330     void setBytes(const std::vector<uint8_t>& vchBytes)
331     {
332         BN_bin2bn(&vchBytes[0], (int) vchBytes.size(), this);
333     }
334
335     std::vector<uint8_t> getBytes() const
336     {
337         int nBytes = BN_num_bytes(this);
338
339         std::vector<uint8_t> vchBytes(nBytes);
340
341         int n = BN_bn2bin(this, &vchBytes[0]);
342         if (n != nBytes) {
343             throw bignum_error("CBigNum::getBytes : BN_bn2bin failed");
344         }
345
346         return vchBytes;
347     }
348
349     void setvch(const std::vector<uint8_t>& vch)
350     {
351         std::vector<uint8_t> vch2(vch.size() + 4);
352         uint32_t nSize = (uint32_t) vch.size();
353         // BIGNUM's byte stream format expects 4 bytes of
354         // big endian size data info at the front
355         vch2[0] = (nSize >> 24) & 0xff;
356         vch2[1] = (nSize >> 16) & 0xff;
357         vch2[2] = (nSize >> 8) & 0xff;
358         vch2[3] = (nSize >> 0) & 0xff;
359         // swap data to big endian
360         reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4);
361         BN_mpi2bn(&vch2[0], (int) vch2.size(), this);
362     }
363
364     std::vector<uint8_t> getvch() const
365     {
366         unsigned int nSize = BN_bn2mpi(this, NULL);
367         if (nSize <= 4)
368             return std::vector<uint8_t>();
369         std::vector<uint8_t> vch(nSize);
370         BN_bn2mpi(this, &vch[0]);
371         vch.erase(vch.begin(), vch.begin() + 4);
372         reverse(vch.begin(), vch.end());
373         return vch;
374     }
375
376     CBigNum& SetCompact(uint32_t nCompact)
377     {
378         uint32_t nSize = nCompact >> 24;
379         std::vector<uint8_t> vch(4 + nSize);
380         vch[3] = nSize;
381         if (nSize >= 1) vch[4] = (nCompact >> 16) & 0xff;
382         if (nSize >= 2) vch[5] = (nCompact >> 8) & 0xff;
383         if (nSize >= 3) vch[6] = (nCompact >> 0) & 0xff;
384         BN_mpi2bn(&vch[0], (int) vch.size(), this);
385         return *this;
386     }
387
388     uint32_t GetCompact() const
389     {
390         uint32_t nSize = BN_bn2mpi(this, NULL);
391         std::vector<uint8_t> vch(nSize);
392         nSize -= 4;
393         BN_bn2mpi(this, &vch[0]);
394         uint32_t nCompact = nSize << 24;
395         if (nSize >= 1) nCompact |= (vch[4] << 16);
396         if (nSize >= 2) nCompact |= (vch[5] << 8);
397         if (nSize >= 3) nCompact |= (vch[6] << 0);
398         return nCompact;
399     }
400
401     void SetHex(const std::string& str)
402     {
403         // skip 0x
404         const char* psz = str.c_str();
405         while (isspace(*psz))
406             psz++;
407         bool fNegative = false;
408         if (*psz == '-')
409         {
410             fNegative = true;
411             psz++;
412         }
413         if (psz[0] == '0' && tolower(psz[1]) == 'x')
414             psz += 2;
415         while (isspace(*psz))
416             psz++;
417
418         // hex string to bignum
419         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 };
420         *this = 0;
421         while (isxdigit(*psz))
422         {
423             *this <<= 4;
424             int n = phexdigit[(uint8_t)*psz++];
425             *this += n;
426         }
427         if (fNegative)
428             *this = 0 - *this;
429     }
430
431     std::string ToString(int nBase=10) const
432     {
433         CAutoBN_CTX pctx;
434         CBigNum bnBase = nBase;
435         CBigNum bn0 = 0;
436         std::string str;
437         CBigNum bn = *this;
438         BN_set_negative(&bn, false);
439         CBigNum dv;
440         CBigNum rem;
441         if (BN_cmp(&bn, &bn0) == 0)
442             return "0";
443         while (BN_cmp(&bn, &bn0) > 0)
444         {
445             if (!BN_div(&dv, &rem, &bn, &bnBase, pctx))
446                 throw bignum_error("CBigNum::ToString() : BN_div failed");
447             bn = dv;
448             uint32_t c = rem.getuint32();
449             str += "0123456789abcdef"[c];
450         }
451         if (BN_is_negative(this))
452             str += "-";
453         reverse(str.begin(), str.end());
454         return str;
455     }
456
457     std::string GetHex() const
458     {
459         return ToString(16);
460     }
461
462     unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const
463     {
464         return ::GetSerializeSize(getvch(), nType, nVersion);
465     }
466
467     template<typename Stream>
468     void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const
469     {
470         ::Serialize(s, getvch(), nType, nVersion);
471     }
472
473     template<typename Stream>
474     void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION)
475     {
476         std::vector<uint8_t> vch;
477         ::Unserialize(s, vch, nType, nVersion);
478         setvch(vch);
479     }
480
481     /**
482     * exponentiation with an int. this^e
483     * @param e the exponent as an int
484     * @return
485     */
486     CBigNum pow(const int e) const {
487         return this->pow(CBigNum(e));
488     }
489
490     /**
491      * exponentiation this^e
492      * @param e the exponent
493      * @return
494      */
495     CBigNum pow(const CBigNum& e) const {
496         CAutoBN_CTX pctx;
497         CBigNum ret;
498         if (!BN_exp(&ret, this, &e, pctx))
499             throw bignum_error("CBigNum::pow : BN_exp failed");
500         return ret;
501     }
502
503     /**
504      * modular multiplication: (this * b) mod m
505      * @param b operand
506      * @param m modulus
507      */
508     CBigNum mul_mod(const CBigNum& b, const CBigNum& m) const {
509         CAutoBN_CTX pctx;
510         CBigNum ret;
511         if (!BN_mod_mul(&ret, this, &b, &m, pctx))
512             throw bignum_error("CBigNum::mul_mod : BN_mod_mul failed");
513
514         return ret;
515     }
516
517     /**
518      * modular exponentiation: this^e mod n
519      * @param e exponent
520      * @param m modulus
521      */
522     CBigNum pow_mod(const CBigNum& e, const CBigNum& m) const {
523         CAutoBN_CTX pctx;
524         CBigNum ret;
525         if( e < 0){
526             // g^-x = (g^-1)^x
527             CBigNum inv = this->inverse(m);
528             CBigNum posE = e * -1;
529             if (!BN_mod_exp(&ret, &inv, &posE, &m, pctx))
530                 throw bignum_error("CBigNum::pow_mod: BN_mod_exp failed on negative exponent");
531         }else
532             if (!BN_mod_exp(&ret, this, &e, &m, pctx))
533                 throw bignum_error("CBigNum::pow_mod : BN_mod_exp failed");
534
535         return ret;
536     }
537
538     /**
539     * Calculates the inverse of this element mod m.
540     * i.e. i such this*i = 1 mod m
541     * @param m the modu
542     * @return the inverse
543     */
544     CBigNum inverse(const CBigNum& m) const {
545         CAutoBN_CTX pctx;
546         CBigNum ret;
547         if (!BN_mod_inverse(&ret, this, &m, pctx))
548             throw bignum_error("CBigNum::inverse*= :BN_mod_inverse");
549         return ret;
550     }
551
552     /**
553      * Generates a random (safe) prime of numBits bits
554      * @param numBits the number of bits
555      * @param safe true for a safe prime
556      * @return the prime
557      */
558     static CBigNum generatePrime(const unsigned int numBits, bool safe = false) {
559         CBigNum ret;
560         if(!BN_generate_prime_ex(&ret, numBits, (safe == true), NULL, NULL, NULL))
561             throw bignum_error("CBigNum::generatePrime*= :BN_generate_prime_ex");
562         return ret;
563     }
564
565     /**
566      * Calculates the greatest common divisor (GCD) of two numbers.
567      * @param m the second element
568      * @return the GCD
569      */
570     CBigNum gcd( const CBigNum& b) const{
571         CAutoBN_CTX pctx;
572         CBigNum ret;
573         if (!BN_gcd(&ret, this, &b, pctx))
574             throw bignum_error("CBigNum::gcd*= :BN_gcd");
575         return ret;
576     }
577
578     /**
579     * Miller-Rabin primality test on this element
580     * @param checks: optional, the number of Miller-Rabin tests to run
581     * default causes error rate of 2^-80.
582     * @return true if prime
583     */
584     bool isPrime(const int checks=BN_prime_checks) const {
585         CAutoBN_CTX pctx;
586         int ret = BN_is_prime(this, checks, NULL, pctx, NULL);
587         if(ret < 0){
588             throw bignum_error("CBigNum::isPrime :BN_is_prime");
589         }
590         return ret != 0;
591     }
592
593     bool isOne() const {
594         return BN_is_one(this);
595     }
596
597
598     bool operator!() const
599     {
600         return BN_is_zero(this);
601     }
602
603     CBigNum& operator+=(const CBigNum& b)
604     {
605         if (!BN_add(this, this, &b))
606             throw bignum_error("CBigNum::operator+= : BN_add failed");
607         return *this;
608     }
609
610     CBigNum& operator-=(const CBigNum& b)
611     {
612         *this = *this - b;
613         return *this;
614     }
615
616     CBigNum& operator*=(const CBigNum& b)
617     {
618         CAutoBN_CTX pctx;
619         if (!BN_mul(this, this, &b, pctx))
620             throw bignum_error("CBigNum::operator*= : BN_mul failed");
621         return *this;
622     }
623
624     CBigNum& operator/=(const CBigNum& b)
625     {
626         *this = *this / b;
627         return *this;
628     }
629
630     CBigNum& operator%=(const CBigNum& b)
631     {
632         *this = *this % b;
633         return *this;
634     }
635
636     CBigNum& operator<<=(unsigned int shift)
637     {
638         if (!BN_lshift(this, this, shift))
639             throw bignum_error("CBigNum:operator<<= : BN_lshift failed");
640         return *this;
641     }
642
643     CBigNum& operator>>=(unsigned int shift)
644     {
645         // Note: BN_rshift segfaults on 64-bit if 2^shift is greater than the number
646         //   if built on ubuntu 9.04 or 9.10, probably depends on version of OpenSSL
647         CBigNum a = 1;
648         a <<= shift;
649         if (BN_cmp(&a, this) > 0)
650         {
651             *this = 0;
652             return *this;
653         }
654
655         if (!BN_rshift(this, this, shift))
656             throw bignum_error("CBigNum:operator>>= : BN_rshift failed");
657         return *this;
658     }
659
660
661     CBigNum& operator++()
662     {
663         // prefix operator
664         if (!BN_add(this, this, BN_value_one()))
665             throw bignum_error("CBigNum::operator++ : BN_add failed");
666         return *this;
667     }
668
669     const CBigNum operator++(int)
670     {
671         // postfix operator
672         const CBigNum ret = *this;
673         ++(*this);
674         return ret;
675     }
676
677     CBigNum& operator--()
678     {
679         // prefix operator
680         CBigNum r;
681         if (!BN_sub(&r, this, BN_value_one()))
682             throw bignum_error("CBigNum::operator-- : BN_sub failed");
683         *this = r;
684         return *this;
685     }
686
687     const CBigNum operator--(int)
688     {
689         // postfix operator
690         const CBigNum ret = *this;
691         --(*this);
692         return ret;
693     }
694
695
696     friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b);
697     friend inline const CBigNum operator/(const CBigNum& a, const CBigNum& b);
698     friend inline const CBigNum operator%(const CBigNum& a, const CBigNum& b);
699     friend inline const CBigNum operator*(const CBigNum& a, const CBigNum& b);
700     friend inline bool operator<(const CBigNum& a, const CBigNum& b);
701 };
702
703
704
705 inline const CBigNum operator+(const CBigNum& a, const CBigNum& b)
706 {
707     CBigNum r;
708     if (!BN_add(&r, &a, &b))
709         throw bignum_error("CBigNum::operator+ : BN_add failed");
710     return r;
711 }
712
713 inline const CBigNum operator-(const CBigNum& a, const CBigNum& b)
714 {
715     CBigNum r;
716     if (!BN_sub(&r, &a, &b))
717         throw bignum_error("CBigNum::operator- : BN_sub failed");
718     return r;
719 }
720
721 inline const CBigNum operator-(const CBigNum& a)
722 {
723     CBigNum r(a);
724     BN_set_negative(&r, !BN_is_negative(&r));
725     return r;
726 }
727
728 inline const CBigNum operator*(const CBigNum& a, const CBigNum& b)
729 {
730     CAutoBN_CTX pctx;
731     CBigNum r;
732     if (!BN_mul(&r, &a, &b, pctx))
733         throw bignum_error("CBigNum::operator* : BN_mul failed");
734     return r;
735 }
736
737 inline const CBigNum operator/(const CBigNum& a, const CBigNum& b)
738 {
739     CAutoBN_CTX pctx;
740     CBigNum r;
741     if (!BN_div(&r, NULL, &a, &b, pctx))
742         throw bignum_error("CBigNum::operator/ : BN_div failed");
743     return r;
744 }
745
746 inline const CBigNum operator%(const CBigNum& a, const CBigNum& b)
747 {
748     CAutoBN_CTX pctx;
749     CBigNum r;
750     if (!BN_nnmod(&r, &a, &b, pctx))
751         throw bignum_error("CBigNum::operator% : BN_div failed");
752     return r;
753 }
754
755 inline const CBigNum operator<<(const CBigNum& a, unsigned int shift)
756 {
757     CBigNum r;
758     if (!BN_lshift(&r, &a, shift))
759         throw bignum_error("CBigNum:operator<< : BN_lshift failed");
760     return r;
761 }
762
763 inline const CBigNum operator>>(const CBigNum& a, unsigned int shift)
764 {
765     CBigNum r = a;
766     r >>= shift;
767     return r;
768 }
769
770 inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) == 0); }
771 inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) != 0); }
772 inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) <= 0); }
773 inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) >= 0); }
774 inline bool operator<(const CBigNum& a, const CBigNum& b)  { return (BN_cmp(&a, &b) < 0); }
775 inline bool operator>(const CBigNum& a, const CBigNum& b)  { return (BN_cmp(&a, &b) > 0); }
776
777 inline std::ostream& operator<<(std::ostream &strm, const CBigNum &b) { return strm << b.ToString(10); }
778
779 typedef  CBigNum Bignum;
780
781 #endif