First cut at a C shared library interface to node.
This commit is contained in:
parent
48e00826e7
commit
9c60d6b5d4
15 changed files with 735 additions and 629 deletions
|
@ -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)
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
#include <boost/property_tree/json_parser.hpp>
|
||||
|
||||
#include <ed25519-donna/ed25519.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <rai/interface.h>
|
||||
#include <rai/node/common.hpp>
|
||||
#include <rai/node/node.hpp>
|
||||
|
||||
#include <ed25519-donna/ed25519.h>
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
#include <ed25519-donna/ed25519.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <rai/interface.h>
|
||||
#include <rai/secure.hpp>
|
||||
|
||||
#include <ed25519-donna/ed25519.h>
|
||||
|
||||
TEST (uint128_union, decode_dec)
|
||||
{
|
||||
rai::uint128_union value;
|
||||
|
|
71
rai/interface.cpp
Normal file
71
rai/interface.cpp
Normal file
|
@ -0,0 +1,71 @@
|
|||
#include <rai/interface.h>
|
||||
|
||||
#include <xxhash/xxhash.h>
|
||||
|
||||
#include <ed25519-donna/ed25519.h>
|
||||
|
||||
#include <blake2/blake2.h>
|
||||
|
||||
#include <rai/numbers.hpp>
|
||||
|
||||
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 <ed25519-donna/ed25519-hash-custom.h>
|
||||
void ed25519_randombytes_unsafe (void * out, size_t outlen)
|
||||
{
|
||||
rai::random_pool.GenerateBlock (reinterpret_cast <uint8_t *> (out), outlen);
|
||||
}
|
||||
void ed25519_hash_init (ed25519_hash_context * ctx)
|
||||
{
|
||||
ctx->blake2 = new blake2b_state;
|
||||
blake2b_init (reinterpret_cast <blake2b_state *> (ctx->blake2), 64);
|
||||
}
|
||||
|
||||
void ed25519_hash_update (ed25519_hash_context * ctx, uint8_t const * in, size_t inlen)
|
||||
{
|
||||
blake2b_update (reinterpret_cast <blake2b_state *> (ctx->blake2), in, inlen);
|
||||
}
|
||||
|
||||
void ed25519_hash_final (ed25519_hash_context * ctx, uint8_t * out)
|
||||
{
|
||||
blake2b_final (reinterpret_cast <blake2b_state *> (ctx->blake2), out, 64);
|
||||
delete reinterpret_cast <blake2b_state *> (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);
|
||||
}
|
||||
}
|
34
rai/interface.h
Normal file
34
rai/interface.h
Normal file
|
@ -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
|
|
@ -1,13 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
#include <rai/interface.h>
|
||||
#include <rai/secure.hpp>
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
#include <xxhash/xxhash.h>
|
||||
|
||||
#include <bitset>
|
||||
|
||||
#include <xxhash/xxhash.h>
|
||||
|
||||
namespace rai
|
||||
{
|
||||
using endpoint = boost::asio::ip::udp::endpoint;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <rai/node/node.hpp>
|
||||
|
||||
#include <rai/interface.h>
|
||||
#include <rai/node/common.hpp>
|
||||
#include <rai/node/rpc.hpp>
|
||||
|
||||
|
@ -18,10 +19,10 @@
|
|||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
|
||||
#include <ed25519-donna/ed25519.h>
|
||||
|
||||
#include <upnpcommands.h>
|
||||
|
||||
#include <ed25519-donna/ed25519.h>
|
||||
|
||||
double constexpr rai::node::price_max;
|
||||
double constexpr rai::node::free_cutoff;
|
||||
std::chrono::seconds constexpr rai::node::period;
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
#include <rai/node/rpc.hpp>
|
||||
|
||||
#include <rai/node/node.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include <rai/interface.h>
|
||||
#include <rai/node/node.hpp>
|
||||
|
||||
#include <ed25519-donna/ed25519.h>
|
||||
|
||||
rai::rpc_config::rpc_config () :
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <rai/node/wallet.hpp>
|
||||
|
||||
#include <rai/interface.h>
|
||||
#include <rai/node/node.hpp>
|
||||
#include <rai/node/xorshift.hpp>
|
||||
|
||||
|
@ -8,10 +9,10 @@
|
|||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
|
||||
#include <ed25519-donna/ed25519.h>
|
||||
|
||||
#include <future>
|
||||
|
||||
#include <ed25519-donna/ed25519.h>
|
||||
|
||||
rai::work_pool::work_pool (unsigned max_threads_a, std::unique_ptr <rai::opencl_work> opencl_a) :
|
||||
ticket (0),
|
||||
done (false),
|
||||
|
|
434
rai/numbers.cpp
Normal file
434
rai/numbers.cpp
Normal file
|
@ -0,0 +1,434 @@
|
|||
#include <rai/numbers.hpp>
|
||||
|
||||
#include <ed25519-donna/ed25519.h>
|
||||
|
||||
#include <blake2/blake2.h>
|
||||
|
||||
#include <cryptopp/aes.h>
|
||||
#include <cryptopp/modes.h>
|
||||
|
||||
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 <uint8_t *> (&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 <uint8_t> () & 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 <rai::uint256_t> ();
|
||||
uint32_t check ((number_l >> 256).convert_to <uint32_t> ());
|
||||
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 <uint8_t *> (&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 <rai::uint256_t> ();
|
||||
uint64_t check (number_l.convert_to <uint64_t> ());
|
||||
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 <uint8_t *> (&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 <uint8_t> ();
|
||||
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 <uint8_t> ();
|
||||
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));
|
||||
}
|
||||
|
143
rai/numbers.hpp
Normal file
143
rai/numbers.hpp
Normal file
|
@ -0,0 +1,143 @@
|
|||
#pragma once
|
||||
|
||||
#include <boost/multiprecision/cpp_int.hpp>
|
||||
|
||||
#include <cryptopp/osrng.h>
|
||||
|
||||
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 <uint8_t, 16> bytes;
|
||||
std::array <char, 16> chars;
|
||||
std::array <uint32_t, 4> dwords;
|
||||
std::array <uint64_t, 2> 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 <uint8_t, 32> bytes;
|
||||
std::array <char, 32> chars;
|
||||
std::array <uint32_t, 8> dwords;
|
||||
std::array <uint64_t, 4> qwords;
|
||||
std::array <uint128_union, 2> 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 <uint8_t, 64> bytes;
|
||||
std::array <uint32_t, 16> dwords;
|
||||
std::array <uint64_t, 8> qwords;
|
||||
std::array <uint256_union, 2> 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 <rai::uint256_union>
|
||||
{
|
||||
size_t operator () (rai::uint256_union const & data_a) const
|
||||
{
|
||||
return *reinterpret_cast <size_t const *> (data_a.bytes.data ());
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct hash <rai::uint256_t>
|
||||
{
|
||||
size_t operator () (rai::uint256_t const & number_a) const
|
||||
{
|
||||
return number_a.convert_to <size_t> ();
|
||||
}
|
||||
};
|
||||
}
|
|
@ -1,16 +1,15 @@
|
|||
#include <rai/secure.hpp>
|
||||
|
||||
#include <rai/interface.h>
|
||||
#include <rai/node/working.hpp>
|
||||
#include <rai/versioning.hpp>
|
||||
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
|
||||
#include <blake2/blake2.h>
|
||||
#include <queue>
|
||||
|
||||
#include <ed25519-donna/ed25519.h>
|
||||
|
||||
#include <queue>
|
||||
|
||||
// Genesis keys for network variants
|
||||
namespace
|
||||
{
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
#include <boost/property_tree/ptree.hpp>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include <blake2/blake2.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template <>
|
||||
|
|
469
rai/utility.cpp
469
rai/utility.cpp
|
@ -1,13 +1,10 @@
|
|||
#include <rai/utility.hpp>
|
||||
|
||||
#include <cryptopp/aes.h>
|
||||
#include <cryptopp/modes.h>
|
||||
|
||||
#include <ed25519-donna/ed25519.h>
|
||||
#include <rai/interface.h>
|
||||
|
||||
#include <lmdb/libraries/liblmdb/lmdb.h>
|
||||
|
||||
thread_local CryptoPP::AutoSeededRandomPool rai::random_pool;
|
||||
#include <ed25519-donna/ed25519.h>
|
||||
|
||||
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 <uint8_t *> (&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 <uint8_t> () & 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 <rai::uint256_t> ();
|
||||
uint32_t check ((number_l >> 256).convert_to <uint32_t> ());
|
||||
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 <uint8_t *> (&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 <rai::uint256_t> ();
|
||||
uint64_t check (number_l.convert_to <uint64_t> ());
|
||||
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 <uint8_t *> (&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 <uint8_t> ();
|
||||
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 <uint8_t> ();
|
||||
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 <ed25519-donna/ed25519-hash-custom.h>
|
||||
void ed25519_randombytes_unsafe (void * out, size_t outlen)
|
||||
{
|
||||
rai::random_pool.GenerateBlock (reinterpret_cast <uint8_t *> (out), outlen);
|
||||
}
|
||||
void ed25519_hash_init (ed25519_hash_context * ctx)
|
||||
{
|
||||
ctx->blake2 = new blake2b_state;
|
||||
blake2b_init (reinterpret_cast <blake2b_state *> (ctx->blake2), 64);
|
||||
}
|
||||
|
||||
void ed25519_hash_update (ed25519_hash_context * ctx, uint8_t const * in, size_t inlen)
|
||||
{
|
||||
blake2b_update (reinterpret_cast <blake2b_state *> (ctx->blake2), in, inlen);
|
||||
}
|
||||
|
||||
void ed25519_hash_final (ed25519_hash_context * ctx, uint8_t * out)
|
||||
{
|
||||
blake2b_final (reinterpret_cast <blake2b_state *> (ctx->blake2), out, 64);
|
||||
delete reinterpret_cast <blake2b_state *> (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)
|
||||
|
|
152
rai/utility.hpp
152
rai/utility.hpp
|
@ -5,12 +5,9 @@
|
|||
#include <condition_variable>
|
||||
#include <type_traits>
|
||||
|
||||
#include <blake2/blake2.h>
|
||||
|
||||
#include <boost/iostreams/device/back_inserter.hpp>
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/multiprecision/cpp_int.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
|
||||
#include <cryptopp/osrng.h>
|
||||
|
@ -18,12 +15,11 @@
|
|||
#include <lmdb/libraries/liblmdb/lmdb.h>
|
||||
|
||||
#include <rai/config.hpp>
|
||||
#include <rai/interface.h>
|
||||
#include <rai/numbers.hpp>
|
||||
|
||||
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 <uint8_t>;
|
||||
using bufferstream = boost::iostreams::stream_buffer <boost::iostreams::basic_array_source <uint8_t>>;
|
||||
|
@ -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 <uint8_t, 16> bytes;
|
||||
std::array <char, 16> chars;
|
||||
std::array <uint32_t, 4> dwords;
|
||||
std::array <uint64_t, 2> 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 <uint8_t, 32> bytes;
|
||||
std::array <char, 32> chars;
|
||||
std::array <uint32_t, 8> dwords;
|
||||
std::array <uint64_t, 4> qwords;
|
||||
std::array <uint128_union, 2> 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 <uint8_t, 64> bytes;
|
||||
std::array <uint32_t, 16> dwords;
|
||||
std::array <uint64_t, 8> qwords;
|
||||
std::array <uint256_union, 2> 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 <rai::uint256_union>
|
||||
{
|
||||
size_t operator () (rai::uint256_union const & data_a) const
|
||||
{
|
||||
return *reinterpret_cast <size_t const *> (data_a.bytes.data ());
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct hash <rai::uint256_t>
|
||||
{
|
||||
size_t operator () (rai::uint256_t const & number_a) const
|
||||
{
|
||||
return number_a.convert_to <size_t> ();
|
||||
}
|
||||
public:
|
||||
transaction (rai::mdb_env &, MDB_txn *, bool);
|
||||
~transaction ();
|
||||
operator MDB_txn * () const;
|
||||
MDB_txn * handle;
|
||||
rai::mdb_env & environment;
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue