From d0b494132164c681999b9b61a81f56a1e5f3fe4e Mon Sep 17 00:00:00 2001 From: Jay D Dee Date: Fri, 19 Mar 2021 15:45:32 -0400 Subject: [PATCH] v3.16.0 --- Makefile.am | 6 +- RELEASE_NOTES | 4 + algo-gate-api.c | 1 + algo/sha/sph_sha2.c | 8 + algo/sha/sph_sha2.h | 4 + algo/verthash/.verthash-gate.c.swp | Bin 0 -> 16384 bytes algo/verthash/Verthash.c | 621 +++++++++++++++++++++++++++++ algo/verthash/Verthash.h | 61 +++ algo/verthash/fopen_utf8.c | 181 +++++++++ algo/verthash/fopen_utf8.h | 25 ++ algo/verthash/tiny_sha3/sha3.c | 191 +++++++++ algo/verthash/tiny_sha3/sha3.h | 55 +++ algo/verthash/verthash-gate.c | 96 +++++ configure | 20 +- configure.ac | 2 +- cpu-miner.c | 12 +- miner.h | 3 + verthash-help.txt | 17 + winbuild-cross.sh | 1 + 19 files changed, 1290 insertions(+), 18 deletions(-) create mode 100644 algo/verthash/.verthash-gate.c.swp create mode 100644 algo/verthash/Verthash.c create mode 100644 algo/verthash/Verthash.h create mode 100644 algo/verthash/fopen_utf8.c create mode 100644 algo/verthash/fopen_utf8.h create mode 100644 algo/verthash/tiny_sha3/sha3.c create mode 100644 algo/verthash/tiny_sha3/sha3.h create mode 100644 algo/verthash/verthash-gate.c create mode 100644 verthash-help.txt diff --git a/Makefile.am b/Makefile.am index c3a999d..f416382 100644 --- a/Makefile.am +++ b/Makefile.am @@ -129,7 +129,7 @@ cpuminer_SOURCES = \ algo/lyra2/allium.c \ algo/lyra2/phi2-4way.c \ algo/lyra2/phi2.c \ - algo//m7m/m7m.c \ + algo/m7m/m7m.c \ algo/m7m/magimath.cpp \ algo/nist5/nist5-gate.c \ algo/nist5/nist5-4way.c \ @@ -192,6 +192,10 @@ cpuminer_SOURCES = \ algo/sm3/sm3-hash-4way.c \ algo/swifftx/swifftx.c \ algo/tiger/sph_tiger.c \ + algo/verthash/verthash-gate.c \ + algo/verthash/Verthash.c \ + algo/verthash/fopen_utf8.c \ + algo/verthash/tiny_sha3/sha3.c \ algo/whirlpool/sph_whirlpool.c \ algo/whirlpool/whirlpool-hash-4way.c \ algo/whirlpool/whirlpool-gate.c \ diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 732b5e6..e6c7f14 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -65,6 +65,10 @@ If not what makes it happen or not happen? Change Log ---------- +v3.16.0 + +Added verthash algo. + v3.15.7 Added accepted/stale/rejected percentage to summary log report. diff --git a/algo-gate-api.c b/algo-gate-api.c index 6f273cc..2fea7af 100644 --- a/algo-gate-api.c +++ b/algo-gate-api.c @@ -349,6 +349,7 @@ bool register_algo_gate( int algo, algo_gate_t *gate ) case ALGO_TRIBUS: register_tribus_algo ( gate ); break; case ALGO_VANILLA: register_vanilla_algo ( gate ); break; case ALGO_VELTOR: register_veltor_algo ( gate ); break; + case ALGO_VERTHASH: register_verthash_algo ( gate ); break; case ALGO_WHIRLPOOL: register_whirlpool_algo ( gate ); break; case ALGO_WHIRLPOOLX: register_whirlpoolx_algo ( gate ); break; case ALGO_X11: register_x11_algo ( gate ); break; diff --git a/algo/sha/sph_sha2.c b/algo/sha/sph_sha2.c index 513a29f..e96a2d1 100644 --- a/algo/sha/sph_sha2.c +++ b/algo/sha/sph_sha2.c @@ -691,6 +691,14 @@ sph_sha256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) // sph_sha256_init(cc); } +void sph_sha256_full( void *dst, const void *data, size_t len ) +{ + sph_sha256_context cc; + sph_sha256_init( &cc ); + sph_sha256( &cc, data, len ); + sph_sha256_close( &cc, dst ); +} + /* see sph_sha2.h */ //void //sph_sha224_comp(const sph_u32 msg[16], sph_u32 val[8]) diff --git a/algo/sha/sph_sha2.h b/algo/sha/sph_sha2.h index df0e836..e3a83eb 100644 --- a/algo/sha/sph_sha2.h +++ b/algo/sha/sph_sha2.h @@ -205,6 +205,10 @@ void sph_sha256_comp(const sph_u32 msg[16], sph_u32 val[8]); #define sph_sha256_comp sph_sha224_comp #endif +void sph_sha256_full( void *dst, const void *data, size_t len ); + + + #if SPH_64 /** diff --git a/algo/verthash/.verthash-gate.c.swp b/algo/verthash/.verthash-gate.c.swp new file mode 100644 index 0000000000000000000000000000000000000000..4c59aa9e76706b9dc6b924ebfa9e701366767038 GIT binary patch literal 16384 zcmeHN%a0tz881v?NC@VUa6kyDycVWsnVFr(&g?8^SF!-ZDrPMiVc_5^m6KBxh!i2ji35pph{!3R905fULY$D`hTwpRP$bAd5JgcWeqZ%-cE_xJLvgkA ztDdf|`o5~)_o(UW9=6VJJjDmiHp6izW4HbL-1Dy=`iQ;sK#N&{>r?eXN3;`lRt{=} z`@bZCOSasS-jX#@)_qvu>x|A_|Tz9OXZ~`=?Y0vrQ?D|L9Ie*;F+hx`Iq#4i*Xa+O`ngPv#W5q>^-_uqp9(;4i=*fj2Or7r6L<>P!lud#fC-!fHh`1BD)2RI@+aVL-?hQQ=Nw`>^@5Rc`pgsN<7dy- z`NApTdeY``z=h`p7QU6>6FCXO9qt4nKc9VD!EF(Xh1v-=N946teYfJhGQ@Om&2?PQ zQFR@?RnvVUu2;a-+l%tnfj`rx`v!9ro0WpU|G%zvP6zm*^diY!hZ|et(}A$h$|&(- zzP83YHCB?aPuYxHa|aQ?eKCQgh`aul@Lap%>+{673-L=!{7K>4kWdJfVTjPN0$WBj zh+QgZpme@MMS4_5_3X*Bn;V-?ARG%J6maRtwq)o!E+W$nd>+MOq{eBxkr*O!kCr3N zbwGSY4X!Gh(x5*`3qGgfj!Fy_@eoweux}0ie$8M0^UCdJ>;{nZun}Mm1g|Q@40w46b~E5|}la8hmSvJ|gc_ zC;js!)ft=7Jaduv+VGvANoIK(d~>ZE|oFn z`fltZP+u&1=7PfNrV9h2aAV_m)uyFim}Fg((t)YcfwD1l=dDX_h&q5i zEo`humhkBVL=J-)TY+mY){f_OX5N>Kh>sb~ScD@Pn~tzzBnc#{UccEo!PqVv27$*z zIdY>|hDAS{HH$Pf8JTwA zORD4zST~Gf(+_-0swP+X_Ly>@fxC}zPvkfG@#FmHb`V}NLy5!_#uwsoXu9^rW_Ddh zf&b7$N)(1r$vsgroVc+W1ztkg%itue&S^w-KG}h^Qo^3W52I}{HM<=eQxR*sG({ZB ziB+C9NtTgGoTlU=EzrP+(znKim!}LEYD!S4uV|kBFs#6j zV!prYpoOlIsLumCH+wd|{IW~{g;Nz(lve8GRdgs}Gj>#Sw}UhXBPegc0*)?rM(UrOYJW1KF zvF_Tc0i`i0iD9m_eGZoKmN%(*7{rLnsVl-U+ZA1fz>2p*bm8E$S{HNMuPGmEtf#K9 zw-K2LLdXpp>vS>OfLOdRxX4XY#Bt~j6U3Wo7|1i^Dn@^~R!e=c7+h+nPV1mPyTtUI zg9P=LL0dIU>saQ)#LBov*5ZpKHoR7J_3QD;=$ZcvunDXKj{vHD)>fZ11DXNNfM!55pc&8%Xa+O`ngPv#Wj=CVQoB&IyF=AY>|+0unpF1Q=e^9?voW6dm;7Mc n=jA)8hxr5cLcUF@-ssTwI=$?*fileName = NULL; + info->data = NULL; + info->dataSize = 0; + info->bitmask = 0; + + // get name + if (file_name == NULL) { return 1; } + size_t fileNameLen = strlen(file_name); + if (fileNameLen == 0) { return 1; } + + info->fileName = (char*)malloc(fileNameLen+1); + if (!info->fileName) + { + // Memory allocation fatal error. + return 2; + } + + memset(info->fileName, 0, fileNameLen+1); + memcpy(info->fileName, file_name, fileNameLen); + + // Load data + FILE *fileMiningData = fopen_utf8(info->fileName, "rb"); + // Failed to open file for reading + if (!fileMiningData) { return 1; } + + // Get file size + fseek(fileMiningData, 0, SEEK_END); + uint64_t fileSize = (uint64_t)ftell(fileMiningData); + fseek(fileMiningData, 0, SEEK_SET); + + // Allocate data + info->data = (uint8_t *)malloc(fileSize); + if (!info->data) + { + fclose(fileMiningData); + // Memory allocation fatal error. + return 2; + } + + // Load data + fread(info->data, fileSize, 1, fileMiningData); + fclose(fileMiningData); + + // Update fields + info->bitmask = ((fileSize - VH_HASH_OUT_SIZE)/VH_BYTE_ALIGNMENT) + 1; + info->dataSize = fileSize; + + return 0; +} + +//----------------------------------------------------------------------------- +void verthash_info_free(verthash_info_t* info) +{ + free(info->fileName); + free(info->data); + info->dataSize = 0; + info->bitmask = 0; +} + + +//----------------------------------------------------------------------------- +// Verthash hash +#define VH_P0_SIZE 64 +#define VH_N_ITER 8 +#define VH_N_SUBSET VH_P0_SIZE*VH_N_ITER +#define VH_N_ROT 32 +#define VH_N_INDEXES 4096 +#define VH_BYTE_ALIGNMENT 16 + +static __thread sha3_ctx_t sha3_midstate_ctx; + +void verthash_sha3_prehash_72( const void *data ) +{ + sha3_init( &sha3_midstate_ctx, 256 ); + sha3_update( &sha3_midstate_ctx, data, 72 ); +} + +void verthash_sha3_final_8( sha3_ctx_t *ctx, void *out, const void *data ) +{ + sha3_update( ctx, data, 8 ); + sha3_final( out, ctx ); +} + +static inline uint32_t fnv1a(const uint32_t a, const uint32_t b) +{ + return (a ^ b) * 0x1000193; +} + +void verthash_hash(const unsigned char* blob_bytes, + const size_t blob_size, + const unsigned char(*input)[VH_HEADER_SIZE], + unsigned char(*output)[VH_HASH_OUT_SIZE]) +{ + unsigned char p1[VH_HASH_OUT_SIZE]; +// sha3_ctx_t sha3_ctx; +// memcpy ( &sha3_ctx, &sha3_midstate_ctx, sizeof sha3_ctx ); +// verthash_sha3_final_8( &sha3_ctx, &p1[0], &input[72] ); + + sha3(&input[0], VH_HEADER_SIZE, &p1[0], VH_HASH_OUT_SIZE); + + unsigned char p0[VH_N_SUBSET]; + + unsigned char input_header[VH_HEADER_SIZE]; + memcpy(input_header, input, VH_HEADER_SIZE); + + for (size_t i = 0; i < VH_N_ITER; ++i) + { + input_header[0] += 1; + sha3(&input_header[0], VH_HEADER_SIZE, p0 + i * VH_P0_SIZE, VH_P0_SIZE); + } + + uint32_t* p0_index = (uint32_t*)p0; + uint32_t seek_indexes[VH_N_INDEXES]; + + for (size_t x = 0; x < VH_N_ROT; ++x) + { + memcpy( seek_indexes + x * (VH_N_SUBSET / sizeof(uint32_t)), + p0, VH_N_SUBSET); + for (size_t y = 0; y < VH_N_SUBSET / sizeof(uint32_t); ++y) + { + *(p0_index + y) = ( *(p0_index + y) << 1 ) + | ( 1 & (*(p0_index + y) >> 31) ); + } + } + + uint32_t* p1_32 = (uint32_t*)p1; + uint32_t* blob_bytes_32 = (uint32_t*)blob_bytes; + uint32_t value_accumulator = 0x811c9dc5; + const uint32_t mdiv = ((blob_size - VH_HASH_OUT_SIZE) / VH_BYTE_ALIGNMENT) + 1; + for (size_t i = 0; i < VH_N_INDEXES; i++) + { + const uint32_t offset = (fnv1a(seek_indexes[i], value_accumulator) % mdiv) * VH_BYTE_ALIGNMENT / sizeof(uint32_t); + for (size_t i2 = 0; i2 < VH_HASH_OUT_SIZE / sizeof(uint32_t); i2++) + { + const uint32_t value = *(blob_bytes_32 + offset + i2); + uint32_t* p1_ptr = p1_32 + i2; + *p1_ptr = fnv1a(*p1_ptr, value); + + value_accumulator = fnv1a(value_accumulator, value); + } + } + + memcpy(output, p1, VH_HASH_OUT_SIZE); +} + +//----------------------------------------------------------------------------- +// Verthash data file generator + +#define NODE_SIZE 32 + +struct Graph +{ + FILE *db; + int64_t log2; + int64_t pow2; + uint8_t *pk; + int64_t index; +}; + +int64_t Log2(int64_t x) +{ + int64_t r = 0; + for (; x > 1; x >>= 1) + { + r++; + } + + return r; +} + +int64_t bfsToPost(struct Graph *g, const int64_t node) +{ + return node & ~g->pow2; +} + +int64_t numXi(int64_t index) +{ + return (1 << ((uint64_t)index)) * (index + 1) * index; +} + +void WriteId(struct Graph *g, uint8_t *Node, const int64_t id) +{ + fseek(g->db, id * NODE_SIZE, SEEK_SET); + fwrite(Node, 1, NODE_SIZE, g->db); +} + +void WriteNode(struct Graph *g, uint8_t *Node, const int64_t id) +{ + const int64_t idx = bfsToPost(g, id); + WriteId(g, Node, idx); +} + +void NewNode(struct Graph *g, const int64_t id, uint8_t *hash) +{ + WriteNode(g, hash, id); +} + +uint8_t *GetId(struct Graph *g, const int64_t id) +{ + fseek(g->db, id * NODE_SIZE, SEEK_SET); + uint8_t *node = (uint8_t *)malloc(NODE_SIZE); + const size_t bytes_read = fread(node, 1, NODE_SIZE, g->db); + if(bytes_read != NODE_SIZE) { + return NULL; + } + return node; +} + +uint8_t *GetNode(struct Graph *g, const int64_t id) +{ + const int64_t idx = bfsToPost(g, id); + return GetId(g, idx); +} + +uint32_t WriteVarInt(uint8_t *buffer, int64_t val) +{ + memset(buffer, 0, NODE_SIZE); + uint64_t uval = ((uint64_t)(val)) << 1; + if (val < 0) + { + uval = ~uval; + } + uint32_t i = 0; + while (uval >= 0x80) + { + buffer[i] = (uint8_t)uval | 0x80; + uval >>= 7; + i++; + } + buffer[i] = (uint8_t)uval; + return i; +} + +void ButterflyGraph(struct Graph *g, int64_t index, int64_t *count) +{ + if (index == 0) + { + index = 1; + } + + int64_t numLevel = 2 * index; + int64_t perLevel = (int64_t)(1 << (uint64_t)index); + int64_t begin = *count - perLevel; + int64_t level, i; + + for (level = 1; level < numLevel; level++) + { + for (i = 0; i < perLevel; i++) + { + int64_t prev; + int64_t shift = index - level; + if (level > numLevel / 2) + { + shift = level - numLevel / 2; + } + if (((i >> (uint64_t)shift) & 1) == 0) + { + prev = i + (1 << (uint64_t)shift); + } + else + { + prev = i - (1 << (uint64_t)shift); + } + + uint8_t *parent0 = GetNode(g, begin + (level - 1) * perLevel + prev); + uint8_t *parent1 = GetNode(g, *count - perLevel); + uint8_t *buf = (uint8_t *)malloc(NODE_SIZE); + WriteVarInt(buf, *count); + uint8_t *hashInput = (uint8_t *)malloc(NODE_SIZE * 4); + memcpy(hashInput, g->pk, NODE_SIZE); + memcpy(hashInput + NODE_SIZE, buf, NODE_SIZE); + memcpy(hashInput + (NODE_SIZE * 2), parent0, NODE_SIZE); + memcpy(hashInput + (NODE_SIZE * 3), parent1, NODE_SIZE); + + uint8_t *hashOutput = (uint8_t *)malloc(NODE_SIZE); + sha3(hashInput, NODE_SIZE * 4, hashOutput, NODE_SIZE); + + NewNode(g, *count, hashOutput); + (*count)++; + + free(hashOutput); + free(hashInput); + free(parent0); + free(parent1); + free(buf); + } + } +} + +void XiGraphIter(struct Graph *g, int64_t index) +{ + int64_t count = g->pow2; + + int8_t stackSize = 5; + int64_t *stack = (int64_t *)malloc(sizeof(int64_t) * stackSize); + for (int i = 0; i < 5; i++) + stack[i] = index; + + int8_t graphStackSize = 5; + int32_t *graphStack = (int32_t *)malloc(sizeof(int32_t) * graphStackSize); + for (int i = 0; i < 5; i++) + graphStack[i] = graphStackSize - i - 1; + + int64_t i = 0; + int64_t graph = 0; + int64_t pow2index = 1 << ((uint64_t)index); + + for (i = 0; i < pow2index; i++) + { + uint8_t *buf = (uint8_t *)malloc(NODE_SIZE); + WriteVarInt(buf, count); + uint8_t *hashInput = (uint8_t *)malloc(NODE_SIZE * 2); + memcpy(hashInput, g->pk, NODE_SIZE); + memcpy(hashInput + NODE_SIZE, buf, NODE_SIZE); + uint8_t *hashOutput = (uint8_t *)malloc(NODE_SIZE); + + sha3(hashInput, NODE_SIZE * 2, hashOutput, NODE_SIZE); + NewNode(g, count, hashOutput); + count++; + + free(hashOutput); + free(hashInput); + free(buf); + } + + if (index == 1) + { + ButterflyGraph(g, index, &count); + return; + } + + while (stackSize != 0 && graphStackSize != 0) + { + + index = stack[stackSize - 1]; + graph = graphStack[graphStackSize - 1]; + + stackSize--; + if (stackSize > 0) + { + int64_t *tempStack = (int64_t *)malloc(sizeof(int64_t) * (stackSize)); + memcpy(tempStack, stack, sizeof(int64_t) * (stackSize)); + free(stack); + stack = tempStack; + } + + graphStackSize--; + if (graphStackSize > 0) + { + int32_t *tempGraphStack = (int32_t *)malloc(sizeof(int32_t) * (graphStackSize)); + memcpy(tempGraphStack, graphStack, sizeof(int32_t) * (graphStackSize)); + free(graphStack); + graphStack = tempGraphStack; + } + + int8_t indicesSize = 5; + int64_t *indices = (int64_t *)malloc(sizeof(int64_t) * indicesSize); + for (int i = 0; i < indicesSize; i++) + indices[i] = index - 1; + + int8_t graphsSize = 5; + int32_t *graphs = (int32_t *)malloc(sizeof(int32_t) * graphsSize); + for (int i = 0; i < graphsSize; i++) + graphs[i] = graphsSize - i - 1; + + int64_t pow2indexInner = 1 << ((uint64_t)index); + int64_t pow2indexInner_1 = 1 << ((uint64_t)index - 1); + + if (graph == 0) + { + uint64_t sources = count - pow2indexInner; + for (i = 0; i < pow2indexInner_1; i++) + { + uint8_t *parent0 = GetNode(g, sources + i); + uint8_t *parent1 = GetNode(g, sources + i + pow2indexInner_1); + + uint8_t *buf = (uint8_t *)malloc(NODE_SIZE); + WriteVarInt(buf, count); + + uint8_t *hashInput = (uint8_t *)malloc(NODE_SIZE * 4); + memcpy(hashInput, g->pk, NODE_SIZE); + memcpy(hashInput + NODE_SIZE, buf, NODE_SIZE); + memcpy(hashInput + (NODE_SIZE * 2), parent0, NODE_SIZE); + memcpy(hashInput + (NODE_SIZE * 3), parent1, NODE_SIZE); + + uint8_t *hashOutput = (uint8_t *)malloc(NODE_SIZE); + sha3(hashInput, NODE_SIZE * 4, hashOutput, NODE_SIZE); + + NewNode(g, count, hashOutput); + count++; + + free(hashOutput); + free(hashInput); + free(parent0); + free(parent1); + free(buf); + } + } + else if (graph == 1) + { + uint64_t firstXi = count; + for (i = 0; i < pow2indexInner_1; i++) + { + uint64_t nodeId = firstXi + i; + uint8_t *parent = GetNode(g, firstXi - pow2indexInner_1 + i); + + uint8_t *buf = (uint8_t *)malloc(NODE_SIZE); + WriteVarInt(buf, nodeId); + + uint8_t *hashInput = (uint8_t *)malloc(NODE_SIZE * 3); + memcpy(hashInput, g->pk, NODE_SIZE); + memcpy(hashInput + NODE_SIZE, buf, NODE_SIZE); + memcpy(hashInput + (NODE_SIZE * 2), parent, NODE_SIZE); + + uint8_t *hashOutput = (uint8_t *)malloc(NODE_SIZE); + sha3(hashInput, NODE_SIZE * 3, hashOutput, NODE_SIZE); + + NewNode(g, count, hashOutput); + count++; + + free(hashOutput); + free(hashInput); + free(parent); + free(buf); + } + } + else if (graph == 2) + { + uint64_t secondXi = count; + for (i = 0; i < pow2indexInner_1; i++) + { + uint64_t nodeId = secondXi + i; + uint8_t *parent = GetNode(g, secondXi - pow2indexInner_1 + i); + + uint8_t *buf = (uint8_t *)malloc(NODE_SIZE); + WriteVarInt(buf, nodeId); + + uint8_t *hashInput = (uint8_t *)malloc(NODE_SIZE * 3); + memcpy(hashInput, g->pk, NODE_SIZE); + memcpy(hashInput + NODE_SIZE, buf, NODE_SIZE); + memcpy(hashInput + (NODE_SIZE * 2), parent, NODE_SIZE); + + uint8_t *hashOutput = (uint8_t *)malloc(NODE_SIZE); + sha3(hashInput, NODE_SIZE * 3, hashOutput, NODE_SIZE); + + NewNode(g, count, hashOutput); + count++; + + free(hashOutput); + free(hashInput); + free(parent); + free(buf); + } + } + else if (graph == 3) + { + uint64_t secondButter = count; + for (i = 0; i < pow2indexInner_1; i++) + { + uint64_t nodeId = secondButter + i; + uint8_t *parent = GetNode(g, secondButter - pow2indexInner_1 + i); + + uint8_t *buf = (uint8_t *)malloc(NODE_SIZE); + WriteVarInt(buf, nodeId); + + uint8_t *hashInput = (uint8_t *)malloc(NODE_SIZE * 3); + memcpy(hashInput, g->pk, NODE_SIZE); + memcpy(hashInput + NODE_SIZE, buf, NODE_SIZE); + memcpy(hashInput + (NODE_SIZE * 2), parent, NODE_SIZE); + + uint8_t *hashOutput = (uint8_t *)malloc(NODE_SIZE); + sha3(hashInput, NODE_SIZE * 3, hashOutput, NODE_SIZE); + + NewNode(g, count, hashOutput); + count++; + + free(hashOutput); + free(hashInput); + free(parent); + free(buf); + } + } + else + { + uint64_t sinks = count; + uint64_t sources = sinks + pow2indexInner - numXi(index); + for (i = 0; i < pow2indexInner_1; i++) + { + uint64_t nodeId0 = sinks + i; + uint64_t nodeId1 = sinks + i + pow2indexInner_1; + uint8_t *parent0 = GetNode(g, sinks - pow2indexInner_1 + i); + uint8_t *parent1_0 = GetNode(g, sources + i); + uint8_t *parent1_1 = GetNode(g, sources + i + pow2indexInner_1); + + uint8_t *buf = (uint8_t *)malloc(NODE_SIZE); + WriteVarInt(buf, nodeId0); + + uint8_t *hashInput = (uint8_t *)malloc(NODE_SIZE * 4); + memcpy(hashInput, g->pk, NODE_SIZE); + memcpy(hashInput + NODE_SIZE, buf, NODE_SIZE); + memcpy(hashInput + (NODE_SIZE * 2), parent0, NODE_SIZE); + memcpy(hashInput + (NODE_SIZE * 3), parent1_0, NODE_SIZE); + + uint8_t *hashOutput0 = (uint8_t *)malloc(NODE_SIZE); + sha3(hashInput, NODE_SIZE * 4, hashOutput0, NODE_SIZE); + + WriteVarInt(buf, nodeId1); + + memcpy(hashInput, g->pk, NODE_SIZE); + memcpy(hashInput + NODE_SIZE, buf, NODE_SIZE); + memcpy(hashInput + (NODE_SIZE * 2), parent0, NODE_SIZE); + memcpy(hashInput + (NODE_SIZE * 3), parent1_1, NODE_SIZE); + + uint8_t *hashOutput1 = (uint8_t *)malloc(NODE_SIZE); + sha3(hashInput, NODE_SIZE * 4, hashOutput1, NODE_SIZE); + + NewNode(g, nodeId0, hashOutput0); + NewNode(g, nodeId1, hashOutput1); + count += 2; + + free(parent0); + free(parent1_0); + free(parent1_1); + free(buf); + free(hashInput); + free(hashOutput0); + free(hashOutput1); + } + } + + if ((graph == 0 || graph == 3) || + ((graph == 1 || graph == 2) && index == 2)) + { + ButterflyGraph(g, index - 1, &count); + } + else if (graph == 1 || graph == 2) + { + + int64_t *tempStack = (int64_t *)malloc(sizeof(int64_t) * (stackSize + indicesSize)); + memcpy(tempStack, stack, stackSize * sizeof(int64_t)); + memcpy(tempStack + stackSize, indices, indicesSize * sizeof(int64_t)); + stackSize += indicesSize; + free(stack); + stack = tempStack; + + int32_t *tempGraphStack = (int32_t *)malloc(sizeof(int32_t) * (graphStackSize + graphsSize)); + memcpy(tempGraphStack, graphStack, graphStackSize * sizeof(int32_t)); + memcpy(tempGraphStack + graphStackSize, graphs, graphsSize * sizeof(int32_t)); + graphStackSize += graphsSize; + free(graphStack); + graphStack = tempGraphStack; + } + + free(indices); + free(graphs); + } + + free(stack); + free(graphStack); +} + +struct Graph *NewGraph(int64_t index, const char* targetFile, uint8_t *pk) +{ + uint8_t exists = 0; + FILE *db; + if ((db = fopen_utf8(targetFile, "r")) != NULL) + { + fclose(db); + exists = 1; + } + + db = fopen_utf8(targetFile, "wb+"); + int64_t size = numXi(index); + int64_t log2 = Log2(size) + 1; + int64_t pow2 = 1 << ((uint64_t)log2); + + struct Graph *g = (struct Graph *)malloc(sizeof(struct Graph)); + g->db = db; + g->log2 = log2; + g->pow2 = pow2; + g->pk = pk; + g->index = index; + + if (exists == 0) + { + XiGraphIter(g, index); + } + + fclose(db); + return g; +} + +//----------------------------------------------------------------------------- +int verthash_generate_data_file(const char* output_file_name) +{ + const char *hashInput = "Verthash Proof-of-Space Datafile"; + uint8_t *pk = (uint8_t*)malloc(NODE_SIZE); + sha3(hashInput, 32, pk, NODE_SIZE); + + int64_t index = 17; + NewGraph(index, output_file_name, pk); + + return 0; +} + diff --git a/algo/verthash/Verthash.h b/algo/verthash/Verthash.h new file mode 100644 index 0000000..5eac0a4 --- /dev/null +++ b/algo/verthash/Verthash.h @@ -0,0 +1,61 @@ +/* + * Copyright 2018-2021 CryptoGraphics + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. See LICENSE for more details. + */ + +#ifndef Verthash_INCLUDE_ONCE +#define Verthash_INCLUDE_ONCE + +#include "tiny_sha3/sha3.h" +#include "fopen_utf8.h" + +#include +#include +#include +#include + +// Verthash constants used to compute bitmask, used inside kernel during IO pass +#define VH_HASH_OUT_SIZE 32 +#define VH_BYTE_ALIGNMENT 16 +#define VH_HEADER_SIZE 80 + +//----------------------------------------------------------------------------- +// Verthash data +//! Verthash C api for data maniputation. +typedef struct VerthashInfo +{ + char* fileName; + uint8_t* data; + uint64_t dataSize; + uint32_t bitmask; +} verthash_info_t; + +//! Must be called before usage. Reset all fields and set a mining data file name. +//! Error codes +//! 0 - Success(No error). +//! 1 - File name is invalid. +//! 2 - Memory allocation error +int verthash_info_init(verthash_info_t* info, const char* file_name); + +//! Reset all fields and free allocated data. +void verthash_info_free(verthash_info_t* info); + +//! Generate verthash data file and save it to specified location. +int verthash_generate_data_file(const char* output_file_name); + +void verthash_sha3_prehash_72( const void *data ); + +void verthash_sha3_final_8( sha3_ctx_t *ctx, void *out, const void *data ); + +void verthash_hash(const unsigned char* blob_bytes, + const size_t blob_size, + const unsigned char(*input)[VH_HEADER_SIZE], + unsigned char(*output)[VH_HASH_OUT_SIZE]); + + +#endif // !Verthash_INCLUDE_ONCE + diff --git a/algo/verthash/fopen_utf8.c b/algo/verthash/fopen_utf8.c new file mode 100644 index 0000000..e2bd4b1 --- /dev/null +++ b/algo/verthash/fopen_utf8.c @@ -0,0 +1,181 @@ +#ifndef H_FOPEN_UTF8 +#define H_FOPEN_UTF8 + +#include "fopen_utf8.h" +#include +#include +#include +#include + +int utf8_char_size(const uint8_t *c) +{ + const uint8_t m0x = 0x80, c0x = 0x00, + m10x = 0xC0, c10x = 0x80, + m110x = 0xE0, c110x = 0xC0, + m1110x = 0xF0, c1110x = 0xE0, + m11110x = 0xF8, c11110x = 0xF0; + + if ((c[0] & m0x) == c0x) + return 1; + + if ((c[0] & m110x) == c110x) + if ((c[1] & m10x) == c10x) + return 2; + + if ((c[0] & m1110x) == c1110x) + if ((c[1] & m10x) == c10x) + if ((c[2] & m10x) == c10x) + return 3; + + if ((c[0] & m11110x) == c11110x) + if ((c[1] & m10x) == c10x) + if ((c[2] & m10x) == c10x) + if ((c[3] & m10x) == c10x) + return 4; + + if ((c[0] & m10x) == c10x) // not a first UTF-8 byte + return 0; + + return -1; // if c[0] is a first byte but the other bytes don't match +} + +uint32_t utf8_to_unicode32(const uint8_t *c, size_t *index) +{ + uint32_t v; + int size; + const uint8_t m6 = 63, m5 = 31, m4 = 15, m3 = 7; + + if (c==NULL) + return 0; + + size = utf8_char_size(c); + + if (size > 0 && index) + *index += size-1; + + switch (size) + { + case 1: + v = c[0]; + break; + case 2: + v = c[0] & m5; + v = v << 6 | (c[1] & m6); + break; + case 3: + v = c[0] & m4; + v = v << 6 | (c[1] & m6); + v = v << 6 | (c[2] & m6); + break; + case 4: + v = c[0] & m3; + v = v << 6 | (c[1] & m6); + v = v << 6 | (c[2] & m6); + v = v << 6 | (c[3] & m6); + break; + case 0: // not a first UTF-8 byte + case -1: // corrupt UTF-8 letter + default: + v = -1; + break; + } + + return v; +} + +int codepoint_utf16_size(uint32_t c) +{ + if (c < 0x10000) return 1; + if (c < 0x110000) return 2; + + return 0; +} + +uint16_t *sprint_utf16(uint16_t *str, uint32_t c) // str must be able to hold 1 to 3 entries and will be null-terminated by this function +{ + int c_size; + + if (str==NULL) + return NULL; + + c_size = codepoint_utf16_size(c); + + switch (c_size) + { + case 1: + str[0] = c; + if (c > 0) + str[1] = '\0'; + break; + + case 2: + c -= 0x10000; + str[0] = 0xD800 + (c >> 10); + str[1] = 0xDC00 + (c & 0x3FF); + str[2] = '\0'; + break; + + default: + str[0] = '\0'; + } + + return str; +} + +size_t strlen_utf8_to_utf16(const uint8_t *str) +{ + size_t i, count; + uint32_t c; + + for (i=0, count=0; ; i++) + { + if (str[i]==0) + return count; + + c = utf8_to_unicode32(&str[i], &i); + count += codepoint_utf16_size(c); + } +} + +uint16_t *utf8_to_utf16(const uint8_t *utf8, uint16_t *utf16) +{ + size_t i, j; + uint32_t c; + + if (utf8==NULL) + return NULL; + + if (utf16==NULL) + utf16 = (uint16_t *) calloc(strlen_utf8_to_utf16(utf8) + 1, sizeof(uint16_t)); + + for (i=0, j=0, c=1; c; i++) + { + c = utf8_to_unicode32(&utf8[i], &i); + sprint_utf16(&utf16[j], c); + j += codepoint_utf16_size(c); + } + + return utf16; +} + +FILE *fopen_utf8(const char *path, const char *mode) +{ + #ifdef _WIN32 + wchar_t *wpath, wmode[8]; + FILE *file; + + if (utf8_to_utf16((const uint8_t *) mode, (uint16_t *) wmode)==NULL) + return NULL; + + wpath = (wchar_t *) utf8_to_utf16((const uint8_t *) path, NULL); + if (wpath==NULL) + return NULL; + + file = _wfopen(wpath, wmode); + free(wpath); + return file; + #else + return fopen(path, mode); + #endif +} +#endif diff --git a/algo/verthash/fopen_utf8.h b/algo/verthash/fopen_utf8.h new file mode 100644 index 0000000..0547313 --- /dev/null +++ b/algo/verthash/fopen_utf8.h @@ -0,0 +1,25 @@ +#ifndef H_FOPEN_UTF8 +#define H_FOPEN_UTF8 +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +int utf8_char_size(const uint8_t *c); +uint32_t utf8_to_unicode32(const uint8_t *c, size_t *index); +int codepoint_utf16_size(uint32_t c); +uint16_t *sprint_utf16(uint16_t *str, uint32_t c); +size_t strlen_utf8_to_utf16(const uint8_t *str); +uint16_t *utf8_to_utf16(const uint8_t *utf8, uint16_t *utf16); + +FILE *fopen_utf8(const char *path, const char *mode); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/algo/verthash/tiny_sha3/sha3.c b/algo/verthash/tiny_sha3/sha3.c new file mode 100644 index 0000000..931ae02 --- /dev/null +++ b/algo/verthash/tiny_sha3/sha3.c @@ -0,0 +1,191 @@ +// sha3.c +// 19-Nov-11 Markku-Juhani O. Saarinen + +// Revised 07-Aug-15 to match with official release of FIPS PUB 202 "SHA3" +// Revised 03-Sep-15 for portability + OpenSSL - style API + +#include "sha3.h" + +// update the state with given number of rounds + +void sha3_keccakf(uint64_t st[25]) +{ + // constants + const uint64_t keccakf_rndc[24] = { + 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, + 0x8000000080008000, 0x000000000000808b, 0x0000000080000001, + 0x8000000080008081, 0x8000000000008009, 0x000000000000008a, + 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, + 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, + 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, + 0x000000000000800a, 0x800000008000000a, 0x8000000080008081, + 0x8000000000008080, 0x0000000080000001, 0x8000000080008008 + }; + const int keccakf_rotc[24] = { + 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, + 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 + }; + const int keccakf_piln[24] = { + 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, + 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 + }; + + // variables + int i, j, r; + uint64_t t, bc[5]; + +#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ + uint8_t *v; + + // endianess conversion. this is redundant on little-endian targets + for (i = 0; i < 25; i++) { + v = (uint8_t *) &st[i]; + st[i] = ((uint64_t) v[0]) | (((uint64_t) v[1]) << 8) | + (((uint64_t) v[2]) << 16) | (((uint64_t) v[3]) << 24) | + (((uint64_t) v[4]) << 32) | (((uint64_t) v[5]) << 40) | + (((uint64_t) v[6]) << 48) | (((uint64_t) v[7]) << 56); + } +#endif + + // actual iteration + for (r = 0; r < KECCAKF_ROUNDS; r++) { + + // Theta + for (i = 0; i < 5; i++) + bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20]; + + for (i = 0; i < 5; i++) { + t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1); + for (j = 0; j < 25; j += 5) + st[j + i] ^= t; + } + + // Rho Pi + t = st[1]; + for (i = 0; i < 24; i++) { + j = keccakf_piln[i]; + bc[0] = st[j]; + st[j] = ROTL64(t, keccakf_rotc[i]); + t = bc[0]; + } + + // Chi + for (j = 0; j < 25; j += 5) { + for (i = 0; i < 5; i++) + bc[i] = st[j + i]; + for (i = 0; i < 5; i++) + st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; + } + + // Iota + st[0] ^= keccakf_rndc[r]; + } + +#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ + // endianess conversion. this is redundant on little-endian targets + for (i = 0; i < 25; i++) { + v = (uint8_t *) &st[i]; + t = st[i]; + v[0] = t & 0xFF; + v[1] = (t >> 8) & 0xFF; + v[2] = (t >> 16) & 0xFF; + v[3] = (t >> 24) & 0xFF; + v[4] = (t >> 32) & 0xFF; + v[5] = (t >> 40) & 0xFF; + v[6] = (t >> 48) & 0xFF; + v[7] = (t >> 56) & 0xFF; + } +#endif +} + +// Initialize the context for SHA3 + +int sha3_init(sha3_ctx_t *c, int mdlen) +{ + int i; + + for (i = 0; i < 25; i++) + c->st.q[i] = 0; + c->mdlen = mdlen; + c->rsiz = 200 - 2 * mdlen; + c->pt = 0; + + return 1; +} + +// update state with more data + +int sha3_update(sha3_ctx_t *c, const void *data, size_t len) +{ + size_t i; + int j; + + j = c->pt; + for (i = 0; i < len; i++) { + c->st.b[j++] ^= ((const uint8_t *) data)[i]; + if (j >= c->rsiz) { + sha3_keccakf(c->st.q); + j = 0; + } + } + c->pt = j; + + return 1; +} + +// finalize and output a hash + +int sha3_final(void *md, sha3_ctx_t *c) +{ + int i; + + c->st.b[c->pt] ^= 0x06; + c->st.b[c->rsiz - 1] ^= 0x80; + sha3_keccakf(c->st.q); + + for (i = 0; i < c->mdlen; i++) { + ((uint8_t *) md)[i] = c->st.b[i]; + } + + return 1; +} + +// compute a SHA-3 hash (md) of given byte length from "in" + +void *sha3(const void *in, size_t inlen, void *md, int mdlen) +{ + sha3_ctx_t sha3; + + sha3_init(&sha3, mdlen); + sha3_update(&sha3, in, inlen); + sha3_final(md, &sha3); + + return md; +} + +// SHAKE128 and SHAKE256 extensible-output functionality + +void shake_xof(sha3_ctx_t *c) +{ + c->st.b[c->pt] ^= 0x1F; + c->st.b[c->rsiz - 1] ^= 0x80; + sha3_keccakf(c->st.q); + c->pt = 0; +} + +void shake_out(sha3_ctx_t *c, void *out, size_t len) +{ + size_t i; + int j; + + j = c->pt; + for (i = 0; i < len; i++) { + if (j >= c->rsiz) { + sha3_keccakf(c->st.q); + j = 0; + } + ((uint8_t *) out)[i] = c->st.b[j++]; + } + c->pt = j; +} + diff --git a/algo/verthash/tiny_sha3/sha3.h b/algo/verthash/tiny_sha3/sha3.h new file mode 100644 index 0000000..2d7bf8d --- /dev/null +++ b/algo/verthash/tiny_sha3/sha3.h @@ -0,0 +1,55 @@ +// sha3.h +// 19-Nov-11 Markku-Juhani O. Saarinen + +#ifndef SHA3_H +#define SHA3_H + +#include +#include + + +#if defined(__cplusplus) +extern "C" { +#endif + +#ifndef KECCAKF_ROUNDS +#define KECCAKF_ROUNDS 24 +#endif + +#ifndef ROTL64 +#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) +#endif + +// state context +typedef struct { + union { // state: + uint8_t b[200]; // 8-bit bytes + uint64_t q[25]; // 64-bit words + } st; + int pt, rsiz, mdlen; // these don't overflow +} sha3_ctx_t; + +// Compression function. +void sha3_keccakf(uint64_t st[25]); + +// OpenSSL - like interfece +int sha3_init(sha3_ctx_t *c, int mdlen); // mdlen = hash output in bytes +int sha3_update(sha3_ctx_t *c, const void *data, size_t len); +int sha3_final(void *md, sha3_ctx_t *c); // digest goes to md + +// compute a sha3 hash (md) of given byte length from "in" +void *sha3(const void *in, size_t inlen, void *md, int mdlen); + +// SHAKE128 and SHAKE256 extensible-output functions +#define shake128_init(c) sha3_init(c, 16) +#define shake256_init(c) sha3_init(c, 32) +#define shake_update sha3_update + +void shake_xof(sha3_ctx_t *c); +void shake_out(sha3_ctx_t *c, void *out, size_t len); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/algo/verthash/verthash-gate.c b/algo/verthash/verthash-gate.c new file mode 100644 index 0000000..a3e0bc3 --- /dev/null +++ b/algo/verthash/verthash-gate.c @@ -0,0 +1,96 @@ +#include "algo-gate-api.h" +#include "algo/sha/sph_sha2.h" +#include "Verthash.h" + +static verthash_info_t verthashInfo; + +// Verthash data file hash in bytes for verification +// 0x48aa21d7afededb63976d48a8ff8ec29d5b02563af4a1110b056cd43e83155a5 +static const uint8_t verthashDatFileHash_bytes[32] = +{ 0xa5, 0x55, 0x31, 0xe8, 0x43, 0xcd, 0x56, 0xb0, + 0x10, 0x11, 0x4a, 0xaf, 0x63, 0x25, 0xb0, 0xd5, + 0x29, 0xec, 0xf8, 0x8f, 0x8a, 0xd4, 0x76, 0x39, + 0xb6, 0xed, 0xed, 0xaf, 0xd7, 0x21, 0xaa, 0x48 }; + +static const char* verthash_data_file_name = "verthash.dat"; + +int scanhash_verthash( struct work *work, uint32_t max_nonce, + uint64_t *hashes_done, struct thr_info *mythr ) +{ + uint32_t edata[20] __attribute__((aligned(64))); + uint32_t hash[8] __attribute__((aligned(64))); + uint32_t *pdata = work->data; + uint32_t *ptarget = work->target; + const uint32_t first_nonce = pdata[19]; + const uint32_t last_nonce = max_nonce - 1; + uint32_t n = first_nonce; + const int thr_id = mythr->id; + const bool bench = opt_benchmark; + + mm128_bswap32_80( edata, pdata ); +// verthash_sha3_prehash_72( edata ); + do + { + edata[19] = n; + verthash_hash( verthashInfo.data, verthashInfo.dataSize, + (const unsigned char (*)[80]) edata, + (unsigned char (*)[32]) hash ); + if ( valid_hash( hash, ptarget ) && !bench ) + { + pdata[19] = bswap_32( n ); + submit_solution( work, hash, mythr ); + } + n++; + } while ( n < last_nonce && !work_restart[thr_id].restart ); + *hashes_done = n - first_nonce; + pdata[19] = n; + return 0; +} + + +bool register_verthash_algo( algo_gate_t* gate ) +{ + + opt_target_factor = 256.0; + gate->scanhash = (void*)&scanhash_verthash; + + // verthash data file + int vhLoadResult = verthash_info_init(&verthashInfo, verthash_data_file_name ); + // Check Verthash initialization status + if (vhLoadResult == 0) // No Error + { + applog(LOG_INFO, "Verthash data file has been loaded succesfully!"); + + // and verify data file(if it was enabled) + if ( true ) +// if (!cmdr.disableVerthashDataFileVerification) + { + uint8_t vhDataFileHash[32] = { 0 }; + sph_sha256_full( vhDataFileHash, verthashInfo.data, + verthashInfo.dataSize ); + + if ( memcmp( vhDataFileHash, verthashDatFileHash_bytes, + sizeof(verthashDatFileHash_bytes) ) == 0 ) + applog(LOG_INFO, "Verthash data file has been verified succesfully!"); + else + applog(LOG_ERR, "Verthash data file verification has failed!"); + } + else + applog(LOG_WARNING, "Verthash data file verification stage is disabled!"); + } + else + { + // Handle Verthash error codes + if (vhLoadResult == 1) + applog(LOG_ERR, "Verthash data file name is invalid"); + else if (vhLoadResult == 2) + applog(LOG_ERR, "Failed to allocate memory for Verthash data"); + else // for debugging purposes + applog(LOG_ERR, "Verthash data initialization unknown error code: %d", + vhLoadResult); + return false; + } + + return true; +} + diff --git a/configure b/configure index 5ae117c..b1b7408 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for cpuminer-opt 3.15.7. +# Generated by GNU Autoconf 2.69 for cpuminer-opt 3.15.8. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -577,8 +577,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='cpuminer-opt' PACKAGE_TARNAME='cpuminer-opt' -PACKAGE_VERSION='3.15.7' -PACKAGE_STRING='cpuminer-opt 3.15.7' +PACKAGE_VERSION='3.15.8' +PACKAGE_STRING='cpuminer-opt 3.15.8' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1332,7 +1332,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures cpuminer-opt 3.15.7 to adapt to many kinds of systems. +\`configure' configures cpuminer-opt 3.15.8 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1404,7 +1404,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of cpuminer-opt 3.15.7:";; + short | recursive ) echo "Configuration of cpuminer-opt 3.15.8:";; esac cat <<\_ACEOF @@ -1509,7 +1509,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -cpuminer-opt configure 3.15.7 +cpuminer-opt configure 3.15.8 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2012,7 +2012,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by cpuminer-opt $as_me 3.15.7, which was +It was created by cpuminer-opt $as_me 3.15.8, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2993,7 +2993,7 @@ fi # Define the identity of the package. PACKAGE='cpuminer-opt' - VERSION='3.15.7' + VERSION='3.15.8' cat >>confdefs.h <<_ACEOF @@ -6690,7 +6690,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by cpuminer-opt $as_me 3.15.7, which was +This file was extended by cpuminer-opt $as_me 3.15.8, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -6756,7 +6756,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -cpuminer-opt config.status 3.15.7 +cpuminer-opt config.status 3.15.8 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index bbe7a18..3923c43 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([cpuminer-opt], [3.15.7]) +AC_INIT([cpuminer-opt], [3.16.0]) AC_PREREQ([2.59c]) AC_CANONICAL_SYSTEM diff --git a/cpu-miner.c b/cpu-miner.c index fe2aed0..3b4839e 100644 --- a/cpu-miner.c +++ b/cpu-miner.c @@ -119,14 +119,14 @@ bool opt_sapling = false; // Need compile time and run time test. #if defined(__linux) && defined(GCC_INT128) #define AFFINITY_USES_UINT128 1 -uint128_t opt_affinity = -1; +static uint128_t opt_affinity = -1; static bool affinity_uses_uint128 = true; #else -uint64_t opt_affinity = -1; +static uint64_t opt_affinity = -1; static bool affinity_uses_uint128 = false; #endif -int opt_priority = 0; +int opt_priority = 0; // deprecated int num_cpus = 1; int num_cpugroups = 1; char *rpc_url = NULL;; @@ -3186,14 +3186,12 @@ void parse_arg(int key, char *arg ) ul = strtoull( p, NULL, 16 ); else ul = atoll( arg ); -// if ( ul > ( 1ULL << num_cpus ) - 1ULL ) -// ul = -1LL; #if AFFINITY_USES_UINT128 // replicate the low 64 bits to make a full 128 bit mask if there are more // than 64 CPUs, otherwise zero extend the upper half. opt_affinity = (uint128_t)ul; if ( num_cpus > 64 ) - opt_affinity = (opt_affinity << 64 ) | opt_affinity; + opt_affinity |= opt_affinity << 64; #else opt_affinity = ul; #endif @@ -3202,6 +3200,8 @@ void parse_arg(int key, char *arg ) v = atoi(arg); if (v < 0 || v > 5) /* sanity check */ show_usage_and_exit(1); + // option is deprecated, show warning + applog( LOG_WARNING, "High priority mining threads may cause system instability"); opt_priority = v; break; case 'N': // N parameter for various scrypt algos diff --git a/miner.h b/miner.h index 234b1cc..e43012d 100644 --- a/miner.h +++ b/miner.h @@ -573,6 +573,7 @@ enum algos { ALGO_TRIBUS, ALGO_VANILLA, ALGO_VELTOR, + ALGO_VERTHASH, ALGO_WHIRLPOOL, ALGO_WHIRLPOOLX, ALGO_X11, @@ -665,6 +666,7 @@ static const char* const algo_names[] = { "tribus", "vanilla", "veltor", + "verthash", "whirlpool", "whirlpoolx", "x11", @@ -824,6 +826,7 @@ Options:\n\ tribus Denarius (DNR)\n\ vanilla blake256r8vnl (VCash)\n\ veltor\n\ + verthash\n\ whirlpool\n\ whirlpoolx\n\ x11 Dash\n\ diff --git a/verthash-help.txt b/verthash-help.txt new file mode 100644 index 0000000..b055ec3 --- /dev/null +++ b/verthash-help.txt @@ -0,0 +1,17 @@ + +The verthash data file must be named verthash.dat and located in the same +directory as the cpuminer executable. A Linux symlink works. + +The verthash data file must be obtained seperately. If you already use +VerthashMiner you can simply copy or link the existing data file to the +cpuminer directory, using the required name. + +Otherwise it may be created using +https://github.com/CryptoGraphics/VerthashMiner/releases +following the instructions. A GPU is not necessary to create the file. + +The same data file can be used by both cpuminer and VerthashMiner +simultaneously. + +Launching cpuminer to mine verthash is the same as any other algorithm, +no extra options are required. diff --git a/winbuild-cross.sh b/winbuild-cross.sh index 58503fe..f6402ba 100755 --- a/winbuild-cross.sh +++ b/winbuild-cross.sh @@ -31,6 +31,7 @@ mkdir release cp README.txt release/ cp README.md release/ cp RELEASE_NOTES release/ +cp verthash-help.txt release/ cp $MINGW_LIB/zlib1.dll release/ cp $MINGW_LIB/libwinpthread-1.dll release/ cp $GCC_MINGW_LIB/libstdc++-6.dll release/