38 #include "sha3_cryptopp.h" 54 #define decsha3(bits) \ 55 int sha3_##bits(uint8_t*, size_t, uint8_t const*, size_t); 62 sha3_256((uint8_t*)ret, 32, data, size);
65 void SHA3_512(uint8_t* ret, uint8_t
const* data,
size_t const size)
67 sha3_512(ret, 64, data, size);
73 #endif //else FASC_BUILD 74 #endif // WITH_CRYPTOPP 91 static bool ethash_compute_cache_nodes(
97 if (cache_size %
sizeof(
node) != 0) {
100 uint32_t
const num_nodes = (uint32_t) (cache_size /
sizeof(
node));
104 for (uint32_t i = 1; i != num_nodes; ++i) {
105 SHA3_512(nodes[i].bytes, nodes[i - 1].bytes, 64);
109 for (uint32_t i = 0; i != num_nodes; i++) {
110 uint32_t
const idx = nodes[i].
words[0] % num_nodes;
112 data = nodes[(num_nodes - 1 + i) % num_nodes];
131 uint32_t num_parent_nodes = (uint32_t) (light->
cache_size /
sizeof(
node));
133 node const* init = &cache_nodes[node_index % num_parent_nodes];
135 ret->
words[0] ^= node_index;
137 #if defined(_M_X64) && ENABLE_SSE 138 __m128i
const fnv_prime = _mm_set1_epi32(
FNV_PRIME);
139 __m128i xmm0 = ret->xmm[0];
140 __m128i xmm1 = ret->xmm[1];
141 __m128i xmm2 = ret->xmm[2];
142 __m128i xmm3 = ret->xmm[3];
143 #elif defined(__MIC__) 144 __m512i
const fnv_prime = _mm512_set1_epi32(
FNV_PRIME);
145 __m512i zmm0 = ret->zmm[0];
149 uint32_t parent_index = fnv_hash(node_index ^ i, ret->
words[i %
NODE_WORDS]) % num_parent_nodes;
150 node const *parent = &cache_nodes[parent_index];
152 #if defined(_M_X64) && ENABLE_SSE 154 xmm0 = _mm_mullo_epi32(xmm0, fnv_prime);
155 xmm1 = _mm_mullo_epi32(xmm1, fnv_prime);
156 xmm2 = _mm_mullo_epi32(xmm2, fnv_prime);
157 xmm3 = _mm_mullo_epi32(xmm3, fnv_prime);
158 xmm0 = _mm_xor_si128(xmm0, parent->xmm[0]);
159 xmm1 = _mm_xor_si128(xmm1, parent->xmm[1]);
160 xmm2 = _mm_xor_si128(xmm2, parent->xmm[2]);
161 xmm3 = _mm_xor_si128(xmm3, parent->xmm[3]);
169 #elif defined(__MIC__) 171 zmm0 = _mm512_mullo_epi32(zmm0, fnv_prime);
174 zmm0 = _mm512_xor_si512(zmm0, parent->zmm[0]);
195 if (full_size % (
sizeof(uint32_t) *
MIX_WORDS) != 0 ||
196 (full_size %
sizeof(
node)) != 0) {
199 uint32_t
const max_n = (uint32_t)(full_size /
sizeof(
node));
200 node* full_nodes = mem;
201 double const progress_change = 1.0f / max_n;
202 double progress = 0.0f;
204 for (uint32_t n = 0; n != max_n; ++n) {
206 n % (max_n / 100) == 0 &&
207 callback((
unsigned int)(ceil(progress * 100.0
f))) != 0) {
211 progress += progress_change;
217 static bool ethash_hash(
219 node const* full_nodes,
240 node*
const mix = s_mix + 1;
241 for (uint32_t w = 0; w !=
MIX_WORDS; ++w) {
245 unsigned const page_size =
sizeof(uint32_t) *
MIX_WORDS;
246 unsigned const num_full_pages = (unsigned) (full_size / page_size);
249 uint32_t
const index = fnv_hash(s_mix->
words[0] ^ i, mix->
words[i %
MIX_WORDS]) % num_full_pages;
251 for (
unsigned n = 0; n !=
MIX_NODES; ++n) {
252 node const* dag_node;
254 dag_node = &full_nodes[
MIX_NODES * index + n];
258 dag_node = &tmp_node;
261 #if defined(_M_X64) && ENABLE_SSE 263 __m128i fnv_prime = _mm_set1_epi32(
FNV_PRIME);
264 __m128i xmm0 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[0]);
265 __m128i xmm1 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[1]);
266 __m128i xmm2 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[2]);
267 __m128i xmm3 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[3]);
268 mix[n].xmm[0] = _mm_xor_si128(xmm0, dag_node->xmm[0]);
269 mix[n].xmm[1] = _mm_xor_si128(xmm1, dag_node->xmm[1]);
270 mix[n].xmm[2] = _mm_xor_si128(xmm2, dag_node->xmm[2]);
271 mix[n].xmm[3] = _mm_xor_si128(xmm3, dag_node->xmm[3]);
273 #elif defined(__MIC__) 277 __m512i fnv_prime = _mm512_set1_epi32(
FNV_PRIME);
278 __m512i zmm0 = _mm512_mullo_epi32(fnv_prime, mix[n].zmm[0]);
279 mix[n].zmm[0] = _mm512_xor_si512(zmm0, dag_node->zmm[0]);
284 mix[n].
words[w] = fnv_hash(mix[n].words[w], dag_node->
words[w]);
303 #if defined(__GNUC__) && (__GNUC__ < 5) 304 #pragma GCC diagnostic push 305 #pragma GCC diagnostic ignored "-Warray-bounds" 306 #endif // define (__GNUC__) 309 for (uint32_t w = 0; w !=
MIX_WORDS; w += 4) {
310 uint32_t reduction = mix->
words[w + 0];
314 mix->
words[w / 4] = reduction;
317 #if defined(__GNUC__) && (__GNUC__ < 5) 318 #pragma GCC diagnostic pop 319 #endif // define (__GNUC__) 331 uint64_t
const nonce,
335 uint8_t buf[64 + 32];
336 memcpy(buf, header_hash, 32);
338 memcpy(&(buf[32]), &nonce, 8);
340 memcpy(&(buf[64]), mix_hash, 32);
341 SHA3_256(return_hash, buf, 64 + 32);
347 ethash_h256_reset(&ret);
349 for (uint32_t i = 0; i < epochs; ++i)
356 uint64_t
const nonce,
364 return ethash_check_difficulty(&return_hash, boundary);
370 ret = calloc(
sizeof(*ret), 1);
375 ret->
cache = _mm_malloc((
size_t)cache_size, 64);
377 ret->
cache = malloc((
size_t)cache_size);
380 goto fail_free_light;
383 if (!ethash_compute_cache_nodes(nodes, cache_size, seed)) {
384 goto fail_free_cache_mem;
391 _mm_free(ret->
cache);
426 if (!ethash_hash(&ret, NULL, light, full_size, header_hash, nonce)) {
442 static bool ethash_mmap(
struct ethash_full* ret, FILE*
f)
454 PROT_READ | PROT_WRITE,
459 if (mmapped_data == MAP_FAILED) {
476 ret = calloc(
sizeof(*ret), 1);
486 if (!ethash_mmap(ret, f)) {
488 goto fail_close_file;
491 node* tmp_nodes = _mm_malloc((
size_t)full_size, 64);
494 uint32_t
const countnodes = (uint32_t) ((
size_t)ret->
file_size /
sizeof(
node));
496 for (uint32_t i = 1; i != countnodes; ++i) {
497 tmp_nodes[i] = ret->
data[i];
499 ret->
data = tmp_nodes;
505 ETHASH_CRITICAL(
"Could not recreate DAG file after finding existing DAG with unexpected size.");
510 if (!ethash_mmap(ret, f)) {
512 goto fail_close_file;
518 ret->
data = _mm_malloc((
size_t)full_size, 64);
522 goto fail_free_full_data;
526 if (fseek(f, 0, SEEK_SET) != 0) {
527 ETHASH_CRITICAL(
"Could not seek to DAG file start to write magic number.");
528 goto fail_free_full_data;
533 goto fail_free_full_data;
535 if (fflush(f) != 0) {
536 ETHASH_CRITICAL(
"Could not flush memory mapped data to DAG file. Insufficient space?");
537 goto fail_free_full_data;
543 munmap(ret->
data, (
size_t)full_size);
bool ethash_compute_full_data(void *mem, uint64_t full_size, ethash_light_t const light, ethash_callback_t callback)
Compute the memory data for a full node's memory.
void ethash_full_delete(ethash_full_t full)
Frees a previously allocated ethash_full handler.
DAG with revision/hash match, but file size was wrong.
uint64_t ethash_get_datasize(uint64_t const block_number)
#define ETHASH_CRITICAL(...)
Logs a critical error in important parts of ethash.
#define fix_endian64_same(val_)
bool ethash_quick_check_difficulty(ethash_h256_t const *header_hash, uint64_t const nonce, ethash_h256_t const *mix_hash, ethash_h256_t const *boundary)
Difficulty quick check for POW preverification.
ethash_light_t ethash_light_new_internal(uint64_t cache_size, ethash_h256_t const *seed)
Allocate and initialize a new ethash_light handler.
ethash_return_value_t ethash_light_compute_internal(ethash_light_t light, uint64_t full_size, ethash_h256_t const header_hash, uint64_t nonce)
Calculate the light client data.
ethash_h256_t ethash_get_seedhash(uint64_t block_number)
Calculate the seedhash for a given block number.
assert(len-trim+(2 *lenIndices)<=WIDTH)
#define ETHASH_DATASET_PARENTS
ethash_full_t ethash_full_new_internal(char const *dirname, ethash_h256_t const seed_hash, uint64_t full_size, ethash_light_t const light, ethash_callback_t callback)
Allocate and initialize a new ethash_full handler.
if(a.IndicesBefore(b, len, lenIndices))
#define ETHASH_EPOCH_LENGTH
SHA3_Final< 64 > SHA3_512
SHA3_Final< 32 > SHA3_256
DAG file existed and revision/hash matched. No need to do anything.
void ethash_light_delete(ethash_light_t light)
Frees a previously allocated ethash_light handler.
const uint64_t cache_sizes[2048]
enum ethash_io_rc ethash_io_prepare(char const *dirname, ethash_h256_t const seedhash, FILE **output_file, uint64_t file_size, bool force_create)
Prepares io for ethash.
decsha3(256) decsha3(512) static inline void SHA3_256(struct ethash_h256 const *ret
#define ETHASH_DAG_MAGIC_NUM_SIZE
std::vector< byte > bytes
#define ETHASH_CACHE_ROUNDS
int ethash_fileno(FILE *f)
Get a file descriptor number from a FILE stream.
Type of a seedhash/blockhash e.t.c.
ethash_light_t ethash_light_new(uint64_t block_number)
Allocate and initialize a new ethash_light handler.
ethash_return_value_t ethash_light_compute(ethash_light_t light, ethash_h256_t const header_hash, uint64_t nonce)
Calculate the light client data.
void ethash_calculate_dag_item(node *const ret, uint32_t node_index, ethash_light_t const light)
uint32_t words[NODE_WORDS]
The DAG file did not exist or there was revision/hash mismatch.
uint64_t ethash_get_cachesize(uint64_t const block_number)
uint8_t const size_t const size
void * memcpy(void *a, const void *b, size_t c)
void ethash_quick_hash(ethash_h256_t *return_hash, ethash_h256_t const *header_hash, uint64_t const nonce, ethash_h256_t const *mix_hash)
#define fix_endian_arr32(arr_, size_)
int(* ethash_callback_t)(unsigned)
#define ETHASH_DAG_MAGIC_NUM
uint64_t ethash_full_dag_size(ethash_full_t full)
Get the size of the DAG data.
ethash_full_t ethash_full_new(ethash_light_t light, ethash_callback_t callback)
Allocate and initialize a new ethash_full handler.
bool ethash_get_default_dirname(char *strbuf, size_t buffsize)
Gets the default directory name for the DAG depending on the system.
void const * ethash_full_dag(ethash_full_t full)
Get a pointer to the full DAG data.
ethash_return_value_t ethash_full_compute(ethash_full_t full, ethash_h256_t const header_hash, uint64_t nonce)
Calculate the full client data.
uint8_t bytes[NODE_WORDS *4]
There has been an IO failure.
#define fix_endian64(dst_, src_)