Skip to content
Merged
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
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,11 @@ Bitmark aims to be a relatively stable, user focused crypto currency, which refi

All Bitmark software releases are published through the github release process, you can download the [latest release](https://github.com/project-bitmark/bitmark/releases) from the releases tab above.

##
v0.9.7.3 Dev Version towards: v0.9.7.4, Stable Release, compatible with latest TLS/SSL Libraries

## v0.9.7.4 Works with newer TLS / SSL libraries in Ubuntu 18-20 and Debian 10
This release uses the latest TLS/SSL libraries.
v0.9.7.4, is compatible with all previous 0.9.7.x series versions.


## Eight Algortihm mPoW Hard Fork (v0.9.7)

Expand Down
5 changes: 3 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ AC_PREREQ([2.60])
define(_CLIENT_VERSION_MAJOR, 0)
define(_CLIENT_VERSION_MINOR, 9)
define(_CLIENT_VERSION_REVISION, 7)
define(_CLIENT_VERSION_BUILD, 3)
define(_CLIENT_VERSION_IS_RELEASE, false)
define(_CLIENT_VERSION_BUILD, 4)
define(_CLIENT_VERSION_IS_RELEASE, true)

define(_COPYRIGHT_YEAR, 2021)
AC_INIT([Bitmark Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[info@bitmark.org],[bitmark])
AC_CONFIG_AUX_DIR([src/build-aux])
Expand Down
153 changes: 95 additions & 58 deletions src/bignum.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#include <openssl/bn.h>

#include "util.h" // for uint64

/** Errors thrown by the bignum class */
class bignum_error : public std::runtime_error
{
Expand Down Expand Up @@ -54,75 +56,87 @@ class CAutoBN_CTX


/** C++ wrapper for BIGNUM (OpenSSL bignum) */
class CBigNum : public BIGNUM
class CBigNum
{
protected:
BIGNUM *bn;

void init()
{
bn = BN_new();
}

public:
CBigNum()
{
BN_init(this);
init();
}

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

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

~CBigNum()
{
BN_clear_free(this);
BN_clear_free(bn);
}

//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); }
BIGNUM *operator &() const
{
return bn;
}

CBigNum(signed char n) { init(); if (n >= 0) setulong(n); else setint64(n); }
CBigNum(short n) { init(); if (n >= 0) setulong(n); else setint64(n); }
CBigNum(int n) { init(); if (n >= 0) setulong(n); else setint64(n); }
CBigNum(long n) { init(); if (n >= 0) setulong(n); else setint64(n); }
CBigNum(long long n) { init(); setint64(n); }

CBigNum(unsigned char n) { init(); setulong(n); }
CBigNum(unsigned short n) { init(); setulong(n); }
CBigNum(unsigned int n) { init(); setulong(n); }
CBigNum(unsigned long n) { init(); setulong(n); }
CBigNum(unsigned long long n) { init(); setuint64(n); }
explicit CBigNum(uint256 n) { init(); setuint256(n); }
explicit CBigNum(const std::vector<unsigned char>& vch)
{
BN_init(this);
init();
setvch(vch);
}

void setulong(unsigned long n)
{
if (!BN_set_word(this, n))
if (!BN_set_word(bn, 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(bn);
}

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

int getint() const
{
unsigned long n = BN_get_word(this);
if (!BN_is_negative(this))
unsigned long n = BN_get_word(bn);
if (!BN_is_negative(bn))
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 @@ -170,7 +184,22 @@ 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, bn);
}

uint64 getuint64()
{
unsigned int nSize = BN_bn2mpi(bn, NULL);
if (nSize < 4)
return 0;
std::vector<unsigned char> vch(nSize);
BN_bn2mpi(bn, &vch[0]);
if (vch.size() > 4)
vch[4] &= 0x7f;
uint64 n = 0;
for (unsigned int i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--)
((unsigned char*)&n)[i] = vch[j];
return n;
}

void setuint64(uint64_t n)
Expand All @@ -197,7 +226,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, bn);
}

void setuint256(uint256 n)
Expand Down Expand Up @@ -225,16 +254,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, bn);
}

uint256 getuint256() const
{
unsigned int nSize = BN_bn2mpi(this, NULL);
unsigned int nSize = BN_bn2mpi(bn, NULL);
if (nSize < 4)
return 0;
std::vector<unsigned char> vch(nSize);
BN_bn2mpi(this, &vch[0]);
BN_bn2mpi(bn, &vch[0]);
if (vch.size() > 4)
vch[4] &= 0x7f;
uint256 n = 0;
Expand All @@ -255,16 +284,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(), bn);
}

std::vector<unsigned char> getvch() const
{
unsigned int nSize = BN_bn2mpi(this, NULL);
unsigned int nSize = BN_bn2mpi(bn, NULL);
if (nSize <= 4)
return std::vector<unsigned char>();
std::vector<unsigned char> vch(nSize);
BN_bn2mpi(this, &vch[0]);
BN_bn2mpi(bn, &vch[0]);
vch.erase(vch.begin(), vch.begin() + 4);
reverse(vch.begin(), vch.end());
return vch;
Expand Down Expand Up @@ -300,28 +329,28 @@ class CBigNum : public BIGNUM
if (nSize <= 3)
{
nWord >>= 8*(3-nSize);
BN_set_word(this, nWord);
BN_set_word(bn, nWord);
}
else
{
BN_set_word(this, nWord);
BN_lshift(this, this, 8*(nSize-3));
BN_set_word(bn, nWord);
BN_lshift(bn, bn, 8*(nSize-3));
}
BN_set_negative(this, fNegative);
BN_set_negative(bn, fNegative);
return *this;
}

