Skip to content

Added compatibility for OpenSSL1.1 & Boost 1.66 #36

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/readme-qt.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ distribution are installed, for Debian and Ubuntu these are:
::

apt-get install qt5-default qt5-qmake qtbase5-dev-tools qttools5-dev-tools \
build-essential libboost-dev libboost-system-dev \
libqt5svg5-dev build-essential libboost-dev libboost-system-dev \
libboost-filesystem-dev libboost-program-options-dev libboost-thread-dev \
libssl-dev libdb++-dev libminiupnpc-dev

Expand Down
138 changes: 74 additions & 64 deletions src/bignum.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,54 +52,61 @@ class CAutoBN_CTX
bool operator!() { return (pctx == NULL); }
};

/* RAII wrapper for BIGNUM instance */
class CBigNumBase
{
protected:
BIGNUM* pbn;

public:
CBigNumBase()
: pbn(BN_new())
{
if (pbn == NULL)
throw bignum_error("CBigNum : BN_new() returned NULL");
}

~CBigNumBase()
{
BN_clear_free(pbn);
}
};

/** C++ wrapper for BIGNUM (OpenSSL bignum) */
class CBigNum : public BIGNUM
class CBigNum : public CBigNumBase
{
public:
CBigNum()
{
BN_init(this);
}
{}

CBigNum(const CBigNum& b)
{
BN_init(this);
if (!BN_copy(this, &b))
{
BN_clear_free(this);
if (!BN_copy(pbn, &b))
throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed");
}
}

CBigNum& operator=(const CBigNum& b)
{
if (!BN_copy(this, &b))
if (!BN_copy(pbn, &b))
throw bignum_error("CBigNum::operator= : BN_copy failed");
return (*this);
}

~CBigNum()
{
BN_clear_free(this);
}

//CBigNum(char n) is not portable. Use 'signed char' or 'unsigned char'.
CBigNum(signed char n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
CBigNum(short n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
CBigNum(int n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
CBigNum(long n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
CBigNum(long long n) { BN_init(this); setint64(n); }
CBigNum(unsigned char n) { BN_init(this); setulong(n); }
CBigNum(unsigned short n) { BN_init(this); setulong(n); }
CBigNum(unsigned int n) { BN_init(this); setulong(n); }
CBigNum(unsigned long n) { BN_init(this); setulong(n); }
CBigNum(unsigned long long n) { BN_init(this); setuint64(n); }
explicit CBigNum(uint256 n) { BN_init(this); setuint256(n); }
CBigNum(signed char n) { if (n >= 0) setulong(n); else setint64(n); }
CBigNum(short n) { if (n >= 0) setulong(n); else setint64(n); }
CBigNum(int n) { if (n >= 0) setulong(n); else setint64(n); }
CBigNum(long n) { if (n >= 0) setulong(n); else setint64(n); }
CBigNum(long long n) { setint64(n); }
CBigNum(unsigned char n) { setulong(n); }
CBigNum(unsigned short n) { setulong(n); }
CBigNum(unsigned int n) { setulong(n); }
CBigNum(unsigned long n) { setulong(n); }
CBigNum(unsigned long long n) { setuint64(n); }
explicit CBigNum(uint256 n) { setuint256(n); }

explicit CBigNum(const std::vector<unsigned char>& vch)
{
BN_init(this);
setvch(vch);
}

Expand Down Expand Up @@ -133,30 +140,30 @@ class CBigNum : public BIGNUM
* @return the size
*/
int bitSize() const{
return BN_num_bits(this);
return BN_num_bits(pbn);
}


void setulong(unsigned long n)
{
if (!BN_set_word(this, n))
if (!BN_set_word(pbn, n))
throw bignum_error("CBigNum conversion from unsigned long : BN_set_word failed");
}

unsigned long getulong() const
{
return BN_get_word(this);
return BN_get_word(pbn);
}

unsigned int getuint() const
{
return BN_get_word(this);
return BN_get_word(pbn);
}

int getint() const
{
unsigned long n = BN_get_word(this);
if (!BN_is_negative(this))
unsigned long n = BN_get_word(pbn);
if (!BN_is_negative(pbn))
return (n > (unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : n);
else
return (n > (unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::min() : -(int)n);
Expand Down Expand Up @@ -202,16 +209,16 @@ class CBigNum : public BIGNUM
pch[1] = (nSize >> 16) & 0xff;
pch[2] = (nSize >> 8) & 0xff;
pch[3] = (nSize) & 0xff;
BN_mpi2bn(pch, p - pch, this);
BN_mpi2bn(pch, p - pch, pbn);
}

uint64_t getuint64()
{
unsigned int nSize = BN_bn2mpi(this, NULL);
unsigned int nSize = BN_bn2mpi(pbn, NULL);
if (nSize < 4)
return 0;
std::vector<unsigned char> vch(nSize);
BN_bn2mpi(this, &vch[0]);
BN_bn2mpi(pbn, &vch[0]);
if (vch.size() > 4)
vch[4] &= 0x7f;
uint64_t n = 0;
Expand Down Expand Up @@ -244,7 +251,7 @@ class CBigNum : public BIGNUM
pch[1] = (nSize >> 16) & 0xff;
pch[2] = (nSize >> 8) & 0xff;
pch[3] = (nSize) & 0xff;
BN_mpi2bn(pch, p - pch, this);
BN_mpi2bn(pch, p - pch, pbn);
}

void setuint256(uint256 n)
Expand Down Expand Up @@ -272,16 +279,16 @@ class CBigNum : public BIGNUM
pch[1] = (nSize >> 16) & 0xff;
pch[2] = (nSize >> 8) & 0xff;
pch[3] = (nSize >> 0) & 0xff;
BN_mpi2bn(pch, p - pch, this);
BN_mpi2bn(pch, p - pch, pbn);
}

uint256 getuint256() const
{
unsigned int nSize = BN_bn2mpi(this, NULL);
unsigned int nSize = BN_bn2mpi(pbn, NULL);
if (nSize < 4)
return 0;
std::vector<unsigned char> vch(nSize);
BN_bn2mpi(this, &vch[0]);
BN_bn2mpi(pbn, &vch[0]);
if (vch.size() > 4)
vch[4] &= 0x7f;
uint256 n = 0;
Expand All @@ -303,16 +310,16 @@ class CBigNum : public BIGNUM
vch2[3] = (nSize >> 0) & 0xff;
// swap data to big endian
reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4);
BN_mpi2bn(&vch2[0], vch2.size(), this);
BN_mpi2bn(&vch2[0], vch2.size(), pbn);
}

std::vector<unsigned char> getvch() const
{
unsigned int nSize = BN_bn2mpi(this, NULL);
unsigned int nSize = BN_bn2mpi(pbn, NULL);
if (nSize <= 4)
return std::vector<unsigned char>();
std::vector<unsigned char> vch(nSize);
BN_bn2mpi(this, &vch[0]);
BN_bn2mpi(pbn, &vch[0]);
vch.erase(vch.begin(), vch.begin() + 4);
reverse(vch.begin(), vch.end());
return vch;
Expand All @@ -326,16 +333,16 @@ class CBigNum : public BIGNUM
if (nSize >= 1) vch[4] = (nCompact >> 16) & 0xff;
if (nSize >= 2) vch[5] = (nCompact >> 8) & 0xff;
if (nSize >= 3) vch[6] = (nCompact >> 0) & 0xff;
BN_mpi2bn(&vch[0], vch.size(), this);
BN_mpi2bn(&vch[0], vch.size(), pbn);
return *this;
}

unsigned int GetCompact() const
{
unsigned int nSize = BN_bn2mpi(this, NULL);
unsigned int nSize = BN_bn2mpi(pbn, NULL);
std::vector<unsigned char> vch(nSize);
nSize -= 4;
BN_bn2mpi(this, &vch[0]);
BN_bn2mpi(pbn, &vch[0]);
unsigned int nCompact = nSize << 24;
if (nSize >= 1) nCompact |= (vch[4] << 16);
if (nSize >= 2) nCompact |= (vch[5] << 8);
Expand Down Expand Up @@ -393,7 +400,7 @@ class CBigNum : public BIGNUM
unsigned int c = rem.getulong();
str += "0123456789abcdef"[c];
}
if (BN_is_negative(this))
if (BN_is_negative(pbn))
str += "-";
reverse(str.begin(), str.end());
return str;
Expand Down Expand Up @@ -440,7 +447,7 @@ class CBigNum : public BIGNUM
CBigNum pow(const CBigNum& e) const {
CAutoBN_CTX pctx;
CBigNum ret;
if (!BN_exp(&ret, this, &e, pctx))
if (!BN_exp(&ret, pbn, &e, pctx))
throw bignum_error("CBigNum::pow : BN_exp failed");
return ret;
}
Expand All @@ -453,7 +460,7 @@ class CBigNum : public BIGNUM
CBigNum mul_mod(const CBigNum& b, const CBigNum& m) const {
CAutoBN_CTX pctx;
CBigNum ret;
if (!BN_mod_mul(&ret, this, &b, &m, pctx))
if (!BN_mod_mul(&ret, pbn, &b, &m, pctx))
throw bignum_error("CBigNum::mul_mod : BN_mod_mul failed");

return ret;
Expand All @@ -474,7 +481,7 @@ class CBigNum : public BIGNUM
if (!BN_mod_exp(&ret, &inv, &posE, &m, pctx))
throw bignum_error("CBigNum::pow_mod: BN_mod_exp failed on negative exponent");
}else
if (!BN_mod_exp(&ret, this, &e, &m, pctx))
if (!BN_mod_exp(&ret, pbn, &e, &m, pctx))
throw bignum_error("CBigNum::pow_mod : BN_mod_exp failed");

return ret;
Expand All @@ -489,7 +496,7 @@ class CBigNum : public BIGNUM
CBigNum inverse(const CBigNum& m) const {
CAutoBN_CTX pctx;
CBigNum ret;
if (!BN_mod_inverse(&ret, this, &m, pctx))
if (!BN_mod_inverse(&ret, pbn, &m, pctx))
throw bignum_error("CBigNum::inverse*= :BN_mod_inverse");
return ret;
}
Expand All @@ -515,7 +522,7 @@ class CBigNum : public BIGNUM
CBigNum gcd( const CBigNum& b) const{
CAutoBN_CTX pctx;
CBigNum ret;
if (!BN_gcd(&ret, this, &b, pctx))
if (!BN_gcd(&ret, pbn, &b, pctx))
throw bignum_error("CBigNum::gcd*= :BN_gcd");
return ret;
}
Expand All @@ -528,26 +535,27 @@ class CBigNum : public BIGNUM
*/
bool isPrime(const int checks=BN_prime_checks) const {
CAutoBN_CTX pctx;
int ret = BN_is_prime(this, checks, NULL, pctx, NULL);
int ret = BN_is_prime_ex(pbn, checks, pctx, NULL);
if(ret < 0){
throw bignum_error("CBigNum::isPrime :BN_is_prime");
throw bignum_error("CBigNum::isPrime :BN_is_prime_ex");
}
return ret;
}

bool isOne() const {
return BN_is_one(this);
bool isOne() const
{
return BN_is_one(pbn);
}


bool operator!() const
{
return BN_is_zero(this);
return BN_is_zero(pbn);
}

CBigNum& operator+=(const CBigNum& b)
{
if (!BN_add(this, this, &b))
if (!BN_add(pbn, pbn, &b))
throw bignum_error("CBigNum::operator+= : BN_add failed");
return *this;
}
Expand All @@ -561,7 +569,7 @@ class CBigNum : public BIGNUM
CBigNum& operator*=(const CBigNum& b)
{
CAutoBN_CTX pctx;
if (!BN_mul(this, this, &b, pctx))
if (!BN_mul(pbn, pbn, &b, pctx))
throw bignum_error("CBigNum::operator*= : BN_mul failed");
return *this;
}
Expand All @@ -580,7 +588,7 @@ class CBigNum : public BIGNUM

CBigNum& operator<<=(unsigned int shift)
{
if (!BN_lshift(this, this, shift))
if (!BN_lshift(pbn, pbn, shift))
throw bignum_error("CBigNum:operator<<= : BN_lshift failed");
return *this;
}
Expand All @@ -591,13 +599,13 @@ class CBigNum : public BIGNUM
// if built on ubuntu 9.04 or 9.10, probably depends on version of OpenSSL
CBigNum a = 1;
a <<= shift;
if (BN_cmp(&a, this) > 0)
if (BN_cmp(&a, pbn) > 0)
{
*this = 0;
return *this;
}

if (!BN_rshift(this, this, shift))
if (!BN_rshift(pbn, pbn, shift))
throw bignum_error("CBigNum:operator>>= : BN_rshift failed");
return *this;
}
Expand All @@ -606,7 +614,7 @@ class CBigNum : public BIGNUM
CBigNum& operator++()
{
// prefix operator
if (!BN_add(this, this, BN_value_one()))
if (!BN_add(pbn, pbn, BN_value_one()))
throw bignum_error("CBigNum::operator++ : BN_add failed");
return *this;
}
Expand All @@ -623,7 +631,7 @@ class CBigNum : public BIGNUM
{
// prefix operator
CBigNum r;
if (!BN_sub(&r, this, BN_value_one()))
if (!BN_sub(&r, pbn, BN_value_one()))
throw bignum_error("CBigNum::operator-- : BN_sub failed");
*this = r;
return *this;
Expand All @@ -637,6 +645,8 @@ class CBigNum : public BIGNUM
return ret;
}

BIGNUM* operator&() { return pbn; }
const BIGNUM* operator&() const { return pbn; }

friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b);
friend inline const CBigNum operator/(const CBigNum& a, const CBigNum& b);
Expand Down
Loading