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