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