diff --git a/Builds/VisualStudio2012/RippleD.vcxproj b/Builds/VisualStudio2012/RippleD.vcxproj index 9c0b4bea79..f3cf873f5e 100644 --- a/Builds/VisualStudio2012/RippleD.vcxproj +++ b/Builds/VisualStudio2012/RippleD.vcxproj @@ -130,6 +130,12 @@ true true + + true + true + true + true + true true @@ -1608,8 +1614,17 @@ + + + + + + + + + @@ -1734,8 +1749,6 @@ - - diff --git a/Builds/VisualStudio2012/RippleD.vcxproj.filters b/Builds/VisualStudio2012/RippleD.vcxproj.filters index 029b599103..ca047f8d84 100644 --- a/Builds/VisualStudio2012/RippleD.vcxproj.filters +++ b/Builds/VisualStudio2012/RippleD.vcxproj.filters @@ -1056,6 +1056,9 @@ [2] Old Ripple\ripple_app\peers + + [1] Ripple\types\impl + @@ -2022,12 +2025,6 @@ [1] Ripple\rpc\impl - - [2] Old Ripple\ripple_basics\types - - - [2] Old Ripple\ripple_basics\types - [1] Ripple\types @@ -2082,6 +2079,33 @@ [2] Old Ripple\ripple_app\peers + + [1] Ripple\types\api + + + [1] Ripple\types\api + + + [1] Ripple\types\api + + + [1] Ripple\types\api + + + [1] Ripple\types\api + + + [1] Ripple\types\api + + + [1] Ripple\types\api + + + [1] Ripple\types\api + + + [1] Ripple\types\api + diff --git a/src/ripple/beast/ripple_beast.cpp b/src/ripple/beast/ripple_beast.cpp index 8b415e02ca..0eebd877a9 100644 --- a/src/ripple/beast/ripple_beast.cpp +++ b/src/ripple/beast/ripple_beast.cpp @@ -25,6 +25,7 @@ #include "../beast/modules/beast_db/beast_db.cpp" #include "../beast/modules/beast_sqdb/beast_sqdb.cpp" +#include "../beast/beast/crypto/Crypto.cpp" #include "../beast/beast/http/HTTP.cpp" #include "../beast/beast/net/Net.cpp" #include "../beast/beast/strings/Strings.cpp" diff --git a/src/ripple/sslutil/api/CBigNum.h b/src/ripple/sslutil/api/CBigNum.h index 5a8060af4f..831e7770e7 100644 --- a/src/ripple/sslutil/api/CBigNum.h +++ b/src/ripple/sslutil/api/CBigNum.h @@ -36,6 +36,7 @@ public: CBigNum (uint64 n); explicit CBigNum (uint256 n); explicit CBigNum (Blob const& vch); + CBigNum (unsigned char const* begin, unsigned char const* end); ~CBigNum (); void setuint (unsigned int n); @@ -46,6 +47,7 @@ public: void setuint64 (uint64 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); diff --git a/src/ripple/sslutil/impl/CBigNum.cpp b/src/ripple/sslutil/impl/CBigNum.cpp index e05521ca44..d014910f68 100644 --- a/src/ripple/sslutil/impl/CBigNum.cpp +++ b/src/ripple/sslutil/impl/CBigNum.cpp @@ -102,7 +102,13 @@ CBigNum::CBigNum (uint256 n) CBigNum::CBigNum (Blob const& vch) { BN_init (this); - setvch (vch); + setvch (&vch.front(), &vch.back()+1); +} + +CBigNum::CBigNum (unsigned char const* begin, unsigned char const* end) +{ + BN_init (this); + setvch (begin, end); } void CBigNum::setuint (unsigned int n) @@ -224,10 +230,11 @@ uint256 CBigNum::getuint256 () return ret; } -void CBigNum::setvch (Blob const& vch) +void CBigNum::setvch (unsigned char const* begin, unsigned char const* end) { - Blob vch2 (vch.size () + 4); - unsigned int nSize = vch.size (); + 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; @@ -235,10 +242,15 @@ void CBigNum::setvch (Blob const& vch) vch2[2] = (nSize >> 8) & 0xff; vch2[3] = (nSize >> 0) & 0xff; // swap data to big endian - std::reverse_copy (vch.begin (), vch.end (), vch2.begin () + 4); + 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, NULL); diff --git a/src/ripple/types/api/Base58.h b/src/ripple/types/api/Base58.h index cb741b8d63..f244493490 100644 --- a/src/ripple/types/api/Base58.h +++ b/src/ripple/types/api/Base58.h @@ -19,6 +19,8 @@ #ifndef RIPPLE_TYPES_BASE58_H #define RIPPLE_TYPES_BASE58_H +#include + #include "Blob.h" namespace ripple { @@ -27,23 +29,73 @@ namespace ripple { class Base58 { public: - // VFALCO TODO clean up this poor API - static char const* getCurrentAlphabet (); - static void setCurrentAlphabet (char const* alphabet); - static char const* getBitcoinAlphabet (); static char const* getRippleAlphabet (); static char const* getTestnetAlphabet (); - static std::string encode ( - const unsigned char* pbegin, - const unsigned char* pend, - char const* alphabet, - bool withCheck); + static std::string raw_encode ( + unsigned char const* begin, unsigned char const* end, + char const* alphabet, bool withCheck); - static std::string encode (const unsigned char* pbegin, const unsigned char* pend); - static std::string encode (Blob const& vch); - static std::string encodeWithCheck (Blob const& vchIn); + static void fourbyte_hash256 (void* out, void const* in, std::size_t bytes); + + template + static std::string encode (InputIt first, InputIt last, char const* alphabet, bool withCheck) + { + typedef typename std::iterator_traits::value_type value_type; + std::vector ::type> v; + std::size_t const size (std::distance (first, last)); + if (withCheck) + { + v.reserve (size + 1 + 4); + v.insert (v.begin(), first, last); + unsigned char hash [4]; + fourbyte_hash256 (hash, &v.front(), v.size()); + v.resize (0); + // Place the hash reversed in the front + std::copy (std::reverse_iterator (hash+4), + std::reverse_iterator (hash), + std::back_inserter (v)); + } + else + { + v.reserve (size + 1); + } + // Append input little endian + std::copy (std::reverse_iterator (last), + std::reverse_iterator (first), + std::back_inserter (v)); + // Pad zero to make the BIGNUM positive + v.push_back (0); + return raw_encode (&v.front(), &v.back()+1, alphabet, withCheck); + } + + // VFALCO NOTE Avoid this interface which uses globals, explicitly + // pass the alphabet in the call to encode! + // + static char const* getCurrentAlphabet (); + static void setCurrentAlphabet (char const* alphabet); + + template + static std::string encode (Container const& container) + { + return encode (container.container.begin(), container.end(), + getCurrentAlphabet(), false); + } + + template + static std::string encodeWithCheck (Container const& container) + { + return encode (&container.front(), &container.back()+1, + getCurrentAlphabet(), true); + } + + static std::string encode (const unsigned char* pbegin, const unsigned char* pend) + { + return encode (pbegin, pend, getCurrentAlphabet(), false); + } + + //-------------------------------------------------------------------------- static bool decode (const char* psz, Blob& vchRet, const char* pAlphabet = getCurrentAlphabet ()); static bool decode (const std::string& str, Blob& vchRet); diff --git a/src/ripple/types/api/CryptoIdentifierStorage.h b/src/ripple/types/api/CryptoIdentifierStorage.h new file mode 100644 index 0000000000..efad14dc6f --- /dev/null +++ b/src/ripple/types/api/CryptoIdentifierStorage.h @@ -0,0 +1,171 @@ +//------------------------------------------------------------------------------ +/* + Copyright (c) 2011-2013, OpenCoin, Inc. +*/ +//============================================================================== + +#ifndef RIPPLE_TYPES_CRYPTOIDENTIFIERSTORAGE_H_INCLUDED +#define RIPPLE_TYPES_CRYPTOIDENTIFIERSTORAGE_H_INCLUDED + +#include "beast/beast/FixedArray.h" + +namespace ripple { + +/** A padded FixedArray used with CryptoIdentifierType traits. */ +template +class CryptoIdentifierStorage +{ +public: + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef uint8 value_type; + typedef value_type* iterator; + typedef value_type const* const_iterator; + typedef value_type& reference; + typedef value_type const& const_reference; + + static size_type const pre_size = PreSize; + static size_type const size = Size; + static size_type const post_size = PostSize; + static size_type const storage_size = pre_size + size + post_size; + + typedef FixedArray < + uint8, storage_size> storage_type; + + /** Value hashing function. + The seed prevents crafted inputs from causing degenarate parent containers. + */ + class hasher + { + public: + explicit hasher (HashValue seedToUse = Random::getSystemRandom ().nextInt ()) + : m_seed (seedToUse) + { + } + + std::size_t operator() (CryptoIdentifierStorage const& storage) const + { + std::size_t hash; + Murmur::Hash (storage.cbegin (), storage.size, m_seed, &hash); + return hash; + } + + private: + std::size_t m_seed; + }; + + /** Container equality testing function. */ + class equal + { + public: + bool operator() (CryptoIdentifierStorage const& lhs, + CryptoIdentifierStorage const& rhs) const + { + return lhs == rhs; + } + }; + + // iterator access + iterator begin() { return &m_storage[pre_size]; } + const_iterator begin() const { return &m_storage[pre_size]; } + const_iterator cbegin() const { return &m_storage[pre_size]; } + iterator end() { return &m_storage[storage_size-post_size]; } + const_iterator end() const { return &m_storage[storage_size-post_size]; } + const_iterator cend() const { return &m_storage[storage_size-post_size]; } + + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + reverse_iterator rbegin() { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } + const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } + const_reverse_iterator crend() const { return const_reverse_iterator(begin()); } + + reference operator[](size_type i) + { + bassert (i < size); + return m_storage[pre_size+i]; + } + + const_reference operator[](size_type i) const + { + bassert (i < size); + return m_storage[pre_size+i]; + } + + reference front() { return m_storage[pre_size]; } + reference back() { return m_storage[storage_size-post_size-1]; } + const_reference front () const { return m_storage[pre_size]; } + const_reference back() const { return m_storage[storage_size-post_size-1]; } + + value_type const* data() const { return &m_storage[pre_size]; } + value_type* data() { return &m_storage[pre_size]; } + value_type* c_array() { return &m_storage[pre_size]; } + + void assign (value_type value) { fill (value); } + void fill (value_type value) { std::fill_n (begin(), size, value); } + void clear () { fill (value_type ()); } + + // Access storage + storage_type& storage() { return m_storage; } + storage_type const& storage() const { return m_storage; } + + void rangecheck (size_type i) + { + if (i >= size) + throw std::out_of_range ("CryptoIdentifierStorage<>: index out of range"); + } + +private: + storage_type m_storage; +}; + +//------------------------------------------------------------------------------ + +template +bool operator== (CryptoIdentifierStorage const& lhs, + CryptoIdentifierStorage const& rhs) +{ + return std::equal (lhs.begin(), lhs.end(), rhs.begin()); +} + +template +bool operator!= (CryptoIdentifierStorage const& lhs, + CryptoIdentifierStorage const& rhs) +{ + return !(lhs==rhs); +} + +template +bool operator< (CryptoIdentifierStorage const& lhs, + CryptoIdentifierStorage const& rhs) +{ + return std::lexicographical_compare (lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); +} + +template +bool operator> (CryptoIdentifierStorage const& lhs, + CryptoIdentifierStorage const& rhs) +{ + return rhs +bool operator<= (CryptoIdentifierStorage const& lhs, + CryptoIdentifierStorage const& rhs) +{ + return !(rhs +bool operator>= (CryptoIdentifierStorage const& lhs, + CryptoIdentifierStorage const& rhs) +{ + return !(lhs +#include +#include +#include +#include + +namespace ripple { + +//------------------------------------------------------------------------------ + +/** Template for generalizing the cryptographic primitives used. */ +template +class CryptoIdentifierType : public Traits::base +{ +public: + static std::size_t const size = Traits::size; + typedef typename Traits::value_type value_type; + typedef typename value_type::const_iterator const_iterator; + typedef typename value_type::const_reverse_iterator const_reverse_iterator; + + /** Wraps Traits::hasher. */ + class hasher + { + public: + hasher() + { } + template + hasher (Arg arg) : m_hasher (arg) + { } + std::size_t operator() (CryptoIdentifierType const& id) const + { return m_hasher(id.value()); } + private: + typename Traits::hasher m_hasher; + }; + + /** Wraps Traits::equal. */ + class equal + { + public: + equal() + { } + template + equal (Arg arg) : m_equal (arg) + { } + bool operator() (CryptoIdentifierType const& lhs, + CryptoIdentifierType const& rhs) const + { return m_equal (lhs.value(), rhs.value()); } + private: + typename Traits::equal m_equal; + }; + + /** Create an uninitialized value. */ + CryptoIdentifierType () + { + } + + /** Create a copy from another value . */ + CryptoIdentifierType (value_type const& value) + : m_value (value) + { + } + + /** Create a copy of the value from range of bytes. */ + CryptoIdentifierType (uint8 const* begin, uint8 const* end) + { + Traits::construct (begin, end, m_value); + } + + /** Conversion construction from any specialized type. */ + template + explicit CryptoIdentifierType (Other const& other) + { + this->operator= (other); + } + + /** Assign a copy from another value. */ + CryptoIdentifierType& operator= (value_type const& value) + { + m_value = value; + return *this; + } + + /** Copy conversion from any specialized type. */ + template + CryptoIdentifierType& operator= (Other const& other) + { + typename Traits::template assign () ( + m_value, other); + return *this; + } + + /** Access the value. */ + value_type const& value() const + { + return m_value; + } + + /** Iterator access. */ + /** @{ */ + const_iterator begin() const { return value().begin(); } + const_iterator end() const { return value().end(); } + const_iterator cbegin() const { return value().cbegin(); } + const_iterator cend() const { return value().cend(); } + const_reverse_iterator rbegin() const { return value().rbegin(); } + const_reverse_iterator rend() const { return value().rend(); } + const_reverse_iterator crbegin() const { return value().crbegin(); } + const_reverse_iterator crend() const { return value().crend(); } + /** @} */ + + /** Conversion to std::string. */ + std::string to_string() const + { + return Traits::to_string (m_value); + } + +private: + value_type m_value; +}; + +//------------------------------------------------------------------------------ + +template +std::ostream& operator<< (std::ostream& os, + CryptoIdentifierType const& id) +{ + os << id.to_string(); + return os; +} + +template +std::istream& operator>> (std::istream& is, + CryptoIdentifierType const& id) +{ + return is; +} + +//------------------------------------------------------------------------------ + +} + +namespace std { + +/** Specialization for hash. */ +template +struct hash > +{ +public: + typedef ripple::CryptoIdentifierType argument_type; + typedef std::size_t result_type; + + hash () + { + static typename argument_type::hasher s_hash; + m_hash = s_hash; + } + + template + explicit hash (Arg arg) + : m_hash (arg) + { + } + + result_type operator() (argument_type const& key) const + { + return m_hash (key); + } + +private: + typename argument_type::hasher m_hash; +}; + +//------------------------------------------------------------------------------ + +/** Specialization for equal_to. */ +template +struct equal_to > +{ +public: + typedef bool result_type; + typedef ripple::CryptoIdentifierType argument_type; + typedef argument_type first_argument_type; + typedef argument_type second_argument_type; + + equal_to () + { + } + + template + explicit equal_to (Arg arg) + : m_equal (arg) + { + } + + result_type operator() (argument_type const& lhs, + argument_type const& rhs) const + { + return m_equal (lhs, rhs); + } + +private: + typename argument_type::equal m_equal; +}; + +} + +#endif diff --git a/src/ripple/types/api/RippleAccountID.h b/src/ripple/types/api/RippleAccountID.h new file mode 100644 index 0000000000..223d9f38e1 --- /dev/null +++ b/src/ripple/types/api/RippleAccountID.h @@ -0,0 +1,49 @@ +//------------------------------------------------------------------------------ +/* + Copyright (c) 2011-2013, OpenCoin, Inc. +*/ +//============================================================================== + +#ifndef RIPPLE_TYPES_RIPPLEACCOUNTID_H_INCLUDED +#define RIPPLE_TYPES_RIPPLEACCOUNTID_H_INCLUDED + +#include "RippleCryptoIdentifier.h" + +namespace ripple { + +class RippleAccountIDTraits + : public RippleCryptoIdentifier <20, 0, true> +{ +public: + template + struct assign + { + void operator() (value_type& value, Other const& other) + { + value = other; + } + }; + + /** Convert to std::string. + */ + // VFALCO TODO Cache results in an associative map, to replicated + // the optimization performed in RippledAddress.cp + // + static std::string to_string (value_type const& value) + { + value_type::storage_type const& storage (value.storage()); + // We will convert to little endian with an extra pad byte + FixedArray le; + std::reverse_copy (storage.begin(), storage.end(), le.begin()); + // Set pad byte zero to make BIGNUM always positive + le.back() = 0; + return Base58::raw_encode (le.begin(), le.end(), + Base58::getRippleAlphabet(), checked); + } +}; + +typedef CryptoIdentifierType RippleAccountID; + +} + +#endif diff --git a/src/ripple/types/api/RippleAccountPrivateKey.h b/src/ripple/types/api/RippleAccountPrivateKey.h new file mode 100644 index 0000000000..bff407ebda --- /dev/null +++ b/src/ripple/types/api/RippleAccountPrivateKey.h @@ -0,0 +1,32 @@ +//------------------------------------------------------------------------------ +/* + Copyright (c) 2011-2013, OpenCoin, Inc. +*/ +//============================================================================== + +#ifndef RIPPLE_TYPES_RIPPLEACCOUNTPRIVATEKEY_H_INCLUDED +#define RIPPLE_TYPES_RIPPLEACCOUNTPRIVATEKEY_H_INCLUDED + +#include "RippleCryptoIdentifier.h" + +namespace ripple { + +class RippleAccountPrivateKeyTraits + : public RippleCryptoIdentifier <32, 34, true> +{ +public: + template + struct assign + { + void operator() (value_type& value, Other const& other) + { + value = other; + } + }; +}; + +typedef CryptoIdentifierType RippleAccountPrivateKey; + +} + +#endif diff --git a/src/ripple/types/api/RippleAccountPublicKey.h b/src/ripple/types/api/RippleAccountPublicKey.h new file mode 100644 index 0000000000..5b6942ae69 --- /dev/null +++ b/src/ripple/types/api/RippleAccountPublicKey.h @@ -0,0 +1,32 @@ +//------------------------------------------------------------------------------ +/* + Copyright (c) 2011-2013, OpenCoin, Inc. +*/ +//============================================================================== + +#ifndef RIPPLE_TYPES_RIPPLEACCOUNTPUBLICKEY_H_INCLUDED +#define RIPPLE_TYPES_RIPPLEACCOUNTPUBLICKEY_H_INCLUDED + +#include "RippleCryptoIdentifier.h" + +namespace ripple { + +class RippleAccountPublicKeyTraits + : public RippleCryptoIdentifier <33, 35, true> +{ +public: + template + struct assign + { + void operator() (value_type& value, Other const& other) + { + value = other; + } + }; +}; + +typedef CryptoIdentifierType RippleAccountPublicKey; + +} + +#endif diff --git a/src/ripple/types/api/RippleCryptoIdentifier.h b/src/ripple/types/api/RippleCryptoIdentifier.h new file mode 100644 index 0000000000..add834a67e --- /dev/null +++ b/src/ripple/types/api/RippleCryptoIdentifier.h @@ -0,0 +1,106 @@ +//------------------------------------------------------------------------------ +/* + Copyright (c) 2011-2013, OpenCoin, Inc. +*/ +//============================================================================== + +#ifndef RIPPLE_TYPES_RIPPLECRYPTOIDENTIFIER_H_INCLUDED +#define RIPPLE_TYPES_RIPPLECRYPTOIDENTIFIER_H_INCLUDED + +#include "beast/beast/FixedArray.h" +#include "beast/beast/intrusive/IntrusiveArray.h" +#include "beast/beast/crypto/Sha256.h" + +#include "Base58.h" + +#include "CryptoIdentifierStorage.h" + +namespace ripple { + +/** Shared CryptoIdentifierType traits for Ripple crypto identifiers. + + @tparam Size The number of bytes in the identifier, exclusive of version, + checksum, or padding. + + @tparam Token A byte prepended to the binary data that distinguishes + the type of identifier. + + @tparam Checked A `bool` indicating whether or not the string + representation includes an appended a four byte checksum on + the data including the Token. +*/ +template +class RippleCryptoIdentifier +{ +public: + typedef std::size_t size_type; + + // 1 token byte, + static std::size_t const pre_size = 1; + static size_type const size = Size; + // 4 checksum bytes (optional) + static std::size_t const post_size = (Checked ? 4 : 0); + static uint8 const token = Token; + static bool const checked = Checked; + + // This is what the wrapper creates, it includes the padding. + typedef CryptoIdentifierStorage < + pre_size, size, post_size> value_type; + + typedef typename value_type::hasher hasher; + typedef typename value_type::equal equal; + + /** Initialize from an input sequence. */ + static void construct ( + uint8 const* begin, uint8 const* end, + value_type& value) + { + value.storage()[0] = Token; + bassert (std::distance (begin, end) == size); + std::copy (begin, end, value.begin()); + if (Checked) + { + Sha256::digest_type digest; + Sha256::hash (Sha256::hash (value.storage().cbegin(), + value.storage().cend() - post_size), digest); + // We use the first 4 bytes as a checksum + std::copy (digest.begin(), digest.begin() + 4, + value.end()); + } + } + + /** Base class for CryptoIdentifierType. */ + class base + { + public: + template + static value_type createFromInteger (UnsignedIntegralType i) + { + static_bassert (size >= sizeof (UnsignedIntegralType)); + FixedArray data; + data.fill (0); + i = toNetworkByteOrder (i); + std::memcpy (data.end () - sizeof (i), &i, std::min (size, sizeof (i))); + value_type value; + construct (data.begin(), data.end(), value); + return value; + } + }; + + /** Convert to std::string. */ + static std::string to_string (value_type const& value) + { + typename value_type::storage_type const& storage (value.storage()); + // We will convert to little endian with an extra pad byte + FixedArray le; + std::reverse_copy (storage.begin(), storage.end(), le.begin()); + // Set pad byte zero to make BIGNUM always positive + le.back() = 0; + return Base58::raw_encode (le.begin(), le.end(), + Base58::getRippleAlphabet(), Checked); + } +}; + +} + +#endif diff --git a/src/ripple/types/api/RipplePrivateKey.h b/src/ripple/types/api/RipplePrivateKey.h new file mode 100644 index 0000000000..3626bb315e --- /dev/null +++ b/src/ripple/types/api/RipplePrivateKey.h @@ -0,0 +1,32 @@ +//------------------------------------------------------------------------------ +/* + Copyright (c) 2011-2013, OpenCoin, Inc. +*/ +//============================================================================== + +#ifndef RIPPLE_TYPES_RIPPLEPRIVATEKEY_H_INCLUDED +#define RIPPLE_TYPES_RIPPLEPRIVATEKEY_H_INCLUDED + +#include "RippleCryptoIdentifier.h" + +namespace ripple { + +class RipplePrivateKeyTraits + : public RippleCryptoIdentifier <32, 32, true> +{ +public: + template + struct assign + { + void operator() (value_type& value, Other const& other) + { + value = other; + } + }; +}; + +typedef CryptoIdentifierType RipplePrivateKey; + +} + +#endif diff --git a/src/ripple/types/api/RipplePublicKey.h b/src/ripple/types/api/RipplePublicKey.h new file mode 100644 index 0000000000..ba1031b76c --- /dev/null +++ b/src/ripple/types/api/RipplePublicKey.h @@ -0,0 +1,32 @@ +//------------------------------------------------------------------------------ +/* + Copyright (c) 2011-2013, OpenCoin, Inc. +*/ +//============================================================================== + +#ifndef RIPPLE_TYPES_RIPPLEPUBLICKEY_H_INCLUDED +#define RIPPLE_TYPES_RIPPLEPUBLICKEY_H_INCLUDED + +#include "RippleCryptoIdentifier.h" + +namespace ripple { + +class RipplePublicKeyTraits + : public RippleCryptoIdentifier <33, 28, true> +{ +public: + template + struct assign + { + void operator() (value_type& value, Other const& other) + { + value = other; + } + }; +}; + +typedef CryptoIdentifierType RipplePublicKey; + +} + +#endif diff --git a/src/ripple_basics/types/RipplePublicKeyHash.h b/src/ripple/types/api/RipplePublicKeyHash.h similarity index 72% rename from src/ripple_basics/types/RipplePublicKeyHash.h rename to src/ripple/types/api/RipplePublicKeyHash.h index 3464567b60..7a4bd35408 100644 --- a/src/ripple_basics/types/RipplePublicKeyHash.h +++ b/src/ripple/types/api/RipplePublicKeyHash.h @@ -4,10 +4,15 @@ */ //============================================================================== -#ifndef RIPPLE_BASICS_RIPPLEPUBLICKEYHASH_H_INCLUDED -#define RIPPLE_BASICS_RIPPLEPUBLICKEYHASH_H_INCLUDED +#ifndef RIPPLE_TYPES_RIPPLEPUBLICKEYHASH_H_INCLUDED +#define RIPPLE_TYPES_RIPPLEPUBLICKEYHASH_H_INCLUDED + +namespace ripple { /** A container holding the hash of a public key in binary format. */ typedef UnsignedInteger <20> RipplePublicKeyHash; +} + #endif + diff --git a/src/ripple/types/impl/Base58.cpp b/src/ripple/types/impl/Base58.cpp index df00fa35b8..a85fa9ab72 100644 --- a/src/ripple/types/impl/Base58.cpp +++ b/src/ripple/types/impl/Base58.cpp @@ -13,14 +13,12 @@ namespace ripple { char const* Base58::s_currentAlphabet = Base58::getRippleAlphabet (); -char const* Base58::getCurrentAlphabet () +void Base58::fourbyte_hash256 (void* out, void const* in, std::size_t bytes) { - return s_currentAlphabet; -} - -void Base58::setCurrentAlphabet (char const* alphabet) -{ - s_currentAlphabet = alphabet; + unsigned char const* const p ( + static_cast (in)); + uint256 hash (SHA256Hash (p, p + bytes)); + memcpy (out, hash.begin(), 4); } char const* Base58::getBitcoinAlphabet () @@ -38,27 +36,23 @@ char const* Base58::getTestnetAlphabet () return "RPShNAF39wBUDnEGHJKLM4pQrsT7VWXYZ2bcdeCg65jkm8ofqi1tuvaxyz"; } -std::string Base58::encode (const unsigned char* pbegin, const unsigned char* pend) +std::string Base58::raw_encode ( + unsigned char const* begin, unsigned char const* end, + char const* alphabet, bool withCheck) { - char const* alphabet = getCurrentAlphabet (); - CAutoBN_CTX pctx; CBigNum bn58 = 58; CBigNum bn0 = 0; - // Convert big endian data to little endian - // Extra zero at the end make sure bignum will interpret as a positive number - Blob vchTmp (pend - pbegin + 1, 0); - std::reverse_copy (pbegin, pend, vchTmp.begin ()); - // Convert little endian data to bignum - CBigNum bn (vchTmp); + CBigNum bn (begin, end); + std::size_t const size (std::distance (begin, end)); // Convert bignum to std::string std::string str; // Expected size increase from base58 conversion is approximately 137% // use 138% to be safe - str.reserve ((pend - pbegin) * 138 / 100 + 1); + str.reserve (size * 138 / 100 + 1); CBigNum dv; CBigNum rem; @@ -71,9 +65,8 @@ std::string Base58::encode (const unsigned char* pbegin, const unsigned char* pe unsigned int c = rem.getuint (); str += alphabet [c]; } - - // Leading zeroes encoded as base58 zeros - for (const unsigned char* p = pbegin; p < pend && *p == 0; p++) + + for (const unsigned char* p = end-2; p >= begin && *p == 0; p--) str += alphabet [0]; // Convert little endian std::string to big endian @@ -81,20 +74,18 @@ std::string Base58::encode (const unsigned char* pbegin, const unsigned char* pe return str; } -std::string Base58::encode (Blob const& vch) +char const* Base58::getCurrentAlphabet () { - return encode (&vch[0], &vch[0] + vch.size ()); + return s_currentAlphabet; } -std::string Base58::encodeWithCheck (Blob const& vchIn) +void Base58::setCurrentAlphabet (char const* alphabet) { - // add 4-byte hash check to the end - Blob vch (vchIn); - uint256 hash = SHA256Hash (vch.begin (), vch.end ()); - vch.insert (vch.end (), (unsigned char*)&hash, (unsigned char*)&hash + 4); - return encode (vch); + s_currentAlphabet = alphabet; } +//------------------------------------------------------------------------------ + bool Base58::decode (const char* psz, Blob& vchRet, const char* pAlpha) { assert (pAlpha != 0); diff --git a/src/ripple/types/impl/RippleCryptoIdentifierTests.cpp b/src/ripple/types/impl/RippleCryptoIdentifierTests.cpp new file mode 100644 index 0000000000..e98e8dc0e0 --- /dev/null +++ b/src/ripple/types/impl/RippleCryptoIdentifierTests.cpp @@ -0,0 +1,11 @@ +//------------------------------------------------------------------------------ +/* + Copyright (c) 2011-2013, OpenCoin, Inc. +*/ +//============================================================================== + +namespace ripple { + +// Relocated to RippleAddress.cpp + +} diff --git a/src/ripple/types/ripple_types.cpp b/src/ripple/types/ripple_types.cpp index 5ae4bc61af..aa1d21989e 100644 --- a/src/ripple/types/ripple_types.cpp +++ b/src/ripple/types/ripple_types.cpp @@ -24,3 +24,4 @@ #include "impl/UInt128.cpp" #include "impl/UInt160.cpp" #include "impl/UInt256.cpp" +#include "impl/RippleCryptoIdentifierTests.cpp" diff --git a/src/ripple/types/ripple_types.h b/src/ripple/types/ripple_types.h index 3e191b12fa..a66974ad80 100644 --- a/src/ripple/types/ripple_types.h +++ b/src/ripple/types/ripple_types.h @@ -8,6 +8,7 @@ #define RIPPLE_TYPES_H_INCLUDED #include "beast/modules/beast_core/beast_core.h" +#include "beast/modules/beast_crypto/beast_crypto.h" // for UnsignedInteger, Remove ASAP! #include "beast/modules/beast_core/system/BeforeBoost.h" #include @@ -36,5 +37,15 @@ using namespace beast; # include "api/UInt256.h" # include "api/RandomNumbers.h" #include "api/HashMaps.h" +#include "api/CryptoIdentifierType.h" +# include "api/CryptoIdentifierStorage.h" + +#include "api/RippleAccountID.h" +#include "api/RippleAccountPublicKey.h" +#include "api/RippleAccountPrivateKey.h" +#include "api/RipplePublicKey.h" +#include "api/RipplePrivateKey.h" + +#include "api/RipplePublicKeyHash.h" #endif diff --git a/src/ripple/validators/impl/ChosenList.h b/src/ripple/validators/impl/ChosenList.h index 09172b7c98..ae1a22a51b 100644 --- a/src/ripple/validators/impl/ChosenList.h +++ b/src/ripple/validators/impl/ChosenList.h @@ -22,7 +22,7 @@ public: } }; - typedef boost::unordered_map MapType; + typedef boost::unordered_map MapType; ChosenList (std::size_t expectedSize = 0) { diff --git a/src/ripple/validators/impl/Logic.h b/src/ripple/validators/impl/Logic.h index 3e4f955155..c1beef9dd0 100644 --- a/src/ripple/validators/impl/Logic.h +++ b/src/ripple/validators/impl/Logic.h @@ -46,7 +46,7 @@ public: }; typedef boost::unordered_map < - PublicKey, ValidatorInfo, PublicKey::HashFunction> MapType; + PublicKey, ValidatorInfo, PublicKey::hasher> MapType; struct State { @@ -318,12 +318,10 @@ public: iter != list->map().end(); ++iter) { Json::Value entry (Json::objectValue); - /* ChosenList::MapType::key_type const& key (iter->first); - ChosenList::MapType::mapped_type const& value (iter->second); - entry ["key"] = key; - entry ["value"] = value; - */ + entry ["key"] = key.to_string(); + //ChosenList::MapType::mapped_type const& value (iter->second); + //entry ["value"] = value.to_string(); entries.append (entry); } } diff --git a/src/ripple/validators/impl/Utilities.cpp b/src/ripple/validators/impl/Utilities.cpp index c916afa790..24e8aba108 100644 --- a/src/ripple/validators/impl/Utilities.cpp +++ b/src/ripple/validators/impl/Utilities.cpp @@ -84,7 +84,7 @@ bool Utilities::parseInfoLine ( else if (deprecatedPublicKey.setNodePublic (encodedKey)) { // We got a public key. - RipplePublicKey publicKey (deprecatedPublicKey.toRipplePublicKey ()); + RipplePublicKey publicKey (deprecatedPublicKey); success = true; } else @@ -238,15 +238,15 @@ Time Utilities::stringToTime (String s) std::string Utilities::publicKeyToString (PublicKey const& publicKey) { - std::string s (PublicKey::sizeInBytes, ' '); + std::string s (PublicKey::size, ' '); std::copy (publicKey.cbegin(), publicKey.cend(), s.begin()); return s; } PublicKey Utilities::stringToPublicKey (std::string const& s) { - bassert (s.size() == PublicKey::sizeInBytes); - return PublicKey (&s.front()); + bassert (s.size() == PublicKey::size); + return PublicKey (); } //------------------------------------------------------------------------------ diff --git a/src/ripple/validators/ripple_validators.h b/src/ripple/validators/ripple_validators.h index 25e4e841d7..1cf9b7bb72 100644 --- a/src/ripple/validators/ripple_validators.h +++ b/src/ripple/validators/ripple_validators.h @@ -8,7 +8,6 @@ #define RIPPLE_VALIDATORS_H_INCLUDED #include "beast/modules/beast_core/beast_core.h" -#include "../ripple_basics/ripple_basics.h" // for RipplePublicKey, remove asap #include "beast/beast/http/URL.h" diff --git a/src/ripple_app/ripple_app.h b/src/ripple_app/ripple_app.h index 07776ccdab..b30895da0d 100644 --- a/src/ripple_app/ripple_app.h +++ b/src/ripple_app/ripple_app.h @@ -22,7 +22,7 @@ #include #include #include -#include +//#include #include #include #include diff --git a/src/ripple_basics/ripple_basics.h b/src/ripple_basics/ripple_basics.h index 8ef953552a..a5abb62769 100644 --- a/src/ripple_basics/ripple_basics.h +++ b/src/ripple_basics/ripple_basics.h @@ -49,8 +49,6 @@ namespace ripple using namespace beast; #include "types/BasicTypes.h" -#include "types/RipplePublicKey.h" -#include "types/RipplePublicKeyHash.h" # include "log/LogSeverity.h" # include "log/LogFile.h" diff --git a/src/ripple_basics/types/RipplePublicKey.h b/src/ripple_basics/types/RipplePublicKey.h deleted file mode 100644 index 8de6be46d7..0000000000 --- a/src/ripple_basics/types/RipplePublicKey.h +++ /dev/null @@ -1,80 +0,0 @@ -//------------------------------------------------------------------------------ -/* - Copyright (c) 2011-2013, OpenCoin, Inc. -*/ -//============================================================================== - -#ifndef RIPPLE_BASICS_RIPPLEPUBLICKEY_H_INCLUDED -#define RIPPLE_BASICS_RIPPLEPUBLICKEY_H_INCLUDED - -/** A container used to hold a public key in binary format. */ -typedef UnsignedInteger <33> RipplePublicKey; -#if 0 -class RipplePublicKey -{ -private: - typedef UnsignedInteger <33> integer_type; - -public: - enum - { - size = integer_type::sizeInBytes - }; - - typedef integer_type::value_type value_type; - typedef integer_type::iterator iterator; - typedef integer_type::const_iterator const_iterator; - - class HashFunction - { - public: - HashFunction (HashValue seedToUse = Random::getSystemRandom().nextInt()) - : m_hash (seedToUse) - { - } - - HashValue operator() (RipplePublicKey const& value) const - { - return m_hash (value); - } - - private: - integer_type::HashFunction m_hash; - }; - - iterator begin() - { - return m_value.begin(); - } - - iterator end() - { - return m_value.end(); - } - - const_iterator begin() const - { - return m_value.begin(); - } - - const_iterator end() const - { - return m_value.end(); - } - - const_iterator cbegin() const - { - return m_value.cbegin(); - } - - const_iterator cend() const - { - return m_value.cend(); - } - -private: - integer_type m_value; -}; -#endif - -#endif diff --git a/src/ripple_data/protocol/RippleAddress.cpp b/src/ripple_data/protocol/RippleAddress.cpp index bb2f3e77c5..5761171829 100644 --- a/src/ripple_data/protocol/RippleAddress.cpp +++ b/src/ripple_data/protocol/RippleAddress.cpp @@ -12,15 +12,6 @@ RippleAddress::RippleAddress () nVersion = VER_NONE; } -RipplePublicKey RippleAddress::toRipplePublicKey () const -{ - Blob const& b (getNodePublic ()); - - check_precondition (b.size () == RipplePublicKey::sizeInBytes); - - return RipplePublicKey (&b [0]); -} - void RippleAddress::clear () { nVersion = VER_NONE; @@ -318,6 +309,10 @@ std::string RippleAddress::humanAccountID () const if (it != rncMap.end ()) return it->second; + // VFALCO NOTE Why do we throw everything out? We could keep two maps + // here, switch back and forth keep one of them full and clear the + // other on a swap - but always check both maps for cache hits. + // if (rncMap.size () > 10000) rncMap.clear (); @@ -953,3 +948,74 @@ public: }; static RippleAddressTests rippleAddressTests; + +//------------------------------------------------------------------------------ + +class RippleCryptoIdentifierTests : public UnitTest +{ +public: + void runTest () + { + beginTestCase ("Seed"); + RippleAddress seed; + expect (seed.setSeedGeneric ("masterpassphrase")); + expect (seed.humanSeed () == "snoPBrXtMeMyMHUVTgbuqAfg1SUTb", seed.humanSeed ()); + + beginTestCase ("RipplePublicKey"); + RippleAddress deprecatedPublicKey (RippleAddress::createNodePublic (seed)); + expect (deprecatedPublicKey.humanNodePublic () == + "n94a1u4jAz288pZLtw6yFWVbi89YamiC6JBXPVUj5zmExe5fTVg9", + deprecatedPublicKey.humanNodePublic ()); + RipplePublicKey publicKey (deprecatedPublicKey); + expect (publicKey.to_string() == deprecatedPublicKey.humanNodePublic(), + publicKey.to_string()); + + beginTestCase ("RipplePrivateKey"); + RippleAddress deprecatedPrivateKey (RippleAddress::createNodePrivate (seed)); + expect (deprecatedPrivateKey.humanNodePrivate () == + "pnen77YEeUd4fFKG7iycBWcwKpTaeFRkW2WFostaATy1DSupwXe", + deprecatedPrivateKey.humanNodePrivate ()); + RipplePrivateKey privateKey (deprecatedPrivateKey); + expect (privateKey.to_string() == deprecatedPrivateKey.humanNodePrivate(), + privateKey.to_string()); + + beginTestCase ("Generator"); + RippleAddress generator (RippleAddress::createGeneratorPublic (seed)); + expect (generator.humanGenerator () == + "fhuJKrhSDzV2SkjLn9qbwm5AaRmrxDPfFsHDCP6yfDZWcxDFz4mt", + generator.humanGenerator ()); + + beginTestCase ("RippleAccountID"); + RippleAddress deprecatedAccountPublicKey ( + RippleAddress::createAccountPublic (generator, 0)); + expect (deprecatedAccountPublicKey.humanAccountID () == + "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + deprecatedAccountPublicKey.humanAccountID ()); + RippleAccountID accountID (deprecatedAccountPublicKey); + expect (accountID.to_string() == + deprecatedAccountPublicKey.humanAccountID(), + accountID.to_string()); + + beginTestCase ("RippleAccountPublicKey"); + expect (deprecatedAccountPublicKey.humanAccountPublic () == + "aBQG8RQAzjs1eTKFEAQXr2gS4utcDiEC9wmi7pfUPTi27VCahwgw", + deprecatedAccountPublicKey.humanAccountPublic ()); + + beginTestCase ("RippleAccountPrivateKey"); + RippleAddress deprecatedAccountPrivateKey ( + RippleAddress::createAccountPrivate (generator, seed, 0)); + expect (deprecatedAccountPrivateKey.humanAccountPrivate () == + "p9JfM6HHi64m6mvB6v5k7G2b1cXzGmYiCNJf6GHPKvFTWdeRVjh", + deprecatedAccountPrivateKey.humanAccountPrivate ()); + RippleAccountPrivateKey accountPrivateKey (deprecatedAccountPrivateKey); + expect (accountPrivateKey.to_string() == + deprecatedAccountPrivateKey.humanAccountPrivate(), + privateKey.to_string()); + } + + RippleCryptoIdentifierTests () : UnitTest ("RippleCryptoIdentifier", "ripple") + { + } +}; + +static RippleCryptoIdentifierTests rippleCryptoIdentifierTests; diff --git a/src/ripple_data/protocol/RippleAddress.h b/src/ripple_data/protocol/RippleAddress.h index 504d33dc42..687fed7c34 100644 --- a/src/ripple_data/protocol/RippleAddress.h +++ b/src/ripple_data/protocol/RippleAddress.h @@ -31,11 +31,6 @@ private: public: RippleAddress (); - // Convert to a binary public key. If the underlying data - // is not appropriate, this will cause a fatal error. - // - RipplePublicKey toRipplePublicKey () const; - // For public and private key, checks if they are legal. bool isValid () const { @@ -209,4 +204,56 @@ public: static RippleAddress createSeedGeneric (const std::string& strText); }; +//------------------------------------------------------------------------------ + +template <> +struct RipplePublicKeyTraits::assign +{ + void operator() (value_type& value, RippleAddress const& v) const + { + Blob const& b (v.getNodePublic ()); + construct (&b.front(), &b.back()+1, value); + } +}; + +template <> +struct RipplePrivateKeyTraits::assign +{ + void operator() (value_type& value, RippleAddress const& v) const + { + uint256 const ui (v.getNodePrivate ()); + construct (ui.begin(), ui.end(), value); + } +}; + +template <> +struct RippleAccountIDTraits::assign +{ + void operator() (value_type& value, RippleAddress const& v) const + { + uint160 const ui (v.getAccountID ()); + construct (ui.begin(), ui.end(), value); + } +}; + +template <> +struct RippleAccountPublicKeyTraits::assign +{ + void operator() (value_type& value, RippleAddress const& v) const + { + Blob const& b (v.getAccountPublic ()); + construct (&b.front(), &b.back()+1, value); + } +}; + +template <> +struct RippleAccountPrivateKeyTraits::assign +{ + void operator() (value_type& value, RippleAddress const& v) const + { + uint256 const ui (v.getAccountPrivate ()); + construct (ui.begin(), ui.end(), value); + } +}; + #endif