From 25a248c57c09aa57343c707fddd69a6d00b57a95 Mon Sep 17 00:00:00 2001 From: Evgeniy Date: Tue, 18 Dec 2018 23:53:26 +0300 Subject: [PATCH] New random generator --- automake/Makefile.am | 2 + client/Makefile | 2 + client/block.c | 3 +- client/commands.c | 6 ++- client/crypt.c | 10 +--- client/crypt.h | 2 +- client/init.c | 9 +++- client/miner.c | 3 +- client/transport.c | 12 ++--- client/transport.h | 3 -- client/utils/random.c | 72 +++++++++++++++++++++++++++++ client/utils/random.h | 21 +++++++++ win/xdaglib/xdaglib.vcxproj | 2 + win/xdaglib/xdaglib.vcxproj.filters | 6 +++ 14 files changed, 126 insertions(+), 27 deletions(-) create mode 100644 client/utils/random.c create mode 100644 client/utils/random.h diff --git a/automake/Makefile.am b/automake/Makefile.am index 3467ff48..4ab9403d 100644 --- a/automake/Makefile.am +++ b/automake/Makefile.am @@ -49,6 +49,7 @@ sources = \ $(utils)/linenoise.c \ $(utils)/dirname.c \ $(utils)/string_utils.c \ + $(utils)/random.c \ $(moving_statistics)/moving_average.c \ $(jsonrpc)/cJSON.c \ $(jsonrpc)/cJSON_Utils.c \ @@ -99,6 +100,7 @@ headers = \ $(utils)/utils.h \ $(utils)/linenoise.h \ $(utils)/string_utils.h \ + $(utils)/random.h \ $(moving_statistics)/moving_average.h \ $(jsonrpc)/cJSON.h \ $(jsonrpc)/cJSON_Utils.h \ diff --git a/client/Makefile b/client/Makefile index e5c6e70b..9926c361 100644 --- a/client/Makefile +++ b/client/Makefile @@ -59,6 +59,7 @@ sources = \ $(utils)/linenoise.c \ $(utils)/dirname.c \ $(utils)/string_utils.c \ + $(utils)/random.c \ $(moving_statistics)/moving_average.c \ $(json-rpc)/cJSON.c \ $(json-rpc)/cJSON_Utils.c \ @@ -115,6 +116,7 @@ headers = \ $(utils)/linenoise.h \ $(utils)/dirname.h \ $(utils)/string_utils.h \ + $(utils)/random.h \ $(moving_statistics)/moving_average.h \ $(json-rpc)/cJSON.h \ $(json-rpc)/cJSON_Utils.h \ diff --git a/client/block.c b/client/block.c index 092dd960..379e7b12 100644 --- a/client/block.c +++ b/client/block.c @@ -28,6 +28,7 @@ #include "time.h" #include "math.h" #include "utils/atomic.h" +#include "utils/random.h" #define MAX_WAITING_MAIN 1 #define MAIN_START_AMOUNT (1ll << 42) @@ -1048,7 +1049,7 @@ int do_mining(struct xdag_block *block, struct block_internal **pretop, xtime_t uint64_t taskIndex = g_xdag_pool_task_index + 1; struct xdag_pool_task *task = &g_xdag_pool_task[taskIndex & 1]; - xdag_generate_random_array(block[0].field[XDAG_BLOCK_FIELDS - 1].data, sizeof(xdag_hash_t)); + GetRandBytes(block[0].field[XDAG_BLOCK_FIELDS - 1].data, sizeof(xdag_hash_t)); task->task_time = MAIN_TIME(send_time); diff --git a/client/commands.c b/client/commands.c index 627b0e70..8928ff79 100644 --- a/client/commands.c +++ b/client/commands.c @@ -919,14 +919,16 @@ int out_balances() char address[33] = {0}; struct out_balances_data d; unsigned i = 0; + xdag_set_log_level(0); xdag_mem_init((xdag_get_frame() - xdag_get_start_frame()) << 17); - xdag_crypt_init(0); + xdag_crypt_init(); memset(&d, 0, sizeof(struct out_balances_data)); xdag_load_blocks(xdag_get_start_frame() << 16, xdag_get_frame() << 16, &i, &add_block_callback); xdag_traverse_all_blocks(&d, out_balances_callback); + qsort(d.blocks, d.blocksCount, sizeof(struct xdag_field), out_sort_callback); - for(i = 0; i < d.blocksCount; ++i) { + for(int i = 0; i < d.blocksCount; ++i) { xdag_hash2address(d.blocks[i].data, address); printf("%s %20.9Lf\n", address, amount2xdags(d.blocks[i].amount)); } diff --git a/client/crypt.c b/client/crypt.c index 88f36400..7310d058 100644 --- a/client/crypt.c +++ b/client/crypt.c @@ -29,15 +29,9 @@ extern unsigned int xOPENSSL_ia32cap_P[4]; extern int xOPENSSL_ia32_cpuid(unsigned int *); // initialization of the encryption system -int xdag_crypt_init(int withrandom) +int xdag_crypt_init() { - if(withrandom) { - uint64_t buf[64]; - xOPENSSL_ia32_cpuid(xOPENSSL_ia32cap_P); - xdag_generate_random_array(buf, sizeof(buf)); - xdag_debug("Seed : [%s]", xdag_log_array(buf, sizeof(buf))); - RAND_seed(buf, sizeof(buf)); - } + xOPENSSL_ia32_cpuid(xOPENSSL_ia32cap_P); #if USE_OPTIMIZED_EC == 1 || USE_OPTIMIZED_EC == 2 ctx_noopenssl = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); diff --git a/client/crypt.h b/client/crypt.h index fb574127..64d7cf98 100644 --- a/client/crypt.h +++ b/client/crypt.h @@ -18,7 +18,7 @@ extern "C" { #endif // initialization of the encryption system -extern int xdag_crypt_init(int withrandom); +extern int xdag_crypt_init(); // creates a new pair of private and public keys extern void *xdag_create_key(xdag_hash_t privkey, xdag_hash_t pubkey, uint8_t *pubkey_bit); diff --git a/client/init.c b/client/init.c index 7f120042..b68cd15f 100644 --- a/client/init.c +++ b/client/init.c @@ -31,6 +31,7 @@ #include "xdag_config.h" #include "json-rpc/rpc_service.h" #include "../dnet/dnet_crypt.h" +#include "utils/random.h" #define ARG_EQUAL(a,b,c) strcmp(c, "") == 0 ? strcmp(a, b) == 0 : (strcmp(a, b) == 0 || strcmp(a, c) == 0) @@ -273,11 +274,15 @@ int pre_init(void) memset(&g_xdag_stats, 0, sizeof(g_xdag_stats)); memset(&g_xdag_extstats, 0, sizeof(g_xdag_extstats)); + RandAddSeed(); + + xdag_mess("Initializing cryptography..."); + if(xdag_crypt_init()) return -1; + //TODO: future xdag.wallet xdag_mess("Reading wallet..."); if(dnet_key_init() < 0) return -1; - xdag_mess("Initializing cryptography..."); - if(xdag_crypt_init(1)) return -1; + if(xdag_wallet_init()) return -1; return 0; diff --git a/client/miner.c b/client/miner.c index 8d963809..df41d657 100644 --- a/client/miner.c +++ b/client/miner.c @@ -25,6 +25,7 @@ #include "algorithms/crc.h" #include "utils/log.h" #include "utils/utils.h" +#include "utils/random.h" #define MINERS_PWD "minersgonnamine" #define SECTOR0_BASE 0x1947f3acu @@ -262,7 +263,7 @@ void *miner_net_thread(void *arg) xdag_hash_update(task->ctx, data[1].data, sizeof(struct xdag_field)); xdag_hash_update(task->ctx, hash, sizeof(xdag_hashlow_t)); - xdag_generate_random_array(task->nonce.data, sizeof(xdag_hash_t)); + GetRandBytes(task->nonce.data, sizeof(xdag_hash_t)); memcpy(task->nonce.data, hash, sizeof(xdag_hashlow_t)); memcpy(task->lastfield.data, task->nonce.data, sizeof(xdag_hash_t)); diff --git a/client/transport.c b/client/transport.c index b6e20a10..6ed18bc9 100644 --- a/client/transport.c +++ b/client/transport.c @@ -15,6 +15,7 @@ #include "version.h" #include "../dnet/dnet_main.h" #include "utils/log.h" +#include "utils/random.h" #define NEW_BLOCK_TTL 5 #define REQUEST_WAIT 64 @@ -303,13 +304,6 @@ int xdag_transport_start(int flags, int nthreads, const char *bindto, int npairs return res; } -/* generates an array with random data */ -int xdag_generate_random_array(void *array, unsigned long size) -{ - //TODO: do we need to generate random array based on DNET key? - return dnet_generate_random_array(array, size); -} - static int do_request(int type, xtime_t start_time, xtime_t end_time, void *data, void *(*callback)(void *block, void *data)) { @@ -323,7 +317,7 @@ static int do_request(int type, xtime_t start_time, xtime_t end_time, void *data b.field[0].time = start_time; b.field[0].end_time = end_time; - xdag_generate_random_array(&id, sizeof(uint64_t)); + GetRandBytes(&id, sizeof(uint64_t)); memset(&b.field[1], 0, sizeof(struct xdag_field)); *(uint64_t*)b.field[1].hash = id; @@ -457,7 +451,7 @@ static void *xdag_update_rip_thread(void *arg) while(1) { if (time(NULL) - last_change_time > REPLY_ID_PVT_TTL) { time(&last_change_time); - xdag_generate_random_array(&reply_id_private, sizeof(uint64_t)); + GetRandBytes(&reply_id_private, sizeof(uint64_t)); } sleep(60); } diff --git a/client/transport.h b/client/transport.h index 12570733..9f6a40dd 100644 --- a/client/transport.h +++ b/client/transport.h @@ -25,9 +25,6 @@ extern "C" { */ extern int xdag_transport_start(int flags, int nthreads, const char *bindto, int npairs, const char **addr_port_pairs); -/* generates an array with random data */ -extern int xdag_generate_random_array(void *array, unsigned long size); - /* sends a new block to network */ extern int xdag_send_new_block(struct xdag_block *b); diff --git a/client/utils/random.c b/client/utils/random.c new file mode 100644 index 00000000..0919fc25 --- /dev/null +++ b/client/utils/random.c @@ -0,0 +1,72 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "random.h" +#ifdef _WIN32 +#include +#else +#include +#endif +#include +#include "log.h" + +static void RandFailure() +{ + xdag_fatal("Failed to read randomness, aborting\n"); + abort(); +} + +static inline int64_t GetPerformanceCounter() +{ + int64_t counter = 0; +#ifdef _WIN32 + QueryPerformanceCounter((LARGE_INTEGER*)&counter); +#else + timeval t; + gettimeofday(&t, NULL); + nCounter = (int64_t)(t.tv_sec * 1000000 + t.tv_usec); +#endif + return counter; +} + +void RandAddSeed() +{ +#ifdef _WIN32 + // mix the contents of the screen into the generator. + RAND_screen(); +#endif + + // Seed with CPU performance counter + int64_t nCounter = GetPerformanceCounter(); + RAND_add(&nCounter, sizeof(nCounter), 1.5); +} + +void GetRandBytes(unsigned char* buf, int num) +{ + if(RAND_bytes(buf, num) != 1) { + RandFailure(); + } +} + +uint64_t GetRand(uint64_t max) +{ + if(max == 0) { + return 0; + } + + // The range of the random source must be a multiple of the modulus + // to give every possible output value an equal possibility + uint64_t range = UINT64_MAX / max * max; + uint64_t randValue = 0; + do { + GetRandBytes((unsigned char*)&randValue, sizeof(randValue)); + } while(randValue >= range); + return (randValue % max); +} + +int GetRandInt(int max) +{ + return GetRand(max); +} diff --git a/client/utils/random.h b/client/utils/random.h new file mode 100644 index 00000000..e628bddb --- /dev/null +++ b/client/utils/random.h @@ -0,0 +1,21 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef RANDOM_H +#define RANDOM_H + +#include + +/* Seed OpenSSL PRNG with additional entropy data */ +void RandAddSeed(); + +/** + * Functions to gather random data via the OpenSSL PRNG + */ +void GetRandBytes(unsigned char* buf, int num); +uint64_t GetRand(uint64_t nMax); +int GetRandInt(int nMax); + +#endif // RANDOM_H diff --git a/win/xdaglib/xdaglib.vcxproj b/win/xdaglib/xdaglib.vcxproj index 7a33ca89..aebf1464 100644 --- a/win/xdaglib/xdaglib.vcxproj +++ b/win/xdaglib/xdaglib.vcxproj @@ -60,6 +60,7 @@ + @@ -111,6 +112,7 @@ + diff --git a/win/xdaglib/xdaglib.vcxproj.filters b/win/xdaglib/xdaglib.vcxproj.filters index 2437e909..c216c66f 100644 --- a/win/xdaglib/xdaglib.vcxproj.filters +++ b/win/xdaglib/xdaglib.vcxproj.filters @@ -183,6 +183,9 @@ dfslib + + client\utils + @@ -378,6 +381,9 @@ dfslib + + client\utils +