From 6bd0dc2a845b4d17d5ffabbdadda80d47d6c2dc3 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 19 Dec 2014 13:07:07 +0100 Subject: [PATCH] arith_uint256: remove initialization from byte vector Remove initialization from vector (as this is only used in the tests). Also implement SetHex and GetHex in terms of uint256, to avoid duplicate code as well as avoid endianness issues (as they work in term of bytes). --- src/arith_uint256.cpp | 39 ++------------------------------ src/arith_uint256.h | 2 -- src/test/arith_uint256_tests.cpp | 35 +++++++++++++++------------- 3 files changed, 21 insertions(+), 55 deletions(-) diff --git a/src/arith_uint256.cpp b/src/arith_uint256.cpp index 11df3b05c..1243823da 100644 --- a/src/arith_uint256.cpp +++ b/src/arith_uint256.cpp @@ -17,14 +17,6 @@ base_uint::base_uint(const std::string& str) SetHex(str); } -template -base_uint::base_uint(const std::vector& vch) -{ - if (vch.size() != sizeof(pn)) - throw uint_error("Converting vector of wrong size to base_uint"); - memcpy(pn, &vch[0], sizeof(pn)); -} - template base_uint& base_uint::operator<<=(unsigned int shift) { @@ -154,39 +146,13 @@ double base_uint::getdouble() const template std::string base_uint::GetHex() const { - char psz[sizeof(pn) * 2 + 1]; - for (unsigned int i = 0; i < sizeof(pn); i++) - sprintf(psz + i * 2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]); - return std::string(psz, psz + sizeof(pn) * 2); + return ArithToUint256(*this).GetHex(); } template void base_uint::SetHex(const char* psz) { - memset(pn, 0, sizeof(pn)); - - // skip leading spaces - while (isspace(*psz)) - psz++; - - // skip 0x - if (psz[0] == '0' && tolower(psz[1]) == 'x') - psz += 2; - - // hex string to uint - const char* pbegin = psz; - while (::HexDigit(*psz) != -1) - psz++; - psz--; - unsigned char* p1 = (unsigned char*)pn; - unsigned char* pend = p1 + WIDTH * 4; - while (psz >= pbegin && p1 < pend) { - *p1 = ::HexDigit(*psz--); - if (psz >= pbegin) { - *p1 |= ((unsigned char)::HexDigit(*psz--) << 4); - p1++; - } - } + *this = UintToArith256(uint256S(psz)); } template @@ -218,7 +184,6 @@ unsigned int base_uint::bits() const // Explicit instantiations for base_uint<256> template base_uint<256>::base_uint(const std::string&); -template base_uint<256>::base_uint(const std::vector&); template base_uint<256>& base_uint<256>::operator<<=(unsigned int); template base_uint<256>& base_uint<256>::operator>>=(unsigned int); template base_uint<256>& base_uint<256>::operator*=(uint32_t b32); diff --git a/src/arith_uint256.h b/src/arith_uint256.h index ec8e15997..b6ba3a108 100644 --- a/src/arith_uint256.h +++ b/src/arith_uint256.h @@ -57,7 +57,6 @@ public: } explicit base_uint(const std::string& str); - explicit base_uint(const std::vector& vch); bool operator!() const { @@ -257,7 +256,6 @@ public: arith_uint256(const base_uint<256>& b) : base_uint<256>(b) {} arith_uint256(uint64_t b) : base_uint<256>(b) {} explicit arith_uint256(const std::string& str) : base_uint<256>(str) {} - explicit arith_uint256(const std::vector& vch) : base_uint<256>(vch) {} /** * The "compact" format is a representation of a whole diff --git a/src/test/arith_uint256_tests.cpp b/src/test/arith_uint256_tests.cpp index 689536753..565b02ae6 100644 --- a/src/test/arith_uint256_tests.cpp +++ b/src/test/arith_uint256_tests.cpp @@ -8,41 +8,48 @@ #include #include #include +#include "uint256.h" #include "arith_uint256.h" #include #include "version.h" BOOST_AUTO_TEST_SUITE(arith_uint256_tests) +/// Convert vector to arith_uint256, via uint256 blob +inline arith_uint256 arith_uint256V(const std::vector& vch) +{ + return UintToArith256(uint256(vch)); +} + const unsigned char R1Array[] = "\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2" "\x22\x81\xaa\xb5\x33\xf0\x08\x32\xd5\x56\xb1\xf9\xea\xe5\x1d\x7d"; const char R1ArrayHex[] = "7D1DE5EAF9B156D53208F033B5AA8122D2d2355d5e12292b121156cfdb4a529c"; const double R1Ldouble = 0.4887374590559308955; // R1L equals roughly R1Ldouble * 2^256 -const arith_uint256 R1L = arith_uint256(std::vector(R1Array,R1Array+32)); +const arith_uint256 R1L = arith_uint256V(std::vector(R1Array,R1Array+32)); const uint64_t R1LLow64 = 0x121156cfdb4a529cULL; const unsigned char R2Array[] = "\x70\x32\x1d\x7c\x47\xa5\x6b\x40\x26\x7e\x0a\xc3\xa6\x9c\xb6\xbf" "\x13\x30\x47\xa3\x19\x2d\xda\x71\x49\x13\x72\xf0\xb4\xca\x81\xd7"; -const arith_uint256 R2L = arith_uint256(std::vector(R2Array,R2Array+32)); +const arith_uint256 R2L = arith_uint256V(std::vector(R2Array,R2Array+32)); const char R1LplusR2L[] = "549FB09FEA236A1EA3E31D4D58F1B1369288D204211CA751527CFC175767850C"; const unsigned char ZeroArray[] = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; -const arith_uint256 ZeroL = arith_uint256(std::vector(ZeroArray,ZeroArray+32)); +const arith_uint256 ZeroL = arith_uint256V(std::vector(ZeroArray,ZeroArray+32)); const unsigned char OneArray[] = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; -const arith_uint256 OneL = arith_uint256(std::vector(OneArray,OneArray+32)); +const arith_uint256 OneL = arith_uint256V(std::vector(OneArray,OneArray+32)); const unsigned char MaxArray[] = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"; -const arith_uint256 MaxL = arith_uint256(std::vector(MaxArray,MaxArray+32)); +const arith_uint256 MaxL = arith_uint256V(std::vector(MaxArray,MaxArray+32)); const arith_uint256 HalfL = (OneL << 255); std::string ArrayToString(const unsigned char A[], unsigned int width) @@ -112,10 +119,6 @@ BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality tmpL = ~R1L; BOOST_CHECK(tmpL == ~R1L); tmpL = ~R2L; BOOST_CHECK(tmpL == ~R2L); tmpL = ~MaxL; BOOST_CHECK(tmpL == ~MaxL); - - // Wrong length must throw exception. - BOOST_CHECK_THROW(arith_uint256(std::vector(OneArray,OneArray+31)), uint_error); - BOOST_CHECK_THROW(arith_uint256(std::vector(OneArray,OneArray+20)), uint_error); } void shiftArrayRight(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift) @@ -155,7 +158,7 @@ BOOST_AUTO_TEST_CASE( shifts ) { // "<<" ">>" "<<=" ">>=" for (unsigned int i = 0; i < 256; ++i) { shiftArrayLeft(TmpArray, OneArray, 32, i); - BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (OneL << i)); + BOOST_CHECK(arith_uint256V(std::vector(TmpArray,TmpArray+32)) == (OneL << i)); TmpL = OneL; TmpL <<= i; BOOST_CHECK(TmpL == (OneL << i)); BOOST_CHECK((HalfL >> (255-i)) == (OneL << i)); @@ -163,22 +166,22 @@ BOOST_AUTO_TEST_CASE( shifts ) { // "<<" ">>" "<<=" ">>=" BOOST_CHECK(TmpL == (OneL << i)); shiftArrayLeft(TmpArray, R1Array, 32, i); - BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (R1L << i)); + BOOST_CHECK(arith_uint256V(std::vector(TmpArray,TmpArray+32)) == (R1L << i)); TmpL = R1L; TmpL <<= i; BOOST_CHECK(TmpL == (R1L << i)); shiftArrayRight(TmpArray, R1Array, 32, i); - BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (R1L >> i)); + BOOST_CHECK(arith_uint256V(std::vector(TmpArray,TmpArray+32)) == (R1L >> i)); TmpL = R1L; TmpL >>= i; BOOST_CHECK(TmpL == (R1L >> i)); shiftArrayLeft(TmpArray, MaxArray, 32, i); - BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (MaxL << i)); + BOOST_CHECK(arith_uint256V(std::vector(TmpArray,TmpArray+32)) == (MaxL << i)); TmpL = MaxL; TmpL <<= i; BOOST_CHECK(TmpL == (MaxL << i)); shiftArrayRight(TmpArray, MaxArray, 32, i); - BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (MaxL >> i)); + BOOST_CHECK(arith_uint256V(std::vector(TmpArray,TmpArray+32)) == (MaxL >> i)); TmpL = MaxL; TmpL >>= i; BOOST_CHECK(TmpL == (MaxL >> i)); } @@ -205,7 +208,7 @@ BOOST_AUTO_TEST_CASE( unaryOperators ) // ! ~ - unsigned char TmpArray[32]; for (unsigned int i = 0; i < 32; ++i) { TmpArray[i] = ~R1Array[i]; } - BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (~R1L)); + BOOST_CHECK(arith_uint256V(std::vector(TmpArray,TmpArray+32)) == (~R1L)); BOOST_CHECK(-ZeroL == ZeroL); BOOST_CHECK(-R1L == (~R1L)+1); @@ -218,7 +221,7 @@ BOOST_AUTO_TEST_CASE( unaryOperators ) // ! ~ - // element of Aarray and Barray, and then converting the result into a arith_uint256. #define CHECKBITWISEOPERATOR(_A_,_B_,_OP_) \ for (unsigned int i = 0; i < 32; ++i) { TmpArray[i] = _A_##Array[i] _OP_ _B_##Array[i]; } \ - BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (_A_##L _OP_ _B_##L)); + BOOST_CHECK(arith_uint256V(std::vector(TmpArray,TmpArray+32)) == (_A_##L _OP_ _B_##L)); #define CHECKASSIGNMENTOPERATOR(_A_,_B_,_OP_) \ TmpL = _A_##L; TmpL _OP_##= _B_##L; BOOST_CHECK(TmpL == (_A_##L _OP_ _B_##L));