diff --git a/Makefile.am b/Makefile.am index 296df350..1dfadfb3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -119,6 +119,7 @@ cpuminer_SOURCES = \ algo/s3.c \ algo/tiger/sph_tiger.c \ algo/timetravel.c \ + algo/timetravel10.c \ algo/veltor.c \ algo/whirlpool/whirlpool.c \ algo/whirlpool/whirlpoolx.c \ diff --git a/README.md b/README.md index dcf34cc4..a31c9bad 100644 --- a/README.md +++ b/README.md @@ -28,9 +28,10 @@ Supported Algorithms cryptonight cryptonote, Monero (XMR) decred deep Deepcoin (DCN) + dmd-gr Diamond-Groestl drop Dropcoin fresh Fresh - groestl dmd-gr, Groestl coin + groestl Groestl coin heavy Heavy hmq1725 Espers hodl Hodlcoin diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 969b2596..f00f6aa1 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -9,6 +9,11 @@ are not yet available. Compile Instructions -------------------- +Requirements: + +Intel Core2 or newer, or AMD Steamroller or newer CPU. +64 bit Linux or Windows operating system. + Building on linux prerequisites: It is assumed users know how to install packages on their system and @@ -25,14 +30,11 @@ are some of the ones that may not be in the default install and need to be installed manually. There may be others, read the error messages they will give a clue as to the missing package. -The folliwing command should install everything you need on Debian based -packages: +The following command should install everything you need on Debian based +distributions such as Ubuntu: sudo apt-get install build-essential libssl-dev libcurl4-openssl-dev libjansson-dev libgmp-dev automake -Building on Linux, see below for Windows. - -Dependencies build-essential (for Ubuntu, Development Tools package group on Fedora) automake @@ -60,7 +62,7 @@ make Start mining. -./cpuminer -a algo ... +./cpuminer -a algo -o url -u username -p password Building on Windows prerequisites: @@ -116,6 +118,12 @@ Support for even older x86_64 without AES_NI or SSE2 is not availble. Change Log ---------- +v3.6.4 + +Added support for Bitcore (BTX) using the timetravel10 algo, optimized for +AES and AVX2. +"-a bitcore" works as an alias and is less typing that "-a timetravel10". + v3.6.3 Fixed all known issues with SHA support on AMD Ryzen CPUs, still no diff --git a/algo-gate-api.c b/algo-gate-api.c index 110ff9d5..8919db64 100644 --- a/algo-gate-api.c +++ b/algo-gate-api.c @@ -150,63 +150,64 @@ bool register_algo_gate( int algo, algo_gate_t *gate ) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wimplicit-function-declaration" - case ALGO_ARGON2: register_argon2_algo ( gate ); break; - case ALGO_AXIOM: register_axiom_algo ( gate ); break; - case ALGO_BASTION: register_bastion_algo ( gate ); break; - case ALGO_BLAKE: register_blake_algo ( gate ); break; - case ALGO_BLAKECOIN: register_blakecoin_algo ( gate ); break; -// case ALGO_BLAKE2B: register_blake2b_algo ( gate ); break; - case ALGO_BLAKE2S: register_blake2s_algo ( gate ); break; - case ALGO_C11: register_c11_algo ( gate ); break; - case ALGO_CRYPTOLIGHT: register_cryptolight_algo( gate ); break; - case ALGO_CRYPTONIGHT: register_cryptonight_algo( gate ); break; - case ALGO_DECRED: register_decred_algo ( gate ); break; - case ALGO_DEEP: register_deep_algo ( gate ); break; - case ALGO_DMD_GR: register_dmd_gr_algo ( gate ); break; - case ALGO_DROP: register_drop_algo ( gate ); break; - case ALGO_FRESH: register_fresh_algo ( gate ); break; - case ALGO_GROESTL: register_groestl_algo ( gate ); break; - case ALGO_HEAVY: register_heavy_algo ( gate ); break; - case ALGO_HMQ1725: register_hmq1725_algo ( gate ); break; - case ALGO_HODL: register_hodl_algo ( gate ); break; - case ALGO_KECCAK: register_keccak_algo ( gate ); break; - case ALGO_LBRY: register_lbry_algo ( gate ); break; - case ALGO_LUFFA: register_luffa_algo ( gate ); break; - 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_LYRA2Z330: register_lyra2z330_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; - case ALGO_NIST5: register_nist5_algo ( gate ); break; - case ALGO_PENTABLAKE: register_pentablake_algo ( gate ); break; - case ALGO_PLUCK: register_pluck_algo ( gate ); break; - case ALGO_QUARK: register_quark_algo ( gate ); break; - case ALGO_QUBIT: register_qubit_algo ( gate ); break; - case ALGO_SCRYPT: register_scrypt_algo ( gate ); break; - case ALGO_SCRYPTJANE: register_scryptjane_algo ( gate ); break; - case ALGO_SHA256D: register_sha256d_algo ( gate ); break; - case ALGO_SHA256T: register_sha256t_algo ( gate ); break; - case ALGO_SHAVITE3: register_shavite_algo ( gate ); break; - case ALGO_SKEIN: register_skein_algo ( gate ); break; - case ALGO_SKEIN2: register_skein2_algo ( gate ); break; - case ALGO_S3: register_s3_algo ( gate ); break; - case ALGO_TIMETRAVEL: register_timetravel_algo ( gate ); break; - case ALGO_VANILLA: register_vanilla_algo ( gate ); break; - case ALGO_VELTOR: register_veltor_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; - case ALGO_X11EVO: register_x11evo_algo ( gate ); break; - case ALGO_X11GOST: register_sib_algo ( gate ); break; - case ALGO_X13: register_x13_algo ( gate ); break; - 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; + case ALGO_ARGON2: register_argon2_algo ( gate ); break; + case ALGO_AXIOM: register_axiom_algo ( gate ); break; + case ALGO_BASTION: register_bastion_algo ( gate ); break; + case ALGO_BLAKE: register_blake_algo ( gate ); break; + case ALGO_BLAKECOIN: register_blakecoin_algo ( gate ); break; +// case ALGO_BLAKE2B: register_blake2b_algo ( gate ); break; + case ALGO_BLAKE2S: register_blake2s_algo ( gate ); break; + case ALGO_C11: register_c11_algo ( gate ); break; + case ALGO_CRYPTOLIGHT: register_cryptolight_algo ( gate ); break; + case ALGO_CRYPTONIGHT: register_cryptonight_algo ( gate ); break; + case ALGO_DECRED: register_decred_algo ( gate ); break; + case ALGO_DEEP: register_deep_algo ( gate ); break; + case ALGO_DMD_GR: register_dmd_gr_algo ( gate ); break; + case ALGO_DROP: register_drop_algo ( gate ); break; + case ALGO_FRESH: register_fresh_algo ( gate ); break; + case ALGO_GROESTL: register_groestl_algo ( gate ); break; + case ALGO_HEAVY: register_heavy_algo ( gate ); break; + case ALGO_HMQ1725: register_hmq1725_algo ( gate ); break; + case ALGO_HODL: register_hodl_algo ( gate ); break; + case ALGO_KECCAK: register_keccak_algo ( gate ); break; + case ALGO_LBRY: register_lbry_algo ( gate ); break; + case ALGO_LUFFA: register_luffa_algo ( gate ); break; + 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_LYRA2Z330: register_lyra2z330_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; + case ALGO_NIST5: register_nist5_algo ( gate ); break; + case ALGO_PENTABLAKE: register_pentablake_algo ( gate ); break; + case ALGO_PLUCK: register_pluck_algo ( gate ); break; + case ALGO_QUARK: register_quark_algo ( gate ); break; + case ALGO_QUBIT: register_qubit_algo ( gate ); break; + case ALGO_SCRYPT: register_scrypt_algo ( gate ); break; + case ALGO_SCRYPTJANE: register_scryptjane_algo ( gate ); break; + case ALGO_SHA256D: register_sha256d_algo ( gate ); break; + case ALGO_SHA256T: register_sha256t_algo ( gate ); break; + case ALGO_SHAVITE3: register_shavite_algo ( gate ); break; + case ALGO_SKEIN: register_skein_algo ( gate ); break; + case ALGO_SKEIN2: register_skein2_algo ( gate ); break; + case ALGO_S3: register_s3_algo ( gate ); break; + case ALGO_TIMETRAVEL: register_timetravel_algo ( gate ); break; + case ALGO_TIMETRAVEL10: register_timetravel10_algo( gate ); break; + case ALGO_VANILLA: register_vanilla_algo ( gate ); break; + case ALGO_VELTOR: register_veltor_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; + case ALGO_X11EVO: register_x11evo_algo ( gate ); break; + case ALGO_X11GOST: register_sib_algo ( gate ); break; + case ALGO_X13: register_x13_algo ( gate ); break; + 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; // restore warnings #pragma GCC diagnostic pop @@ -253,42 +254,42 @@ void exec_hash_function( int algo, void *output, const void *pdata ) gate.hash( output, pdata, 0 ); } -// an algo can have multiple aliases but the aliases must be unique - #define PROPER (1) #define ALIAS (0) // The only difference between the alias and the proper algo name is the -// proper name is the one that is defined in ALGO_NAMES, there may be +// proper name is the one that is defined in ALGO_NAMES. There may be // multiple aliases that map to the same proper name. // New aliases can be added anywhere in the array as long as NULL is last. // Alphabetic order of alias is recommended. const char* const algo_alias_map[][2] = { // alias proper - { "blake256r8", "blakecoin" }, - { "blake256r8vnl", "vanilla" }, - { "sia", "blake2b" }, - { "blake256r14", "blake" }, - { "blake256r14dcr", "decred" }, - { "cryptonote", "cryptonight" }, - { "cryptonight-light", "cryptolight" }, - { "diamond", "dmd-gr" }, - { "droplp", "drop" }, - { "espers", "hmq1725" }, - { "flax", "c11" }, - { "jane", "scryptjane" }, - { "lyra2", "lyra2re" }, - { "lyra2v2", "lyra2rev2" }, - { "lyra2zoin", "lyra2z330" }, - { "myriad", "myr-gr" }, - { "neo", "neoscrypt" }, - { "sib", "x11gost" }, - { "yes", "yescrypt" }, - { "ziftr", "zr5" }, - { "zcoin", "lyra2z" }, - { "zoin", "lyra2z330" }, - { NULL, NULL } + { "bitcore", "timetravel10" }, + { "blake256r8", "blakecoin" }, + { "blake256r8vnl", "vanilla" }, + { "blake256r14", "blake" }, + { "blake256r14dcr", "decred" }, + { "cryptonote", "cryptonight" }, + { "cryptonight-light", "cryptolight" }, + { "diamond", "dmd-gr" }, + { "droplp", "drop" }, + { "espers", "hmq1725" }, + { "flax", "c11" }, + { "jane", "scryptjane" }, + { "lyra2", "lyra2re" }, + { "lyra2v2", "lyra2rev2" }, + { "lyra2zoin", "lyra2z330" }, + { "myriad", "myr-gr" }, + { "neo", "neoscrypt" }, +// { "sia", "blake2b" }, + { "sib", "x11gost" }, + { "timetravel8", "timetravel" }, + { "yes", "yescrypt" }, + { "ziftr", "zr5" }, + { "zcoin", "lyra2z" }, + { "zoin", "lyra2z330" }, + { NULL, NULL } }; // if arg is a valid alias for a known algo it is updated with the proper name. diff --git a/algo/lbry.c b/algo/lbry.c index d1015112..b13ed507 100644 --- a/algo/lbry.c +++ b/algo/lbry.c @@ -16,30 +16,6 @@ #define LBRY_WORK_DATA_SIZE 192 #define LBRY_WORK_CMP_SIZE 76 // same as default -/* Move init out of loop, so init once externally, and then use one single memcpy with that bigger memory block */ -typedef struct { -#if defined __SHA__ - SHA256_CTX sha256; -#else - sph_sha256_context sha256; -#endif - sph_sha512_context sha512; - sph_ripemd160_context ripemd; -} lbryhash_context_holder; - -/* no need to copy, because close reinit the context */ -static lbryhash_context_holder ctx __attribute__ ((aligned (64))); - -void init_lbry_contexts(void *dummy) -{ -#if defined __SHA__ - SHA256_Init( &ctx.sha256 ); -#else - sph_sha256_init( &ctx.sha256 ); -#endif - sph_sha512_init( &ctx.sha512 ); - sph_ripemd160_init( &ctx.ripemd ); -} void lbry_hash(void* output, const void* input) { diff --git a/algo/timetravel10.c b/algo/timetravel10.c new file mode 100644 index 00000000..274a7c46 --- /dev/null +++ b/algo/timetravel10.c @@ -0,0 +1,429 @@ +#include +#include "algo-gate-api.h" + +#include +#include +#include +#include +#include "avxdefs.h" + +#include "algo/blake/sph_blake.h" +#include "algo/bmw/sph_bmw.h" +#include "algo/jh/sph_jh.h" +#include "algo/keccak/sph_keccak.h" +#include "algo/skein/sph_skein.h" +#include "algo/luffa/sse2/luffa_for_sse2.h" +#include "algo/cubehash/sse2/cubehash_sse2.h" +#include "algo/shavite/sph_shavite.h" +#include "algo/simd/sse2/nist.h" + +#ifdef NO_AES_NI + #include "algo/groestl/sph_groestl.h" +#else + #include "algo/groestl/aes_ni/hash-groestl.h" +#endif + +// BitCore Genesis Timestamp +#define HASH_FUNC_BASE_TIMESTAMP 1492973331U + +#define HASH_FUNC_COUNT 10 +#define HASH_FUNC_COUNT_PERMUTATIONS 40320 + +static __thread uint32_t s_ntime = UINT32_MAX; +static __thread int permutation[HASH_FUNC_COUNT] = { 0 }; + +inline void tt10_swap( int *a, int *b ) +{ + int c = *a; + *a = *b; + *b = c; +} + +inline void reverse( int *pbegin, int *pend ) +{ + while ( (pbegin != pend) && (pbegin != --pend) ) + { + tt10_swap( pbegin, pend ); + pbegin++; + } +} + +static void next_permutation( int *pbegin, int *pend ) +{ + if ( pbegin == pend ) + return; + + int *i = pbegin; + ++i; + if ( i == pend ) + return; + + i = pend; + --i; + + while (1) + { + int *j = i; + --i; + + if ( *i < *j ) + { + int *k = pend; + + while ( !(*i < *--k) ) /* do nothing */ ; + + tt10_swap( i, k ); + reverse(j, pend); + return; // true + } + + if ( i == pbegin ) + { + reverse(pbegin, pend); + return; // false + } + // else? + } +} + +typedef struct { + sph_blake512_context blake; + sph_bmw512_context bmw; + sph_skein512_context skein; + sph_jh512_context jh; + sph_keccak512_context keccak; + hashState_luffa luffa; + cubehashParam cube; + sph_shavite512_context shavite; + hashState_sd simd; +#ifdef NO_AES_NI + sph_groestl512_context groestl; +#else + hashState_groestl groestl; +#endif +} tt10_ctx_holder; + +tt10_ctx_holder tt10_ctx __attribute__ ((aligned (64))); +__thread tt10_ctx_holder tt10_mid __attribute__ ((aligned (64))); + +void init_tt10_ctx() +{ + sph_blake512_init( &tt10_ctx.blake ); + sph_bmw512_init( &tt10_ctx.bmw ); + sph_skein512_init( &tt10_ctx.skein ); + sph_jh512_init( &tt10_ctx.jh ); + sph_keccak512_init( &tt10_ctx.keccak ); + init_luffa( &tt10_ctx.luffa, 512 ); + cubehashInit( &tt10_ctx.cube, 512, 16, 32 ); + sph_shavite512_init( &tt10_ctx.shavite ); + init_sd( &tt10_ctx.simd, 512 ); +#ifdef NO_AES_NI + sph_groestl512_init( &tt10_ctx.groestl ); +#else + init_groestl( &tt10_ctx.groestl, 64 ); +#endif +}; + +void timetravel10_hash(void *output, const void *input) +{ + uint32_t hash[128] __attribute__ ((aligned (64))); + uint32_t *hashA, *hashB; + tt10_ctx_holder ctx __attribute__ ((aligned (64))); + uint32_t dataLen = 64; + uint32_t *work_data = (uint32_t *)input; + int i; + const int midlen = 64; // bytes + const int tail = 80 - midlen; // 16 + + memcpy( &ctx, &tt10_ctx, sizeof(tt10_ctx) ); + + for ( i = 0; i < HASH_FUNC_COUNT; i++ ) + { + if (i == 0) + { + dataLen = 80; + hashA = work_data; + } + else + { + dataLen = 64; + hashA = &hash[16 * (i - 1)]; + } + hashB = &hash[16 * i]; + + switch ( permutation[i] ) + { + case 0: + if ( i == 0 ) + { + memcpy( &ctx.blake, &tt10_mid.blake, sizeof tt10_mid.blake ); + sph_blake512( &ctx.blake, input + midlen, tail ); + sph_blake512_close( &ctx.blake, hashB ); + } + else + { + sph_blake512( &ctx.blake, hashA, dataLen ); + sph_blake512_close( &ctx.blake, hashB ); + } + break; + case 1: + if ( i == 0 ) + { + memcpy( &ctx.bmw, &tt10_mid.bmw, sizeof tt10_mid.bmw ); + sph_bmw512( &ctx.bmw, input + midlen, tail ); + sph_bmw512_close( &ctx.bmw, hashB ); + } + else + { + sph_bmw512( &ctx.bmw, hashA, dataLen ); + sph_bmw512_close( &ctx.bmw, hashB ); + } + break; + case 2: +#ifdef NO_AES_NI + if ( i == 0 ) + { + memcpy( &ctx.groestl, &tt10_mid.groestl, sizeof tt10_mid.groestl ); + sph_groestl512( &ctx.groestl, input + midlen, tail ); + sph_groestl512_close( &ctx.groestl, hashB ); + } + else + { + sph_groestl512( &ctx.groestl, hashA, dataLen ); + sph_groestl512_close( &ctx.groestl, hashB ); + } +#else +// groestl midstate is slower +// if ( i == 0 ) +// { +// memcpy( &ctx.groestl, &tt10_mid.groestl, sizeof tt10_mid.groestl ); +// update_and_final_groestl( &ctx.groestl, (char*)hashB, +// (char*)input + midlen, tail*8 ); +// } +// else +// { + update_and_final_groestl( &ctx.groestl, (char*)hashB, + (char*)hashA, dataLen*8 ); +// } +#endif + break; + case 3: + if ( i == 0 ) + { + memcpy( &ctx.skein, &tt10_mid.skein, sizeof tt10_mid.skein ); + sph_skein512( &ctx.skein, input + midlen, tail ); + sph_skein512_close( &ctx.skein, hashB ); + } + else + { + sph_skein512( &ctx.skein, hashA, dataLen ); + sph_skein512_close( &ctx.skein, hashB ); + } + break; + case 4: + if ( i == 0 ) + { + memcpy( &ctx.jh, &tt10_mid.jh, sizeof tt10_mid.jh ); + sph_jh512( &ctx.jh, input + midlen, tail ); + sph_jh512_close( &ctx.jh, hashB ); + } + else + { + sph_jh512( &ctx.jh, hashA, dataLen ); + sph_jh512_close( &ctx.jh, hashB); + } + break; + case 5: + if ( i == 0 ) + { + memcpy( &ctx.keccak, &tt10_mid.keccak, sizeof tt10_mid.keccak ); + sph_keccak512( &ctx.keccak, input + midlen, tail ); + sph_keccak512_close( &ctx.keccak, hashB ); + } + else + { + sph_keccak512( &ctx.keccak, hashA, dataLen ); + sph_keccak512_close( &ctx.keccak, hashB ); + } + break; + case 6: + if ( i == 0 ) + { + memcpy( &ctx.luffa, &tt10_mid.luffa, sizeof tt10_mid.luffa ); + update_and_final_luffa( &ctx.luffa, (BitSequence*)hashB, + (const BitSequence *)input + 64, 16 ); + } + else + { + update_and_final_luffa( &ctx.luffa, (BitSequence*)hashB, + (const BitSequence *)hashA, dataLen ); + } + break; + case 7: + if ( i == 0 ) + { + memcpy( &ctx.cube, &tt10_mid.cube, sizeof tt10_mid.cube ); + cubehashUpdateDigest( &ctx.cube, (byte*)hashB, + (const byte*)input + midlen, tail ); + } + else + { + cubehashUpdateDigest( &ctx.cube, (byte*)hashB, (const byte*)hashA, + dataLen ); + } + break; + case 8: + if ( i == 0 ) + { + memcpy( &ctx.shavite, &tt10_mid.shavite, sizeof tt10_mid.shavite ); + sph_shavite512( &ctx.shavite, input + midlen, tail*8 ); + sph_shavite512_close( &ctx.shavite, hashB ); + } + else + { + sph_shavite512( &ctx.shavite, hashA, dataLen ); + sph_shavite512_close( &ctx.shavite, hashB ); + } + break; + case 9: + if ( i == 0 ) + { + memcpy( &ctx.simd, &tt10_mid.simd, sizeof tt10_mid.simd ); + update_final_sd( &ctx.simd, (BitSequence *)hashB, + (const BitSequence *)input + midlen, tail*8 ); + } + else + { + update_final_sd( &ctx.simd, (BitSequence *)hashB, + (const BitSequence *)hashA, dataLen*8 ); + } + break; + default: + break; + } + } + + memcpy(output, &hash[16 * (HASH_FUNC_COUNT - 1)], 32); +} + +int scanhash_timetravel10( 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); + int i; + + if (opt_benchmark) + ptarget[7] = 0x0cff; + + for (int k=0; k < 19; k++) + be32enc(&endiandata[k], pdata[k]); + + const uint32_t timestamp = endiandata[17]; + if ( timestamp != s_ntime ) + { + const int steps = ( timestamp - HASH_FUNC_BASE_TIMESTAMP ) + % HASH_FUNC_COUNT_PERMUTATIONS; + for ( i = 0; i < HASH_FUNC_COUNT; i++ ) + permutation[i] = i; + for ( i = 0; i < steps; i++ ) + next_permutation( permutation, permutation + HASH_FUNC_COUNT ); + s_ntime = timestamp; + + // do midstate precalc for first function + switch ( permutation[0] ) + { + case 0: + memcpy( &tt10_mid.blake, &tt10_ctx.blake, sizeof(tt10_mid.blake) ); + sph_blake512( &tt10_mid.blake, endiandata, 64 ); + break; + case 1: + memcpy( &tt10_mid.bmw, &tt10_ctx.bmw, sizeof(tt10_mid.bmw) ); + sph_bmw512( &tt10_mid.bmw, endiandata, 64 ); + break; + case 2: +#ifdef NO_AES_NI + memcpy( &tt10_mid.groestl, &tt10_ctx.groestl, sizeof(tt10_mid.groestl ) ); + sph_groestl512( &tt10_mid.groestl, endiandata, 64 ); +#else +// groestl midstate is slower +// memcpy( &tt10_mid.groestl, &tt10_ctx.groestl, sizeof(tt10_mid.groestl ) ); +// update_groestl( &tt10_mid.groestl, (char*)endiandata, 64*8 ); +#endif + break; + case 3: + memcpy( &tt10_mid.skein, &tt10_ctx.skein, sizeof(tt10_mid.skein ) ); + sph_skein512( &tt10_mid.skein, endiandata, 64 ); + break; + case 4: + memcpy( &tt10_mid.jh, &tt10_ctx.jh, sizeof(tt10_mid.jh ) ); + sph_jh512( &tt10_mid.jh, endiandata, 64 ); + break; + case 5: + memcpy( &tt10_mid.keccak, &tt10_ctx.keccak, sizeof(tt10_mid.keccak ) ); + sph_keccak512( &tt10_mid.keccak, endiandata, 64 ); + break; + case 6: + memcpy( &tt10_mid.luffa, &tt10_ctx.luffa, sizeof(tt10_mid.luffa ) ); + update_luffa( &tt10_mid.luffa, (const BitSequence*)endiandata, 64 ); + break; + case 7: + memcpy( &tt10_mid.cube, &tt10_ctx.cube, sizeof(tt10_mid.cube ) ); + cubehashUpdate( &tt10_mid.cube, (const byte*)endiandata, 64 ); + break; + case 8: + memcpy( &tt10_mid.shavite, &tt10_ctx.shavite, sizeof(tt10_mid.shavite ) ); + sph_shavite512( &tt10_mid.shavite, endiandata, 64 ); + break; + case 9: + memcpy( &tt10_mid.simd, &tt10_ctx.simd, sizeof(tt10_mid.simd ) ); + update_sd( &tt10_mid.simd, (const BitSequence *)endiandata, 512 ); + break; + default: + break; + } + } + + do { + be32enc( &endiandata[19], nonce ); + timetravel10_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 timetravel10_set_target( struct work* work, double job_diff ) +{ + work_set_target( work, job_diff / (256.0 * opt_diff_factor) ); +} + +bool register_timetravel10_algo( algo_gate_t* gate ) +{ + gate->optimizations = SSE2_OPT | AES_OPT | AVX_OPT | AVX2_OPT; + init_tt10_ctx(); + gate->scanhash = (void*)&scanhash_timetravel10; + gate->hash = (void*)&timetravel10_hash; + gate->set_target = (void*)&timetravel10_set_target; + gate->get_max64 = (void*)&get_max64_0xffffLL; + return true; +}; + diff --git a/configure.ac b/configure.ac index 01b9531e..96cc8ddc 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([cpuminer-opt], [3.6.3]) +AC_INIT([cpuminer-opt], [3.6.4]) AC_PREREQ([2.59c]) AC_CANONICAL_SYSTEM diff --git a/miner.h b/miner.h index 43ee818c..80215034 100644 --- a/miner.h +++ b/miner.h @@ -519,6 +519,7 @@ enum algos { ALGO_SKEIN2, ALGO_S3, ALGO_TIMETRAVEL, + ALGO_TIMETRAVEL10, ALGO_VANILLA, ALGO_VELTOR, ALGO_WHIRLPOOL, @@ -581,6 +582,7 @@ static const char* const algo_names[] = { "skein2", "s3", "timetravel", + "timetravel10", "vanilla", "veltor", "whirlpool", @@ -696,7 +698,8 @@ Options:\n\ shavite3 Shavite3\n\ skein Skein+Sha (Skeincoin)\n\ skein2 Double Skein (Woodcoin)\n\ - timetravel Machinecoin\n\ + timetravel timeravel8, Machinecoin (MAC)\n\ + timetravel10 Bitcore (BTX)\n\ vanilla blake256r8vnl (VCash)\n\ veltor\n\ whirlpool\n\