diff --git a/Builds/VisualStudio2013/RippleD.vcxproj b/Builds/VisualStudio2013/RippleD.vcxproj
index 3e358f52f7..08916b7fb5 100644
--- a/Builds/VisualStudio2013/RippleD.vcxproj
+++ b/Builds/VisualStudio2013/RippleD.vcxproj
@@ -2639,6 +2639,8 @@
+
+
@@ -2659,6 +2661,10 @@
True
True
+
+ True
+ True
+
True
True
diff --git a/Builds/VisualStudio2013/RippleD.vcxproj.filters b/Builds/VisualStudio2013/RippleD.vcxproj.filters
index 15ca986ed7..c401660506 100644
--- a/Builds/VisualStudio2013/RippleD.vcxproj.filters
+++ b/Builds/VisualStudio2013/RippleD.vcxproj.filters
@@ -3339,6 +3339,9 @@
ripple\protocol
+
+ ripple\protocol
+
ripple\protocol
@@ -3357,6 +3360,9 @@
ripple\protocol\impl
+
+ ripple\protocol\impl
+
ripple\protocol\impl
diff --git a/src/BeastConfig.h b/src/BeastConfig.h
index a36422da94..225ed982e0 100644
--- a/src/BeastConfig.h
+++ b/src/BeastConfig.h
@@ -187,4 +187,9 @@
#define RIPPLE_ENABLE_MULTI_SIGN 0
#endif
+// Uses OpenSSL instead of alternatives
+#ifndef RIPPLE_USE_OPENSSL
+#define RIPPLE_USE_OPENSSL 0
+#endif
+
#endif
diff --git a/src/ripple/protocol/digest.h b/src/ripple/protocol/digest.h
new file mode 100644
index 0000000000..ae81f3c1f2
--- /dev/null
+++ b/src/ripple/protocol/digest.h
@@ -0,0 +1,158 @@
+//------------------------------------------------------------------------------
+/*
+ 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.
+*/
+//==============================================================================
+
+#ifndef RIPPLE_PROTOCOL_DIGEST_H_INCLUDED
+#define RIPPLE_PROTOCOL_DIGEST_H_INCLUDED
+
+#include
+#include
+#include
+#include
+#include
+
+namespace ripple {
+
+/* Message digest functions used in the Ripple Protocol
+
+ Modeled to meet the requirements of `Hasher` in the
+ `hash_append` interface, currently in proposal:
+
+ N3980 "Types Don't Know #"
+ http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3980.html
+*/
+
+//------------------------------------------------------------------------------
+
+/** RIPEMD-160 digest
+
+ @note This uses the OpenSSL implementation
+*/
+struct openssl_ripemd160_hasher
+{
+public:
+ static beast::endian const endian =
+ beast::endian::native;
+
+ using result_type =
+ std::array;
+
+ openssl_ripemd160_hasher();
+
+ void
+ operator()(void const* data,
+ std::size_t size) noexcept;
+
+ explicit
+ operator result_type() noexcept;
+
+private:
+ char ctx_[96];
+};
+
+/** SHA-256 digest
+
+ @note This uses the OpenSSL implementation
+*/
+struct openssl_sha256_hasher
+{
+public:
+ static beast::endian const endian =
+ beast::endian::native;
+
+ using result_type =
+ std::array;
+
+ openssl_sha256_hasher();
+
+ void
+ operator()(void const* data,
+ std::size_t size) noexcept;
+
+ explicit
+ operator result_type() noexcept;
+
+private:
+ char ctx_[112];
+};
+
+//------------------------------------------------------------------------------
+
+// Aliases to choose the correct digest implementation
+
+#if RIPPLE_USE_OPENSSL
+using ripemd160_hasher = openssl_ripemd160_hasher;
+using sha256_hasher = openssl_sha256_hasher;
+#else
+using ripemd160_hasher = beast::ripemd160_hasher;
+using sha256_hasher = beast::sha256_hasher;
+#endif
+
+//------------------------------------------------------------------------------
+
+/** Returns the RIPEMD-160 digest of the SHA256 hash of the message.
+
+ This operation is used to compute the 160-bit identifier
+ representing a Ripple account, from a message. Typically the
+ message is the public key of the account - which is not
+ stored in the account root.
+
+ The same computation is used regardless of the cryptographic
+ scheme implied by the public key. For example, the public key
+ may be an ed25519 public key or a secp256k1 public key. Support
+ for new cryptographic systems may be added, using the same
+ formula for calculating the account identifier.
+
+ Meets the requirements of Hasher (in hash_append)
+
+ @param digest A buffer of at least 20 bytes
+*/
+struct ripesha_hasher
+{
+private:
+ sha256_hasher h_;
+
+public:
+ static beast::endian const endian =
+ beast::endian::native;
+
+ using result_type =
+ std::array;
+
+ void
+ operator()(void const* data,
+ std::size_t size) noexcept
+ {
+ h_(data, size);
+ }
+
+ explicit
+ operator result_type() noexcept
+ {
+ auto const d0 = static_cast<
+ decltype(h_)::result_type>(h_);
+ ripemd160_hasher rh;
+ rh(d0.data(), d0.size());
+ return static_cast<
+ decltype(rh)::result_type>(rh);
+ }
+};
+
+} // ripple
+
+#endif
diff --git a/src/ripple/protocol/impl/digest.cpp b/src/ripple/protocol/impl/digest.cpp
new file mode 100644
index 0000000000..ca7f5a5d3d
--- /dev/null
+++ b/src/ripple/protocol/impl/digest.cpp
@@ -0,0 +1,86 @@
+//------------------------------------------------------------------------------
+/*
+ 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.
+*/
+//==============================================================================
+
+#include
+#include
+#include //
+#include
+#include
+
+namespace ripple {
+
+static_assert(sizeof(decltype(
+ openssl_ripemd160_hasher::ctx_)) ==
+ sizeof(RIPEMD160_CTX), "");
+
+openssl_ripemd160_hasher::openssl_ripemd160_hasher()
+{
+ auto const ctx = reinterpret_cast<
+ RIPEMD160_CTX*>(ctx_);
+ RIPEMD160_Init(ctx);
+}
+
+void
+openssl_ripemd160_hasher::operator()(void const* data,
+ std::size_t size) noexcept
+{
+ auto const ctx = reinterpret_cast<
+ RIPEMD160_CTX*>(ctx_);
+ RIPEMD160_Update(ctx, data, size);
+}
+
+openssl_ripemd160_hasher::operator result_type() noexcept
+{
+ auto const ctx = reinterpret_cast<
+ RIPEMD160_CTX*>(ctx_);
+ result_type digest;
+ RIPEMD160_Final(digest.data(), ctx);
+ return digest;
+}
+
+static_assert(sizeof(decltype(
+ openssl_sha256_hasher::ctx_)) ==
+ sizeof(SHA256_CTX), "");
+
+openssl_sha256_hasher::openssl_sha256_hasher()
+{
+ auto const ctx = reinterpret_cast<
+ SHA256_CTX*>(ctx_);
+ SHA256_Init(ctx);
+}
+
+void
+openssl_sha256_hasher::operator()(void const* data,
+ std::size_t size) noexcept
+{
+ auto const ctx = reinterpret_cast<
+ SHA256_CTX*>(ctx_);
+ SHA256_Update(ctx, data, size);
+}
+
+openssl_sha256_hasher::operator result_type() noexcept
+{
+ auto const ctx = reinterpret_cast<
+ SHA256_CTX*>(ctx_);
+ result_type digest;
+ SHA256_Final(digest.data(), ctx);
+ return digest;
+}
+
+} // ripple
diff --git a/src/ripple/unity/protocol.cpp b/src/ripple/unity/protocol.cpp
index 120e0cae1a..a65aa47eb4 100644
--- a/src/ripple/unity/protocol.cpp
+++ b/src/ripple/unity/protocol.cpp
@@ -23,6 +23,7 @@
#include
#include
#include
+#include
#include
#include
#include