diff --git a/Makefile.am b/Makefile.am index 832fe6f..d31ac60 100644 --- a/Makefile.am +++ b/Makefile.am @@ -106,6 +106,7 @@ cpuminer_SOURCES = \ algo/lyra2/lyra2rev2.c \ algo/lyra2/lyra2re.c \ algo/lyra2/zcoin.c \ + algo/lyra2/zoin.c \ algo/keccak/sse2/keccak.c \ algo/m7m.c \ algo/neoscrypt.c \ @@ -134,6 +135,7 @@ cpuminer_SOURCES = \ algo/x14/x14.c \ algo/x15/x15.c \ algo/x17/x17.c \ + algo/xevan.c \ algo/yescrypt/yescrypt.c \ algo/yescrypt/yescrypt-common.c \ algo/yescrypt/sha256_Y.c\ diff --git a/RELEASE_ANNOUNCEMENT b/RELEASE_ANNOUNCEMENT index efb153a..2c4f52c 100644 --- a/RELEASE_ANNOUNCEMENT +++ b/RELEASE_ANNOUNCEMENT @@ -1,6 +1,3 @@ -Release 3.4.8 of cpuminer-opt is available for download with support for -Windows. - cpuminer-opt now supports 38 algorithms on CPUs with at least SSE2 capabilities including Intel Core2, Nehalem and AMD equivalent. See the performance chart below for details. @@ -10,12 +7,11 @@ CPUs with AES_NI for even greater performance, including the Intel Westbridge and newer and AMD equivalent. See the performance comparison below. -New in 3.4.8 +New in 3.4.9 -- added zcoin support, optimized for AVX2 but no increase in performance -- fixed API display of diff for cryptonight -- --show-diff is now the default, use "--hide-diff" to disable -- cleaned up some cpuminer-multi artifacts +- fixed zr5 +- added xevan algo (Bitsend, BSD) with 10% improvement +- added lyra2zoin (Zoin, ZOI) fully optimized but YMMV Users with non-SSE2 CPUs or who want to mine algos not supported by cpuminer-opt may find cpuminer-multi by TPruvot useful. diff --git a/algo-gate-api.c b/algo-gate-api.c index d161fe2..ad8a8c9 100644 --- a/algo-gate-api.c +++ b/algo-gate-api.c @@ -170,6 +170,7 @@ bool register_algo_gate( int algo, algo_gate_t *gate ) case ALGO_LYRA2RE: register_lyra2re_algo ( gate ); break; case ALGO_LYRA2REV2: register_lyra2rev2_algo ( gate ); break; case ALGO_LYRA2Z: register_zcoin_algo ( gate ); break; + case ALGO_LYRA2ZOIN: register_zoin_algo ( gate ); break; case ALGO_M7M: register_m7m_algo ( gate ); break; case ALGO_MYR_GR: register_myriad_algo ( gate ); break; case ALGO_NEOSCRYPT: register_neoscrypt_algo ( gate ); break; @@ -196,6 +197,7 @@ bool register_algo_gate( int algo, algo_gate_t *gate ) case ALGO_X14: register_x14_algo ( gate ); break; case ALGO_X15: register_x15_algo ( gate ); break; case ALGO_X17: register_x17_algo ( gate ); break; + case ALGO_XEVAN: register_xevan_algo ( gate ); break; case ALGO_YESCRYPT: register_yescrypt_algo ( gate ); break; case ALGO_ZR5: register_zr5_algo ( gate ); break; @@ -270,6 +272,7 @@ const char* const algo_alias_map[][2] = { "yes", "yescrypt" }, { "ziftr", "zr5" }, { "zcoin", "lyra2z" }, + { "zoin", "lyra2zoin" }, { NULL, NULL } }; diff --git a/algo-gate-api.h b/algo-gate-api.h index bf7bebf..0ffbe10 100644 --- a/algo-gate-api.h +++ b/algo-gate-api.h @@ -212,6 +212,7 @@ int64_t get_max64_0x40LL(); int64_t get_max64_0x3ffff(); int64_t get_max64_0x3fffffLL(); int64_t get_max64_0x1ffff(); +int64_t get_max64_0xffffLL(); void std_set_target ( struct work *work, double job_diff ); void scrypt_set_target( struct work *work, double job_diff ); diff --git a/algo/lyra2/zcoin.c b/algo/lyra2/zcoin.c index 2c7a747..62c8cb9 100644 --- a/algo/lyra2/zcoin.c +++ b/algo/lyra2/zcoin.c @@ -50,7 +50,7 @@ int scanhash_zcoin( int thr_id, struct work *work, uint32_t max_nonce, return 0; } -int64_t get_max64_0xffffLL() { return 0xffffLL; }; +//int64_t get_max64_0xffffLL() { return 0xffffLL; }; void zcoin_set_target( struct work* work, double job_diff ) { diff --git a/algo/lyra2/zoin.c b/algo/lyra2/zoin.c new file mode 100644 index 0000000..625060e --- /dev/null +++ b/algo/lyra2/zoin.c @@ -0,0 +1,74 @@ +#include +#include "miner.h" +#include "algo-gate-api.h" +#include "lyra2.h" + +void zoin_hash(void *state, const void *input, uint32_t height) +{ + + uint32_t _ALIGN(256) hash[16]; + + LYRA2Z(hash, 32, input, 80, input, 80, 2, 330, 256); + + memcpy(state, hash, 32); +} + +int scanhash_zoin( int thr_id, struct work *work, uint32_t max_nonce, + uint64_t *hashes_done ) +{ + uint32_t _ALIGN(128) hash[8]; + uint32_t _ALIGN(128) endiandata[20]; + uint32_t *pdata = work->data; + uint32_t *ptarget = work->target; + const uint32_t Htarg = ptarget[7]; + const uint32_t first_nonce = pdata[19]; + uint32_t nonce = first_nonce; + if (opt_benchmark) + ptarget[7] = 0x0000ff; + + for (int i=0; i < 19; i++) { + be32enc(&endiandata[i], pdata[i]); + } + + do { + be32enc(&endiandata[19], nonce); + zoin_hash( hash, endiandata, work->height ); + + if (hash[7] <= Htarg && fulltest(hash, ptarget)) { + work_set_target_ratio(work, hash); + pdata[19] = nonce; + *hashes_done = pdata[19] - first_nonce; + return 1; + } + nonce++; + + } while (nonce < max_nonce && !work_restart[thr_id].restart); + + pdata[19] = nonce; + *hashes_done = pdata[19] - first_nonce + 1; + return 0; +} + +void zoin_set_target( struct work* work, double job_diff ) +{ + work_set_target( work, job_diff / (256.0 * opt_diff_factor) ); +} + +bool zoin_get_work_height( struct work* work, struct stratum_ctx* sctx ) +{ + work->height = sctx->bloc_height; + return false; +} + +bool register_zoin_algo( algo_gate_t* gate ) +{ + gate->optimizations = SSE2_OPT | AES_OPT | AVX_OPT | AVX2_OPT; + gate->scanhash = (void*)&scanhash_zoin; + gate->hash = (void*)&zoin_hash; + gate->hash_alt = (void*)&zoin_hash; + gate->get_max64 = (void*)&get_max64_0xffffLL; + gate->set_target = (void*)&zoin_set_target; + gate->prevent_dupes = (void*)&zoin_get_work_height; + return true; +}; + diff --git a/algo/xevan.c b/algo/xevan.c new file mode 100644 index 0000000..42f72a7 --- /dev/null +++ b/algo/xevan.c @@ -0,0 +1,246 @@ +#include +#include "algo-gate-api.h" + +#include +#include +#include +#include + +#include "algo/blake/sph_blake.h" +#include "algo/bmw/sph_bmw.h" +#include "algo/groestl/sph_groestl.h" +#include "algo/jh/sph_jh.h" +#include "algo/keccak/sph_keccak.h" +#include "algo/skein/sph_skein.h" +#include "algo/shavite/sph_shavite.h" +#include "algo/luffa/sph_luffa.h" +#include "algo/simd/sph_simd.h" +#include "algo/echo/sph_echo.h" +#include "algo/hamsi/sph_hamsi.h" +#include "algo/fugue/sph_fugue.h" +#include "algo/shabal/sph_shabal.h" +#include "algo/whirlpool/sph_whirlpool.h" +#include "algo/sha3/sph_sha2.h" +#include "algo/haval/sph-haval.h" + +#include "algo/cubehash/sse2/cubehash_sse2.h" + +typedef struct { + sph_blake512_context blake; + sph_bmw512_context bmw; + sph_groestl512_context groestl; + sph_skein512_context skein; + sph_jh512_context jh; + sph_keccak512_context keccak; + sph_luffa512_context luffa; + cubehashParam cubehash; + sph_shavite512_context shavite; + sph_simd512_context simd; + sph_echo512_context echo; + sph_hamsi512_context hamsi; + sph_fugue512_context fugue; + sph_shabal512_context shabal; + sph_whirlpool_context whirlpool; + sph_sha512_context sha512; + sph_haval256_5_context haval; +} xevan_ctx_holder; + +xevan_ctx_holder xevan_ctx; + +void init_xevan_ctx() +{ + sph_blake512_init(&xevan_ctx.blake); + sph_bmw512_init(&xevan_ctx.bmw); + sph_groestl512_init(&xevan_ctx.groestl); + sph_skein512_init(&xevan_ctx.skein); + sph_jh512_init(&xevan_ctx.jh); + sph_keccak512_init(&xevan_ctx.keccak); + sph_luffa512_init(&xevan_ctx.luffa); + cubehashInit( &xevan_ctx.cubehash, 512, 16, 32 ); + sph_shavite512_init( &xevan_ctx.shavite ); + sph_simd512_init(&xevan_ctx.simd); + sph_echo512_init(&xevan_ctx.echo); + sph_hamsi512_init( &xevan_ctx.hamsi ); + sph_fugue512_init( &xevan_ctx.fugue ); + sph_shabal512_init( &xevan_ctx.shabal ); + sph_whirlpool_init( &xevan_ctx.whirlpool ); + sph_sha512_init(&xevan_ctx.sha512); + sph_haval256_5_init(&xevan_ctx.haval); +}; + +void xevan_hash(void *output, const void *input) +{ + uint32_t _ALIGN(64) hash[32]; // 128 bytes required + const int dataLen = 128; + + xevan_ctx_holder ctx; + memcpy( &ctx, &xevan_ctx, sizeof(xevan_ctx) ); + + sph_blake512(&ctx.blake, input, 80); + sph_blake512_close(&ctx.blake, hash); + + memset(&hash[16], 0, 64); + + sph_bmw512(&ctx.bmw, hash, dataLen); + sph_bmw512_close(&ctx.bmw, hash); + + sph_groestl512(&ctx.groestl, hash, dataLen); + sph_groestl512_close(&ctx.groestl, hash); + + sph_skein512(&ctx.skein, hash, dataLen); + sph_skein512_close(&ctx.skein, hash); + + sph_jh512(&ctx.jh, hash, dataLen); + sph_jh512_close(&ctx.jh, hash); + + sph_keccak512(&ctx.keccak, hash, dataLen); + sph_keccak512_close(&ctx.keccak, hash); + + sph_luffa512(&ctx.luffa, hash, dataLen); + sph_luffa512_close(&ctx.luffa, hash); + + cubehashUpdate( &ctx.cubehash, (const byte*) hash, dataLen ); + cubehashDigest( &ctx.cubehash, (byte*)hash); + + sph_shavite512(&ctx.shavite, hash, dataLen); + sph_shavite512_close(&ctx.shavite, hash); + + sph_simd512(&ctx.simd, hash, dataLen); + sph_simd512_close(&ctx.simd, hash); + + sph_echo512(&ctx.echo, hash, dataLen); + sph_echo512_close(&ctx.echo, hash); + + sph_hamsi512(&ctx.hamsi, hash, dataLen); + sph_hamsi512_close(&ctx.hamsi, hash); + + sph_fugue512(&ctx.fugue, hash, dataLen); + sph_fugue512_close(&ctx.fugue, hash); + + sph_shabal512(&ctx.shabal, hash, dataLen); + sph_shabal512_close(&ctx.shabal, hash); + + sph_whirlpool(&ctx.whirlpool, hash, dataLen); + sph_whirlpool_close(&ctx.whirlpool, hash); + + sph_sha512(&ctx.sha512,(const void*) hash, dataLen); + sph_sha512_close(&ctx.sha512,(void*) hash); + + sph_haval256_5(&ctx.haval,(const void*) hash, dataLen); + sph_haval256_5_close(&ctx.haval, hash); + + memset(&hash[8], 0, dataLen - 32); + + memcpy( &ctx, &xevan_ctx, sizeof(xevan_ctx) ); + + sph_blake512(&ctx.blake, hash, dataLen); + sph_blake512_close(&ctx.blake, hash); + + sph_bmw512(&ctx.bmw, hash, dataLen); + sph_bmw512_close(&ctx.bmw, hash); + + sph_groestl512(&ctx.groestl, hash, dataLen); + sph_groestl512_close(&ctx.groestl, hash); + + sph_skein512(&ctx.skein, hash, dataLen); + sph_skein512_close(&ctx.skein, hash); + + sph_jh512(&ctx.jh, hash, dataLen); + sph_jh512_close(&ctx.jh, hash); + + sph_keccak512(&ctx.keccak, hash, dataLen); + sph_keccak512_close(&ctx.keccak, hash); + + sph_luffa512(&ctx.luffa, hash, dataLen); + sph_luffa512_close(&ctx.luffa, hash); + + cubehashUpdate( &ctx.cubehash, (const byte*) hash, dataLen ); + cubehashDigest( &ctx.cubehash, (byte*)hash); + + sph_shavite512(&ctx.shavite, hash, dataLen); + sph_shavite512_close(&ctx.shavite, hash); + + sph_simd512(&ctx.simd, hash, dataLen); + sph_simd512_close(&ctx.simd, hash); + + sph_echo512(&ctx.echo, hash, dataLen); + sph_echo512_close(&ctx.echo, hash); + + sph_hamsi512(&ctx.hamsi, hash, dataLen); + sph_hamsi512_close(&ctx.hamsi, hash); + + sph_fugue512(&ctx.fugue, hash, dataLen); + sph_fugue512_close(&ctx.fugue, hash); + + sph_shabal512(&ctx.shabal, hash, dataLen); + sph_shabal512_close(&ctx.shabal, hash); + + sph_whirlpool(&ctx.whirlpool, hash, dataLen); + sph_whirlpool_close(&ctx.whirlpool, hash); + + sph_sha512(&ctx.sha512,(const void*) hash, dataLen); + sph_sha512_close(&ctx.sha512,(void*) hash); + + sph_haval256_5(&ctx.haval,(const void*) hash, dataLen); + sph_haval256_5_close(&ctx.haval, hash); + + memcpy(output, hash, 32); +} + +int scanhash_xevan(int thr_id, struct work *work, uint32_t max_nonce, uint64_t *hashes_done) +{ + uint32_t _ALIGN(64) hash[8]; + uint32_t _ALIGN(64) endiandata[20]; + uint32_t *pdata = work->data; + uint32_t *ptarget = work->target; + + const uint32_t Htarg = ptarget[7]; + const uint32_t first_nonce = pdata[19]; + uint32_t nonce = first_nonce; + volatile uint8_t *restart = &(work_restart[thr_id].restart); + + if (opt_benchmark) + ptarget[7] = 0x0cff; + + for (int k=0; k < 19; k++) + be32enc(&endiandata[k], pdata[k]); + + do { + be32enc(&endiandata[19], nonce); + xevan_hash(hash, endiandata); + + if (hash[7] <= Htarg && fulltest(hash, ptarget)) { + work_set_target_ratio(work, hash); + pdata[19] = nonce; + *hashes_done = pdata[19] - first_nonce; + return 1; + } + nonce++; + + } while (nonce < max_nonce && !(*restart)); + + pdata[19] = nonce; + *hashes_done = pdata[19] - first_nonce + 1; + return 0; +} + +void xevan_set_target( struct work* work, double job_diff ) +{ + work_set_target( work, job_diff / (256.0 * opt_diff_factor) ); +} + +//int64_t xevan_get_max64() { return 0xffffLL; } + +bool register_xevan_algo( algo_gate_t* gate ) +{ + gate->optimizations = SSE2_OPT | AES_OPT | AVX_OPT | AVX2_OPT; + init_xevan_ctx(); + gate->scanhash = (void*)&scanhash_xevan; + gate->hash = (void*)&xevan_hash; +// gate->hash_alt = (void*)&xevanhash_alt; + gate->set_target = (void*)&xevan_set_target; +// gate->get_max64 = (void*)&xevan_get_max64; + gate->get_max64 = (void*)&get_max64_0xffffLL; + return true; +}; + diff --git a/configure.ac b/configure.ac index 3ddd890..7a4ec6d 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([cpuminer-opt], [3.4.8]) +AC_INIT([cpuminer-opt], [3.4.9]) AC_PREREQ([2.59c]) AC_CANONICAL_SYSTEM diff --git a/cpu-miner.c b/cpu-miner.c index 9a057a4..c2d7f91 100644 --- a/cpu-miner.c +++ b/cpu-miner.c @@ -1417,6 +1417,8 @@ int64_t get_max64_0x40LL() { return 0x40LL; } int64_t get_max64_0x3ffff() { return 0x3ffff; } int64_t get_max64_0x3fffffLL() { return 0x3fffffLL; } int64_t get_max64_0x1ffff() { return 0x1ffff; } +int64_t get_max64_0xffffLL() { return 0xffffLL; }; + void sha256d_gen_merkle_root( char* merkle_root, struct stratum_ctx* sctx ) { diff --git a/miner.h b/miner.h index b619ef2..8adb2cd 100644 --- a/miner.h +++ b/miner.h @@ -493,6 +493,7 @@ enum algos { ALGO_LYRA2RE, ALGO_LYRA2REV2, ALGO_LYRA2Z, + ALGO_LYRA2ZOIN, ALGO_M7M, ALGO_MYR_GR, ALGO_NEOSCRYPT, @@ -519,6 +520,7 @@ enum algos { ALGO_X14, ALGO_X15, ALGO_X17, + ALGO_XEVAN, ALGO_YESCRYPT, ALGO_ZR5, ALGO_COUNT @@ -548,6 +550,7 @@ static const char *algo_names[] = { "lyra2re", "lyra2rev2", "lyra2z", + "lyra2zoin", "m7m", "myr-gr", "neoscrypt", @@ -574,8 +577,8 @@ static const char *algo_names[] = { "x14", "x15", "x17", + "xevan", "yescrypt", - "lyra2z", "zr5", "\0" }; @@ -658,6 +661,7 @@ Options:\n\ lyra2re lyra2\n\ lyra2rev2 lyrav2\n\ lyra2z Zcoin (XZC)\n\ + lyra2zoin Zoin (ZOI)\n\ m7m Magi (XMG)\n\ myr-gr Myriad-Groestl\n\ neoscrypt NeoScrypt(128, 2, 1)\n\ @@ -685,6 +689,7 @@ Options:\n\ x14 X14\n\ x15 X15\n\ x17\n\ + xevan Bitsend\n\ yescrypt\n\ zr5 Ziftr\n\ -o, --url=URL URL of mining server\n\