From 9c60d6b5d4d7bf4b14830377799e2f1fc99586bc Mon Sep 17 00:00:00 2001 From: clemahieu Date: Sat, 9 Dec 2017 23:15:57 -0600 Subject: [PATCH] First cut at a C shared library interface to node. --- CMakeLists.txt | 22 +- rai/core_test/block.cpp | 7 +- rai/core_test/uint256_union.cpp | 5 +- rai/interface.cpp | 71 +++++ rai/interface.h | 34 +++ rai/node/common.hpp | 5 +- rai/node/node.cpp | 5 +- rai/node/rpc.cpp | 4 +- rai/node/wallet.cpp | 5 +- rai/numbers.cpp | 434 +++++++++++++++++++++++++++++ rai/numbers.hpp | 143 ++++++++++ rai/secure.cpp | 5 +- rai/secure.hpp | 3 + rai/utility.cpp | 469 +------------------------------- rai/utility.hpp | 152 +---------- 15 files changed, 735 insertions(+), 629 deletions(-) create mode 100644 rai/interface.cpp create mode 100644 rai/interface.h create mode 100644 rai/numbers.cpp create mode 100644 rai/numbers.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index e2288bcc..909fba74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -203,6 +203,12 @@ add_library (secure rai/versioning.hpp rai/versioning.cpp) +add_library (rai_lib SHARED + rai/interface.cpp + rai/interface.h + rai/numbers.cpp + rai/numbers.hpp) + add_library (node ${PLATFORM_NODE_SOURCE} rai/node/bootstrap.cpp @@ -290,7 +296,7 @@ add_executable (rai_node set_target_properties (argon2 PROPERTIES COMPILE_FLAGS "${PLATFORM_C_FLAGS} ${PLATFORM_COMPILE_FLAGS}") set_target_properties (blake2 PROPERTIES COMPILE_FLAGS "${PLATFORM_C_FLAGS} ${PLATFORM_COMPILE_FLAGS} -D__SSE2__") set_target_properties (ed25519 PROPERTIES COMPILE_FLAGS "${PLATFORM_C_FLAGS} ${PLATFORM_COMPILE_FLAGS} -DED25519_CUSTOMHASH -DED25519_CUSTOMRNG") -set_target_properties (secure node rai_node PROPERTIES COMPILE_FLAGS "${PLATFORM_CXX_FLAGS} ${PLATFORM_COMPILE_FLAGS} -DQT_NO_KEYWORDS -DACTIVE_NETWORK=${ACTIVE_NETWORK} -DRAIBLOCKS_VERSION_MAJOR=${CPACK_PACKAGE_VERSION_MAJOR} -DRAIBLOCKS_VERSION_MINOR=${CPACK_PACKAGE_VERSION_MINOR} -DBOOST_ASIO_HAS_STD_ARRAY=1") +set_target_properties (secure node rai_node rai_lib PROPERTIES COMPILE_FLAGS "${PLATFORM_CXX_FLAGS} ${PLATFORM_COMPILE_FLAGS} -DQT_NO_KEYWORDS -DACTIVE_NETWORK=${ACTIVE_NETWORK} -DRAIBLOCKS_VERSION_MAJOR=${CPACK_PACKAGE_VERSION_MAJOR} -DRAIBLOCKS_VERSION_MINOR=${CPACK_PACKAGE_VERSION_MINOR} -DBOOST_ASIO_HAS_STD_ARRAY=1") set_target_properties (secure node rai_node PROPERTIES LINK_FLAGS "${PLATFORM_LINK_FLAGS}") if (WIN32) @@ -306,20 +312,22 @@ else (WIN32) endif (WIN32) if (RAIBLOCKS_TEST) - target_link_libraries (core_test node secure lmdb xxhash ed25519 argon2 blake2 ${CRYPTOPP_LIBRARY} gtest_main gtest libminiupnpc-static ${Boost_ATOMIC_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_THREAD_LIBRARY} ${PLATFORM_LIBS}) + target_link_libraries (core_test node secure lmdb rai_lib argon2 ${CRYPTOPP_LIBRARY} gtest_main gtest libminiupnpc-static ${Boost_ATOMIC_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_THREAD_LIBRARY} ${PLATFORM_LIBS}) - target_link_libraries (slow_test node secure lmdb xxhash ed25519 argon2 blake2 ${CRYPTOPP_LIBRARY} gtest_main gtest libminiupnpc-static ${Boost_ATOMIC_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} ${PLATFORM_LIBS}) + target_link_libraries (slow_test node secure lmdb rai_lib argon2 ${CRYPTOPP_LIBRARY} gtest_main gtest libminiupnpc-static ${Boost_ATOMIC_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} ${PLATFORM_LIBS}) endif (RAIBLOCKS_TEST) if (RAIBLOCKS_GUI) - target_link_libraries (qt_test node secure lmdb xxhash ed25519 qt argon2 blake2 ${CRYPTOPP_LIBRARY} gtest libminiupnpc-static ${Boost_ATOMIC_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Test ${QT_QTGUI_LIBRARY} ${PLATFORM_LIBS}) + target_link_libraries (qt_test node secure lmdb rai_lib qt argon2 ${CRYPTOPP_LIBRARY} gtest libminiupnpc-static ${Boost_ATOMIC_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Test ${QT_QTGUI_LIBRARY} ${PLATFORM_LIBS}) - target_link_libraries (qt_system node secure lmdb xxhash ed25519 qt argon2 blake2 ${CRYPTOPP_LIBRARY} gtest libminiupnpc-static ${Boost_ATOMIC_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} Qt5::Core Qt5::Gui Qt5::Widgets ${QT_QTGUI_LIBRARY} ${PLATFORM_LIBS}) + target_link_libraries (qt_system node secure lmdb rai_lib qt argon2 ${CRYPTOPP_LIBRARY} gtest libminiupnpc-static ${Boost_ATOMIC_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} Qt5::Core Qt5::Gui Qt5::Widgets ${QT_QTGUI_LIBRARY} ${PLATFORM_LIBS}) - target_link_libraries (rai_wallet node secure lmdb xxhash ed25519 qt argon2 blake2 ${CRYPTOPP_LIBRARY} libminiupnpc-static ${Boost_ATOMIC_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} Qt5::Core Qt5::Gui Qt5::Widgets ${QT_QTGUI_LIBRARY} ${PLATFORM_LIBS} ${PLATFORM_WALLET_LIBS}) + target_link_libraries (rai_wallet node secure lmdb rai_lib qt argon2 ${CRYPTOPP_LIBRARY} libminiupnpc-static ${Boost_ATOMIC_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} Qt5::Core Qt5::Gui Qt5::Widgets ${QT_QTGUI_LIBRARY} ${PLATFORM_LIBS} ${PLATFORM_WALLET_LIBS}) endif (RAIBLOCKS_GUI) -target_link_libraries (rai_node node secure lmdb xxhash ed25519 argon2 blake2 ${CRYPTOPP_LIBRARY} libminiupnpc-static ${Boost_ATOMIC_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} ${PLATFORM_LIBS}) +target_link_libraries (rai_lib xxhash ed25519 blake2 ${CRYPTOPP_LIBRARY}) + +target_link_libraries (rai_node node secure lmdb rai_lib argon2 ${CRYPTOPP_LIBRARY} libminiupnpc-static ${Boost_ATOMIC_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} ${PLATFORM_LIBS}) set (CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/LICENSE) if (RAIBLOCKS_GUI) diff --git a/rai/core_test/block.cpp b/rai/core_test/block.cpp index 88d9cd99..65fab6ed 100644 --- a/rai/core_test/block.cpp +++ b/rai/core_test/block.cpp @@ -1,14 +1,15 @@ #include -#include - #include #include +#include #include #include +#include + TEST (ed25519, signing) { rai::uint256_union prv (0); @@ -323,4 +324,4 @@ TEST (block, confirm_req_serialization) ASSERT_FALSE (error); ASSERT_EQ (req, req2); ASSERT_EQ (*req.block, *req2.block); -} \ No newline at end of file +} diff --git a/rai/core_test/uint256_union.cpp b/rai/core_test/uint256_union.cpp index f1b000be..45ed6df1 100644 --- a/rai/core_test/uint256_union.cpp +++ b/rai/core_test/uint256_union.cpp @@ -1,9 +1,10 @@ -#include - #include +#include #include +#include + TEST (uint128_union, decode_dec) { rai::uint128_union value; diff --git a/rai/interface.cpp b/rai/interface.cpp new file mode 100644 index 00000000..9a47adcd --- /dev/null +++ b/rai/interface.cpp @@ -0,0 +1,71 @@ +#include + +#include + +#include + +#include + +#include + +extern "C" { +void xrb_uint256_to_string (xrb_uint256 source, char * destination) +{ + +} + +void xrb_uint512_to_string (xrb_uint512 source, char * destination) +{ + +} + +int xrb_uint256_from_string (char * source, xrb_uint256 destination) +{ + return 1; +} + +int xrb_uint512_from_string (char * source, xrb_uint512 destination) +{ + return 1; +} + +int xrb_valid_address (char * account) +{ + return 1; +} + +void sign_transaction (char * transaction, xrb_uint256 private_key, xrb_uint512 signature) +{ + +} + +#include +void ed25519_randombytes_unsafe (void * out, size_t outlen) +{ + rai::random_pool.GenerateBlock (reinterpret_cast (out), outlen); +} +void ed25519_hash_init (ed25519_hash_context * ctx) +{ + ctx->blake2 = new blake2b_state; + blake2b_init (reinterpret_cast (ctx->blake2), 64); +} + +void ed25519_hash_update (ed25519_hash_context * ctx, uint8_t const * in, size_t inlen) +{ + blake2b_update (reinterpret_cast (ctx->blake2), in, inlen); +} + +void ed25519_hash_final (ed25519_hash_context * ctx, uint8_t * out) +{ + blake2b_final (reinterpret_cast (ctx->blake2), out, 64); + delete reinterpret_cast (ctx->blake2); +} + +void ed25519_hash (uint8_t * out, uint8_t const * in, size_t inlen) +{ + ed25519_hash_context ctx; + ed25519_hash_init (&ctx); + ed25519_hash_update (&ctx, in, inlen); + ed25519_hash_final (&ctx, out); +} +} diff --git a/rai/interface.h b/rai/interface.h new file mode 100644 index 00000000..68f3a1c6 --- /dev/null +++ b/rai/interface.h @@ -0,0 +1,34 @@ +#ifndef XRB_INTERFACE_H +#define XRB_INTERFACE_H + +#if __cplusplus +extern "C" { +#endif + +typedef char * xrb_uint256; // 32byte array for public and private keys +typedef char * xrb_uint512; // 64byte array for signatures + +// Convert public/private key bytes 'source' to a 64 byte not-null-terminated hex string 'destination' +void xrb_uint256_to_string (xrb_uint256 source, char * destination); +// Convert public/private key bytes 'source' to a 128 byte not-null-terminated hex string 'destination' +void xrb_uint512_to_string (xrb_uint512 source, char * destination); + +// Convert 64 byte hex string 'source' to a byte array 'destination' +// Return 0 on success, nonzero on error +int xrb_uint256_from_string (char * source, xrb_uint256 destination); +// Convert 128 byte hex string 'source' to a byte array 'destination' +// Return 0 on success, nonzero on error +int xrb_uint512_from_string (char * source, xrb_uint512 destination); + +// Check if the null-terminated string 'account' is a valid xrb account number +// Return 0 on correct, nonzero on invalid +int xrb_valid_address (char * account); + +// Sign 'transaction' using 'private_key' and write to 'signature' +void sign_transaction (char * transaction, xrb_uint256 private_key, xrb_uint512 signature); + +#if __cplusplus +} // extern "C" +#endif + +#endif // XRB_INTERFACE_H diff --git a/rai/node/common.hpp b/rai/node/common.hpp index bdb2dea1..28da3e7f 100644 --- a/rai/node/common.hpp +++ b/rai/node/common.hpp @@ -1,13 +1,14 @@ #pragma once +#include #include #include -#include - #include +#include + namespace rai { using endpoint = boost::asio::ip::udp::endpoint; diff --git a/rai/node/node.cpp b/rai/node/node.cpp index 15427fe3..7bda1a9a 100755 --- a/rai/node/node.cpp +++ b/rai/node/node.cpp @@ -1,5 +1,6 @@ #include +#include #include #include @@ -18,10 +19,10 @@ #include #include -#include - #include +#include + double constexpr rai::node::price_max; double constexpr rai::node::free_cutoff; std::chrono::seconds constexpr rai::node::period; diff --git a/rai/node/rpc.cpp b/rai/node/rpc.cpp index fcd3b981..786cd382 100755 --- a/rai/node/rpc.cpp +++ b/rai/node/rpc.cpp @@ -1,8 +1,10 @@ #include -#include #include +#include +#include + #include rai::rpc_config::rpc_config () : diff --git a/rai/node/wallet.cpp b/rai/node/wallet.cpp index 00796e3f..4b40356b 100644 --- a/rai/node/wallet.cpp +++ b/rai/node/wallet.cpp @@ -1,5 +1,6 @@ #include +#include #include #include @@ -8,10 +9,10 @@ #include #include -#include - #include +#include + rai::work_pool::work_pool (unsigned max_threads_a, std::unique_ptr opencl_a) : ticket (0), done (false), diff --git a/rai/numbers.cpp b/rai/numbers.cpp new file mode 100644 index 00000000..224cfc3e --- /dev/null +++ b/rai/numbers.cpp @@ -0,0 +1,434 @@ +#include + +#include + +#include + +#include +#include + +thread_local CryptoPP::AutoSeededRandomPool rai::random_pool; + +namespace +{ + char const * base58_reverse ("~012345678~~~~~~~9:;<=>?@~ABCDE~FGHIJKLMNOP~~~~~~QRSTUVWXYZ[~\\]^_`abcdefghi"); + uint8_t base58_decode (char value) + { + assert (value >= '0'); + assert (value <= '~'); + auto result (base58_reverse [value - 0x30] - 0x30); + return result; + } + char const * account_lookup ("13456789abcdefghijkmnopqrstuwxyz"); + char const * account_reverse ("~0~1234567~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~89:;<=>?@AB~CDEFGHIJK~LMNO~~~~~"); + char account_encode (uint8_t value) + { + assert (value < 32); + auto result (account_lookup [value]); + return result; + } + uint8_t account_decode (char value) + { + assert (value >= '0'); + assert (value <= '~'); + auto result (account_reverse [value - 0x30] - 0x30); + return result; + } +} + +void rai::uint256_union::encode_account (std::string & destination_a) const +{ + assert (destination_a.empty ()); + destination_a.reserve (64); + uint64_t check (0); + blake2b_state hash; + blake2b_init (&hash, 5); + blake2b_update (&hash, bytes.data (), bytes.size ()); + blake2b_final (&hash, reinterpret_cast (&check), 5); + rai::uint512_t number_l (number ()); + number_l <<= 40; + number_l |= rai::uint512_t (check); + for (auto i (0); i < 60; ++i) + { + auto r (number_l.convert_to () & 0x1f); + number_l >>= 5; + destination_a.push_back (account_encode (r)); + } + destination_a.append ("_brx"); // xrb_ + std::reverse (destination_a.begin (), destination_a.end ()); +} + +std::string rai::uint256_union::to_account_split () const +{ + auto result (to_account ()); + assert (result.size () == 64); + result.insert (32, "\n"); + return result; +} + +std::string rai::uint256_union::to_account () const +{ + std::string result; + encode_account (result); + return result; +} + +bool rai::uint256_union::decode_account_v1 (std::string const & source_a) +{ + auto result (source_a.size () != 50); + if (!result) + { + rai::uint512_t number_l; + for (auto i (source_a.begin ()), j (source_a.end ()); !result && i != j; ++i) + { + uint8_t character (*i); + result = character < 0x30 || character >= 0x80; + if (!result) + { + uint8_t byte (base58_decode (character)); + result = byte == '~'; + if (!result) + { + number_l *= 58; + number_l += byte; + } + } + } + if (!result) + { + *this = number_l.convert_to (); + uint32_t check ((number_l >> 256).convert_to ()); + result = (number_l >> (256 + 32)) != 13; + if (!result) + { + uint32_t validation; + blake2b_state hash; + blake2b_init (&hash, sizeof (validation)); + blake2b_update (&hash, bytes.data (), sizeof (bytes)); + blake2b_final (&hash, reinterpret_cast (&validation), sizeof (validation)); + result = check != validation; + } + } + } + return result; +} + +bool rai::uint256_union::decode_account (std::string const & source_a) +{ + auto result (source_a.size () != 64); + if (!result) + { + if (source_a [0] == 'x' && source_a [1] == 'r' && source_a [2] == 'b' && (source_a [3] == '_' || source_a [3] == '-')) + { + rai::uint512_t number_l; + for (auto i (source_a.begin () + 4), j (source_a.end ()); !result && i != j; ++i) + { + uint8_t character (*i); + result = character < 0x30 || character >= 0x80; + if (!result) + { + uint8_t byte (account_decode (character)); + result = byte == '~'; + if (!result) + { + number_l <<= 5; + number_l += byte; + } + } + } + if (!result) + { + *this = (number_l >> 40).convert_to (); + uint64_t check (number_l.convert_to ()); + check &= 0xffffffffff; + uint64_t validation (0); + blake2b_state hash; + blake2b_init (&hash, 5); + blake2b_update (&hash, bytes.data (), bytes.size ()); + blake2b_final (&hash, reinterpret_cast (&validation), 5); + result = check != validation; + } + } + else + { + result = true; + } + } + else + { + result = decode_account_v1 (source_a); + } + return result; +} + +rai::uint256_union::uint256_union (rai::uint256_t const & number_a) +{ + rai::uint256_t number_l (number_a); + for (auto i (bytes.rbegin ()), n (bytes.rend ()); i != n; ++i) + { + *i = ((number_l) & 0xff).convert_to (); + number_l >>= 8; + } +} + +bool rai::uint256_union::operator == (rai::uint256_union const & other_a) const +{ + return bytes == other_a.bytes; +} + +// Construct a uint256_union = AES_ENC_CTR (cleartext, key, iv) +void rai::uint256_union::encrypt (rai::raw_key const & cleartext, rai::raw_key const & key, uint128_union const & iv) +{ + CryptoPP::AES::Encryption alg (key.data.bytes.data (), sizeof (key.data.bytes)); + CryptoPP::CTR_Mode_ExternalCipher::Encryption enc (alg, iv.bytes.data ()); + enc.ProcessData (bytes.data (), cleartext.data.bytes.data (), sizeof (cleartext.data.bytes)); +} + +bool rai::uint256_union::is_zero () const +{ + return qwords [0] == 0 && qwords [1] == 0 && qwords [2] == 0 && qwords [3] == 0; +} + +std::string rai::uint256_union::to_string () const +{ + std::string result; + encode_hex (result); + return result; +} + +bool rai::uint256_union::operator < (rai::uint256_union const & other_a) const +{ + return number () < other_a.number (); +} + +rai::uint256_union & rai::uint256_union::operator ^= (rai::uint256_union const & other_a) +{ + auto j (other_a.qwords.begin ()); + for (auto i (qwords.begin ()), n (qwords.end ()); i != n; ++i, ++j) + { + *i ^= *j; + } + return *this; +} + +rai::uint256_union rai::uint256_union::operator ^ (rai::uint256_union const & other_a) const +{ + rai::uint256_union result; + auto k (result.qwords.begin ()); + for (auto i (qwords.begin ()), j (other_a.qwords.begin ()), n (qwords.end ()); i != n; ++i, ++j, ++k) + { + *k = *i ^ *j; + } + return result; +} + +rai::uint256_union::uint256_union (std::string const & hex_a) +{ + decode_hex (hex_a); +} + +void rai::uint256_union::clear () +{ + qwords.fill (0); +} + +rai::uint256_t rai::uint256_union::number () const +{ + rai::uint256_t result; + auto shift (0); + for (auto i (bytes.begin ()), n (bytes.end ()); i != n; ++i) + { + result <<= shift; + result |= *i; + shift = 8; + } + return result; +} + +void rai::uint256_union::encode_hex (std::string & text) const +{ + assert (text.empty ()); + std::stringstream stream; + stream << std::hex << std::noshowbase << std::setw (64) << std::setfill ('0'); + stream << number (); + text = stream.str (); +} + +bool rai::uint256_union::decode_hex (std::string const & text) +{ + auto result (false); + if (!text.empty ()) + { + if (text.size () <= 64) + { + std::stringstream stream (text); + stream << std::hex << std::noshowbase; + rai::uint256_t number_l; + try + { + stream >> number_l; + *this = number_l; + if (!stream.eof ()) + { + result = true; + } + } + catch (std::runtime_error &) + { + result = true; + } + } + else + { + result = true; + } + } + else + { + result = true; + } + return result; +} + +void rai::uint256_union::encode_dec (std::string & text) const +{ + assert (text.empty ()); + std::stringstream stream; + stream << std::dec << std::noshowbase; + stream << number (); + text = stream.str (); +} + +bool rai::uint256_union::decode_dec (std::string const & text) +{ + auto result (text.size () > 78); + if (!result) + { + std::stringstream stream (text); + stream << std::dec << std::noshowbase; + rai::uint256_t number_l; + try + { + stream >> number_l; + *this = number_l; + } + catch (std::runtime_error &) + { + result = true; + } + } + return result; +} + +rai::uint256_union::uint256_union (uint64_t value0) +{ + *this = rai::uint256_t (value0); +} + +bool rai::uint256_union::operator != (rai::uint256_union const & other_a) const +{ + return ! (*this == other_a); +} + +bool rai::uint512_union::operator == (rai::uint512_union const & other_a) const +{ + return bytes == other_a.bytes; +} + +rai::uint512_union::uint512_union (rai::uint512_t const & number_a) +{ + rai::uint512_t number_l (number_a); + for (auto i (bytes.rbegin ()), n (bytes.rend ()); i != n; ++i) + { + *i = ((number_l) & 0xff).convert_to (); + number_l >>= 8; + } +} + +void rai::uint512_union::clear () +{ + bytes.fill (0); +} + +rai::uint512_t rai::uint512_union::number () const +{ + rai::uint512_t result; + auto shift (0); + for (auto i (bytes.begin ()), n (bytes.end ()); i != n; ++i) + { + result <<= shift; + result |= *i; + shift = 8; + } + return result; +} + +void rai::uint512_union::encode_hex (std::string & text) const +{ + assert (text.empty ()); + std::stringstream stream; + stream << std::hex << std::noshowbase << std::setw (128) << std::setfill ('0'); + stream << number (); + text = stream.str (); +} + +bool rai::uint512_union::decode_hex (std::string const & text) +{ + auto result (text.size () > 128); + if (!result) + { + std::stringstream stream (text); + stream << std::hex << std::noshowbase; + rai::uint512_t number_l; + try + { + stream >> number_l; + *this = number_l; + if (!stream.eof ()) + { + result = true; + } + } + catch (std::runtime_error &) + { + result = true; + } + } + return result; +} + +bool rai::uint512_union::operator != (rai::uint512_union const & other_a) const +{ + return ! (*this == other_a); +} + +rai::uint512_union & rai::uint512_union::operator ^= (rai::uint512_union const & other_a) +{ + uint256s [0] ^= other_a.uint256s [0]; + uint256s [1] ^= other_a.uint256s [1]; + return *this; +} + +rai::raw_key::~raw_key () +{ + data.clear (); +} + +bool rai::raw_key::operator == (rai::raw_key const & other_a) const +{ + return data == other_a.data; +} + +bool rai::raw_key::operator != (rai::raw_key const & other_a) const +{ + return !(*this == other_a); +} + +// This this = AES_DEC_CTR (ciphertext, key, iv) +void rai::raw_key::decrypt (rai::uint256_union const & ciphertext, rai::raw_key const & key_a, uint128_union const & iv) +{ + CryptoPP::AES::Encryption alg (key_a.data.bytes.data (), sizeof (key_a.data.bytes)); + CryptoPP::CTR_Mode_ExternalCipher::Decryption dec (alg, iv.bytes.data ()); + dec.ProcessData (data.bytes.data (), ciphertext.bytes.data (), sizeof (ciphertext.bytes)); +} + diff --git a/rai/numbers.hpp b/rai/numbers.hpp new file mode 100644 index 00000000..e9fbaa92 --- /dev/null +++ b/rai/numbers.hpp @@ -0,0 +1,143 @@ +#pragma once + +#include + +#include + +namespace rai { +// Random pool used by RaiBlocks. +// This must be thread_local as long as the AutoSeededRandomPool implementation requires it +extern thread_local CryptoPP::AutoSeededRandomPool random_pool; +using uint128_t = boost::multiprecision::uint128_t; +using uint256_t = boost::multiprecision::uint256_t; +using uint512_t = boost::multiprecision::uint512_t; +// SI dividers +rai::uint128_t const Gxrb_ratio = rai::uint128_t ("1000000000000000000000000000000000"); // 10^33 +rai::uint128_t const Mxrb_ratio = rai::uint128_t ("1000000000000000000000000000000"); // 10^30 +rai::uint128_t const kxrb_ratio = rai::uint128_t ("1000000000000000000000000000"); // 10^27 +rai::uint128_t const xrb_ratio = rai::uint128_t ("1000000000000000000000000"); // 10^24 +rai::uint128_t const mxrb_ratio = rai::uint128_t ("1000000000000000000000"); // 10^21 +rai::uint128_t const uxrb_ratio = rai::uint128_t ("1000000000000000000"); // 10^18 + +union uint128_union +{ +public: + uint128_union () = default; + uint128_union (std::string const &); + uint128_union (uint64_t); + uint128_union (rai::uint128_union const &) = default; + uint128_union (rai::uint128_t const &); + bool operator == (rai::uint128_union const &) const; + bool operator != (rai::uint128_union const &) const; + bool operator < (rai::uint128_union const &) const; + bool operator > (rai::uint128_union const &) const; + void encode_hex (std::string &) const; + bool decode_hex (std::string const &); + void encode_dec (std::string &) const; + bool decode_dec (std::string const &); + rai::uint128_t number () const; + void clear (); + bool is_zero () const; + std::string to_string () const; + std::string to_string_dec () const; + std::array bytes; + std::array chars; + std::array dwords; + std::array qwords; +}; +// Balances are 128 bit. +using amount = uint128_union; +class raw_key; +union uint256_union +{ + uint256_union () = default; + uint256_union (std::string const &); + uint256_union (uint64_t); + uint256_union (rai::uint256_t const &); + void encrypt (rai::raw_key const &, rai::raw_key const &, uint128_union const &); + uint256_union & operator ^= (rai::uint256_union const &); + uint256_union operator ^ (rai::uint256_union const &) const; + bool operator == (rai::uint256_union const &) const; + bool operator != (rai::uint256_union const &) const; + bool operator < (rai::uint256_union const &) const; + void encode_hex (std::string &) const; + bool decode_hex (std::string const &); + void encode_dec (std::string &) const; + bool decode_dec (std::string const &); + void encode_account (std::string &) const; + std::string to_account () const; + std::string to_account_split () const; + bool decode_account_v1 (std::string const &); + bool decode_account (std::string const &); + std::array bytes; + std::array chars; + std::array dwords; + std::array qwords; + std::array owords; + void clear (); + bool is_zero () const; + std::string to_string () const; + rai::uint256_t number () const; +}; +// All keys and hashes are 256 bit. +using block_hash = uint256_union; +using account = uint256_union; +using public_key = uint256_union; +using private_key = uint256_union; +using secret_key = uint256_union; +using checksum = uint256_union; +class raw_key +{ +public: + raw_key () = default; + ~raw_key (); + void decrypt (rai::uint256_union const &, rai::raw_key const &, uint128_union const &); + raw_key (rai::raw_key const &) = delete; + raw_key (rai::raw_key const &&) = delete; + rai::raw_key & operator = (rai::raw_key const &) = delete; + bool operator == (rai::raw_key const &) const; + bool operator != (rai::raw_key const &) const; + rai::uint256_union data; +}; +union uint512_union +{ + uint512_union () = default; + uint512_union (rai::uint512_t const &); + bool operator == (rai::uint512_union const &) const; + bool operator != (rai::uint512_union const &) const; + rai::uint512_union & operator ^= (rai::uint512_union const &); + void encode_hex (std::string &) const; + bool decode_hex (std::string const &); + std::array bytes; + std::array dwords; + std::array qwords; + std::array uint256s; + void clear (); + rai::uint512_t number () const; +}; +// Only signatures are 512 bit. +using signature = uint512_union; + +rai::uint512_union sign_message (rai::raw_key const &, rai::public_key const &, rai::uint256_union const &); +bool validate_message (rai::public_key const &, rai::uint256_union const &, rai::uint512_union const &); +} + +namespace std +{ +template <> +struct hash +{ + size_t operator () (rai::uint256_union const & data_a) const + { + return *reinterpret_cast (data_a.bytes.data ()); + } +}; +template <> +struct hash +{ + size_t operator () (rai::uint256_t const & number_a) const + { + return number_a.convert_to (); + } +}; +} diff --git a/rai/secure.cpp b/rai/secure.cpp index ba1e9dc0..f7c7a4dd 100755 --- a/rai/secure.cpp +++ b/rai/secure.cpp @@ -1,16 +1,15 @@ #include +#include #include #include #include -#include +#include #include -#include - // Genesis keys for network variants namespace { diff --git a/rai/secure.hpp b/rai/secure.hpp index 2c43f20e..b3e91ff4 100644 --- a/rai/secure.hpp +++ b/rai/secure.hpp @@ -5,6 +5,9 @@ #include #include + +#include + namespace boost { template <> diff --git a/rai/utility.cpp b/rai/utility.cpp index 9fc79200..e1c827c2 100644 --- a/rai/utility.cpp +++ b/rai/utility.cpp @@ -1,13 +1,10 @@ #include -#include -#include - -#include +#include #include -thread_local CryptoPP::AutoSeededRandomPool rai::random_pool; +#include boost::filesystem::path rai::unique_path () { @@ -308,473 +305,17 @@ std::string rai::uint128_union::to_string_dec () const return result; } -bool rai::uint256_union::operator == (rai::uint256_union const & other_a) const -{ - return bytes == other_a.bytes; -} - -// Construct a uint256_union = AES_ENC_CTR (cleartext, key, iv) -void rai::uint256_union::encrypt (rai::raw_key const & cleartext, rai::raw_key const & key, uint128_union const & iv) -{ - CryptoPP::AES::Encryption alg (key.data.bytes.data (), sizeof (key.data.bytes)); - CryptoPP::CTR_Mode_ExternalCipher::Encryption enc (alg, iv.bytes.data ()); - enc.ProcessData (bytes.data (), cleartext.data.bytes.data (), sizeof (cleartext.data.bytes)); -} - -bool rai::uint256_union::is_zero () const -{ - return qwords [0] == 0 && qwords [1] == 0 && qwords [2] == 0 && qwords [3] == 0; -} - -std::string rai::uint256_union::to_string () const -{ - std::string result; - encode_hex (result); - return result; -} - -bool rai::uint256_union::operator < (rai::uint256_union const & other_a) const -{ - return number () < other_a.number (); -} - -rai::uint256_union & rai::uint256_union::operator ^= (rai::uint256_union const & other_a) -{ - auto j (other_a.qwords.begin ()); - for (auto i (qwords.begin ()), n (qwords.end ()); i != n; ++i, ++j) - { - *i ^= *j; - } - return *this; -} - -rai::uint256_union rai::uint256_union::operator ^ (rai::uint256_union const & other_a) const -{ - rai::uint256_union result; - auto k (result.qwords.begin ()); - for (auto i (qwords.begin ()), j (other_a.qwords.begin ()), n (qwords.end ()); i != n; ++i, ++j, ++k) - { - *k = *i ^ *j; - } - return result; -} - -rai::uint256_union::uint256_union (std::string const & hex_a) -{ - decode_hex (hex_a); -} - -void rai::uint256_union::clear () -{ - qwords.fill (0); -} - -rai::uint256_t rai::uint256_union::number () const -{ - rai::uint256_t result; - auto shift (0); - for (auto i (bytes.begin ()), n (bytes.end ()); i != n; ++i) - { - result <<= shift; - result |= *i; - shift = 8; - } - return result; -} - -void rai::uint256_union::encode_hex (std::string & text) const -{ - assert (text.empty ()); - std::stringstream stream; - stream << std::hex << std::noshowbase << std::setw (64) << std::setfill ('0'); - stream << number (); - text = stream.str (); -} - -bool rai::uint256_union::decode_hex (std::string const & text) -{ - auto result (false); - if (!text.empty ()) - { - if (text.size () <= 64) - { - std::stringstream stream (text); - stream << std::hex << std::noshowbase; - rai::uint256_t number_l; - try - { - stream >> number_l; - *this = number_l; - if (!stream.eof ()) - { - result = true; - } - } - catch (std::runtime_error &) - { - result = true; - } - } - else - { - result = true; - } - } - else - { - result = true; - } - return result; -} - -void rai::uint256_union::encode_dec (std::string & text) const -{ - assert (text.empty ()); - std::stringstream stream; - stream << std::dec << std::noshowbase; - stream << number (); - text = stream.str (); -} - -bool rai::uint256_union::decode_dec (std::string const & text) -{ - auto result (text.size () > 78); - if (!result) - { - std::stringstream stream (text); - stream << std::dec << std::noshowbase; - rai::uint256_t number_l; - try - { - stream >> number_l; - *this = number_l; - } - catch (std::runtime_error &) - { - result = true; - } - } - return result; -} - -rai::uint256_union::uint256_union (uint64_t value0) -{ - *this = rai::uint256_t (value0); -} - -bool rai::uint256_union::operator != (rai::uint256_union const & other_a) const -{ - return ! (*this == other_a); -} - -rai::raw_key::~raw_key () -{ - data.clear (); -} - -bool rai::raw_key::operator == (rai::raw_key const & other_a) const -{ - return data == other_a.data; -} - -bool rai::raw_key::operator != (rai::raw_key const & other_a) const -{ - return !(*this == other_a); -} - -// This this = AES_DEC_CTR (ciphertext, key, iv) -void rai::raw_key::decrypt (rai::uint256_union const & ciphertext, rai::raw_key const & key_a, uint128_union const & iv) -{ - CryptoPP::AES::Encryption alg (key_a.data.bytes.data (), sizeof (key_a.data.bytes)); - CryptoPP::CTR_Mode_ExternalCipher::Decryption dec (alg, iv.bytes.data ()); - dec.ProcessData (data.bytes.data (), ciphertext.bytes.data (), sizeof (ciphertext.bytes)); -} - -namespace -{ - char const * base58_reverse ("~012345678~~~~~~~9:;<=>?@~ABCDE~FGHIJKLMNOP~~~~~~QRSTUVWXYZ[~\\]^_`abcdefghi"); - uint8_t base58_decode (char value) - { - assert (value >= '0'); - assert (value <= '~'); - auto result (base58_reverse [value - 0x30] - 0x30); - return result; - } - char const * account_lookup ("13456789abcdefghijkmnopqrstuwxyz"); - char const * account_reverse ("~0~1234567~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~89:;<=>?@AB~CDEFGHIJK~LMNO~~~~~"); - char account_encode (uint8_t value) - { - assert (value < 32); - auto result (account_lookup [value]); - return result; - } - uint8_t account_decode (char value) - { - assert (value >= '0'); - assert (value <= '~'); - auto result (account_reverse [value - 0x30] - 0x30); - return result; - } -} - -void rai::uint256_union::encode_account (std::string & destination_a) const -{ - assert (destination_a.empty ()); - destination_a.reserve (64); - uint64_t check (0); - blake2b_state hash; - blake2b_init (&hash, 5); - blake2b_update (&hash, bytes.data (), bytes.size ()); - blake2b_final (&hash, reinterpret_cast (&check), 5); - rai::uint512_t number_l (number ()); - number_l <<= 40; - number_l |= rai::uint512_t (check); - for (auto i (0); i < 60; ++i) - { - auto r (number_l.convert_to () & 0x1f); - number_l >>= 5; - destination_a.push_back (account_encode (r)); - } - destination_a.append ("_brx"); // xrb_ - std::reverse (destination_a.begin (), destination_a.end ()); -} - -std::string rai::uint256_union::to_account_split () const -{ - auto result (to_account ()); - assert (result.size () == 64); - result.insert (32, "\n"); - return result; -} - -std::string rai::uint256_union::to_account () const -{ - std::string result; - encode_account (result); - return result; -} - -bool rai::uint256_union::decode_account_v1 (std::string const & source_a) -{ - auto result (source_a.size () != 50); - if (!result) - { - rai::uint512_t number_l; - for (auto i (source_a.begin ()), j (source_a.end ()); !result && i != j; ++i) - { - uint8_t character (*i); - result = character < 0x30 || character >= 0x80; - if (!result) - { - uint8_t byte (base58_decode (character)); - result = byte == '~'; - if (!result) - { - number_l *= 58; - number_l += byte; - } - } - } - if (!result) - { - *this = number_l.convert_to (); - uint32_t check ((number_l >> 256).convert_to ()); - result = (number_l >> (256 + 32)) != 13; - if (!result) - { - uint32_t validation; - blake2b_state hash; - blake2b_init (&hash, sizeof (validation)); - blake2b_update (&hash, bytes.data (), sizeof (bytes)); - blake2b_final (&hash, reinterpret_cast (&validation), sizeof (validation)); - result = check != validation; - } - } - } - return result; -} - -bool rai::uint256_union::decode_account (std::string const & source_a) -{ - auto result (source_a.size () != 64); - if (!result) - { - if (source_a [0] == 'x' && source_a [1] == 'r' && source_a [2] == 'b' && (source_a [3] == '_' || source_a [3] == '-')) - { - rai::uint512_t number_l; - for (auto i (source_a.begin () + 4), j (source_a.end ()); !result && i != j; ++i) - { - uint8_t character (*i); - result = character < 0x30 || character >= 0x80; - if (!result) - { - uint8_t byte (account_decode (character)); - result = byte == '~'; - if (!result) - { - number_l <<= 5; - number_l += byte; - } - } - } - if (!result) - { - *this = (number_l >> 40).convert_to (); - uint64_t check (number_l.convert_to ()); - check &= 0xffffffffff; - uint64_t validation (0); - blake2b_state hash; - blake2b_init (&hash, 5); - blake2b_update (&hash, bytes.data (), bytes.size ()); - blake2b_final (&hash, reinterpret_cast (&validation), 5); - result = check != validation; - } - } - else - { - result = true; - } - } - else - { - result = decode_account_v1 (source_a); - } - return result; -} - -rai::uint256_union::uint256_union (rai::uint256_t const & number_a) -{ - rai::uint256_t number_l (number_a); - for (auto i (bytes.rbegin ()), n (bytes.rend ()); i != n; ++i) - { - *i = ((number_l) & 0xff).convert_to (); - number_l >>= 8; - } -} - -bool rai::uint512_union::operator == (rai::uint512_union const & other_a) const -{ - return bytes == other_a.bytes; -} - -rai::uint512_union::uint512_union (rai::uint512_t const & number_a) -{ - rai::uint512_t number_l (number_a); - for (auto i (bytes.rbegin ()), n (bytes.rend ()); i != n; ++i) - { - *i = ((number_l) & 0xff).convert_to (); - number_l >>= 8; - } -} - -void rai::uint512_union::clear () -{ - bytes.fill (0); -} - -rai::uint512_t rai::uint512_union::number () const -{ - rai::uint512_t result; - auto shift (0); - for (auto i (bytes.begin ()), n (bytes.end ()); i != n; ++i) - { - result <<= shift; - result |= *i; - shift = 8; - } - return result; -} - -void rai::uint512_union::encode_hex (std::string & text) const -{ - assert (text.empty ()); - std::stringstream stream; - stream << std::hex << std::noshowbase << std::setw (128) << std::setfill ('0'); - stream << number (); - text = stream.str (); -} - -bool rai::uint512_union::decode_hex (std::string const & text) -{ - auto result (text.size () > 128); - if (!result) - { - std::stringstream stream (text); - stream << std::hex << std::noshowbase; - rai::uint512_t number_l; - try - { - stream >> number_l; - *this = number_l; - if (!stream.eof ()) - { - result = true; - } - } - catch (std::runtime_error &) - { - result = true; - } - } - return result; -} - -bool rai::uint512_union::operator != (rai::uint512_union const & other_a) const -{ - return ! (*this == other_a); -} - -rai::uint512_union & rai::uint512_union::operator ^= (rai::uint512_union const & other_a) -{ - uint256s [0] ^= other_a.uint256s [0]; - uint256s [1] ^= other_a.uint256s [1]; - return *this; -} - -extern "C" -{ -#include -void ed25519_randombytes_unsafe (void * out, size_t outlen) -{ - rai::random_pool.GenerateBlock (reinterpret_cast (out), outlen); -} -void ed25519_hash_init (ed25519_hash_context * ctx) -{ - ctx->blake2 = new blake2b_state; - blake2b_init (reinterpret_cast (ctx->blake2), 64); -} - -void ed25519_hash_update (ed25519_hash_context * ctx, uint8_t const * in, size_t inlen) -{ - blake2b_update (reinterpret_cast (ctx->blake2), in, inlen); -} - -void ed25519_hash_final (ed25519_hash_context * ctx, uint8_t * out) -{ - blake2b_final (reinterpret_cast (ctx->blake2), out, 64); - delete reinterpret_cast (ctx->blake2); -} - -void ed25519_hash (uint8_t * out, uint8_t const * in, size_t inlen) -{ - ed25519_hash_context ctx; - ed25519_hash_init (&ctx); - ed25519_hash_update (&ctx, in, inlen); - ed25519_hash_final (&ctx, out); -} -} - rai::uint512_union rai::sign_message (rai::raw_key const & private_key, rai::public_key const & public_key, rai::uint256_union const & message) { rai::uint512_union result; - ed25519_sign (message.bytes.data (), sizeof (message.bytes), private_key.data.bytes.data (), public_key.bytes.data (), result.bytes.data ()); + ed25519_sign (message.bytes.data (), sizeof (message.bytes), private_key.data.bytes.data (), public_key.bytes.data (), result.bytes.data ()); return result; } bool rai::validate_message (rai::public_key const & public_key, rai::uint256_union const & message, rai::uint512_union const & signature) { - auto result (0 != ed25519_sign_open (message.bytes.data (), sizeof (message.bytes), public_key.bytes.data (), signature.bytes.data ())); - return result; + auto result (0 != ed25519_sign_open (message.bytes.data (), sizeof (message.bytes), public_key.bytes.data (), signature.bytes.data ())); + return result; } void rai::open_or_create (std::fstream & stream_a, std::string const & path_a) diff --git a/rai/utility.hpp b/rai/utility.hpp index fef4ea23..8952ac9a 100755 --- a/rai/utility.hpp +++ b/rai/utility.hpp @@ -5,12 +5,9 @@ #include #include -#include - #include #include #include -#include #include #include @@ -18,12 +15,11 @@ #include #include +#include +#include namespace rai { -// Random pool used by RaiBlocks. -// This must be thread_local as long as the AutoSeededRandomPool implementation requires it -extern thread_local CryptoPP::AutoSeededRandomPool random_pool; // We operate on streams of uint8_t by convention using stream = std::basic_streambuf ; using bufferstream = boost::iostreams::stream_buffer >; @@ -123,16 +119,6 @@ bool fetch_object (T & object, boost::filesystem::path const & path_a, std::fstr std::string to_string_hex (uint64_t); bool from_string_hex (std::string const &, uint64_t &); -using uint128_t = boost::multiprecision::uint128_t; -using uint256_t = boost::multiprecision::uint256_t; -using uint512_t = boost::multiprecision::uint512_t; -// SI dividers -rai::uint128_t const Gxrb_ratio = rai::uint128_t ("1000000000000000000000000000000000"); // 10^33 -rai::uint128_t const Mxrb_ratio = rai::uint128_t ("1000000000000000000000000000000"); // 10^30 -rai::uint128_t const kxrb_ratio = rai::uint128_t ("1000000000000000000000000000"); // 10^27 -rai::uint128_t const xrb_ratio = rai::uint128_t ("1000000000000000000000000"); // 10^24 -rai::uint128_t const mxrb_ratio = rai::uint128_t ("1000000000000000000000"); // 10^21 -rai::uint128_t const uxrb_ratio = rai::uint128_t ("1000000000000000000"); // 10^18 class mdb_env { public: @@ -141,116 +127,6 @@ public: operator MDB_env * () const; MDB_env * environment; }; -class transaction -{ -public: - transaction (rai::mdb_env &, MDB_txn *, bool); - ~transaction (); - operator MDB_txn * () const; - MDB_txn * handle; - rai::mdb_env & environment; -}; -union uint128_union -{ -public: - uint128_union () = default; - uint128_union (std::string const &); - uint128_union (uint64_t); - uint128_union (rai::uint128_union const &) = default; - uint128_union (rai::uint128_t const &); - bool operator == (rai::uint128_union const &) const; - bool operator != (rai::uint128_union const &) const; - bool operator < (rai::uint128_union const &) const; - bool operator > (rai::uint128_union const &) const; - void encode_hex (std::string &) const; - bool decode_hex (std::string const &); - void encode_dec (std::string &) const; - bool decode_dec (std::string const &); - rai::uint128_t number () const; - void clear (); - bool is_zero () const; - std::string to_string () const; - std::string to_string_dec () const; - std::array bytes; - std::array chars; - std::array dwords; - std::array qwords; -}; -// Balances are 128 bit. -using amount = uint128_union; -class raw_key; -class mdb_val; -union uint256_union -{ - uint256_union () = default; - uint256_union (std::string const &); - uint256_union (uint64_t); - uint256_union (rai::uint256_t const &); - void encrypt (rai::raw_key const &, rai::raw_key const &, uint128_union const &); - uint256_union & operator ^= (rai::uint256_union const &); - uint256_union operator ^ (rai::uint256_union const &) const; - bool operator == (rai::uint256_union const &) const; - bool operator != (rai::uint256_union const &) const; - bool operator < (rai::uint256_union const &) const; - void encode_hex (std::string &) const; - bool decode_hex (std::string const &); - void encode_dec (std::string &) const; - bool decode_dec (std::string const &); - void encode_account (std::string &) const; - std::string to_account () const; - std::string to_account_split () const; - bool decode_account_v1 (std::string const &); - bool decode_account (std::string const &); - std::array bytes; - std::array chars; - std::array dwords; - std::array qwords; - std::array owords; - void clear (); - bool is_zero () const; - std::string to_string () const; - rai::uint256_t number () const; -}; -// All keys and hashes are 256 bit. -using block_hash = uint256_union; -using account = uint256_union; -using public_key = uint256_union; -using private_key = uint256_union; -using secret_key = uint256_union; -using checksum = uint256_union; -class raw_key -{ -public: - raw_key () = default; - ~raw_key (); - void decrypt (rai::uint256_union const &, rai::raw_key const &, uint128_union const &); - raw_key (rai::raw_key const &) = delete; - raw_key (rai::raw_key const &&) = delete; - rai::raw_key & operator = (rai::raw_key const &) = delete; - bool operator == (rai::raw_key const &) const; - bool operator != (rai::raw_key const &) const; - rai::uint256_union data; -}; -union uint512_union -{ - uint512_union () = default; - uint512_union (rai::uint512_t const &); - bool operator == (rai::uint512_union const &) const; - bool operator != (rai::uint512_union const &) const; - rai::uint512_union & operator ^= (rai::uint512_union const &); - void encode_hex (std::string &) const; - bool decode_hex (std::string const &); - std::array bytes; - std::array dwords; - std::array qwords; - std::array uint256s; - void clear (); - rai::uint512_t number () const; -}; -// Only signatures are 512 bit. -using signature = uint512_union; -rai::uint512_union sign_message (rai::raw_key const &, rai::public_key const &, rai::uint256_union const &); -bool validate_message (rai::public_key const &, rai::uint256_union const &, rai::uint512_union const &); class mdb_val { public: @@ -266,23 +142,13 @@ public: operator MDB_val const & () const; MDB_val value; }; -} -namespace std +class transaction { -template <> -struct hash -{ - size_t operator () (rai::uint256_union const & data_a) const - { - return *reinterpret_cast (data_a.bytes.data ()); - } -}; -template <> -struct hash -{ - size_t operator () (rai::uint256_t const & number_a) const - { - return number_a.convert_to (); - } +public: + transaction (rai::mdb_env &, MDB_txn *, bool); + ~transaction (); + operator MDB_txn * () const; + MDB_txn * handle; + rai::mdb_env & environment; }; }