X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fbignum.h;h=1042758d9709a3252ed5f6723c49ebe3b8218b65;hb=77a43545b4491b9703d803765da9059d2bdd5aaa;hp=6b2bada027911f2268f883574ace6884267c4bc2;hpb=57c556df79e2b413da4715e3867922933083b513;p=novacoin.git diff --git a/src/bignum.h b/src/bignum.h index 6b2bada..1042758 100644 --- a/src/bignum.h +++ b/src/bignum.h @@ -8,8 +8,7 @@ #include #include #include - -#include "util.h" // for uint64 +#include "util.h" /** Errors thrown by the bignum class */ class bignum_error : public std::runtime_error @@ -83,12 +82,10 @@ public: 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(int64 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(uint64 n) { BN_init(this); setuint64(n); } explicit CBigNum(uint256 n) { BN_init(this); setuint256(n); } explicit CBigNum(const std::vector& vch) @@ -156,14 +153,14 @@ public: return (n > (unsigned long)std::numeric_limits::max() ? std::numeric_limits::min() : -(int)n); } - void setint64(int64 sn) + void setint64(int64_t sn) { unsigned char pch[sizeof(sn) + 6]; unsigned char* p = pch + 4; bool fNegative; - uint64 n; + uint64_t n; - if (sn < (int64)0) + if (sn < (int64_t)0) { // 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 n = -(sn + 1); @@ -199,7 +196,7 @@ public: BN_mpi2bn(pch, p - pch, this); } - uint64 getuint64() + uint64_t getuint64() { unsigned int nSize = BN_bn2mpi(this, NULL); if (nSize < 4) @@ -208,13 +205,13 @@ public: BN_bn2mpi(this, &vch[0]); if (vch.size() > 4) vch[4] &= 0x7f; - uint64 n = 0; + uint64_t 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 n) + void setuint64(uint64_t n) { unsigned char pch[sizeof(n) + 6]; unsigned char* p = pch + 4; @@ -241,6 +238,49 @@ public: BN_mpi2bn(pch, p - pch, this); } + void setuint160(uint160 n) + { + unsigned char pch[sizeof(n) + 6]; + unsigned char* p = pch + 4; + bool fLeadingZeroes = true; + unsigned char* pbegin = (unsigned char*)&n; + unsigned char* psrc = pbegin + sizeof(n); + while (psrc != pbegin) + { + unsigned char c = *(--psrc); + if (fLeadingZeroes) + { + if (c == 0) + continue; + if (c & 0x80) + *p++ = 0; + fLeadingZeroes = false; + } + *p++ = c; + } + unsigned int nSize = p - (pch + 4); + pch[0] = (nSize >> 24) & 0xff; + pch[1] = (nSize >> 16) & 0xff; + pch[2] = (nSize >> 8) & 0xff; + pch[3] = (nSize >> 0) & 0xff; + BN_mpi2bn(pch, p - pch, this); + } + + uint160 getuint160() const + { + unsigned int nSize = BN_bn2mpi(this, NULL); + if (nSize < 4) + return 0; + std::vector vch(nSize); + BN_bn2mpi(this, &vch[0]); + if (vch.size() > 4) + vch[4] &= 0x7f; + uint160 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 setuint256(uint256 n) { unsigned char pch[sizeof(n) + 6]; @@ -284,6 +324,24 @@ public: return n; } + void setBytes(const std::vector& vchBytes) + { + BN_bin2bn(&vchBytes[0], vchBytes.size(), this); + } + + std::vector getBytes() const + { + int nBytes = BN_num_bytes(this); + + std::vector vchBytes(nBytes); + + int n = BN_bn2bin(this, &vchBytes[0]); + if (n != nBytes) { + throw bignum_error("CBigNum::getBytes : BN_bn2bin failed"); + } + + return vchBytes; + } void setvch(const std::vector& vch) {