diff --git a/setup.py b/setup.py index 29d6ad6d..eedd337a 100755 --- a/setup.py +++ b/setup.py @@ -25,9 +25,9 @@ author = "Matthew Wampler-Doty", author_email = "matthew.wampler.doty@gmail.com", license = 'GPL', - version = '23', + version = '23.1', url = 'https://github.com/ethereum/ethash', - download_url = 'https://github.com/ethereum/ethash/tarball/v23', + download_url = 'https://github.com/ethereum/ethash/tarball/v23.1', description = 'Python wrappers for ethash, the ethereum proof of work hashing function', ext_modules = [pyethash], ) diff --git a/src/libethash/data_sizes.h b/src/libethash/data_sizes.h index 3b747b3e..cf52ae4f 100644 --- a/src/libethash/data_sizes.h +++ b/src/libethash/data_sizes.h @@ -48,7 +48,7 @@ extern "C" { // Sow[i*HashBytes]; j++]]]][[2]][[1]] -static const size_t dag_sizes[2048] = { +static const uint64_t dag_sizes[2048] = { 1073739904U, 1082130304U, 1090514816U, 1098906752U, 1107293056U, 1115684224U, 1124070016U, 1132461952U, 1140849536U, 1149232768U, 1157627776U, 1166013824U, 1174404736U, 1182786944U, 1191180416U, @@ -477,7 +477,7 @@ static const size_t dag_sizes[2048] = { // While[! PrimeQ[i], i--]; // Sow[i*HashBytes]; j++]]]][[2]][[1]] -const size_t cache_sizes[2048] = { +const uint64_t cache_sizes[2048] = { 16776896U, 16907456U, 17039296U, 17170112U, 17301056U, 17432512U, 17563072U, 17693888U, 17824192U, 17955904U, 18087488U, 18218176U, 18349504U, 18481088U, 18611392U, 18742336U, 18874304U, 19004224U, 19135936U, 19267264U, 19398208U, diff --git a/src/libethash/ethash.h b/src/libethash/ethash.h index a7159de6..cc3d634d 100644 --- a/src/libethash/ethash.h +++ b/src/libethash/ethash.h @@ -43,8 +43,8 @@ extern "C" { #endif typedef struct ethash_params { - size_t full_size; // Size of full data set (in bytes, multiple of mix size (128)). - size_t cache_size; // Size of compute cache (in bytes, multiple of node size (64)). + uint64_t full_size; // Size of full data set (in bytes, multiple of mix size (128)). + uint64_t cache_size; // Size of compute cache (in bytes, multiple of node size (64)). } ethash_params; typedef struct ethash_return_value { @@ -52,45 +52,52 @@ typedef struct ethash_return_value { uint8_t mix_hash[32]; } ethash_return_value; -size_t ethash_get_datasize(const uint32_t block_number); -size_t ethash_get_cachesize(const uint32_t block_number); +uint64_t ethash_get_datasize(const uint32_t block_number); +uint64_t ethash_get_cachesize(const uint32_t block_number); -// initialize the parameters -static inline void ethash_params_init(ethash_params *params, const uint32_t block_number) { +// Initialize the Parameters +static inline int ethash_params_init(ethash_params *params, const uint32_t block_number) { params->full_size = ethash_get_datasize(block_number); + if (params->full_size == 0) + return 0; + params->cache_size = ethash_get_cachesize(block_number); + if (params->cache_size == 0) + return 0; + + return 1; } typedef struct ethash_cache { void *mem; } ethash_cache; -void ethash_mkcache(ethash_cache *cache, ethash_params const *params, const uint8_t seed[32]); -void ethash_compute_full_data(void *mem, ethash_params const *params, ethash_cache const *cache); -void ethash_full(ethash_return_value *ret, void const *full_mem, ethash_params const *params, const uint8_t header_hash[32], const uint64_t nonce); -void ethash_light(ethash_return_value *ret, ethash_cache const *cache, ethash_params const *params, const uint8_t header_hash[32], const uint64_t nonce); +int ethash_mkcache(ethash_cache *cache, ethash_params const *params, const uint8_t seed[32]); +int ethash_compute_full_data(void *mem, ethash_params const *params, ethash_cache const *cache); +int ethash_full(ethash_return_value *ret, void const *full_mem, ethash_params const *params, const uint8_t header_hash[32], const uint64_t nonce); +int ethash_light(ethash_return_value *ret, ethash_cache const *cache, ethash_params const *params, const uint8_t header_hash[32], const uint64_t nonce); void ethash_get_seedhash(uint8_t seedhash[32], const uint32_t block_number); -static inline void ethash_prep_light(void *cache, ethash_params const *params, const uint8_t seed[32]) { +static inline int ethash_prep_light(void *cache, ethash_params const *params, const uint8_t seed[32]) { ethash_cache c; c.mem = cache; - ethash_mkcache(&c, params, seed); + return ethash_mkcache(&c, params, seed); } -static inline void ethash_compute_light(ethash_return_value *ret, void const *cache, ethash_params const *params, const uint8_t header_hash[32], const uint64_t nonce) { +static inline int ethash_compute_light(ethash_return_value *ret, void const *cache, ethash_params const *params, const uint8_t header_hash[32], const uint64_t nonce) { ethash_cache c; c.mem = (void *) cache; - ethash_light(ret, &c, params, header_hash, nonce); + return ethash_light(ret, &c, params, header_hash, nonce); } -static inline void ethash_prep_full(void *full, ethash_params const *params, void const *cache) { +static inline int ethash_prep_full(void *full, ethash_params const *params, void const *cache) { ethash_cache c; c.mem = (void *) cache; - ethash_compute_full_data(full, params, &c); + return ethash_compute_full_data(full, params, &c); } -static inline void ethash_compute_full(ethash_return_value *ret, void const *full, ethash_params const *params, const uint8_t header_hash[32], const uint64_t nonce) { - ethash_full(ret, full, params, header_hash, nonce); +static inline int ethash_compute_full(ethash_return_value *ret, void const *full, ethash_params const *params, const uint8_t header_hash[32], const uint64_t nonce) { + return ethash_full(ret, full, params, header_hash, nonce); } // Returns if hash is less than or equal to difficulty diff --git a/src/libethash/internal.c b/src/libethash/internal.c index 0a7e767e..ea0b630f 100644 --- a/src/libethash/internal.c +++ b/src/libethash/internal.c @@ -20,7 +20,6 @@ * @date 2015 */ -#include #include #include #include "ethash.h" @@ -37,24 +36,29 @@ #include "sha3.h" #endif // WITH_CRYPTOPP -size_t ethash_get_datasize(const uint32_t block_number) { - assert(block_number / EPOCH_LENGTH < 2048); +uint64_t ethash_get_datasize(const uint32_t block_number) { + if (block_number / EPOCH_LENGTH >= 2048) + return 0; return dag_sizes[block_number / EPOCH_LENGTH]; } -size_t ethash_get_cachesize(const uint32_t block_number) { - assert(block_number / EPOCH_LENGTH < 2048); +uint64_t ethash_get_cachesize(const uint32_t block_number) { + if (block_number / EPOCH_LENGTH >= 2048) + return 0; return cache_sizes[block_number / EPOCH_LENGTH]; } // Follows Sergio's "STRICT MEMORY HARD HASHING FUNCTIONS" (2014) // https://bitslog.files.wordpress.com/2013/12/memohash-v0-3.pdf // SeqMemoHash(s, R, N) -void static ethash_compute_cache_nodes( +int static ethash_compute_cache_nodes( node *const nodes, ethash_params const *params, const uint8_t seed[32]) { - assert((params->cache_size % sizeof(node)) == 0); + + if ((params->cache_size % sizeof(node)) != 0) + return 0; + uint32_t const num_nodes = (uint32_t) (params->cache_size / sizeof(node)); SHA3_512(nodes[0].bytes, seed, 32); @@ -82,22 +86,27 @@ void static ethash_compute_cache_nodes( nodes->words[w] = fix_endian32(nodes->words[w]); } #endif + + return 1; } -void ethash_mkcache( +int ethash_mkcache( ethash_cache *cache, ethash_params const *params, const uint8_t seed[32]) { node *nodes = (node *) cache->mem; - ethash_compute_cache_nodes(nodes, params, seed); + return ethash_compute_cache_nodes(nodes, params, seed); } -void ethash_calculate_dag_item( +int ethash_calculate_dag_item( node *const ret, const unsigned node_index, const struct ethash_params *params, const struct ethash_cache *cache) { + if (params->cache_size % sizeof(node) != 0) + return 0; + uint32_t num_parent_nodes = (uint32_t) (params->cache_size / sizeof(node)); node const *cache_nodes = (node const *) cache->mem; node const *init = &cache_nodes[node_index % num_parent_nodes]; @@ -145,23 +154,30 @@ void ethash_calculate_dag_item( } SHA3_512(ret->bytes, ret->bytes, sizeof(node)); + return 1; } -void ethash_compute_full_data( +int ethash_compute_full_data( void *mem, ethash_params const *params, ethash_cache const *cache) { - assert((params->full_size % (sizeof(uint32_t) * MIX_WORDS)) == 0); - assert((params->full_size % sizeof(node)) == 0); + + if ((params->full_size % (sizeof(uint32_t) * MIX_WORDS)) != 0) + return 0; + + if ((params->full_size % sizeof(node)) != 0) + return 0; + node *full_nodes = mem; // now compute full nodes for (unsigned n = 0; n != (params->full_size / sizeof(node)); ++n) { ethash_calculate_dag_item(&(full_nodes[n]), n, params, cache); } + return 1; } -static void ethash_hash( +static int ethash_hash( ethash_return_value *ret, node const *full_nodes, ethash_cache const *cache, @@ -169,10 +185,10 @@ static void ethash_hash( const uint8_t header_hash[32], const uint64_t nonce) { - assert((params->full_size % MIX_WORDS) == 0); + if ((params->full_size % MIX_WORDS) != 0) + return 0; // pack hash and nonce together into first 40 bytes of s_mix - assert(sizeof(node) * 8 == 512); node s_mix[MIX_NODES + 1]; memcpy(s_mix[0].bytes, header_hash, 32); @@ -254,6 +270,7 @@ static void ethash_hash( memcpy(ret->mix_hash, mix->bytes, 32); // final Keccak hash SHA3_256(ret->result, s_mix->bytes, 64 + 32); // Keccak-256(s + compressed_mix) + return 1; } void ethash_quick_hash( @@ -291,10 +308,10 @@ int ethash_quick_check_difficulty( return ethash_check_difficulty(return_hash, difficulty); } -void ethash_full(ethash_return_value *ret, void const *full_mem, ethash_params const *params, const uint8_t previous_hash[32], const uint64_t nonce) { - ethash_hash(ret, (node const *) full_mem, NULL, params, previous_hash, nonce); +int ethash_full(ethash_return_value *ret, void const *full_mem, ethash_params const *params, const uint8_t previous_hash[32], const uint64_t nonce) { + return ethash_hash(ret, (node const *) full_mem, NULL, params, previous_hash, nonce); } -void ethash_light(ethash_return_value *ret, ethash_cache const *cache, ethash_params const *params, const uint8_t previous_hash[32], const uint64_t nonce) { - ethash_hash(ret, NULL, cache, params, previous_hash, nonce); +int ethash_light(ethash_return_value *ret, ethash_cache const *cache, ethash_params const *params, const uint8_t previous_hash[32], const uint64_t nonce) { + return ethash_hash(ret, NULL, cache, params, previous_hash, nonce); } \ No newline at end of file diff --git a/src/libethash/internal.h b/src/libethash/internal.h index bcbacdaa..19d6ccd2 100644 --- a/src/libethash/internal.h +++ b/src/libethash/internal.h @@ -30,7 +30,7 @@ typedef union node { } node; -void ethash_calculate_dag_item( +int ethash_calculate_dag_item( node *const ret, const unsigned node_index, ethash_params const *params, diff --git a/src/python/core.c b/src/python/core.c index 35973599..6d0a40ad 100644 --- a/src/python/core.c +++ b/src/python/core.c @@ -58,7 +58,7 @@ mkcache_bytes(PyObject *self, PyObject *args) { } ethash_params params; - params.cache_size = (size_t) cache_size; + params.cache_size = (uint64_t) cache_size; ethash_cache cache; cache.mem = malloc(cache_size); ethash_mkcache(&cache, ¶ms, (uint8_t *) seed); @@ -92,8 +92,8 @@ calc_dataset_bytes(PyObject *self, PyObject *args) { } ethash_params params; - params.cache_size = (size_t) cache_size; - params.full_size = (size_t) full_size; + params.cache_size = (uint64_t) cache_size; + params.full_size = (uint64_t) full_size; ethash_cache cache; cache.mem = (void *) cache_bytes; void *mem = malloc(params.full_size); @@ -138,8 +138,8 @@ hashimoto_light(PyObject *self, PyObject *args) { ethash_return_value out; ethash_params params; - params.cache_size = (size_t) cache_size; - params.full_size = (size_t) full_size; + params.cache_size = (uint64_t) cache_size; + params.full_size = (uint64_t) full_size; ethash_cache cache; cache.mem = (void *) cache_bytes; ethash_light(&out, &cache, ¶ms, (uint8_t *) header, nonce); @@ -175,7 +175,7 @@ hashimoto_full(PyObject *self, PyObject *args) { ethash_return_value out; ethash_params params; - params.full_size = (size_t) full_size; + params.full_size = (uint64_t) full_size; ethash_full(&out, (void *) full_bytes, ¶ms, (uint8_t *) header, nonce); return Py_BuildValue("{s:s#, s:s#}", "mix digest", out.mix_hash, 32, @@ -216,7 +216,7 @@ mine(PyObject *self, PyObject *args) { ethash_return_value out; ethash_params params; - params.full_size = (size_t) full_size; + params.full_size = (uint64_t) full_size; // TODO: Multi threading? do { diff --git a/test/c/test.cpp b/test/c/test.cpp index 21cb251f..8c854ecb 100644 --- a/test/c/test.cpp +++ b/test/c/test.cpp @@ -17,7 +17,7 @@ #include #include -std::string bytesToHexString(const uint8_t *str, const size_t s) { +std::string bytesToHexString(const uint8_t *str, const uint32_t s) { std::ostringstream ret; for (int i = 0; i < s; ++i) @@ -80,9 +80,11 @@ BOOST_AUTO_TEST_CASE(ethash_params_init_genesis_check) { BOOST_AUTO_TEST_CASE(ethash_params_init_genesis_calcifide_check) { ethash_params params; - ethash_params_init(¶ms, 0); - const uint32_t expected_full_size = 1073739904; - const uint32_t expected_cache_size = 16776896; + BOOST_REQUIRE_MESSAGE(ethash_params_init(¶ms, 0), + "Params could not be initialized"); + const uint32_t + expected_full_size = 1073739904, + expected_cache_size = 16776896; BOOST_REQUIRE_MESSAGE(params.full_size == expected_full_size, "\nexpected: " << expected_cache_size << "\n" << "actual: " << params.full_size << "\n");