]> Git Repo - VerusCoin.git/blame - src/test/bignum.h
Auto merge of #1474 - ageis:update-release-process, r=str4d
[VerusCoin.git] / src / test / bignum.h
CommitLineData
8bd66202 1// Copyright (c) 2009-2010 Satoshi Nakamoto
f914f1a7 2// Copyright (c) 2009-2013 The Bitcoin Core developers
78253fcb 3// Distributed under the MIT software license, see the accompanying
3a25a2b9 4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
51ed9ec9 5
84738627
PJ
6#ifndef BITCOIN_TEST_BIGNUM_H
7#define BITCOIN_TEST_BIGNUM_H
8bd66202 8
ccc84e09 9#include <algorithm>
017abaf6 10#include <cassert>
ccc84e09 11#include <limits>
8bd66202 12#include <stdexcept>
51ed9ec9 13#include <stdint.h>
f25e3adf 14#include <string>
8bd66202 15#include <vector>
8bd66202 16
51ed9ec9 17#include <openssl/bn.h>
8bd66202
GA
18
19class bignum_error : public std::runtime_error
20{
21public:
22 explicit bignum_error(const std::string& str) : std::runtime_error(str) {}
23};
24
25
7e05b972 26/** C++ wrapper for BIGNUM (OpenSSL bignum) */
fa318aa9 27class CBigNum
8bd66202 28{
fa318aa9 29 BIGNUM* bn;
8bd66202
GA
30public:
31 CBigNum()
32 {
fa318aa9 33 bn = BN_new();
017abaf6 34 assert(bn);
8bd66202
GA
35 }
36
37 CBigNum(const CBigNum& b)
38 {
fa318aa9 39 bn = BN_new();
017abaf6 40 assert(bn);
fa318aa9 41 if (!BN_copy(bn, b.bn))
8bd66202 42 {
fa318aa9 43 BN_clear_free(bn);
5262fde0 44 throw bignum_error("CBigNum::CBigNum(const CBigNum&): BN_copy failed");
8bd66202
GA
45 }
46 }
47
48 CBigNum& operator=(const CBigNum& b)
49 {
fa318aa9 50 if (!BN_copy(bn, b.bn))
5262fde0 51 throw bignum_error("CBigNum::operator=: BN_copy failed");
8bd66202
GA
52 return (*this);
53 }
54
55 ~CBigNum()
56 {
fa318aa9 57 BN_clear_free(bn);
8bd66202
GA
58 }
59
017abaf6 60 CBigNum(long long n) { bn = BN_new(); assert(bn); setint64(n); }
8bd66202
GA
61
62 explicit CBigNum(const std::vector<unsigned char>& vch)
63 {
fa318aa9 64 bn = BN_new();
017abaf6 65 assert(bn);
8bd66202
GA
66 setvch(vch);
67 }
68
8bd66202
GA
69 int getint() const
70 {
fa318aa9
JG
71 BN_ULONG n = BN_get_word(bn);
72 if (!BN_is_negative(bn))
63c17613 73 return (n > (BN_ULONG)std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : n);
8bd66202 74 else
63c17613 75 return (n > (BN_ULONG)std::numeric_limits<int>::max() ? std::numeric_limits<int>::min() : -(int)n);
8bd66202
GA
76 }
77
51ed9ec9 78 void setint64(int64_t sn)
8bd66202 79 {
fe78c9ae 80 unsigned char pch[sizeof(sn) + 6];
8bd66202 81 unsigned char* p = pch + 4;
fe78c9ae 82 bool fNegative;
51ed9ec9 83 uint64_t n;
fe78c9ae 84
51ed9ec9 85 if (sn < (int64_t)0)
8bd66202 86 {
f0bf5fb2 87 // Since the minimum signed integer cannot be represented as positive so long as its type is signed,
88 // and it's not well-defined what happens if you make it unsigned before negating it,
89 // we instead increment the negative integer by 1, convert it, then increment the (now positive) unsigned integer by 1 to compensate
0f5a2a82
LD
90 n = -(sn + 1);
91 ++n;
8bd66202 92 fNegative = true;
fe78c9ae
RC
93 } else {
94 n = sn;
95 fNegative = false;
8bd66202 96 }
fe78c9ae 97
8bd66202
GA
98 bool fLeadingZeroes = true;
99 for (int i = 0; i < 8; i++)
100 {
101 unsigned char c = (n >> 56) & 0xff;
102 n <<= 8;
103 if (fLeadingZeroes)
104 {
105 if (c == 0)
106 continue;
107 if (c & 0x80)
108 *p++ = (fNegative ? 0x80 : 0);
109 else if (fNegative)
110 c |= 0x80;
111 fLeadingZeroes = false;
112 }
113 *p++ = c;
114 }
115 unsigned int nSize = p - (pch + 4);
116 pch[0] = (nSize >> 24) & 0xff;
117 pch[1] = (nSize >> 16) & 0xff;
118 pch[2] = (nSize >> 8) & 0xff;
119 pch[3] = (nSize) & 0xff;
fa318aa9 120 BN_mpi2bn(pch, p - pch, bn);
8bd66202
GA
121 }
122
8bd66202
GA
123 void setvch(const std::vector<unsigned char>& vch)
124 {
125 std::vector<unsigned char> vch2(vch.size() + 4);
126 unsigned int nSize = vch.size();
a9d3af88
DH
127 // BIGNUM's byte stream format expects 4 bytes of
128 // big endian size data info at the front
8bd66202
GA
129 vch2[0] = (nSize >> 24) & 0xff;
130 vch2[1] = (nSize >> 16) & 0xff;
131 vch2[2] = (nSize >> 8) & 0xff;
132 vch2[3] = (nSize >> 0) & 0xff;
a9d3af88 133 // swap data to big endian
8bd66202 134 reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4);
fa318aa9 135 BN_mpi2bn(&vch2[0], vch2.size(), bn);
8bd66202
GA
136 }
137
138 std::vector<unsigned char> getvch() const
139 {
fa318aa9 140 unsigned int nSize = BN_bn2mpi(bn, NULL);
a06113b0 141 if (nSize <= 4)
8bd66202
GA
142 return std::vector<unsigned char>();
143 std::vector<unsigned char> vch(nSize);
fa318aa9 144 BN_bn2mpi(bn, &vch[0]);
8bd66202
GA
145 vch.erase(vch.begin(), vch.begin() + 4);
146 reverse(vch.begin(), vch.end());
147 return vch;
148 }
149
fa318aa9 150 friend inline const CBigNum operator+(const CBigNum& a, const CBigNum& b);
8bd66202 151 friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b);
fa318aa9
JG
152 friend inline const CBigNum operator-(const CBigNum& a);
153 friend inline bool operator==(const CBigNum& a, const CBigNum& b);
154 friend inline bool operator!=(const CBigNum& a, const CBigNum& b);
155 friend inline bool operator<=(const CBigNum& a, const CBigNum& b);
156 friend inline bool operator>=(const CBigNum& a, const CBigNum& b);
157 friend inline bool operator<(const CBigNum& a, const CBigNum& b);
158 friend inline bool operator>(const CBigNum& a, const CBigNum& b);
8bd66202
GA
159};
160
161
162
163inline const CBigNum operator+(const CBigNum& a, const CBigNum& b)
164{
165 CBigNum r;
fa318aa9 166 if (!BN_add(r.bn, a.bn, b.bn))
5262fde0 167 throw bignum_error("CBigNum::operator+: BN_add failed");
8bd66202
GA
168 return r;
169}
170
171inline const CBigNum operator-(const CBigNum& a, const CBigNum& b)
172{
173 CBigNum r;
fa318aa9 174 if (!BN_sub(r.bn, a.bn, b.bn))
5262fde0 175 throw bignum_error("CBigNum::operator-: BN_sub failed");
8bd66202
GA
176 return r;
177}
178
179inline const CBigNum operator-(const CBigNum& a)
180{
181 CBigNum r(a);
fa318aa9 182 BN_set_negative(r.bn, !BN_is_negative(r.bn));
8bd66202
GA
183 return r;
184}
185
fa318aa9
JG
186inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.bn, b.bn) == 0); }
187inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.bn, b.bn) != 0); }
188inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.bn, b.bn) <= 0); }
189inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.bn, b.bn) >= 0); }
190inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.bn, b.bn) < 0); }
191inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.bn, b.bn) > 0); }
223b6f1b 192
84738627 193#endif // BITCOIN_TEST_BIGNUM_H
This page took 0.201605 seconds and 4 git commands to generate.