unsigned int GetCompact() const
{
unsigned int nSize = BN_num_bytes(this);
unsigned int nSize = BN_num_bytes(bn);
unsigned int nCompact = 0;
if (nSize <= 3)
nCompact = BN_get_word(this) << 8*(3-nSize);
nCompact = BN_get_word(bn) << 8*(3-nSize);
else
{
CBigNum bn;
BN_rshift(&bn, this, 8*(nSize-3));
nCompact = BN_get_word(&bn);
CBigNum bn1;
BN_rshift(&bn1, bn, 8*(nSize-3));
nCompact = BN_get_word(&bn1);
}
// The 0x00800000 bit denotes the sign.
// Thus, if it is already set, divide the mantissa by 256 and increase the exponent.
Expand All @@ -331,7 +360,7 @@ class CBigNum : public BIGNUM
nSize++;
}
nCompact |= nSize << 24;
nCompact |= (BN_is_negative(this) ? 0x00800000 : 0);
nCompact |= (BN_is_negative(bn) ? 0x00800000 : 0);
return nCompact;
}

Expand All @@ -353,6 +382,14 @@ class CBigNum : public BIGNUM
psz++;

// hex string to bignum
// 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 };
// *this = 0;
// while (isxdigit(*psz))
// {
// *this <<= 4;
// int n = phexdigit[(unsigned char)*psz++];
// *this += n;
// }
*this = 0;
int n;
while ((n = HexDigit(*psz)) != -1)
Expand All @@ -371,21 +408,21 @@ class CBigNum : public BIGNUM
CBigNum bnBase = nBase;
CBigNum bn0 = 0;
std::string str;
CBigNum bn = *this;
BN_set_negative(&bn, false);
CBigNum bn1 = *this;
BN_set_negative(&bn1, false);
CBigNum dv;
CBigNum rem;
if (BN_cmp(&bn, &bn0) == 0)
if (BN_cmp(&bn1, &bn0) == 0)
return "0";
while (BN_cmp(&bn, &bn0) > 0)
while (BN_cmp(&bn1, &bn0) > 0)
{
if (!BN_div(&dv, &rem, &bn, &bnBase, pctx))
if (!BN_div(&dv, &rem, &bn1, &bnBase, pctx))
throw bignum_error("CBigNum::ToString() : BN_div failed");
bn = dv;
bn1 = dv;
unsigned int c = rem.getulong();
str += "0123456789abcdef"[c];
}
if (BN_is_negative(this))
if (BN_is_negative(bn))
str += "-";
reverse(str.begin(), str.end());
return str;
Expand Down Expand Up @@ -418,12 +455,12 @@ class CBigNum : public BIGNUM

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

CBigNum& operator+=(const CBigNum& b)
{
if (!BN_add(this, this, &b))
if (!BN_add(bn, bn, &b))
throw bignum_error("CBigNum::operator+= : BN_add failed");
return *this;
}
Expand All @@ -437,7 +474,7 @@ class CBigNum : public BIGNUM
CBigNum& operator*=(const CBigNum& b)
{
CAutoBN_CTX pctx;
if (!BN_mul(this, this, &b, pctx))
if (!BN_mul(bn, bn, &b, pctx))
throw bignum_error("CBigNum::operator*= : BN_mul failed");
return *this;
}
Expand All @@ -456,7 +493,7 @@ class CBigNum : public BIGNUM

CBigNum& operator<<=(unsigned int shift)
{
if (!BN_lshift(this, this, shift))
if (!BN_lshift(bn, bn, shift))
throw bignum_error("CBigNum:operator<<= : BN_lshift failed");
return *this;
}
Expand All @@ -467,13 +504,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, bn) > 0)
{
*this = 0;
return *this;
}

if (!BN_rshift(this, this, shift))
if (!BN_rshift(bn, bn, shift))
throw bignum_error("CBigNum:operator>>= : BN_rshift failed");
return *this;
}
Expand All @@ -482,7 +519,7 @@ class CBigNum : public BIGNUM
CBigNum& operator++()
{
// prefix operator
if (!BN_add(this, this, BN_value_one()))
if (!BN_add(bn, bn, BN_value_one()))
throw bignum_error("CBigNum::operator++ : BN_add failed");
return *this;
}
Expand All @@ -499,7 +536,7 @@ class CBigNum : public BIGNUM
{
// prefix operator
CBigNum r;
if (!BN_sub(&r, this, BN_value_one()))
if (!BN_sub(&r, bn, BN_value_one()))
throw bignum_error("CBigNum::operator-- : BN_sub failed");
*this = r;
return *this;
Expand Down
Loading