diff --git a/Builds/VisualStudio2015/RippleD.vcxproj b/Builds/VisualStudio2015/RippleD.vcxproj
index e1aaf544cc..70a2c5b51f 100644
--- a/Builds/VisualStudio2015/RippleD.vcxproj
+++ b/Builds/VisualStudio2015/RippleD.vcxproj
@@ -2079,20 +2079,12 @@
-
-
-
-
-
- True
- True
-
True
True
@@ -2137,10 +2129,6 @@
-
- True
- True
-
True
True
diff --git a/Builds/VisualStudio2015/RippleD.vcxproj.filters b/Builds/VisualStudio2015/RippleD.vcxproj.filters
index 20e2439c7f..472d40ac00 100644
--- a/Builds/VisualStudio2015/RippleD.vcxproj.filters
+++ b/Builds/VisualStudio2015/RippleD.vcxproj.filters
@@ -2604,12 +2604,6 @@
ripple\core
-
- ripple\crypto
-
-
- ripple\crypto
-
ripple\crypto
@@ -2619,9 +2613,6 @@
ripple\crypto
-
- ripple\crypto\impl
-
ripple\crypto\impl
@@ -2664,9 +2655,6 @@
ripple\crypto
-
- ripple\crypto\tests
-
ripple\crypto\tests
diff --git a/src/ripple/crypto/CAutoBN_CTX.h b/src/ripple/crypto/CAutoBN_CTX.h
deleted file mode 100644
index 7db906c81f..0000000000
--- a/src/ripple/crypto/CAutoBN_CTX.h
+++ /dev/null
@@ -1,80 +0,0 @@
-//------------------------------------------------------------------------------
-/*
- This file is part of rippled: https://github.com/ripple/rippled
- Copyright (c) 2012, 2013 Ripple Labs Inc.
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-//==============================================================================
-
-// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2011 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-#ifndef RIPPLE_CRYPTO_CAUTOBN_CTX_H_INCLUDED
-#define RIPPLE_CRYPTO_CAUTOBN_CTX_H_INCLUDED
-
-#include
-
-#include
-
-#include
-#include
-
-namespace ripple {
-
-class CAutoBN_CTX
-{
-protected:
- BN_CTX* pctx;
-
-public:
- CAutoBN_CTX ()
- {
- pctx = BN_CTX_new ();
-
- if (pctx == nullptr)
- Throw ("CAutoBN_CTX : BN_CTX_new() returned nullptr");
- }
-
- ~CAutoBN_CTX ()
- {
- if (pctx != nullptr)
- BN_CTX_free (pctx);
- }
-
- CAutoBN_CTX (CAutoBN_CTX const&) = delete;
- CAutoBN_CTX& operator= (CAutoBN_CTX const&) = delete;
-
- operator BN_CTX* ()
- {
- return pctx;
- }
- BN_CTX& operator* ()
- {
- return *pctx;
- }
- BN_CTX** operator& ()
- {
- return &pctx;
- }
- bool operator! ()
- {
- return (pctx == nullptr);
- }
-};
-
-}
-
-#endif
diff --git a/src/ripple/crypto/CBigNum.h b/src/ripple/crypto/CBigNum.h
deleted file mode 100644
index 213bfb9ae1..0000000000
--- a/src/ripple/crypto/CBigNum.h
+++ /dev/null
@@ -1,119 +0,0 @@
-//------------------------------------------------------------------------------
-/*
- This file is part of rippled: https://github.com/ripple/rippled
- Copyright (c) 2012, 2013 Ripple Labs Inc.
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-//==============================================================================
-
-// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2011 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-#ifndef RIPPLE_CRYPTO_CBIGNUM_H_INCLUDED
-#define RIPPLE_CRYPTO_CBIGNUM_H_INCLUDED
-
-#include
-#include
-
-namespace ripple {
-
-// VFALCO TODO figure out a way to remove the dependency on openssl in the
-// header. Maybe rewrite this to use cryptopp.
-
-class CBigNum : public BIGNUM
-{
-public:
- CBigNum ();
- CBigNum (const CBigNum& b);
- CBigNum& operator= (const CBigNum& b);
- CBigNum (char n);
- CBigNum (short n);
- CBigNum (int n);
- CBigNum (long n);
- CBigNum (long long n);
- CBigNum (unsigned char n);
- CBigNum (unsigned short n);
- CBigNum (unsigned int n);
- CBigNum (unsigned long long n);
- explicit CBigNum (uint256 n);
- explicit CBigNum (Blob const& vch);
- explicit CBigNum (BIGNUM const* b);
- CBigNum (unsigned char const* begin, unsigned char const* end);
- ~CBigNum ();
-
- void setuint (unsigned int n);
- unsigned int getuint () const;
- int getint () const;
- void setint64 (std::int64_t n);
- std::uint64_t getuint64 () const;
- void setuint64 (std::uint64_t n);
- void setuint256 (uint256 const& n);
- uint256 getuint256 ();
- void setvch (unsigned char const* begin, unsigned char const* end);
- void setvch (Blob const& vch);
- Blob getvch () const;
- CBigNum& SetCompact (unsigned int nCompact);
- unsigned int GetCompact () const;
- void SetHex (std::string const& str);
- std::string ToString (int nBase = 10) const;
- std::string GetHex () const;
- bool operator! () const;
- CBigNum& operator+= (const CBigNum& b);
- CBigNum& operator-= (const CBigNum& b);
- CBigNum& operator*= (const CBigNum& b);
- CBigNum& operator/= (const CBigNum& b);
- CBigNum& operator%= (const CBigNum& b);
- CBigNum& operator<<= (unsigned int shift);
- CBigNum& operator>>= (unsigned int shift);
- CBigNum& operator++ ();
- CBigNum& operator-- ();
- const CBigNum operator++ (int);
- const CBigNum operator-- (int);
-
-private:
- // private because the size of an unsigned long varies by platform
-
- void setulong (unsigned long n);
- unsigned long getulong () const;
-};
-
-const CBigNum operator+ (const CBigNum& a, const CBigNum& b);
-const CBigNum operator- (const CBigNum& a, const CBigNum& b);
-const CBigNum operator- (const CBigNum& a);
-const CBigNum operator* (const CBigNum& a, const CBigNum& b);
-const CBigNum operator/ (const CBigNum& a, const CBigNum& b);
-const CBigNum operator% (const CBigNum& a, const CBigNum& b);
-const CBigNum operator<< (const CBigNum& a, unsigned int shift);
-const CBigNum operator>> (const CBigNum& a, unsigned int shift);
-
-bool operator== (const CBigNum& a, const CBigNum& b);
-bool operator!= (const CBigNum& a, const CBigNum& b);
-bool operator<= (const CBigNum& a, const CBigNum& b);
-bool operator>= (const CBigNum& a, const CBigNum& b);
-bool operator< (const CBigNum& a, const CBigNum& b);
-bool operator> (const CBigNum& a, const CBigNum& b);
-
-//------------------------------------------------------------------------------
-
-// Only STAmount uses these (January 2016).
-int BN_add_word64 (BIGNUM* a, std::uint64_t w);
-int BN_sub_word64 (BIGNUM* a, std::uint64_t w);
-int BN_mul_word64 (BIGNUM* a, std::uint64_t w);
-int BN_div_word64 (BIGNUM* a, std::uint64_t w);
-
-}
-
-#endif
diff --git a/src/ripple/crypto/impl/CBigNum.cpp b/src/ripple/crypto/impl/CBigNum.cpp
deleted file mode 100644
index 44aa8fed2f..0000000000
--- a/src/ripple/crypto/impl/CBigNum.cpp
+++ /dev/null
@@ -1,689 +0,0 @@
-//------------------------------------------------------------------------------
-/*
- This file is part of rippled: https://github.com/ripple/rippled
- Copyright (c) 2012, 2013 Ripple Labs Inc.
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-//==============================================================================
-
-// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2011 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-namespace ripple {
-
-CBigNum::CBigNum ()
-{
- BN_init (this);
-}
-
-CBigNum::CBigNum (const CBigNum& b)
-: CBigNum (&b)
-{ }
-
-CBigNum& CBigNum::operator= (const CBigNum& b)
-{
- if (!BN_copy (this, &b))
- Throw ("CBigNum::operator= : BN_copy failed");
-
- return (*this);
-}
-
-CBigNum::~CBigNum ()
-{
- BN_clear_free (this);
-}
-
-CBigNum::CBigNum (char n)
-{
- BN_init (this);
-
- if (n >= 0) setulong (n);
- else setint64 (n);
-}
-CBigNum::CBigNum (short n)
-{
- BN_init (this);
-
- if (n >= 0) setulong (n);
- else setint64 (n);
-}
-CBigNum::CBigNum (int n)
-{
- BN_init (this);
-
- if (n >= 0) setulong (n);
- else setint64 (n);
-}
-CBigNum::CBigNum (long n)
-{
- BN_init (this);
-
- if (n >= 0) setulong (n);
- else setint64 (n);
-}
-CBigNum::CBigNum (long long n)
-{
- BN_init (this);
- setint64 (n);
-}
-CBigNum::CBigNum (unsigned char n)
-{
- BN_init (this);
- setulong (n);
-}
-CBigNum::CBigNum (unsigned short n)
-{
- BN_init (this);
- setulong (n);
-}
-CBigNum::CBigNum (unsigned int n)
-{
- BN_init (this);
- setulong (n);
-}
-CBigNum::CBigNum (unsigned long long n)
-{
- BN_init (this);
- setuint64 (n);
-}
-CBigNum::CBigNum (uint256 n)
-{
- BN_init (this);
- setuint256 (n);
-}
-
-CBigNum::CBigNum (Blob const& vch)
-{
- BN_init (this);
- setvch (&vch.front(), &vch.back()+1);
-}
-
-CBigNum::CBigNum (BIGNUM const* b)
-{
- BN_init (this);
-
- if (!BN_copy (this, b))
- {
- BN_clear_free (this);
- Throw ("CBigNum::CBigNum(BIGNUM const* b) : BN_copy failed");
- }
-}
-
-CBigNum::CBigNum (unsigned char const* begin, unsigned char const* end)
-{
- BN_init (this);
- setvch (begin, end);
-}
-
-void CBigNum::setuint (unsigned int n)
-{
- setulong (static_cast (n));
-}
-
-unsigned int CBigNum::getuint () const
-{
- return BN_get_word (this);
-}
-
-int CBigNum::getint () const
-{
- unsigned long n = BN_get_word (this);
-
- if (!BN_is_negative (this))
- return (n > INT_MAX ? INT_MAX : n);
- else
- return (n > INT_MAX ? INT_MIN : - (int)n);
-}
-
-void CBigNum::setint64 (std::int64_t n)
-{
- unsigned char pch[sizeof (n) + 6];
- unsigned char* p = pch + 4;
- bool fNegative = false;
-
- if (n < (std::int64_t)0)
- {
- n = -n;
- fNegative = true;
- }
-
- bool fLeadingZeroes = true;
-
- for (int i = 0; i < 8; i++)
- {
- unsigned char c = (n >> 56) & 0xff;
- n <<= 8;
-
- if (fLeadingZeroes)
- {
- if (c == 0)
- continue;
-
- if (c & 0x80)
- *p++ = (fNegative ? 0x80 : 0);
- else if (fNegative)
- c |= 0x80;
-
- 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) & 0xff;
- BN_mpi2bn (pch, p - pch, this);
-}
-
-std::uint64_t CBigNum::getuint64 () const
-{
-#if (ULONG_MAX > UINT_MAX)
- return static_cast (getulong ());
-#else
- int len = BN_num_bytes (this);
-
- if (len > 8)
- Throw ("BN getuint64 overflow");
-
- unsigned char buf[8];
- memset (buf, 0, sizeof (buf));
- BN_bn2bin (this, buf + 8 - len);
- return
- static_cast (buf[0]) << 56 | static_cast (buf[1]) << 48 |
- static_cast (buf[2]) << 40 | static_cast (buf[3]) << 32 |
- static_cast (buf[4]) << 24 | static_cast (buf[5]) << 16 |
- static_cast (buf[6]) << 8 | static_cast (buf[7]);
-#endif
-}
-
-void CBigNum::setuint64 (std::uint64_t n)
-{
-#if (ULONG_MAX > UINT_MAX)
- setulong (static_cast (n));
-#else
- unsigned char buf[8];
- buf[0] = static_cast ((n >> 56) & 0xff);
- buf[1] = static_cast ((n >> 48) & 0xff);
- buf[2] = static_cast ((n >> 40) & 0xff);
- buf[3] = static_cast ((n >> 32) & 0xff);
- buf[4] = static_cast ((n >> 24) & 0xff);
- buf[5] = static_cast ((n >> 16) & 0xff);
- buf[6] = static_cast ((n >> 8) & 0xff);
- buf[7] = static_cast ((n) & 0xff);
- BN_bin2bn (buf, 8, this);
-#endif
-}
-
-void CBigNum::setuint256 (uint256 const& n)
-{
- BN_bin2bn (n.begin (), n.size (), this);
-}
-
-uint256 CBigNum::getuint256 ()
-{
- uint256 ret;
- unsigned int size = BN_num_bytes (this);
-
- if (size > ret.size ())
- return ret;
-
- BN_bn2bin (this, ret.begin () + (ret.size () - BN_num_bytes (this)));
- return ret;
-}
-
-void CBigNum::setvch (unsigned char const* begin, unsigned char const* end)
-{
- std::size_t const size (std::distance (begin, end));
- Blob vch2 (size + 4);
- unsigned int nSize (size);
- // BIGNUM's byte stream format expects 4 bytes of
- // big endian size data info at the front
- vch2[0] = (nSize >> 24) & 0xff;
- vch2[1] = (nSize >> 16) & 0xff;
- vch2[2] = (nSize >> 8) & 0xff;
- vch2[3] = (nSize >> 0) & 0xff;
- // swap data to big endian
- std::reverse_copy (begin, end, vch2.begin() + 4);
- BN_mpi2bn (&vch2[0], vch2.size (), this);
-}
-
-void CBigNum::setvch (Blob const& vch)
-{
- setvch (&vch.front(), &vch.back()+1);
-}
-
-Blob CBigNum::getvch () const
-{
- unsigned int nSize = BN_bn2mpi (this, nullptr);
-
- if (nSize < 4)
- return Blob ();
-
- Blob vch (nSize);
- BN_bn2mpi (this, &vch[0]);
- vch.erase (vch.begin (), vch.begin () + 4);
- reverse (vch.begin (), vch.end ());
- return vch;
-}
-
-CBigNum& CBigNum::SetCompact (unsigned int nCompact)
-{
- unsigned int nSize = nCompact >> 24;
- Blob vch (4 + nSize);
- vch[3] = nSize;
-
- 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);
- return *this;
-}
-
-unsigned int CBigNum::GetCompact () const
-{
- unsigned int nSize = BN_bn2mpi (this, nullptr);
- Blob vch (nSize);
- nSize -= 4;
- BN_bn2mpi (this, &vch[0]);
- unsigned int nCompact = nSize << 24;
-
- if (nSize >= 1) nCompact |= (vch[4] << 16);
-
- if (nSize >= 2) nCompact |= (vch[5] << 8);
-
- if (nSize >= 3) nCompact |= (vch[6] << 0);
-
- return nCompact;
-}
-
-void CBigNum::SetHex (std::string const& str)
-{
- // skip 0x
- const char* psz = str.c_str ();
-
- while (isspace (*psz))
- psz++;
-
- bool fNegative = false;
-
- if (*psz == '-')
- {
- fNegative = true;
- psz++;
- }
-
- if (psz[0] == '0' && tolower (psz[1]) == 'x')
- psz += 2;
-
- while (isspace (*psz))
- psz++;
-
- // hex string to bignum
- static 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[ (int) * psz++];
- *this += n;
- }
-
- if (fNegative)
- *this = 0 - *this;
-}
-
-std::string CBigNum::ToString (int nBase) const
-{
- CAutoBN_CTX pctx;
- CBigNum bnBase = nBase;
- CBigNum bn0 = 0;
- std::string str;
- CBigNum bn = *this;
- BN_set_negative (&bn, false);
- CBigNum dv;
- CBigNum rem;
-
- if (BN_cmp (&bn, &bn0) == 0)
- return "0";
-
- while (BN_cmp (&bn, &bn0) > 0)
- {
- if (!BN_div (&dv, &rem, &bn, &bnBase, pctx))
- Throw ("CBigNum::ToString() : BN_div failed");
-
- bn = dv;
- unsigned int c = rem.getuint ();
- str += "0123456789abcdef"[c];
- }
-
- if (BN_is_negative (this))
- str += "-";
-
- reverse (str.begin (), str.end ());
- return str;
-}
-
-std::string CBigNum::GetHex () const
-{
- return ToString (16);
-}
-
-bool CBigNum::operator! () const
-{
- return BN_is_zero (this);
-}
-
-CBigNum& CBigNum::operator+= (const CBigNum& b)
-{
- if (!BN_add (this, this, &b))
- Throw ("CBigNum::operator+= : BN_add failed");
-
- return *this;
-}
-
-CBigNum& CBigNum::operator-= (const CBigNum& b)
-{
- *this = *this - b;
- return *this;
-}
-
-CBigNum& CBigNum::operator*= (const CBigNum& b)
-{
- CAutoBN_CTX pctx;
-
- if (!BN_mul (this, this, &b, pctx))
- Throw ("CBigNum::operator*= : BN_mul failed");
-
- return *this;
-}
-
-CBigNum& CBigNum::operator/= (const CBigNum& b)
-{
- *this = *this / b;
- return *this;
-}
-
-CBigNum& CBigNum::operator%= (const CBigNum& b)
-{
- *this = *this % b;
- return *this;
-}
-
-CBigNum& CBigNum::operator<<= (unsigned int shift)
-{
- if (!BN_lshift (this, this, shift))
- Throw ("CBigNum:operator<<= : BN_lshift failed");
-
- return *this;
-}
-
-CBigNum& CBigNum::operator>>= (unsigned int shift)
-{
- // Note: BN_rshift segfaults on 64-bit if 2^shift is greater than the number
- // 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)
- {
- *this = 0;
- return *this;
- }
-
- if (! BN_rshift (this, this, shift))
- Throw ("CBigNum:operator>>= : BN_rshift failed");
-
- return *this;
-}
-
-
-CBigNum& CBigNum::operator++ ()
-{
- // prefix operator
- if (! BN_add (this, this, BN_value_one ()))
- Throw ("CBigNum::operator++ : BN_add failed");
-
- return *this;
-}
-
-const CBigNum CBigNum::operator++ (int)
-{
- // postfix operator
- const CBigNum ret = *this;
- ++ (*this);
- return ret;
-}
-
-CBigNum& CBigNum::operator-- ()
-{
- // prefix operator
- CBigNum r;
-
- if (! BN_sub (&r, this, BN_value_one ()))
- Throw ("CBigNum::operator-- : BN_sub failed");
-
- *this = r;
- return *this;
-}
-
-const CBigNum CBigNum::operator-- (int)
-{
- // postfix operator
- const CBigNum ret = *this;
- -- (*this);
- return ret;
-}
-
-void CBigNum::setulong (unsigned long n)
-{
- if (! BN_set_word (this, n))
- Throw (
- "CBigNum conversion from unsigned long : BN_set_word failed");
-}
-
-unsigned long CBigNum::getulong () const
-{
- return BN_get_word (this);
-}
-
-const CBigNum operator+ (const CBigNum& a, const CBigNum& b)
-{
- CBigNum r;
-
- if (! BN_add (&r, &a, &b))
- Throw ("CBigNum::operator+ : BN_add failed");
-
- return r;
-}
-
-const CBigNum operator- (const CBigNum& a, const CBigNum& b)
-{
- CBigNum r;
-
- if (! BN_sub (&r, &a, &b))
- Throw ("CBigNum::operator- : BN_sub failed");
-
- return r;
-}
-
-const CBigNum operator- (const CBigNum& a)
-{
- CBigNum r (a);
- BN_set_negative (&r, !BN_is_negative (&r));
- return r;
-}
-
-const CBigNum operator* (const CBigNum& a, const CBigNum& b)
-{
- CAutoBN_CTX pctx;
- CBigNum r;
-
- if (! BN_mul (&r, &a, &b, pctx))
- Throw ("CBigNum::operator* : BN_mul failed");
-
- return r;
-}
-
-const CBigNum operator/ (const CBigNum& a, const CBigNum& b)
-{
- CAutoBN_CTX pctx;
- CBigNum r;
-
- if (! BN_div (&r, nullptr, &a, &b, pctx))
- Throw ("CBigNum::operator/ : BN_div failed");
-
- return r;
-}
-
-const CBigNum operator% (const CBigNum& a, const CBigNum& b)
-{
- CAutoBN_CTX pctx;
- CBigNum r;
-
- if (! BN_mod (&r, &a, &b, pctx))
- Throw ("CBigNum::operator% : BN_div failed");
-
- return r;
-}
-
-const CBigNum operator<< (const CBigNum& a, unsigned int shift)
-{
- CBigNum r;
-
- if (! BN_lshift (&r, &a, shift))
- Throw ("CBigNum:operator<< : BN_lshift failed");
-
- return r;
-}
-
-const CBigNum operator>> (const CBigNum& a, unsigned int shift)
-{
- CBigNum r = a;
- r >>= shift;
- return r;
-}
-
-bool operator== (const CBigNum& a, const CBigNum& b)
-{
- return (BN_cmp (&a, &b) == 0);
-}
-
-bool operator!= (const CBigNum& a, const CBigNum& b)
-{
- return (BN_cmp (&a, &b) != 0);
-}
-
-bool operator<= (const CBigNum& a, const CBigNum& b)
-{
- return (BN_cmp (&a, &b) <= 0);
-}
-
-bool operator>= (const CBigNum& a, const CBigNum& b)
-{
- return (BN_cmp (&a, &b) >= 0);
-}
-
-bool operator< (const CBigNum& a, const CBigNum& b)
-{
- return (BN_cmp (&a, &b) < 0);
-}
-
-bool operator> (const CBigNum& a, const CBigNum& b)
-{
- return (BN_cmp (&a, &b) > 0);
-}
-
-#if (ULONG_MAX > UINT_MAX)
-
-int BN_add_word64 (BIGNUM* bn, std::uint64_t word)
-{
- return BN_add_word (bn, word);
-}
-
-int BN_sub_word64 (BIGNUM* bn, std::uint64_t word)
-{
- return BN_sub_word (bn, word);
-}
-
-int BN_mul_word64 (BIGNUM* bn, std::uint64_t word)
-{
- return BN_mul_word (bn, word);
-}
-
-// This function returns 1 on success like the three preceding functions.
-// In contrast, BN_div_word returns ( BN_ULONG )-1 on error.
-int BN_div_word64 (BIGNUM* bn, std::uint64_t word)
-{
- BN_ULONG const remainder {BN_div_word (bn, word)};
- return remainder == static_cast(-1) ? 0 : 1;
-}
-
-#else
-
-int BN_add_word64 (BIGNUM* a, std::uint64_t w)
-{
- CBigNum bn (w);
- return BN_add (a, a, &bn);
-}
-
-int BN_sub_word64 (BIGNUM* a, std::uint64_t w)
-{
- CBigNum bn (w);
- return BN_sub (a, a, &bn);
-}
-
-int BN_mul_word64 (BIGNUM* a, std::uint64_t w)
-{
- CBigNum bn (w);
- CAutoBN_CTX ctx;
- return BN_mul (a, a, &bn, ctx);
-}
-
-int BN_div_word64 (BIGNUM* a, std::uint64_t w)
-{
- CBigNum bn (w);
- CBigNum temp (a); // Copy a. Destination may not be the same as dividend.
- CAutoBN_CTX ctx;
- return BN_div (a, nullptr, &temp, &bn, ctx);
-}
-
-#endif
-
-}
diff --git a/src/ripple/crypto/tests/CBigNum_test.cpp b/src/ripple/crypto/tests/CBigNum_test.cpp
deleted file mode 100644
index a573312866..0000000000
--- a/src/ripple/crypto/tests/CBigNum_test.cpp
+++ /dev/null
@@ -1,580 +0,0 @@
-//------------------------------------------------------------------------------
-/*
- This file is part of rippled: https://github.com/ripple/rippled
- Copyright (c) 2016 Ripple Labs Inc.
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-//==============================================================================
-
-#include
-#include
-#include
-#include
-
-namespace ripple {
-
-class CBigNum_test : public beast::unit_test::suite
-{
-private:
- // Generic test for constructing CBigNum from native types.
- template
- void
- testNativeCtor()
- {
- static_assert (std::numeric_limits::is_integer, "Requires int type");
- if (std::numeric_limits::is_signed)
- {
- CBigNum const neg (static_cast(std::numeric_limits::min()));
- this->expect (neg == std::numeric_limits::min());
- this->expect (neg < 0);
- }
- else
- {
- CBigNum const naught (static_cast(0));
- this->expect (naught == 0);
- }
- CBigNum const big (static_cast(std::numeric_limits::max()));
- this->expect (big == std::numeric_limits::max());
- this->expect (big > 0);
- }
-
- // Return pointer to start of array.
- template
- static auto
- array_cbegin(T (&a)[N]) -> T const*
- {
- return &a[0];
- }
-
- // Return pointer to one past end of array.
- template
- static auto
- array_cend(T (&a)[N]) -> T const*
- {
- return &a[N];
- }
-
-public:
- void
- run ()
- {
- {
- // Default constructor.
- CBigNum const big0;
- expect (big0 == 0);
- // Construct from unsigned char.
- CBigNum const big1 (static_cast(1));
- expect (big1 == 1);
- // Assignment.
- CBigNum bigA;
- bigA = big1;
- expect (bigA == big1);
- }
- {
- // Test constructing from native types.
- testNativeCtor();
- testNativeCtor();
- testNativeCtor();
- testNativeCtor();
- testNativeCtor();
- testNativeCtor();
- testNativeCtor();
-// testNativeCtor(); // unsigned long not supported
- testNativeCtor();
- testNativeCtor();
- }
- {
- // Construction from uint256.
- uint256 const naught256 (0);
- uint256 big256 = naught256;
- --big256;
- CBigNum naught (naught256);
- expect (naught == 0);
- CBigNum big (big256);
- expect (big.GetHex() == "ffffffff"
- "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
- }
- {
- // Construction from Blob.
- Blob const naughtBlob (67, 0);
- Blob const bigBlob (40, 255);
- CBigNum const naught (naughtBlob);
- expect (naught == 0);
- CBigNum big (bigBlob);
- expect (big.GetHex() == "-7fffffffffffffffffffffff"
- "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
- }
- {
- // Construction from BIGNUM*.
- BIGNUM b;
- BN_init (&b);
- // Scope guard to free b when we leave scope.
- std::shared_ptr guard (nullptr, [&b] (void*)
- {
- BN_clear_free (&b);
- });
- expect (BN_set_word (&b, 0x123456789ABCDF0ull) == 1);
- CBigNum big (&b);
- --big;
- expect (BN_cmp (&big, &b) == -1);
- ++big;
- expect (BN_cmp (&big, &b) == 0);
- ++big;
- expect (BN_cmp (&big, &b) == 1);
- }
- {
- // Construction from unsigned char*.
- static unsigned char const a[] {0x0,0xF,
- 0xE,0xD,0xC,0xB,0xA,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0};
- CBigNum big (array_cbegin(a), array_cend(a));
- expect (big.GetHex() == "102030405060708090a0b0c0d0e0f00");
- }
- {
- // setuint() and getuint().
- CBigNum big;
- expect (big.getuint() == 0);
- --big;
- // Note that getuint() does not throw an exception on underflow.
- expect (big.getuint() == 1);
-
- unsigned int const biggest_uint =
- std::numeric_limits::max();
- big.setuint (biggest_uint);
- expect (big.getuint() == biggest_uint);
- // Note that getuint() does not throw an exception on overflow.
- ++big;
- expect (big.getuint() == 0);
- }
- {
- // getint().
- CBigNum neg (std::numeric_limits::min());
- expect (neg.getint() == std::numeric_limits::min());
- // Note that getint() limits at INT_MIN on negative overflow.
- --neg;
- expect (neg.getint() == std::numeric_limits::min());
-
- CBigNum pos (std::numeric_limits::max());
- expect (pos.getint() == std::numeric_limits::max());
- // Note that getint() limits at INT_MAX on positive overflow.
- ++pos;
- expect (pos.getint() == std::numeric_limits::max());
- }
- {
- // setint64().
- CBigNum big;
- big.setint64 (std::numeric_limits::min());
- expect (big.GetHex() == "-8000000000000000");
- --big;
- expect (big.GetHex() == "-8000000000000001");
-
- big.setint64 (std::numeric_limits::max());
- expect (big.GetHex() == "7fffffffffffffff");
- ++big;
- expect (big.GetHex() == "8000000000000000");
- }
- {
- // setuint64() and getuint64().
- CBigNum big;
- big.setuint64 (static_cast(0));
- expect (big.getuint64() == 0);
- // Note that getuint64() drops the sign.
- --big;
- expect (big.getuint64() == 1);
-
- big.setuint64 (std::numeric_limits::max());
- expect (
- big.getuint64() == std::numeric_limits::max());
- // Note that one some platforms getuint() throws on positive
- // overflow and on other platforms it does not. Hence the macro.
- ++big;
-#if (ULONG_MAX > UINT_MAX)
- expect (
- big.getuint64() == std::numeric_limits::max());
-#else
- bool overflowException = false;
- try
- {
- big.getuint64();
- }
- catch (std::runtime_error const&)
- {
- overflowException = true;
- }
- expect (overflowException);
-#endif
- }
- {
- // setuint256() and getuint256().
- uint256 const naught256 (Blob (32, 0));
- uint256 const max256 (Blob (32, 0xFF));
-
- CBigNum big;
- big.setuint256(max256);
- expect (big.GetHex() == "ffffffffffffffff"
- "ffffffffffffffffffffffffffffffffffffffffffffffff");
- expect (big.getuint256() == max256);
-
- // Note that getuint256() returns zero on overflow.
- ++big;
- expect (big.GetHex() == "1000000000000000"
- "0000000000000000000000000000000000000000000000000");
- expect (big.getuint256() == naught256);
-
- --big;
- expect (big.getuint256() == max256);
-
- big.setuint256(naught256);
- expect (big == 0);
- expect (big.getuint256() == naught256);
- --big;
- expect (big == -1);
- ++big;
- expect (big.getuint256() == naught256);
- }
- {
- // setvch() and getvch().
- CBigNum big;
- expect (big.getvch().size() == 0);
-
- // Small values.
- static unsigned char const one[] {1,0};
- big.setvch(array_cbegin(one), array_cend(one));
- expect (big == 1);
- --big;
- expect (big.getvch().size() == 0);
- --big;
- Blob smallBlob = big.getvch();
- expect (smallBlob.size() == 1);
- expect (smallBlob[0] ==0x81);
- smallBlob[0] = 0xff;
- expect (big == -1);
- big.setvch(smallBlob);
- expect (big == -127);
- expect (big.getvch().size() == 1);
-
- // Big values
- static unsigned char const large[80] {
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
- };
- static unsigned char const larger[81] {
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00
- };
-
- big.setvch (array_cbegin(large), array_cend(large));
- CBigNum bigger;
- bigger.setvch(array_cbegin(larger), array_cend(larger));
- expect (big > 0);
- expect (big < bigger);
-
- Blob bigBlob = big.getvch();
- expect (bigBlob.size() == 80);
- expect (bigBlob.back() == 0x7f);
-
- ++big;
- expect (big == bigger);
- bigBlob = big.getvch();
- expect (bigBlob.size() == 81);
- expect (std::equal(array_cbegin(larger), array_cend(larger),
- bigBlob.begin(), bigBlob.end()));
-
- bigBlob[0] = 1;
- bigger.setvch(bigBlob);
- expect (big < bigger);
- ++big;
- expect (big == bigger);
- }
- {
- // GetCompact() and SetCompact().
- CBigNum big (0);
- expect (big.GetCompact() == 0);
- big.SetCompact (0x1010000);
- expect (big == 1);
- big.SetCompact (0x1810000);
- expect (big == -1);
-
- // Positive values.
- big.SetCompact (0x2010000);
- expect (big.GetCompact() == 0x2010000);
- ++big;
- expect (big.GetCompact() == 0x2010100);
-
- big.SetCompact (0x3010000);
- expect (big.GetCompact() == 0x3010000);
- ++big;
- expect (big.GetCompact() == 0x3010001);
-
- {
- big.SetCompact (0x4010000);
- expect (big.getuint64() == 0x1000000);
- unsigned int const compact = big.GetCompact();
- ++big;
- expect (compact == big.GetCompact());
- }
- big.SetCompact (0xFF7FFFFF);
- --big;
- expect (big.GetCompact() == 0xFF7FFFFE);
- expect (big.GetHex() ==
- "7ffffefffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffff");
-
- // Negative values.
- big.SetCompact (0x2810000);
- expect (big.GetCompact() == 0x2810000);
- --big;
- expect (big.GetCompact() == 0x2810100);
-
- big.SetCompact (0x3810000);
- expect (big.GetCompact() == 0x3810000);
- --big;
- expect (big.GetCompact() == 0x3810001);
-
- {
- big.SetCompact (0x4810000);
- expect (big.getint() == -16777216);
- unsigned int const compact = big.GetCompact();
- --big;
- expect (compact == big.GetCompact());
- }
- big.SetCompact (0xFFFFFFFF);
- ++big;
- expect (big.GetCompact() == 0xFFFFFFFE);
- expect (big.GetHex() ==
- "-7ffffefffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffffffffffffffffffffff"
- "fffffffffffffff");
- }
- {
- // SetHex() and GetHex().
- CBigNum big (1);
- expect (big != 0);
- big.SetHex (" ");
- expect (big == 0);
- big.SetHex (" -0x 1");
- expect (big == -1);
- big.SetHex (" -0");
- expect (big.GetHex() == "0");
- big.SetHex ("Feeble");
- expect (big.GetHex () == "feeb");
- }
- {
- // ToString().
- CBigNum big;
- expect (big.ToString (0) == "0");
-
- // Trying to use base 0 throws an exception.
- ++big;
- {
- bool badDivisor = false;
- try
- {
- big.ToString (0);
- }
- catch (std::runtime_error const&)
- {
- badDivisor = true;
- }
- expect (badDivisor);
- }
- ++big;
- expect (big.ToString (2) == "10");
- expect (big.ToString (10) == "2");
- }
- {
- // Member math operators.
- CBigNum big;
- expect (!big);
- --big;
- expect (! (!big));
- big += 2;
- expect (big == 1);
- big -= 3;
- expect (big == -2);
- big *= -1;
- expect (big == 2);
- big /= 2;
- expect (big == 1);
- big = 8;
- big %= 5;
- expect (big == 3);
- ++big;
- expect (big == 4);
- --big;
- expect (big == 3);
- {
- CBigNum const preIncr = big++;
- expect (preIncr == 3);
- expect (big == 4);
- }
- {
- CBigNum const preDecr = big--;
- expect (preDecr == 4);
- expect (big == 3);
- }
- big.setuint64 (0x80);
- big >>= 1;
- expect (big == 0x40);
- big <<= 2;
- expect (big == 0x100);
- big >>= 9;
- expect (big == 0);
- }
- {
- // Non-member math operators.
- CBigNum a (5);
- CBigNum b (3);
- CBigNum c = a + b;
- expect (c == 8);
- c = c * a;
- expect (c == 40);
- c = c - b;
- expect (c == 37);
- a = c / b;
- expect (a == 12);
- a = c % b;
- expect (a == 1);
- a = -c;
- expect (a == -37);
- b = a << 1;
- expect (b == -74);
- a = c >> 2;
- expect (a == 9);
- // All right shifts of negative numbers yield zero.
- a = (b >> 1);
- expect (a == 0);
- }
- {
- // Test non-member comparison operators.
- auto comparison_test = [this] (int center)
- {
- CBigNum delta (1);
- CBigNum lo (center);
- lo -= delta;
- CBigNum const ref (center);
- CBigNum const mid (center);
- CBigNum hi (center);
- hi += delta;
-
- this->expect ( (lo < ref));
- this->expect (!(mid < ref));
- this->expect (!(hi < ref));
-
- this->expect ( (lo <= ref));
- this->expect ( (mid <= ref));
- this->expect (!(hi <= ref));
-
- this->expect (!(lo > ref));
- this->expect (!(mid > ref));
- this->expect ( (hi > ref));
-
- this->expect (!(lo >= ref));
- this->expect ( (mid >= ref));
- this->expect ( (hi >= ref));
-
- this->expect (!(lo == ref));
- this->expect ( (mid == ref));
- this->expect (!(hi == ref));
-
- this->expect ( (lo != ref));
- this->expect (!(mid != ref));
- this->expect ( (hi != ref));
- };
-
- comparison_test (537);
- comparison_test (0);
- comparison_test (-2058);
- }
- {
- // BN math functions defined in CBigNum.h.
- CBigNum a;
- expect (BN_is_zero (&a));
- expect (BN_add_word64 (&a, 0xF000000000000000ull) == 1);
- expect (BN_add_word64 (&a, 0x0FFFFFFFFFFFFFFFull) == 1);
-
- CBigNum b;
- expect (BN_set_word (&b, 0xFFFFFFFFFFFFFFFFull) == 1);
- expect (BN_cmp (&a, &b) == 0);
-
- expect (BN_sub_word64 (&a, 0xFF00000000000000ull) == 1);
- expect (BN_set_word (&b, 0x00FFFFFFFFFFFFFFull) == 1);
- expect (BN_cmp (&a, &b) == 0);
-
- expect (BN_mul_word64 (&a, 0x10) == 1);
- expect (BN_set_word (&b, 0x0FFFFFFFFFFFFFF0ull) == 1);
- expect (BN_cmp (&a, &b) == 0);
-
- expect (BN_div_word64 (&a, 0x10) == 1);
- expect (BN_set_word (&b, 0x00FFFFFFFFFFFFFFull) == 1);
- expect (BN_cmp (&a, &b) == 0);
-
- expect (BN_div_word64 (&a, 0x200) == 1);
- expect (BN_set_word (&b, 0x00007FFFFFFFFFFFull) == 1);
- expect (BN_cmp (&a, &b) == 0);
-
- a *= -1;
- expect (a < 0);
- expect (BN_div_word64 (&a, 0x400) == 1);
- expect (BN_set_word (&b, 0x0000001FFFFFFFFFull) == 1);
- b *= -1;
- expect (a == b);
-
- // Divide by 0 should return an error.
- expect (BN_div_word64 (&a, 0) != 1);
- }
- }
-};
-
-BEAST_DEFINE_TESTSUITE(CBigNum,ripple_data,ripple);
-
-} // ripple
diff --git a/src/ripple/protocol/STAmount.h b/src/ripple/protocol/STAmount.h
index c9ddc5d606..4338316f64 100644
--- a/src/ripple/protocol/STAmount.h
+++ b/src/ripple/protocol/STAmount.h
@@ -171,8 +171,6 @@ public:
STAmount
zeroed() const
{
- // TODO(tom): what does this next comment mean here?
- // See https://ripplelabs.atlassian.net/browse/WC-1847?jql=
return STAmount (mIssue);
}
diff --git a/src/ripple/protocol/impl/STAmount.cpp b/src/ripple/protocol/impl/STAmount.cpp
index 106b571b0d..906075dd9e 100644
--- a/src/ripple/protocol/impl/STAmount.cpp
+++ b/src/ripple/protocol/impl/STAmount.cpp
@@ -22,13 +22,13 @@
#include
#include
#include
-#include
#include
#include
#include
#include
#include
#include
+#include
#include
#include
#include
@@ -980,6 +980,58 @@ operator- (STAmount const& value)
// Arithmetic
//
//------------------------------------------------------------------------------
+
+// Calculate (a * b) / c when all three values are 64-bit
+// without loss of precision:
+static
+std::uint64_t
+muldiv(
+ std::uint64_t multiplier,
+ std::uint64_t multiplicand,
+ std::uint64_t divisor)
+{
+ boost::multiprecision::uint128_t ret;
+
+ boost::multiprecision::multiply(ret, multiplier, multiplicand);
+ ret /= divisor;
+
+ if (ret > std::numeric_limits::max())
+ {
+ Throw ("overflow: (" +
+ std::to_string (multiplier) + " * " +
+ std::to_string (multiplicand) + ") / " +
+ std::to_string (divisor));
+ }
+
+ return static_cast(ret);
+}
+
+static
+std::uint64_t
+muldiv_round(
+ std::uint64_t multiplier,
+ std::uint64_t multiplicand,
+ std::uint64_t divisor,
+ std::uint64_t rounding)
+{
+ boost::multiprecision::uint128_t ret;
+
+ boost::multiprecision::multiply(ret, multiplier, multiplicand);
+ ret += rounding;
+ ret /= divisor;
+
+ if (ret > std::numeric_limits::max())
+ {
+ Throw ("overflow: ((" +
+ std::to_string (multiplier) + " * " +
+ std::to_string (multiplicand) + ") + " +
+ std::to_string (rounding) + ") / " +
+ std::to_string (divisor));
+ }
+
+ return static_cast(ret);
+}
+
STAmount
divide (STAmount const& num, STAmount const& den, Issue const& issue)
{
@@ -1013,23 +1065,15 @@ divide (STAmount const& num, STAmount const& den, Issue const& issue)
}
}
- // Compute (numerator * 10^17) / denominator
- CBigNum v;
-
- if ((BN_add_word64 (&v, numVal) != 1) ||
- (BN_mul_word64 (&v, tenTo17) != 1) ||
- (BN_div_word64 (&v, denVal) != 1))
- {
- Throw ("internal bn error");
- }
-
- // 10^16 <= quotient <= 10^18
- assert (BN_num_bytes (&v) <= 64);
-
- // TODO(tom): where do 5 and 17 come from?
- return STAmount (issue, v.getuint64 () + 5,
- numOffset - denOffset - 17,
- num.negative() != den.negative());
+ // We divide the two mantissas (each is between 10^15
+ // and 10^16). To maintain precision, we multiply the
+ // numerator by 10^17 (the product is in the range of
+ // 10^32 to 10^33) followed by a division, so the result
+ // is in the range of 10^16 to 10^15.
+ return STAmount (issue,
+ muldiv(numVal, tenTo17, denVal) + 5,
+ numOffset - denOffset - 17,
+ num.negative() != den.negative());
}
STAmount
@@ -1077,32 +1121,20 @@ multiply (STAmount const& v1, STAmount const& v2, Issue const& issue)
}
}
- // Compute (numerator * denominator) / 10^14 with rounding
- // 10^16 <= result <= 10^18
- CBigNum v;
-
- if ((BN_add_word64 (&v, value1) != 1) ||
- (BN_mul_word64 (&v, value2) != 1) ||
- (BN_div_word64 (&v, tenTo14) != 1))
- {
- Throw ("internal bn error");
- }
-
- // 10^16 <= product <= 10^18
- assert (BN_num_bytes (&v) <= 64);
-
- // TODO(tom): where do 7 and 14 come from?
- return STAmount (issue, v.getuint64 () + 7,
- offset1 + offset2 + 14, v1.negative() != v2.negative());
+ // We multiply the two mantissas (each is between 10^15
+ // and 10^16), so their product is in the 10^30 to 10^32
+ // range. Dividing their product by 10^14 maintains the
+ // precision, by scaling the result to 10^16 to 10^18.
+ return STAmount (issue,
+ muldiv(value1, value2, tenTo14) + 7,
+ offset1 + offset2 + 14,
+ v1.negative() != v2.negative());
}
static
void
-canonicalizeRound (bool native, std::uint64_t& value, int& offset, bool roundUp)
+canonicalizeRound (bool native, std::uint64_t& value, int& offset)
{
- if (!roundUp) // canonicalize already rounds down
- return;
-
if (native)
{
if (offset < 0)
@@ -1142,7 +1174,9 @@ mulRound (STAmount const& v1, STAmount const& v2, Issue const& issue,
if (v1 == zero || v2 == zero)
return {issue};
- if (v1.native() && v2.native() && isXRP (issue))
+ bool const xrp = isXRP (issue);
+
+ if (v1.native() && v2.native() && xrp)
{
std::uint64_t minV = (getSNValue (v1) < getSNValue (v2)) ?
getSNValue (v1) : getSNValue (v2);
@@ -1179,32 +1213,29 @@ mulRound (STAmount const& v1, STAmount const& v2, Issue const& issue,
}
}
- bool resultNegative = v1.negative() != v2.negative();
- // Compute (numerator * denominator) / 10^14 with rounding
- // 10^16 <= result <= 10^18
- CBigNum v;
+ bool const resultNegative = v1.negative() != v2.negative();
- if ((BN_add_word64 (&v, value1) != 1) || (BN_mul_word64 (&v, value2) != 1))
- Throw ("internal bn error");
+ // We multiply the two mantissas (each is between 10^15
+ // and 10^16), so their product is in the 10^30 to 10^32
+ // range. Dividing their product by 10^14 maintains the
+ // precision, by scaling the result to 10^16 to 10^18.
+ //
+ // If the we're rounding up, we want to round up away
+ // from zero, and if we're rounding down, truncation
+ // is implicit.
+ std::uint64_t amount = muldiv_round (
+ value1, value2, tenTo14,
+ (resultNegative != roundUp) ? tenTo14m1 : 0);
- if (resultNegative != roundUp) // rounding down is automatic when we divide
- BN_add_word64 (&v, tenTo14m1);
-
- if (BN_div_word64 (&v, tenTo14) != 1)
- Throw ("internal bn error");
-
- // 10^16 <= product <= 10^18
- assert (BN_num_bytes (&v) <= 64);
-
- std::uint64_t amount = v.getuint64 ();
int offset = offset1 + offset2 + 14;
- canonicalizeRound (
- isXRP (issue), amount, offset, resultNegative != roundUp);
+ if (resultNegative != roundUp)
+ canonicalizeRound (xrp, amount, offset);
STAmount result (issue, amount, offset, resultNegative);
+
// Control when bugfixes that require switchover dates are enabled
if (roundUp && !resultNegative && !result && *stAmountCalcSwitchover)
{
- if (isXRP(issue) && *stAmountCalcSwitchover2)
+ if (xrp && *stAmountCalcSwitchover2)
{
// return the smallest value above zero
amount = 1;
@@ -1235,40 +1266,43 @@ divRound (STAmount const& num, STAmount const& den,
int numOffset = num.exponent(), denOffset = den.exponent();
if (num.native())
+ {
while (numVal < STAmount::cMinValue)
{
- // Need to bring into range
numVal *= 10;
--numOffset;
}
+ }
if (den.native())
+ {
while (denVal < STAmount::cMinValue)
{
denVal *= 10;
--denOffset;
}
+ }
- bool resultNegative = num.negative() != den.negative();
- // Compute (numerator * 10^17) / denominator
- CBigNum v;
+ bool const resultNegative =
+ (num.negative() != den.negative());
- if ((BN_add_word64 (&v, numVal) != 1) || (BN_mul_word64 (&v, tenTo17) != 1))
- Throw ("internal bn error");
+ // We divide the two mantissas (each is between 10^15
+ // and 10^16). To maintain precision, we multiply the
+ // numerator by 10^17 (the product is in the range of
+ // 10^32 to 10^33) followed by a division, so the result
+ // is in the range of 10^16 to 10^15.
+ //
+ // We round away from zero if we're rounding up or
+ // truncate if we're rounding down.
+ std::uint64_t amount = muldiv_round (
+ numVal, tenTo17, denVal,
+ (resultNegative != roundUp) ? denVal - 1 : 0);
- if (resultNegative != roundUp) // Rounding down is automatic when we divide
- BN_add_word64 (&v, denVal - 1);
-
- if (BN_div_word64 (&v, denVal) != 1)
- Throw ("internal bn error");
-
- // 10^16 <= quotient <= 10^18
- assert (BN_num_bytes (&v) <= 64);
-
- std::uint64_t amount = v.getuint64 ();
int offset = numOffset - denOffset - 17;
- canonicalizeRound (
- isXRP (issue), amount, offset, resultNegative != roundUp);
+
+ if (resultNegative != roundUp)
+ canonicalizeRound (isXRP (issue), amount, offset);
+
STAmount result (issue, amount, offset, resultNegative);
// Control when bugfixes that require switchover dates are enabled
if (roundUp && !resultNegative && !result && *stAmountCalcSwitchover)
diff --git a/src/ripple/protocol/tests/STAmount.test.cpp b/src/ripple/protocol/tests/STAmount.test.cpp
index 3ec27429c5..a7ed160739 100644
--- a/src/ripple/protocol/tests/STAmount.test.cpp
+++ b/src/ripple/protocol/tests/STAmount.test.cpp
@@ -20,7 +20,6 @@
#include
#include
#include
-#include
#include
#include
@@ -404,24 +403,6 @@ public:
{
testcase ("arithmetic");
- CBigNum b;
-
- for (int i = 0; i < 16; ++i)
- {
- std::uint64_t r = rand_int();
- b.setuint64 (r);
-
- if (b.getuint64 () != r)
- {
- log << r << " != " << b.getuint64 () << " " << b.ToString (16);
- fail ("setull64/getull64 failure");
- }
- else
- {
- pass ();
- }
- }
-
// Test currency multiplication and division operations such as
// convertToDisplayAmount, convertToInternalAmount, getRate, getClaimed, and getNeeded
diff --git a/src/ripple/unity/crypto.cpp b/src/ripple/unity/crypto.cpp
index 906f46f380..928a6e8fb2 100644
--- a/src/ripple/unity/crypto.cpp
+++ b/src/ripple/unity/crypto.cpp
@@ -19,7 +19,6 @@
#include
-#include
#include
#include
#include
@@ -29,7 +28,6 @@
#include
#include
-#include
#include
#if DOXYGEN