Compare commits

..

2 Commits

Author SHA1 Message Date
Jay D Dee
88f81fda0b v3.11.7 2020-01-26 04:33:39 -05:00
Jay D Dee
103e6ad36c v3.11.6 2020-01-23 00:11:08 -05:00
46 changed files with 1165 additions and 1443 deletions

View File

@@ -33,3 +33,6 @@ Jay D Dee
xcouiz@gmail.com
Cryply
Colin Percival
Alexander Peslyak

View File

@@ -80,7 +80,6 @@ cpuminer_SOURCES = \
algo/cryptonight/cryptonight-common.c\
algo/cryptonight/cryptonight-aesni.c\
algo/cryptonight/cryptonight.c\
algo/cubehash/sph_cubehash.c \
algo/cubehash/cubehash_sse2.c\
algo/cubehash/cube-hash-2way.c \
algo/echo/sph_echo.c \
@@ -121,6 +120,8 @@ cpuminer_SOURCES = \
algo/keccak/keccak-hash-4way.c \
algo/keccak/keccak-4way.c\
algo/keccak/keccak-gate.c \
algo/keccak/sha3d-4way.c \
algo/keccak/sha3d.c \
algo/lanehash/lane.c \
algo/luffa/sph_luffa.c \
algo/luffa/luffa.c \
@@ -180,6 +181,7 @@ cpuminer_SOURCES = \
algo/sha/sph_sha2big.c \
algo/sha/sha256-hash-4way.c \
algo/sha/sha512-hash-4way.c \
algo/sha/hmac-sha256-hash.c \
algo/sha/sha2.c \
algo/sha/sha256t-gate.c \
algo/sha/sha256t-4way.c \
@@ -292,12 +294,11 @@ cpuminer_SOURCES = \
algo/x22/x25x.c \
algo/x22/x25x-4way.c \
algo/yescrypt/yescrypt.c \
algo/yescrypt/sha256_Y.c \
algo/yescrypt/yescrypt-best.c \
algo/yespower/yespower-gate.c \
algo/yespower/yespower-blake2b.c \
algo/yespower/crypto/blake2b-yp.c \
algo/yespower/sha256_p.c \
algo/yespower/yescrypt-r8g.c \
algo/yespower/yespower-opt.c
disable_flags =

View File

@@ -97,10 +97,10 @@ Supported Algorithms
qubit Qubit
scrypt scrypt(1024, 1, 1) (default)
scrypt:N scrypt(N, 1, 1)
scryptjane:nf
sha256d Double SHA-256
sha256q Quad SHA-256, Pyrite (PYE)
sha256t Triple SHA-256, Onecoin (OC)
sha3d Double keccak256 (BSHA3)
shavite3 Shavite3
skein Skein+Sha (Skeincoin)
skein2 Double Skein (Woodcoin)
@@ -134,6 +134,7 @@ Supported Algorithms
xevan Bitsend (BSD)
yescrypt Globalboost-Y (BSTY)
yescryptr8 BitZeny (ZNY)
yescryptr8g Koto (KOTO)
yescryptr16 Eli
yescryptr32 WAVI
yespower Cryply

View File

@@ -65,6 +65,24 @@ If not what makes it happen or not happen?
Change Log
----------
v3.11.7
Added yescryptr8g algo fotr KOTO, including support for block version 5.
Added sha3d algo for BSHA3.
Removed memcmp and clean_job checks from get_new_work, now only check job_id.
Small improvement to sha512 and sha256 parallel implementations that don't
use SHA.
v3.11.6
Fixed CPU temperature regression from v3.11.5.
More improvements to share log. More compact, highlight incremented counter,
block height when solved, job id when stale.
v3.11.5
Fixed AVX512 detection that could cause compilation errors on CPUs

View File

@@ -209,6 +209,7 @@ bool register_algo_gate( int algo, algo_gate_t *gate )
case ALGO_SHA256D: register_sha256d_algo ( gate ); break;
case ALGO_SHA256Q: register_sha256q_algo ( gate ); break;
case ALGO_SHA256T: register_sha256t_algo ( gate ); break;
case ALGO_SHA3D: register_sha3d_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;
@@ -247,6 +248,7 @@ bool register_algo_gate( int algo, algo_gate_t *gate )
*/
case ALGO_YESCRYPT: register_yescrypt_algo ( gate ); break;
case ALGO_YESCRYPTR8: register_yescryptr8_algo ( gate ); break;
case ALGO_YESCRYPTR8G: register_yescryptr8g_algo ( gate ); break;
case ALGO_YESCRYPTR16: register_yescryptr16_algo ( gate ); break;
case ALGO_YESCRYPTR32: register_yescryptr32_algo ( gate ); break;
case ALGO_YESPOWER: register_yespower_algo ( gate ); break;

View File

@@ -127,8 +127,7 @@ bool ( *miner_thread_init ) ( int );
void ( *stratum_gen_work ) ( struct stratum_ctx*, struct work* );
// Get thread local copy of blockheader with unique nonce.
void ( *get_new_work ) ( struct work*, struct work*, int, uint32_t*,
bool );
void ( *get_new_work ) ( struct work*, struct work*, int, uint32_t* );
// Return pointer to nonce in blockheader.
uint32_t *( *get_nonceptr ) ( uint32_t* );
@@ -147,7 +146,9 @@ void ( *gen_merkle_root ) ( char*, struct stratum_ctx* );
void ( *build_extraheader ) ( struct work*, struct stratum_ctx* );
void ( *build_block_header ) ( struct work*, uint32_t, uint32_t*,
uint32_t*, uint32_t, uint32_t );
uint32_t*, uint32_t, uint32_t,
unsigned char* );
// Build mining.submit message
void ( *build_stratum_request ) ( char*, struct work*, struct stratum_ctx* );
@@ -168,7 +169,7 @@ bool ( *do_this_thread ) ( int );
void ( *resync_threads ) ( struct work* );
json_t* (*longpoll_rpc_call) ( CURL*, int*, char* );
bool ( *stratum_handle_response )( json_t* );
bool ( *stratum_handle_response ) ( json_t* );
set_t optimizations;
int ( *get_work_data_size ) ();
int ntime_index;
@@ -225,7 +226,7 @@ uint32_t *std_get_nonceptr( uint32_t *work_data );
uint32_t *jr2_get_nonceptr( uint32_t *work_data );
void std_get_new_work( struct work *work, struct work *g_work, int thr_id,
uint32_t* end_nonce_ptr, bool clean_job );
uint32_t* end_nonce_ptr );
void jr2_get_new_work( struct work *work, struct work *g_work, int thr_id,
uint32_t* end_nonce_ptr );
@@ -256,7 +257,8 @@ double std_calc_network_diff( struct work *work );
void std_build_block_header( struct work* g_work, uint32_t version,
uint32_t *prevhash, uint32_t *merkle_root,
uint32_t ntime, uint32_t nbits );
uint32_t ntime, uint32_t nbits,
unsigned char *final_sapling_hash );
void std_build_extraheader( struct work *work, struct stratum_ctx *sctx );

View File

@@ -28,26 +28,28 @@ int scanhash_keccak_8way( struct work *work, uint32_t max_nonce,
const uint32_t first_nonce = pdata[19];
__m512i *noncev = (__m512i*)vdata + 9; // aligned
const uint32_t Htarg = ptarget[7];
int thr_id = mythr->id;
const int thr_id = mythr->id;
const bool bench = opt_benchmark;
mm512_bswap32_intrlv80_8x64( vdata, pdata );
do {
*noncev = mm512_intrlv_blend_32( mm512_bswap_32(
*noncev = mm512_intrlv_blend_32(
_mm512_set_epi32( n+7, 0, n+6, 0, n+5, 0, n+4, 0,
n+3, 0, n+2, 0, n+1, 0, n , 0 ) ), *noncev );
n+3, 0, n+2, 0, n+1, 0, n , 0 ), *noncev );
do {
keccakhash_8way( hash, vdata );
for ( int lane = 0; lane < 8; lane++ )
if ( hash7[ lane<<1 ] <= Htarg )
if unlikely( hash7[ lane<<1 ] <= Htarg && !bench )
{
extr_lane_8x64( lane_hash, hash, lane, 256 );
if ( fulltest( lane_hash, ptarget ) && !opt_benchmark )
if ( valid_hash( lane_hash, ptarget ) )
{
pdata[19] = n + lane;
pdata[19] = bswap_32( n + lane );
submit_lane_solution( work, lane_hash, mythr, lane );
}
}
*noncev = _mm512_add_epi32( *noncev,
m512_const1_64( 0x0000000800000000 ) );
n += 8;
} while ( (n < max_nonce-8) && !work_restart[thr_id].restart);
@@ -79,27 +81,28 @@ int scanhash_keccak_4way( struct work *work, uint32_t max_nonce,
const uint32_t first_nonce = pdata[19];
__m256i *noncev = (__m256i*)vdata + 9; // aligned
const uint32_t Htarg = ptarget[7];
int thr_id = mythr->id;
const int thr_id = mythr->id;
const bool bench = opt_benchmark;
mm256_bswap32_intrlv80_4x64( vdata, pdata );
*noncev = mm256_intrlv_blend_32(
_mm256_set_epi32( n+3, 0, n+2, 0, n+1, 0, n, 0 ), *noncev );
do {
*noncev = mm256_intrlv_blend_32( mm256_bswap_32(
_mm256_set_epi32( n+3, 0, n+2, 0, n+1, 0, n, 0 ) ), *noncev );
keccakhash_4way( hash, vdata );
for ( int lane = 0; lane < 4; lane++ )
if ( hash7[ lane<<1 ] <= Htarg )
if unlikely( hash7[ lane<<1 ] <= Htarg && !bench )
{
extr_lane_4x64( lane_hash, hash, lane, 256 );
if ( fulltest( lane_hash, ptarget ) && !opt_benchmark )
if ( valid_hash( lane_hash, ptarget ))
{
pdata[19] = n + lane;
pdata[19] = bswap_32( n + lane );
submit_lane_solution( work, lane_hash, mythr, lane );
}
}
*noncev = _mm256_add_epi32( *noncev,
m256_const1_64( 0x0000000400000000 ) );
n += 4;
} while ( (n < max_nonce-4) && !work_restart[thr_id].restart);
*hashes_done = n - first_nonce + 1;

View File

@@ -1,5 +1,9 @@
#include "keccak-gate.h"
#include "sph_keccak.h"
int hard_coded_eb = 1;
// KECCAK
bool register_keccak_algo( algo_gate_t* gate )
{
@@ -19,6 +23,8 @@ bool register_keccak_algo( algo_gate_t* gate )
return true;
};
// KECCAKC
bool register_keccakc_algo( algo_gate_t* gate )
{
gate->optimizations = AVX2_OPT | AVX512_OPT;
@@ -37,3 +43,50 @@ bool register_keccakc_algo( algo_gate_t* gate )
return true;
};
// SHA3D
void sha3d( void *state, const void *input, int len )
{
uint32_t _ALIGN(64) buffer[16], hash[16];
sph_keccak_context ctx_keccak;
sph_keccak256_init( &ctx_keccak );
sph_keccak256 ( &ctx_keccak, input, len );
sph_keccak256_close( &ctx_keccak, (void*) buffer );
sph_keccak256_init( &ctx_keccak );
sph_keccak256 ( &ctx_keccak, buffer, 32 );
sph_keccak256_close( &ctx_keccak, (void*) hash );
memcpy(state, hash, 32);
}
void sha3d_gen_merkle_root( char* merkle_root, struct stratum_ctx* sctx )
{
sha3d( merkle_root, sctx->job.coinbase, (int) sctx->job.coinbase_size );
for ( int i = 0; i < sctx->job.merkle_count; i++ )
{
memcpy( merkle_root + 32, sctx->job.merkle[i], 32 );
sha256d( merkle_root, merkle_root, 64 );
}
}
bool register_sha3d_algo( algo_gate_t* gate )
{
hard_coded_eb = 6;
opt_extranonce = false;
gate->optimizations = AVX2_OPT | AVX512_OPT;
gate->gen_merkle_root = (void*)&sha3d_gen_merkle_root;
#if defined (KECCAK_8WAY)
gate->scanhash = (void*)&scanhash_sha3d_8way;
gate->hash = (void*)&sha3d_hash_8way;
#elif defined (KECCAK_4WAY)
gate->scanhash = (void*)&scanhash_sha3d_4way;
gate->hash = (void*)&sha3d_hash_4way;
#else
gate->scanhash = (void*)&scanhash_sha3d;
gate->hash = (void*)&sha3d_hash;
#endif
return true;
};

View File

@@ -10,24 +10,37 @@
#define KECCAK_4WAY 1
#endif
extern int hard_coded_eb;
#if defined(KECCAK_8WAY)
void keccakhash_8way( void *state, const void *input );
int scanhash_keccak_8way( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr );
void sha3d_hash_8way( void *state, const void *input );
int scanhash_sha3d_8way( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr );
#elif defined(KECCAK_4WAY)
void keccakhash_4way( void *state, const void *input );
int scanhash_keccak_4way( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr );
void sha3d_hash_4way( void *state, const void *input );
int scanhash_sha3d_4way( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr );
#else
void keccakhash( void *state, const void *input );
int scanhash_keccak( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr );
#endif
void sha3d_hash( void *state, const void *input );
int scanhash_sha3d( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr );
#endif
#endif

View File

@@ -1,6 +1,7 @@
#include <stddef.h>
#include <stdint.h>
#include "keccak-hash-4way.h"
#include "keccak-gate.h"
static const uint64_t RC[] = {
0x0000000000000001, 0x0000000000008082,
@@ -168,7 +169,7 @@ static void keccak64_8way_close( keccak64_ctx_m512i *kc, void *dst,
size_t j;
size_t m512_len = byte_len >> 3;
eb = 0x100 >> 8;
eb = hard_coded_eb;
if ( kc->ptr == (lim - 8) )
{
const uint64_t t = eb | 0x8000000000000000;
@@ -349,7 +350,7 @@ static void keccak64_close( keccak64_ctx_m256i *kc, void *dst, size_t byte_len,
size_t j;
size_t m256_len = byte_len >> 3;
eb = 0x100 >> 8;
eb = hard_coded_eb;
if ( kc->ptr == (lim - 8) )
{
const uint64_t t = eb | 0x8000000000000000;

View File

@@ -18,35 +18,33 @@ void keccakhash(void *state, const void *input)
memcpy(state, hash, 32);
}
int scanhash_keccak( struct work *work,
uint32_t max_nonce, uint64_t *hashes_done, struct thr_info *mythr )
int scanhash_keccak( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr )
{
uint32_t _ALIGN(64) hash64[8];
uint32_t _ALIGN(64) endiandata[32];
uint32_t *pdata = work->data;
uint32_t *ptarget = work->target;
uint32_t n = pdata[19] - 1;
uint32_t n = pdata[19];
const uint32_t first_nonce = pdata[19];
//const uint32_t Htarg = ptarget[7];
int thr_id = mythr->id; // thr_id arg is deprecated
const uint32_t last_nonce = max_nonce;
const int thr_id = mythr->id;
uint32_t _ALIGN(32) hash64[8];
uint32_t endiandata[32];
for (int i=0; i < 19; i++)
be32enc(&endiandata[i], pdata[i]);
for ( int i=0; i < 19; i++ )
be32enc( &endiandata[i], pdata[i] );
do {
pdata[19] = ++n;
be32enc(&endiandata[19], n);
keccakhash(hash64, endiandata);
if (((hash64[7]&0xFFFFFF00)==0) &&
fulltest(hash64, ptarget)) {
*hashes_done = n - first_nonce + 1;
return true;
be32enc( &endiandata[19], n );
keccakhash( hash64, endiandata );
if ( valid_hash( hash64, ptarget ) && !opt_benchmark )
{
pdata[19] = n;
submit_solution( work, hash64, mythr );
}
} while (n < max_nonce && !work_restart[thr_id].restart);
n++;
} while ( n < last_nonce && !work_restart[thr_id].restart );
*hashes_done = n - first_nonce + 1;
*hashes_done = n - first_nonce;
pdata[19] = n;
return 0;
}

126
algo/keccak/sha3d-4way.c Normal file
View File

@@ -0,0 +1,126 @@
#include "keccak-gate.h"
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "sph_keccak.h"
#include "keccak-hash-4way.h"
#if defined(KECCAK_8WAY)
void sha3d_hash_8way(void *state, const void *input)
{
uint32_t buffer[16*8] __attribute__ ((aligned (128)));
keccak256_8way_context ctx;
keccak256_8way_init( &ctx );
keccak256_8way_update( &ctx, input, 80 );
keccak256_8way_close( &ctx, buffer );
keccak256_8way_init( &ctx );
keccak256_8way_update( &ctx, buffer, 32 );
keccak256_8way_close( &ctx, state );
}
int scanhash_sha3d_8way( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr )
{
uint32_t vdata[24*8] __attribute__ ((aligned (128)));
uint32_t hash[16*8] __attribute__ ((aligned (64)));
uint32_t lane_hash[8] __attribute__ ((aligned (64)));
uint32_t *hash7 = &(hash[49]); // 3*16+1
uint32_t *pdata = work->data;
uint32_t *ptarget = work->target;
uint32_t n = pdata[19];
const uint32_t first_nonce = pdata[19];
const uint32_t last_nonce = max_nonce - 8;
__m512i *noncev = (__m512i*)vdata + 9; // aligned
const uint32_t Htarg = ptarget[7];
const int thr_id = mythr->id;
const bool bench = opt_benchmark;
mm512_bswap32_intrlv80_8x64( vdata, pdata );
*noncev = mm512_intrlv_blend_32(
_mm512_set_epi32( n+7, 0, n+6, 0, n+5, 0, n+4, 0,
n+3, 0, n+2, 0, n+1, 0, n , 0 ), *noncev );
do {
sha3d_hash_8way( hash, vdata );
for ( int lane = 0; lane < 8; lane++ )
if unlikely( hash7[ lane<<1 ] <= Htarg && !bench )
{
extr_lane_8x64( lane_hash, hash, lane, 256 );
if ( valid_hash( lane_hash, ptarget ) )
{
pdata[19] = bswap_32( n + lane );
submit_lane_solution( work, lane_hash, mythr, lane );
}
}
*noncev = _mm512_add_epi32( *noncev,
m512_const1_64( 0x0000000800000000 ) );
n += 8;
} while ( (n < last_nonce) && !work_restart[thr_id].restart);
*hashes_done = n - first_nonce;
return 0;
}
#elif defined(KECCAK_4WAY)
void sha3d_hash_4way(void *state, const void *input)
{
uint32_t buffer[16*4] __attribute__ ((aligned (64)));
keccak256_4way_context ctx;
keccak256_4way_init( &ctx );
keccak256_4way_update( &ctx, input, 80 );
keccak256_4way_close( &ctx, buffer );
keccak256_4way_init( &ctx );
keccak256_4way_update( &ctx, buffer, 32 );
keccak256_4way_close( &ctx, state );
}
int scanhash_sha3d_4way( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr )
{
uint32_t vdata[24*4] __attribute__ ((aligned (64)));
uint32_t hash[16*4] __attribute__ ((aligned (32)));
uint32_t lane_hash[8] __attribute__ ((aligned (32)));
uint32_t *hash7 = &(hash[25]); // 3*8+1
uint32_t *pdata = work->data;
uint32_t *ptarget = work->target;
uint32_t n = pdata[19];
const uint32_t first_nonce = pdata[19];
const uint32_t last_nonce = max_nonce - 4;
__m256i *noncev = (__m256i*)vdata + 9; // aligned
const uint32_t Htarg = ptarget[7];
const int thr_id = mythr->id;
const bool bench = opt_benchmark;
mm256_bswap32_intrlv80_4x64( vdata, pdata );
*noncev = mm256_intrlv_blend_32(
_mm256_set_epi32( n+3, 0, n+2, 0, n+1, 0, n, 0 ), *noncev );
do {
sha3d_hash_4way( hash, vdata );
for ( int lane = 0; lane < 4; lane++ )
if unlikely( hash7[ lane<<1 ] <= Htarg && !bench )
{
extr_lane_4x64( lane_hash, hash, lane, 256 );
if ( valid_hash( lane_hash, ptarget ) )
{
pdata[19] = bswap_32( n + lane );
submit_lane_solution( work, lane_hash, mythr, lane );
}
}
*noncev = _mm256_add_epi32( *noncev,
m256_const1_64( 0x0000000400000000 ) );
n += 4;
} while ( (n < last_nonce) && !work_restart[thr_id].restart);
*hashes_done = n - first_nonce;
return 0;
}
#endif

50
algo/keccak/sha3d.c Normal file
View File

@@ -0,0 +1,50 @@
#include "algo-gate-api.h"
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "sph_keccak.h"
void sha3d_hash(void *state, const void *input)
{
uint32_t buffer[16];
sph_keccak256_context ctx_keccak;
sph_keccak256_init( &ctx_keccak );
sph_keccak256 ( &ctx_keccak, input, 80 );
sph_keccak256_close( &ctx_keccak, buffer );
sph_keccak256_init( &ctx_keccak );
sph_keccak256 ( &ctx_keccak, buffer, 32 );
sph_keccak256_close( &ctx_keccak, state );
}
int scanhash_sha3d( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr )
{
uint32_t _ALIGN(64) hash64[8];
uint32_t _ALIGN(64) endiandata[32];
uint32_t *pdata = work->data;
uint32_t *ptarget = work->target;
uint32_t n = pdata[19];
const uint32_t first_nonce = pdata[19];
const uint32_t last_nonce = max_nonce;
const int thr_id = mythr->id;
for ( int i=0; i < 19; i++ )
be32enc( &endiandata[i], pdata[i] );
do {
be32enc( &endiandata[19], n );
sha3d_hash( hash64, endiandata );
if ( valid_hash( hash64, ptarget ) && !opt_benchmark )
{
pdata[19] = n;
submit_solution( work, hash64, mythr );
}
n++;
} while ( n < last_nonce && !work_restart[thr_id].restart );
*hashes_done = n - first_nonce;
pdata[19] = n;
return 0;
}

View File

@@ -32,8 +32,8 @@
#include <stddef.h>
#include <string.h>
#include "sph_keccak.h"
#include "keccak-gate.h"
#ifdef __cplusplus
extern "C"{
@@ -1616,7 +1616,7 @@ keccak_core(sph_keccak_context *kc, const void *data, size_t len, size_t lim)
} u; \
size_t j; \
\
eb = (0x100 | (ub & 0xFF)) >> (8 - n); \
eb = hard_coded_eb; \
if (kc->ptr == (lim - 1)) { \
if (n == 7) { \
u.tmp[0] = eb; \

View File

@@ -263,37 +263,31 @@ int scanhash_allium_16way( struct work *work, uint32_t max_nonce,
const uint32_t first_nonce = pdata[19];
uint32_t n = first_nonce;
const uint32_t last_nonce = max_nonce - 16;
const uint32_t Htarg = ptarget[7];
__m512i *noncev = (__m512i*)vdata + 19; // aligned
int thr_id = mythr->id; // thr_id arg is deprecated
const int thr_id = mythr->id;
const bool bench = opt_benchmark;
if ( opt_benchmark )
( (uint32_t*)ptarget )[7] = 0x0000ff;
if ( bench ) ( (uint32_t*)ptarget )[7] = 0x0000ff;
mm512_bswap32_intrlv80_16x32( vdata, pdata );
*noncev = _mm512_set_epi32( n+15, n+14, n+13, n+12, n+11, n+10, n+ 9, n+ 8,
n+ 7, n+ 6, n+ 5, n+ 4, n+ 3, n+ 2, n +1, n );
blake256_16way_init( &allium_16way_ctx.blake );
blake256_16way_update( &allium_16way_ctx.blake, vdata, 64 );
do {
*noncev = mm512_bswap_32( _mm512_set_epi32( n+15, n+14, n+13, n+12,
n+11, n+10, n+ 9, n+ 8,
n+ 7, n+ 6, n+ 5, n+ 4,
n+ 3, n+ 2, n +1, n ) );
allium_16way_hash( hash, vdata );
pdata[19] = n;
for ( int lane = 0; lane < 16; lane++ ) if ( (hash+(lane<<3))[7] <= Htarg )
for ( int lane = 0; lane < 16; lane++ )
if unlikely( valid_hash( hash+(lane<<3), ptarget ) && !bench )
{
if ( fulltest( hash+(lane<<3), ptarget ) && !opt_benchmark )
{
pdata[19] = n + lane;
pdata[19] = bswap_32( n + lane );
submit_lane_solution( work, hash+(lane<<3), mythr, lane );
}
}
*noncev = _mm512_add_epi32( *noncev, m512_const1_32( 16 ) );
n += 16;
} while ( (n < last_nonce) && !work_restart[thr_id].restart);
*hashes_done = n - first_nonce;
return 0;
}
@@ -320,18 +314,19 @@ bool init_allium_8way_ctx()
return true;
}
void allium_8way_hash( void *state, const void *input )
void allium_8way_hash( void *hash, const void *input )
{
uint32_t vhashA[8*8] __attribute__ ((aligned (64)));
uint32_t vhashB[8*8] __attribute__ ((aligned (64)));
uint32_t hash0[8] __attribute__ ((aligned (32)));
uint32_t hash1[8] __attribute__ ((aligned (32)));
uint32_t hash2[8] __attribute__ ((aligned (32)));
uint32_t hash3[8] __attribute__ ((aligned (32)));
uint32_t hash4[8] __attribute__ ((aligned (64)));
uint32_t hash5[8] __attribute__ ((aligned (32)));
uint32_t hash6[8] __attribute__ ((aligned (32)));
uint32_t hash7[8] __attribute__ ((aligned (32)));
uint64_t vhashA[4*8] __attribute__ ((aligned (64)));
uint64_t vhashB[4*8] __attribute__ ((aligned (64)));
// uint64_t hash[4*8] __attribute__ ((aligned (64)));
uint64_t *hash0 = (uint64_t*)hash;
uint64_t *hash1 = (uint64_t*)hash+ 4;
uint64_t *hash2 = (uint64_t*)hash+ 8;
uint64_t *hash3 = (uint64_t*)hash+12;
uint64_t *hash4 = (uint64_t*)hash+16;
uint64_t *hash5 = (uint64_t*)hash+20;
uint64_t *hash6 = (uint64_t*)hash+24;
uint64_t *hash7 = (uint64_t*)hash+28;
allium_8way_ctx_holder ctx __attribute__ ((aligned (64)));
memcpy( &ctx, &allium_8way_ctx, sizeof(allium_8way_ctx) );
@@ -398,69 +393,66 @@ void allium_8way_hash( void *state, const void *input )
dintrlv_4x64( hash0, hash1, hash2, hash3, vhashA, 256 );
dintrlv_4x64( hash4, hash5, hash6, hash7, vhashB, 256 );
update_and_final_groestl256( &ctx.groestl, state, hash0, 256 );
update_and_final_groestl256( &ctx.groestl, hash0, hash0, 256 );
memcpy( &ctx.groestl, &allium_8way_ctx.groestl,
sizeof(hashState_groestl256) );
update_and_final_groestl256( &ctx.groestl, state+32, hash1, 256 );
update_and_final_groestl256( &ctx.groestl, hash1, hash1, 256 );
memcpy( &ctx.groestl, &allium_8way_ctx.groestl,
sizeof(hashState_groestl256) );
update_and_final_groestl256( &ctx.groestl, state+64, hash2, 256 );
update_and_final_groestl256( &ctx.groestl, hash2, hash2, 256 );
memcpy( &ctx.groestl, &allium_8way_ctx.groestl,
sizeof(hashState_groestl256) );
update_and_final_groestl256( &ctx.groestl, state+96, hash3, 256 );
update_and_final_groestl256( &ctx.groestl, hash3, hash3, 256 );
memcpy( &ctx.groestl, &allium_8way_ctx.groestl,
sizeof(hashState_groestl256) );
update_and_final_groestl256( &ctx.groestl, state+128, hash4, 256 );
update_and_final_groestl256( &ctx.groestl, hash4, hash4, 256 );
memcpy( &ctx.groestl, &allium_8way_ctx.groestl,
sizeof(hashState_groestl256) );
update_and_final_groestl256( &ctx.groestl, state+160, hash5, 256 );
update_and_final_groestl256( &ctx.groestl, hash5, hash5, 256 );
memcpy( &ctx.groestl, &allium_8way_ctx.groestl,
sizeof(hashState_groestl256) );
update_and_final_groestl256( &ctx.groestl, state+192, hash6, 256 );
update_and_final_groestl256( &ctx.groestl, hash6, hash6, 256 );
memcpy( &ctx.groestl, &allium_8way_ctx.groestl,
sizeof(hashState_groestl256) );
update_and_final_groestl256( &ctx.groestl, state+224, hash7, 256 );
update_and_final_groestl256( &ctx.groestl, hash7, hash7, 256 );
}
int scanhash_allium_8way( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr )
{
uint32_t hash[8*8] __attribute__ ((aligned (64)));
uint64_t hash[4*8] __attribute__ ((aligned (64)));
uint32_t vdata[20*8] __attribute__ ((aligned (64)));
uint32_t *pdata = work->data;
uint32_t *ptarget = work->target;
uint64_t *ptarget = (uint64_t*)work->target;
const uint32_t first_nonce = pdata[19];
const uint32_t last_nonce = max_nonce - 8;
uint32_t n = first_nonce;
const uint32_t Htarg = ptarget[7];
__m256i *noncev = (__m256i*)vdata + 19; // aligned
int thr_id = mythr->id;
if ( opt_benchmark )
( (uint32_t*)ptarget )[7] = 0x0000ff;
const int thr_id = mythr->id;
const bool bench = opt_benchmark;
mm256_bswap32_intrlv80_8x32( vdata, pdata );
*noncev = _mm256_set_epi32( n+7, n+6, n+5, n+4, n+3, n+2, n+1, n );
blake256_8way_init( &allium_8way_ctx.blake );
blake256_8way_update( &allium_8way_ctx.blake, vdata, 64 );
do {
*noncev = mm256_bswap_32( _mm256_set_epi32( n+7, n+6, n+5, n+4,
n+3, n+2, n+1, n ) );
allium_8way_hash( hash, vdata );
pdata[19] = n;
for ( int lane = 0; lane < 8; lane++ ) if ( (hash+(lane<<3))[7] <= Htarg )
for ( int lane = 0; lane < 8; lane++ )
{
if ( fulltest( hash+(lane<<3), ptarget ) && !opt_benchmark )
const uint64_t *lane_hash = hash + (lane<<2);
if unlikely( valid_hash( lane_hash, ptarget ) && !bench )
{
pdata[19] = n + lane;
submit_lane_solution( work, hash+(lane<<3), mythr, lane );
pdata[19] = bswap_32( n + lane );
submit_lane_solution( work, lane_hash, mythr, lane );
}
}
n += 8;
} while ( (n < last_nonce) && !work_restart[thr_id].restart);
*noncev = _mm256_add_epi32( *noncev, m256_const1_32( 8 ) );
} while likely( (n <= last_nonce) && !work_restart[thr_id].restart );
pdata[19] = n;
*hashes_done = n - first_nonce;
return 0;
}

View File

@@ -220,7 +220,7 @@ void phi2_build_extraheader( struct work* g_work, struct stratum_ctx* sctx )
// Assemble block header
algo_gate.build_block_header( g_work, le32dec( sctx->job.version ),
(uint32_t*) sctx->job.prevhash, (uint32_t*) merkle_tree,
le32dec( sctx->job.ntime ), le32dec(sctx->job.nbits) );
le32dec( sctx->job.ntime ), le32dec(sctx->job.nbits), NULL );
for ( t = 0; t < 16; t++ )
g_work->data[ 20+t ] = ((uint32_t*)sctx->job.extra)[t];
}

View File

@@ -267,8 +267,13 @@ int scanhash_m7m_hash( struct work* work, uint64_t max_nonce,
SHA256_Final( (unsigned char*) hash, &ctxf_sha256 );
}
if ( unlikely( hash[7] <= ptarget[7] ) )
if ( likely( fulltest( hash, ptarget ) && !opt_benchmark ) )
if ( unlikely( valid_hash( (uint64_t*)hash, (uint64_t*)ptarget )
&& !opt_benchmark ) )
// if ( unlikely( hash[7] <= ptarget[7] ) )
// if ( likely( fulltest( hash, ptarget ) && !opt_benchmark ) )
{
if ( opt_debug )
{

View File

@@ -154,14 +154,13 @@ int scanhash_zr5( struct work *work, uint32_t max_nonce,
}
void zr5_get_new_work( struct work* work, struct work* g_work, int thr_id,
uint32_t* end_nonce_ptr, bool clean_job )
uint32_t* end_nonce_ptr )
{
// ignore POK in first word
// const int nonce_i = 19;
const int wkcmp_sz = 72; // (19-1) * sizeof(uint32_t)
uint32_t *nonceptr = algo_gate.get_nonceptr( work->data );
if ( memcmp( &work->data[1], &g_work->data[1], wkcmp_sz )
&& ( clean_job || ( *nonceptr >= *end_nonce_ptr ) ) )
|| ( *nonceptr >= *end_nonce_ptr ) )
{
work_free( work );
work_copy( work, g_work );

View File

@@ -28,46 +28,10 @@
#include <stdint.h>
#include <string.h>
#include "sysendian.h"
#include "sha256_p.h"
#include "simd-utils.h"
#include "hmac-sha256-hash.h"
#include "compat.h"
/* Elementary functions used by SHA256 */
#define Ch(x, y, z) ((x & (y ^ z)) ^ z)
#define Maj(x, y, z) ((x & (y | z)) | (y & z))
#define SHR(x, n) (x >> n)
#define ROTR(x, n) ((x >> n) | (x << (32 - n)))
#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
/* SHA256 round function */
#define RND(a, b, c, d, e, f, g, h, k) \
t0 = h + S1(e) + Ch(e, f, g) + k; \
t1 = S0(a) + Maj(a, b, c); \
d += t0; \
h = t0 + t1;
/* Adjusted round function for rotating state */
#define RNDr(S, W, i, k) \
RND(S[(64 - i) % 8], S[(65 - i) % 8], \
S[(66 - i) % 8], S[(67 - i) % 8], \
S[(68 - i) % 8], S[(69 - i) % 8], \
S[(70 - i) % 8], S[(71 - i) % 8], \
W[i] + k)
/*
static unsigned char PAD[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
*/
/**
* SHA256_Buf(in, len, digest):
* Compute the SHA256 hash of ${len} bytes from ${in} and write it to ${digest}.
@@ -87,11 +51,10 @@ SHA256_Buf( const void * in, size_t len, uint8_t digest[32] )
* length ${Klen}, and write the result to ${digest}.
*/
void
HMAC_SHA256_Buf(const void * K, size_t Klen, const void * in, size_t len,
HMAC_SHA256_Buf( const void *K, size_t Klen, const void *in, size_t len,
uint8_t digest[32])
{
HMAC_SHA256_CTX ctx;
HMAC_SHA256_Init( &ctx, K, Klen );
HMAC_SHA256_Update( &ctx, in, len );
HMAC_SHA256_Final( digest, &ctx );
@@ -99,7 +62,7 @@ HMAC_SHA256_Buf(const void * K, size_t Klen, const void * in, size_t len,
/* Initialize an HMAC-SHA256 operation with the given key. */
void
HMAC_SHA256_Init( HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen )
HMAC_SHA256_Init( HMAC_SHA256_CTX *ctx, const void *_K, size_t Klen )
{
unsigned char pad[64];
unsigned char khash[32];
@@ -107,7 +70,8 @@ HMAC_SHA256_Init( HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen )
size_t i;
/* If Klen > 64, the key is really SHA256(K). */
if (Klen > 64) {
if ( Klen > 64 )
{
SHA256_Init( &ctx->ictx );
SHA256_Update( &ctx->ictx, K, Klen );
SHA256_Final( khash, &ctx->ictx );
@@ -128,23 +92,19 @@ HMAC_SHA256_Init( HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen )
for ( i = 0; i < Klen; i++ )
pad[i] ^= K[i];
SHA256_Update( &ctx->octx, pad, 64 );
/* Clean the stack. */
//memset(khash, 0, 32);
}
/* Add bytes to the HMAC-SHA256 operation. */
void
HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void *in, size_t len)
HMAC_SHA256_Update( HMAC_SHA256_CTX *ctx, const void *in, size_t len )
{
/* Feed data to the inner SHA256 operation. */
SHA256_Update( &ctx->ictx, in, len );
}
/* Finish an HMAC-SHA256 operation. */
void
HMAC_SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX * ctx )
HMAC_SHA256_Final( unsigned char digest[32], HMAC_SHA256_CTX *ctx )
{
unsigned char ihash[32];
@@ -156,9 +116,6 @@ HMAC_SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX * ctx )
/* Finish the outer SHA256 operation. */
SHA256_Final( digest, &ctx->octx );
/* Clean the stack. */
//memset(ihash, 0, 32);
}
/**
@@ -167,52 +124,51 @@ HMAC_SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX * ctx )
* write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
*/
void
PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen)
PBKDF2_SHA256( const uint8_t *passwd, size_t passwdlen, const uint8_t *salt,
size_t saltlen, uint64_t c, uint8_t *buf, size_t dkLen )
{
HMAC_SHA256_CTX PShctx, hctx;
uint8_t _ALIGN(128) T[32];
uint8_t _ALIGN(128) U[32];
uint8_t ivec[4];
uint32_t ivec;
size_t i, clen;
uint64_t j;
int k;
/* Compute HMAC state after processing P and S. */
HMAC_SHA256_Init(&PShctx, passwd, passwdlen);
HMAC_SHA256_Update(&PShctx, salt, saltlen);
HMAC_SHA256_Init( &PShctx, passwd, passwdlen );
HMAC_SHA256_Update( &PShctx, salt, saltlen );
/* Iterate through the blocks. */
for (i = 0; i * 32 < dkLen; i++) {
for ( i = 0; i * 32 < dkLen; i++ )
{
/* Generate INT(i + 1). */
be32enc(ivec, (uint32_t)(i + 1));
ivec = bswap_32( i+1 );
/* Compute U_1 = PRF(P, S || INT(i)). */
memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX));
HMAC_SHA256_Update(&hctx, ivec, 4);
HMAC_SHA256_Final(U, &hctx);
memcpy( &hctx, &PShctx, sizeof(HMAC_SHA256_CTX) );
HMAC_SHA256_Update( &hctx, &ivec, 4 );
HMAC_SHA256_Final( U, &hctx );
/* T_i = U_1 ... */
memcpy(T, U, 32);
memcpy( T, U, 32 );
for (j = 2; j <= c; j++) {
for ( j = 2; j <= c; j++ )
{
/* Compute U_j. */
HMAC_SHA256_Init(&hctx, passwd, passwdlen);
HMAC_SHA256_Update(&hctx, U, 32);
HMAC_SHA256_Final(U, &hctx);
HMAC_SHA256_Init( &hctx, passwd, passwdlen );
HMAC_SHA256_Update( &hctx, U, 32 );
HMAC_SHA256_Final( U, &hctx );
/* ... xor U_j ... */
for (k = 0; k < 32; k++)
for ( k = 0; k < 32; k++ )
T[k] ^= U[k];
}
/* Copy as many bytes as necessary into buf. */
clen = dkLen - i * 32;
if (clen > 32)
if ( clen > 32 )
clen = 32;
memcpy(&buf[i * 32], T, clen);
memcpy( &buf[i * 32], T, clen );
}
/* Clean PShctx, since we never called _Final on it. */
//memset(&PShctx, 0, sizeof(HMAC_SHA256_CTX_Y));
}

View File

@@ -26,23 +26,24 @@
* $FreeBSD: src/lib/libmd/sha256_Y.h,v 1.2 2006/01/17 15:35:56 phk Exp $
*/
#ifndef _SHA256_H_
#define _SHA256_H_
#ifndef HMAC_SHA256_H__
#define HMAC_SHA256_H__
#include <sys/types.h>
#include <stdint.h>
#include <openssl/sha.h>
typedef struct HMAC_SHA256Context {
typedef struct HMAC_SHA256Context
{
SHA256_CTX ictx;
SHA256_CTX octx;
} HMAC_SHA256_CTX;
void SHA256_Buf( const void * in, size_t len, uint8_t digest[32] );
void SHA256_Buf( const void *, size_t len, uint8_t digest[32] );
void HMAC_SHA256_Init( HMAC_SHA256_CTX *, const void *, size_t );
void HMAC_SHA256_Update( HMAC_SHA256_CTX *, const void *, size_t );
void HMAC_SHA256_Final( unsigned char [32], HMAC_SHA256_CTX * );
void HMAC_SHA256_Buf( const void * K, size_t Klen, const void * in,
void HMAC_SHA256_Buf( const void *, size_t Klen, const void *,
size_t len, uint8_t digest[32] );
/**
@@ -53,4 +54,4 @@ void HMAC_SHA256_Buf( const void * K, size_t Klen, const void * in,
void PBKDF2_SHA256( const uint8_t *, size_t, const uint8_t *, size_t,
uint64_t, uint8_t *, size_t);
#endif /* !_SHA256_H_ */
#endif // HMAC_SHA256_H__

View File

@@ -94,6 +94,37 @@ static const uint32_t K256[64] =
_mm_xor_si128( _mm_xor_si128( \
mm128_ror_32(x, 17), mm128_ror_32(x, 19) ), _mm_srli_epi32(x, 10) )
#define SHA2s_4WAY_STEP(A, B, C, D, E, F, G, H, i, j) \
do { \
__m128i K = _mm_set1_epi32( K256[( (j)+(i) )] ); \
__m128i T1 = mm128_ror_32( E, 14 ); \
__m128i T2 = mm128_ror_32( A, 9 ); \
__m128i T3 = _mm_xor_si128( F, G ); \
__m128i T4 = _mm_or_si128( A, B ); \
__m128i T5 = _mm_and_si128( A, B ); \
K = _mm_add_epi32( K, W[i] ); \
T1 = _mm_xor_si128( T1, E ); \
T2 = _mm_xor_si128( T2, A ); \
T3 = _mm_and_si128( T3, E ); \
T4 = _mm_and_si128( T4, C ); \
K = _mm_add_epi32( H, K ); \
T1 = mm128_ror_32( T1, 5 ); \
T2 = mm128_ror_32( T2, 11 ); \
T3 = _mm_xor_si128( T3, G ); \
T4 = _mm_or_si128( T4, T5 ); \
T1 = _mm_xor_si128( T1, E ); \
T2 = _mm_xor_si128( T2, A ); \
T1 = mm128_ror_32( T1, 6 ); \
T2 = mm128_ror_32( T2, 2 ); \
T1 = _mm_add_epi32( T1, T3 ); \
T2 = _mm_add_epi32( T2, T4 ); \
T1 = _mm_add_epi32( T1, K ); \
H = _mm_add_epi32( T1, T2 ); \
D = _mm_add_epi32( D, T1 ); \
} while (0)
/*
#define SHA2s_4WAY_STEP(A, B, C, D, E, F, G, H, i, j) \
do { \
__m128i T1, T2; \
@@ -104,6 +135,8 @@ do { \
D = _mm_add_epi32( D, T1 ); \
H = _mm_add_epi32( T1, T2 ); \
} while (0)
*/
static void
sha256_4way_round( sha256_4way_context *ctx, __m128i *in, __m128i r[8] )

View File

@@ -319,7 +319,7 @@ void sha512_8way_close( sha512_8way_context *sc, void *dst )
// SHA-512 4 way 64 bit
/*
#define CH(X, Y, Z) \
_mm256_xor_si256( _mm256_and_si256( _mm256_xor_si256( Y, Z ), X ), Z )
@@ -327,6 +327,15 @@ void sha512_8way_close( sha512_8way_context *sc, void *dst )
_mm256_or_si256( _mm256_and_si256( X, Y ), \
_mm256_and_si256( _mm256_or_si256( X, Y ), Z ) )
#define BSG5_0(x) \
mm256_ror_64( _mm256_xor_si256( mm256_ror_64( \
_mm256_xor_si256( mm256_ror_64( x, 5 ), x ), 6 ), x ), 28 )
#define BSG5_1(x) \
mm256_ror_64( _mm256_xor_si256( mm256_ror_64( \
_mm256_xor_si256( mm256_ror_64( x, 23 ), x ), 4 ), x ), 14 )
*/
/*
#define BSG5_0(x) \
_mm256_xor_si256( _mm256_xor_si256( \
mm256_ror_64(x, 28), mm256_ror_64(x, 34) ), mm256_ror_64(x, 39) )
@@ -334,7 +343,8 @@ void sha512_8way_close( sha512_8way_context *sc, void *dst )
#define BSG5_1(x) \
_mm256_xor_si256( _mm256_xor_si256( \
mm256_ror_64(x, 14), mm256_ror_64(x, 18) ), mm256_ror_64(x, 41) )
*/
/*
#define SSG5_0(x) \
_mm256_xor_si256( _mm256_xor_si256( \
mm256_ror_64(x, 1), mm256_ror_64(x, 8) ), _mm256_srli_epi64(x, 7) )
@@ -342,7 +352,7 @@ void sha512_8way_close( sha512_8way_context *sc, void *dst )
#define SSG5_1(x) \
_mm256_xor_si256( _mm256_xor_si256( \
mm256_ror_64(x, 19), mm256_ror_64(x, 61) ), _mm256_srli_epi64(x, 6) )
*/
// Interleave SSG0 & SSG1 for better throughput.
// return ssg0(w0) + ssg1(w1)
static inline __m256i ssg512_add( __m256i w0, __m256i w1 )
@@ -361,7 +371,7 @@ static inline __m256i ssg512_add( __m256i w0, __m256i w1 )
return _mm256_add_epi64( w0a, w1a );
}
/*
#define SSG512x2_0( w0, w1, i ) do \
{ \
__m256i X0a, X1a, X0b, X1b; \
@@ -391,7 +401,51 @@ static inline __m256i ssg512_add( __m256i w0, __m256i w1 )
w0 = _mm256_xor_si256( X0a, X0b ); \
w1 = _mm256_xor_si256( X1a, X1b ); \
} while(0)
*/
#define SHA3_4WAY_STEP(A, B, C, D, E, F, G, H, i) \
do { \
__m256i K = _mm256_set1_epi64x( K512[ i ] ); \
__m256i T1 = mm256_ror_64( E, 23 ); \
__m256i T2 = mm256_ror_64( A, 5 ); \
__m256i T3 = _mm256_xor_si256( F, G ); \
__m256i T4 = _mm256_or_si256( A, B ); \
__m256i T5 = _mm256_and_si256( A, B ); \
K = _mm256_add_epi64( K, W[i] ); \
T1 = _mm256_xor_si256( T1, E ); \
T2 = _mm256_xor_si256( T2, A ); \
T3 = _mm256_and_si256( T3, E ); \
T4 = _mm256_and_si256( T4, C ); \
K = _mm256_add_epi64( H, K ); \
T1 = mm256_ror_64( T1, 4 ); \
T2 = mm256_ror_64( T2, 6 ); \
T3 = _mm256_xor_si256( T3, G ); \
T4 = _mm256_or_si256( T4, T5 ); \
T1 = _mm256_xor_si256( T1, E ); \
T2 = _mm256_xor_si256( T2, A ); \
T1 = mm256_ror_64( T1, 14 ); \
T2 = mm256_ror_64( T2, 28 ); \
T1 = _mm256_add_epi64( T1, T3 ); \
T2 = _mm256_add_epi64( T2, T4 ); \
T1 = _mm256_add_epi64( T1, K ); \
H = _mm256_add_epi64( T1, T2 ); \
D = _mm256_add_epi64( D, T1 ); \
} while (0)
/*
#define SHA3_4WAY_STEP(A, B, C, D, E, F, G, H, i) \
do { \
__m256i K = _mm256_add_epi64( W[i], _mm256_set1_epi64x( K512[ i ] ) ); \
__m256i T1 = BSG5_1(E); \
__m256i T2 = BSG5_0(A); \
T1 = mm256_add4_64( T1, H, CH(E, F, G), K ); \
T2 = _mm256_add_epi64( T2, MAJ(A, B, C) ); \
D = _mm256_add_epi64( D, T1 ); \
H = _mm256_add_epi64( T1, T2 ); \
} while (0)
*/
/*
#define SHA3_4WAY_STEP(A, B, C, D, E, F, G, H, i) \
do { \
__m256i T1, T2; \
@@ -402,7 +456,7 @@ do { \
D = _mm256_add_epi64( D, T1 ); \
H = _mm256_add_epi64( T1, T2 ); \
} while (0)
*/
static void
sha512_4way_round( sha512_4way_context *ctx, __m256i *in, __m256i r[8] )

View File

@@ -214,14 +214,14 @@ int scanhash_drop( struct work *work, uint32_t max_nonce,
}
void drop_get_new_work( struct work* work, struct work* g_work, int thr_id,
uint32_t* end_nonce_ptr, bool clean_job )
uint32_t* end_nonce_ptr )
{
// ignore POK in first word
// const int nonce_i = 19;
const int wkcmp_sz = 72; // (19-1) * sizeof(uint32_t)
uint32_t *nonceptr = algo_gate.get_nonceptr( work->data );
if ( memcmp( &work->data[1], &g_work->data[1], wkcmp_sz )
&& ( clean_job || ( *nonceptr >= *end_nonce_ptr ) ) )
|| ( *nonceptr >= *end_nonce_ptr ) )
{
work_free( work );
work_copy( work, g_work );

View File

@@ -299,25 +299,28 @@ int scanhash_x17_8way( struct work *work, uint32_t max_nonce,
uint32_t n = first_nonce;
const int thr_id = mythr->id;
const uint32_t Htarg = ptarget[7];
const bool bench = opt_benchmark;
mm512_bswap32_intrlv80_8x64( vdata, pdata );
*noncev = mm512_intrlv_blend_32(
_mm512_set_epi32( n+7, 0, n+6, 0, n+5, 0, n+4, 0,
n+3, 0, n+2, 0, n+1, 0, n, 0 ), *noncev );
do
{
*noncev = mm512_intrlv_blend_32( mm512_bswap_32(
_mm512_set_epi32( n+7, 0, n+6, 0, n+5, 0, n+4, 0,
n+3, 0, n+2, 0, n+1, 0, n, 0 ) ), *noncev );
x17_8way_hash( hash, vdata );
for ( int lane = 0; lane < 8; lane++ )
if unlikely( ( hash7[ lane ] <= Htarg ) )
if unlikely( ( hash7[ lane ] <= Htarg ) && !bench )
{
extr_lane_8x32( lane_hash, hash, lane, 256 );
if ( likely( fulltest( lane_hash, ptarget ) && !opt_benchmark ) )
if likely( valid_hash( lane_hash, ptarget ) )
{
pdata[19] = n + lane;
pdata[19] = bswap_32( n + lane );
submit_lane_solution( work, lane_hash, mythr, lane );
}
}
*noncev = _mm512_add_epi32( *noncev,
m512_const1_64( 0x0000000800000000 ) );
n += 8;
} while ( likely( ( n < last_nonce ) && !work_restart[thr_id].restart ) );
@@ -351,7 +354,7 @@ typedef union _x17_4way_context_overlay x17_4way_context_overlay;
void x17_4way_hash( void *state, const void *input )
{
uint64_t vhash[8*4] __attribute__ ((aligned (128)));
uint64_t vhash[8*4] __attribute__ ((aligned (64)));
uint64_t vhashA[8*4] __attribute__ ((aligned (64)));
uint64_t vhashB[8*4] __attribute__ ((aligned (64)));
uint64_t hash0[8] __attribute__ ((aligned (64)));
@@ -471,8 +474,8 @@ void x17_4way_hash( void *state, const void *input )
int scanhash_x17_4way( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr )
{
uint32_t hash[16*4] __attribute__ ((aligned (128)));
uint32_t vdata[24*4] __attribute__ ((aligned (64)));
uint32_t hash[16*4] __attribute__ ((aligned (64)));
uint32_t vdata[20*4] __attribute__ ((aligned (64)));
uint32_t lane_hash[8] __attribute__ ((aligned (64)));
uint32_t *hash7 = &(hash[7<<2]);
uint32_t *pdata = work->data;
@@ -483,27 +486,30 @@ int scanhash_x17_4way( struct work *work, uint32_t max_nonce,
uint32_t n = first_nonce;
const int thr_id = mythr->id;
const uint32_t Htarg = ptarget[7];
const bool bench = opt_benchmark;
mm256_bswap32_intrlv80_4x64( vdata, pdata );
*noncev = mm256_intrlv_blend_32(
_mm256_set_epi32( n+3, 0, n+2, 0, n+1, 0, n, 0 ), *noncev );
do
{
*noncev = mm256_intrlv_blend_32( mm256_bswap_32(
_mm256_set_epi32( n+3, 0, n+2, 0, n+1, 0, n, 0 ) ), *noncev );
x17_4way_hash( hash, vdata );
for ( int lane = 0; lane < 4; lane++ )
if unlikely( ( hash7[ lane ] <= Htarg ) )
if ( unlikely( hash7[ lane ] <= Htarg && !bench ) )
{
extr_lane_4x32( lane_hash, hash, lane, 256 );
if ( likely( fulltest( lane_hash, ptarget ) && !opt_benchmark ) )
if ( valid_hash( lane_hash, ptarget ) )
{
pdata[19] = n + lane;
pdata[19] = bswap_32( n + lane );
submit_lane_solution( work, lane_hash, mythr, lane );
}
}
*noncev = _mm256_add_epi32( *noncev,
m256_const1_64( 0x0000000400000000 ) );
n += 4;
} while ( likely( ( n < last_nonce ) && !work_restart[thr_id].restart ) );
} while ( likely( ( n <= last_nonce ) && !work_restart[thr_id].restart ) );
pdata[19] = n;
*hashes_done = n - first_nonce;
return 0;
}

View File

@@ -1,409 +0,0 @@
/*-
* Copyright 2005,2007,2009 Colin Percival
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/types.h>
#include <stdint.h>
#include <string.h>
#include "sysendian.h"
#include "sha256_Y.h"
#include "compat.h"
/*
* Encode a length len/4 vector of (uint32_t) into a length len vector of
* (unsigned char) in big-endian form. Assumes len is a multiple of 4.
*/
static void
be32enc_vect(unsigned char *dst, const uint32_t *src, size_t len)
{
size_t i;
for (i = 0; i < len / 4; i++)
be32enc(dst + i * 4, src[i]);
}
/*
* Decode a big-endian length len vector of (unsigned char) into a length
* len/4 vector of (uint32_t). Assumes len is a multiple of 4.
*/
static void
be32dec_vect(uint32_t *dst, const unsigned char *src, size_t len)
{
size_t i;
for (i = 0; i < len / 4; i++)
dst[i] = be32dec(src + i * 4);
}
/* Elementary functions used by SHA256 */
#define Ch(x, y, z) ((x & (y ^ z)) ^ z)
#define Maj(x, y, z) ((x & (y | z)) | (y & z))
#define SHR(x, n) (x >> n)
#define ROTR(x, n) ((x >> n) | (x << (32 - n)))
#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
/* SHA256 round function */
#define RND(a, b, c, d, e, f, g, h, k) \
t0 = h + S1(e) + Ch(e, f, g) + k; \
t1 = S0(a) + Maj(a, b, c); \
d += t0; \
h = t0 + t1;
/* Adjusted round function for rotating state */
#define RNDr(S, W, i, k) \
RND(S[(64 - i) % 8], S[(65 - i) % 8], \
S[(66 - i) % 8], S[(67 - i) % 8], \
S[(68 - i) % 8], S[(69 - i) % 8], \
S[(70 - i) % 8], S[(71 - i) % 8], \
W[i] + k)
/*
* SHA256 block compression function. The 256-bit state is transformed via
* the 512-bit input block to produce a new state.
*/
static void
SHA256_Transform_Y(uint32_t * state, const unsigned char block[64])
{
uint32_t _ALIGN(128) W[64], S[8];
uint32_t t0, t1;
int i;
/* 1. Prepare message schedule W. */
be32dec_vect(W, block, 64);
for (i = 16; i < 64; i++)
W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
/* 2. Initialize working variables. */
memcpy(S, state, 32);
/* 3. Mix. */
RNDr(S, W, 0, 0x428a2f98);
RNDr(S, W, 1, 0x71374491);
RNDr(S, W, 2, 0xb5c0fbcf);
RNDr(S, W, 3, 0xe9b5dba5);
RNDr(S, W, 4, 0x3956c25b);
RNDr(S, W, 5, 0x59f111f1);
RNDr(S, W, 6, 0x923f82a4);
RNDr(S, W, 7, 0xab1c5ed5);
RNDr(S, W, 8, 0xd807aa98);
RNDr(S, W, 9, 0x12835b01);
RNDr(S, W, 10, 0x243185be);
RNDr(S, W, 11, 0x550c7dc3);
RNDr(S, W, 12, 0x72be5d74);
RNDr(S, W, 13, 0x80deb1fe);
RNDr(S, W, 14, 0x9bdc06a7);
RNDr(S, W, 15, 0xc19bf174);
RNDr(S, W, 16, 0xe49b69c1);
RNDr(S, W, 17, 0xefbe4786);
RNDr(S, W, 18, 0x0fc19dc6);
RNDr(S, W, 19, 0x240ca1cc);
RNDr(S, W, 20, 0x2de92c6f);
RNDr(S, W, 21, 0x4a7484aa);
RNDr(S, W, 22, 0x5cb0a9dc);
RNDr(S, W, 23, 0x76f988da);
RNDr(S, W, 24, 0x983e5152);
RNDr(S, W, 25, 0xa831c66d);
RNDr(S, W, 26, 0xb00327c8);
RNDr(S, W, 27, 0xbf597fc7);
RNDr(S, W, 28, 0xc6e00bf3);
RNDr(S, W, 29, 0xd5a79147);
RNDr(S, W, 30, 0x06ca6351);
RNDr(S, W, 31, 0x14292967);
RNDr(S, W, 32, 0x27b70a85);
RNDr(S, W, 33, 0x2e1b2138);
RNDr(S, W, 34, 0x4d2c6dfc);
RNDr(S, W, 35, 0x53380d13);
RNDr(S, W, 36, 0x650a7354);
RNDr(S, W, 37, 0x766a0abb);
RNDr(S, W, 38, 0x81c2c92e);
RNDr(S, W, 39, 0x92722c85);
RNDr(S, W, 40, 0xa2bfe8a1);
RNDr(S, W, 41, 0xa81a664b);
RNDr(S, W, 42, 0xc24b8b70);
RNDr(S, W, 43, 0xc76c51a3);
RNDr(S, W, 44, 0xd192e819);
RNDr(S, W, 45, 0xd6990624);
RNDr(S, W, 46, 0xf40e3585);
RNDr(S, W, 47, 0x106aa070);
RNDr(S, W, 48, 0x19a4c116);
RNDr(S, W, 49, 0x1e376c08);
RNDr(S, W, 50, 0x2748774c);
RNDr(S, W, 51, 0x34b0bcb5);
RNDr(S, W, 52, 0x391c0cb3);
RNDr(S, W, 53, 0x4ed8aa4a);
RNDr(S, W, 54, 0x5b9cca4f);
RNDr(S, W, 55, 0x682e6ff3);
RNDr(S, W, 56, 0x748f82ee);
RNDr(S, W, 57, 0x78a5636f);
RNDr(S, W, 58, 0x84c87814);
RNDr(S, W, 59, 0x8cc70208);
RNDr(S, W, 60, 0x90befffa);
RNDr(S, W, 61, 0xa4506ceb);
RNDr(S, W, 62, 0xbef9a3f7);
RNDr(S, W, 63, 0xc67178f2);
/* 4. Mix local working variables into global state */
for (i = 0; i < 8; i++)
state[i] += S[i];
#if 0
/* Clean the stack. */
memset(W, 0, 256);
memset(S, 0, 32);
t0 = t1 = 0;
#endif
}
static unsigned char PAD[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* Add padding and terminating bit-count. */
static void
SHA256_Pad_Y(SHA256_CTX_Y * ctx)
{
unsigned char len[8];
uint32_t r, plen;
/*
* Convert length to a vector of bytes -- we do this now rather
* than later because the length will change after we pad.
*/
be32enc_vect(len, ctx->count, 8);
/* Add 1--64 bytes so that the resulting length is 56 mod 64 */
r = (ctx->count[1] >> 3) & 0x3f;
plen = (r < 56) ? (56 - r) : (120 - r);
SHA256_Update_Y(ctx, PAD, (size_t)plen);
/* Add the terminating bit-count */
SHA256_Update_Y(ctx, len, 8);
}
/* SHA-256 initialization. Begins a SHA-256 operation. */
void
SHA256_Init_Y(SHA256_CTX_Y * ctx)
{
/* Zero bits processed so far */
ctx->count[0] = ctx->count[1] = 0;
/* Magic initialization constants */
ctx->state[0] = 0x6A09E667;
ctx->state[1] = 0xBB67AE85;
ctx->state[2] = 0x3C6EF372;
ctx->state[3] = 0xA54FF53A;
ctx->state[4] = 0x510E527F;
ctx->state[5] = 0x9B05688C;
ctx->state[6] = 0x1F83D9AB;
ctx->state[7] = 0x5BE0CD19;
}
/* Add bytes into the hash */
void
SHA256_Update_Y(SHA256_CTX_Y * ctx, const void *in, size_t len)
{
uint32_t bitlen[2];
uint32_t r;
const unsigned char *src = in;
/* Number of bytes left in the buffer from previous updates */
r = (ctx->count[1] >> 3) & 0x3f;
/* Convert the length into a number of bits */
bitlen[1] = ((uint32_t)len) << 3;
bitlen[0] = (uint32_t)(len >> 29);
/* Update number of bits */
if ((ctx->count[1] += bitlen[1]) < bitlen[1])
ctx->count[0]++;
ctx->count[0] += bitlen[0];
/* Handle the case where we don't need to perform any transforms */
if (len < 64 - r) {
memcpy(&ctx->buf[r], src, len);
return;
}
/* Finish the current block */
memcpy(&ctx->buf[r], src, 64 - r);
SHA256_Transform_Y(ctx->state, ctx->buf);
src += 64 - r;
len -= 64 - r;
/* Perform complete blocks */
while (len >= 64) {
SHA256_Transform_Y(ctx->state, src);
src += 64;
len -= 64;
}
/* Copy left over data into buffer */
memcpy(ctx->buf, src, len);
}
/*
* SHA-256 finalization. Pads the input data, exports the hash value,
* and clears the context state.
*/
void
SHA256_Final_Y(unsigned char digest[32], SHA256_CTX_Y * ctx)
{
/* Add padding */
SHA256_Pad_Y(ctx);
/* Write the hash */
be32enc_vect(digest, ctx->state, 32);
/* Clear the context state */
memset((void *)ctx, 0, sizeof(*ctx));
}
/* Initialize an HMAC-SHA256 operation with the given key. */
void
HMAC_SHA256_Init_Y(HMAC_SHA256_CTX_Y * ctx, const void * _K, size_t Klen)
{
unsigned char pad[64];
unsigned char khash[32];
const unsigned char * K = _K;
size_t i;
/* If Klen > 64, the key is really SHA256(K). */
if (Klen > 64) {
SHA256_Init(&ctx->ictx);
SHA256_Update(&ctx->ictx, K, Klen);
SHA256_Final(khash, &ctx->ictx);
K = khash;
Klen = 32;
}
/* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */
SHA256_Init(&ctx->ictx);
memset(pad, 0x36, 64);
for (i = 0; i < Klen; i++)
pad[i] ^= K[i];
SHA256_Update(&ctx->ictx, pad, 64);
/* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */
SHA256_Init(&ctx->octx);
memset(pad, 0x5c, 64);
for (i = 0; i < Klen; i++)
pad[i] ^= K[i];
SHA256_Update(&ctx->octx, pad, 64);
/* Clean the stack. */
//memset(khash, 0, 32);
}
/* Add bytes to the HMAC-SHA256 operation. */
void
HMAC_SHA256_Update_Y(HMAC_SHA256_CTX_Y * ctx, const void *in, size_t len)
{
/* Feed data to the inner SHA256 operation. */
SHA256_Update(&ctx->ictx, in, len);
}
/* Finish an HMAC-SHA256 operation. */
void
HMAC_SHA256_Final_Y(unsigned char digest[32], HMAC_SHA256_CTX_Y * ctx)
{
unsigned char ihash[32];
/* Finish the inner SHA256 operation. */
SHA256_Final(ihash, &ctx->ictx);
/* Feed the inner hash to the outer SHA256 operation. */
SHA256_Update(&ctx->octx, ihash, 32);
/* Finish the outer SHA256 operation. */
SHA256_Final(digest, &ctx->octx);
/* Clean the stack. */
//memset(ihash, 0, 32);
}
/**
* PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
* Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
* write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
*/
void
PBKDF2_SHA256_Y(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen)
{
HMAC_SHA256_CTX_Y PShctx, hctx;
uint8_t _ALIGN(128) T[32];
uint8_t _ALIGN(128) U[32];
uint8_t ivec[4];
size_t i, clen;
uint64_t j;
int k;
/* Compute HMAC state after processing P and S. */
HMAC_SHA256_Init_Y(&PShctx, passwd, passwdlen);
HMAC_SHA256_Update_Y(&PShctx, salt, saltlen);
/* Iterate through the blocks. */
for (i = 0; i * 32 < dkLen; i++) {
/* Generate INT(i + 1). */
be32enc(ivec, (uint32_t)(i + 1));
/* Compute U_1 = PRF(P, S || INT(i)). */
memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX_Y));
HMAC_SHA256_Update_Y(&hctx, ivec, 4);
HMAC_SHA256_Final_Y(U, &hctx);
/* T_i = U_1 ... */
memcpy(T, U, 32);
for (j = 2; j <= c; j++) {
/* Compute U_j. */
HMAC_SHA256_Init_Y(&hctx, passwd, passwdlen);
HMAC_SHA256_Update_Y(&hctx, U, 32);
HMAC_SHA256_Final_Y(U, &hctx);
/* ... xor U_j ... */
for (k = 0; k < 32; k++)
T[k] ^= U[k];
}
/* Copy as many bytes as necessary into buf. */
clen = dkLen - i * 32;
if (clen > 32)
clen = 32;
memcpy(&buf[i * 32], T, clen);
}
/* Clean PShctx, since we never called _Final on it. */
//memset(&PShctx, 0, sizeof(HMAC_SHA256_CTX_Y));
}

View File

@@ -1,124 +0,0 @@
/*-
* Copyright 2007-2009 Colin Percival
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file was originally written by Colin Percival as part of the Tarsnap
* online backup system.
*/
#ifndef _SYSENDIAN_H_
#define _SYSENDIAN_H_
/* If we don't have be64enc, the <sys/endian.h> we have isn't usable. */
#if !HAVE_DECL_BE64ENC
#undef HAVE_SYS_ENDIAN_H
#endif
#ifdef HAVE_SYS_ENDIAN_H
#include <sys/endian.h>
#else
#include <stdint.h>
static __inline uint64_t
be64dec(const void *pp)
{
const uint8_t *p = (uint8_t const *)pp;
return ((uint64_t)(p[7]) + ((uint64_t)(p[6]) << 8) +
((uint64_t)(p[5]) << 16) + ((uint64_t)(p[4]) << 24) +
((uint64_t)(p[3]) << 32) + ((uint64_t)(p[2]) << 40) +
((uint64_t)(p[1]) << 48) + ((uint64_t)(p[0]) << 56));
}
static __inline void
be64enc(void *pp, uint64_t x)
{
uint8_t * p = (uint8_t *)pp;
p[7] = x & 0xff;
p[6] = (x >> 8) & 0xff;
p[5] = (x >> 16) & 0xff;
p[4] = (x >> 24) & 0xff;
p[3] = (x >> 32) & 0xff;
p[2] = (x >> 40) & 0xff;
p[1] = (x >> 48) & 0xff;
p[0] = (x >> 56) & 0xff;
}
static __inline uint64_t
le64dec(const void *pp)
{
const uint8_t *p = (uint8_t const *)pp;
return ((uint64_t)(p[0]) + ((uint64_t)(p[1]) << 8) +
((uint64_t)(p[2]) << 16) + ((uint64_t)(p[3]) << 24) +
((uint64_t)(p[4]) << 32) + ((uint64_t)(p[5]) << 40) +
((uint64_t)(p[6]) << 48) + ((uint64_t)(p[7]) << 56));
}
static __inline void
le64enc(void *pp, uint64_t x)
{
uint8_t * p = (uint8_t *)pp;
p[0] = x & 0xff;
p[1] = (x >> 8) & 0xff;
p[2] = (x >> 16) & 0xff;
p[3] = (x >> 24) & 0xff;
p[4] = (x >> 32) & 0xff;
p[5] = (x >> 40) & 0xff;
p[6] = (x >> 48) & 0xff;
p[7] = (x >> 56) & 0xff;
}
static __inline uint32_t
be32dec(const void *pp)
{
const uint8_t *p = (uint8_t const *)pp;
return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) +
((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24));
}
static __inline void
be32enc(void *pp, uint32_t x)
{
uint8_t * p = (uint8_t *)pp;
p[3] = x & 0xff;
p[2] = (x >> 8) & 0xff;
p[1] = (x >> 16) & 0xff;
p[0] = (x >> 24) & 0xff;
}
#endif /* !HAVE_SYS_ENDIAN_H */
#endif /* !_SYSENDIAN_H_ */

View File

@@ -48,9 +48,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "sha256_Y.h"
#include "sysendian.h"
#include "algo/sha/hmac-sha256-hash.h"
#include "yescrypt.h"
#include "yescrypt-platform.h"
@@ -1312,7 +1310,7 @@ yescrypt_kdf(const yescrypt_shared_t * shared, yescrypt_local_t * local,
}
/* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
PBKDF2_SHA256_Y(passwd, passwdlen, salt, saltlen, 1, B, B_size);
PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, B_size);
if (t || flags)
memcpy(sha256, B, sizeof(sha256));
@@ -1342,7 +1340,7 @@ yescrypt_kdf(const yescrypt_shared_t * shared, yescrypt_local_t * local,
}
/* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
PBKDF2_SHA256_Y(passwd, passwdlen, B, B_size, 1, buf, buflen);
PBKDF2_SHA256(passwd, passwdlen, B, B_size, 1, buf, buflen);
/*
* Except when computing classic scrypt, allow all computation so far
@@ -1354,14 +1352,14 @@ yescrypt_kdf(const yescrypt_shared_t * shared, yescrypt_local_t * local,
if ((t || flags) && buflen == sizeof(sha256)) {
/* Compute ClientKey */
{
HMAC_SHA256_CTX_Y ctx;
HMAC_SHA256_Init_Y(&ctx, buf, buflen);
HMAC_SHA256_CTX ctx;
HMAC_SHA256_Init(&ctx, buf, buflen);
if ( yescrypt_client_key )
HMAC_SHA256_Update_Y( &ctx, (uint8_t*)yescrypt_client_key,
HMAC_SHA256_Update( &ctx, (uint8_t*)yescrypt_client_key,
yescrypt_client_key_len );
else
HMAC_SHA256_Update_Y( &ctx, salt, saltlen );
HMAC_SHA256_Final_Y(sha256, &ctx);
HMAC_SHA256_Update( &ctx, salt, saltlen );
HMAC_SHA256_Final(sha256, &ctx);
}
/* Compute StoredKey */
{

View File

@@ -25,7 +25,7 @@
#include "compat.h"
#include "yescrypt.h"
#include "sha256_Y.h"
#include "algo/sha/hmac-sha256-hash.h"
#include "algo-gate-api.h"
#define BYTES2CHARS(bytes) \
@@ -389,30 +389,25 @@ int scanhash_yescrypt( struct work *work, uint32_t max_nonce,
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];
const uint32_t last_nonce = max_nonce;
uint32_t n = first_nonce;
int thr_id = mythr->id; // thr_id arg is deprecated
for (int k = 0; k < 19; k++)
be32enc(&endiandata[k], pdata[k]);
for ( int k = 0; k < 19; k++ )
be32enc( &endiandata[k], pdata[k] );
endiandata[19] = n;
do {
be32enc(&endiandata[19], n);
yescrypt_hash((char*) endiandata, (char*) vhash, 80);
if (vhash[7] <= Htarg && fulltest(vhash, ptarget )
&& !opt_benchmark )
if unlikely( valid_hash( vhash, ptarget ) && !opt_benchmark )
{
pdata[19] = n;
be32enc( pdata+19, n );
submit_solution( work, vhash, mythr );
}
n++;
} while (n < max_nonce && !work_restart[thr_id].restart);
*hashes_done = n - first_nonce + 1;
endiandata[19] = ++n;
} while ( n < last_nonce && !work_restart[thr_id].restart );
*hashes_done = n - first_nonce;
pdata[19] = n;
return 0;
}

View File

@@ -30,9 +30,8 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "simd-utils.h"
#include <algo/yespower/crypto/sph_types.h>
#include <algo/yespower/utils/sysendian.h>
#include "blake2b-yp.h"
// Cyclic right rotation.
@@ -272,7 +271,7 @@ void pbkdf2_blake2b_yp(const uint8_t * passwd, size_t passwdlen, const uint8_t *
{
hmac_yp_ctx PShctx, hctx;
size_t i;
uint8_t ivec[4];
uint32_t ivec;
uint8_t U[32];
uint8_t T[32];
uint64_t j;
@@ -286,11 +285,11 @@ void pbkdf2_blake2b_yp(const uint8_t * passwd, size_t passwdlen, const uint8_t *
/* Iterate through the blocks. */
for (i = 0; i * 32 < dkLen; i++) {
/* Generate INT(i + 1). */
be32enc(ivec, (uint32_t)(i + 1));
ivec = bswap_32( i+1 );
/* Compute U_1 = PRF(P, S || INT(i)). */
memcpy(&hctx, &PShctx, sizeof(hmac_yp_ctx));
hmac_blake2b_yp_update(&hctx, ivec, 4);
hmac_blake2b_yp_update(&hctx, &ivec, 4);
hmac_blake2b_yp_final(&hctx, U);
/* T_i = U_1 ... */

View File

@@ -1 +0,0 @@
#define insecure_memzero(buf, len) /* empty */

View File

@@ -1,94 +0,0 @@
/*-
* Copyright 2007-2014 Colin Percival
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _SYSENDIAN_H_
#define _SYSENDIAN_H_
#include <stdint.h>
/* Avoid namespace collisions with BSD <sys/endian.h>. */
#define be32dec libcperciva_be32dec
#define be32enc libcperciva_be32enc
#define be64enc libcperciva_be64enc
#define le32dec libcperciva_le32dec
#define le32enc libcperciva_le32enc
static inline uint32_t
be32dec(const void * pp)
{
const uint8_t * p = (uint8_t const *)pp;
return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) +
((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24));
}
static inline void
be32enc(void * pp, uint32_t x)
{
uint8_t * p = (uint8_t *)pp;
p[3] = x & 0xff;
p[2] = (x >> 8) & 0xff;
p[1] = (x >> 16) & 0xff;
p[0] = (x >> 24) & 0xff;
}
static inline void
be64enc(void * pp, uint64_t x)
{
uint8_t * p = (uint8_t *)pp;
p[7] = x & 0xff;
p[6] = (x >> 8) & 0xff;
p[5] = (x >> 16) & 0xff;
p[4] = (x >> 24) & 0xff;
p[3] = (x >> 32) & 0xff;
p[2] = (x >> 40) & 0xff;
p[1] = (x >> 48) & 0xff;
p[0] = (x >> 56) & 0xff;
}
static inline uint32_t
le32dec(const void * pp)
{
const uint8_t * p = (uint8_t const *)pp;
return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) +
((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24));
}
static inline void
le32enc(void * pp, uint32_t x)
{
uint8_t * p = (uint8_t *)pp;
p[0] = x & 0xff;
p[1] = (x >> 8) & 0xff;
p[2] = (x >> 16) & 0xff;
p[3] = (x >> 24) & 0xff;
}
#endif /* !_SYSENDIAN_H_ */

View File

@@ -1 +0,0 @@
#define insecure_memzero(buf, len) /* empty */

View File

@@ -1,94 +0,0 @@
/*-
* Copyright 2007-2014 Colin Percival
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _SYSENDIAN_H_
#define _SYSENDIAN_H_
#include <stdint.h>
/* Avoid namespace collisions with BSD <sys/endian.h>. */
#define be32dec libcperciva_be32dec
#define be32enc libcperciva_be32enc
#define be64enc libcperciva_be64enc
#define le32dec libcperciva_le32dec
#define le32enc libcperciva_le32enc
static inline uint32_t
be32dec(const void * pp)
{
const uint8_t * p = (uint8_t const *)pp;
return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) +
((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24));
}
static inline void
be32enc(void * pp, uint32_t x)
{
uint8_t * p = (uint8_t *)pp;
p[3] = x & 0xff;
p[2] = (x >> 8) & 0xff;
p[1] = (x >> 16) & 0xff;
p[0] = (x >> 24) & 0xff;
}
static inline void
be64enc(void * pp, uint64_t x)
{
uint8_t * p = (uint8_t *)pp;
p[7] = x & 0xff;
p[6] = (x >> 8) & 0xff;
p[5] = (x >> 16) & 0xff;
p[4] = (x >> 24) & 0xff;
p[3] = (x >> 32) & 0xff;
p[2] = (x >> 40) & 0xff;
p[1] = (x >> 48) & 0xff;
p[0] = (x >> 56) & 0xff;
}
static inline uint32_t
le32dec(const void * pp)
{
const uint8_t * p = (uint8_t const *)pp;
return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) +
((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24));
}
static inline void
le32enc(void * pp, uint32_t x)
{
uint8_t * p = (uint8_t *)pp;
p[0] = x & 0xff;
p[1] = (x >> 8) & 0xff;
p[2] = (x >> 16) & 0xff;
p[3] = (x >> 24) & 0xff;
}
#endif /* !_SYSENDIAN_H_ */

View File

@@ -0,0 +1,80 @@
/*-
* Copyright 2013-2018 Alexander Peslyak
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "cpuminer-config.h"
#include "miner.h"
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "yescrypt-r8g.h"
int scanhash_yespower_r8g( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr )
{
uint64_t hash[4] __attribute__((aligned(64)));
uint32_t endiandata[32];
uint32_t *pdata = work->data;
const uint64_t *ptarget = (const uint64_t*)work->target;
uint32_t n = pdata[19];
const uint32_t first_nonce = pdata[19];
const uint32_t last_nonce = max_nonce;
const int thr_id = mythr->id;
yespower_params_t params =
{
.version = YESPOWER_0_5,
.N = 2048,
.r = 8,
.pers = (const uint8_t *)endiandata,
.perslen = work->sapling ? 112 : 80,
};
//we need bigendian data...
for ( int i = 0 ; i < 32; i++ )
be32enc( &endiandata[ i], pdata[ i ]);
endiandata[19] = n;
do {
yespower_tls( (unsigned char *)endiandata, params.perslen,
&params, (yespower_binary_t*)hash );
if unlikely( valid_hash( hash, ptarget ) && !opt_benchmark )
{
be32enc( pdata+19, n );
submit_solution( work, hash, mythr );
}
endiandata[19] = ++n;
} while (n < last_nonce && !work_restart[thr_id].restart);
*hashes_done = n - first_nonce + 1;
pdata[19] = n;
return 0;
}
bool register_yescryptr8g_algo( algo_gate_t* gate )
{
gate->optimizations = SSE2_OPT | SHA_OPT;
gate->scanhash = (void*)&scanhash_yespower_r8g;
gate->hash = (void*)&yespower_tls;
opt_target_factor = 65536.0;
return true;
};

View File

@@ -1,5 +1,6 @@
/*-
* Copyright 2005,2007,2009 Colin Percival
* Copyright 2009 Colin Percival
* Copyright 2013-2018 Alexander Peslyak
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -23,47 +24,26 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: src/lib/libmd/sha256_Y.h,v 1.2 2006/01/17 15:35:56 phk Exp $
* This file was originally written by Colin Percival as part of the Tarsnap
* online backup system.
*/
#ifndef _YESPOWERR8G_H_
#define _YESPOWERR8G_H_
#ifndef _SHA256_H_
#define _SHA256_H_
#include <sys/types.h>
#include <stdint.h>
#include <openssl/sha.h>
#include <stdlib.h> /* for size_t */
#include "algo-gate-api.h"
#include "algo/yespower/yespower.h"
typedef struct SHA256Context {
uint32_t state[8];
uint32_t count[2];
unsigned char buf[64];
} SHA256_CTX_Y;
#ifdef __cplusplus
extern "C" {
#endif
/*
typedef struct HMAC_SHA256Context {
SHA256_CTX_Y ictx;
SHA256_CTX_Y octx;
} HMAC_SHA256_CTX_Y;
*/
extern int yespowerr8g_tls(const uint8_t *src, size_t srclen,
const yespower_params_t *params, yespower_binary_t *dst);
typedef struct HMAC_SHA256Context {
SHA256_CTX ictx;
SHA256_CTX octx;
} HMAC_SHA256_CTX_Y;
#ifdef __cplusplus
}
#endif
void SHA256_Init_Y(SHA256_CTX_Y *);
void SHA256_Update_Y(SHA256_CTX_Y *, const void *, size_t);
void SHA256_Final_Y(unsigned char [32], SHA256_CTX_Y *);
void HMAC_SHA256_Init_Y(HMAC_SHA256_CTX_Y *, const void *, size_t);
void HMAC_SHA256_Update_Y(HMAC_SHA256_CTX_Y *, const void *, size_t);
void HMAC_SHA256_Final_Y(unsigned char [32], HMAC_SHA256_CTX_Y *);
/**
* PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
* Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
* write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
*/
void PBKDF2_SHA256_Y(const uint8_t *, size_t, const uint8_t *, size_t,
uint64_t, uint8_t *, size_t);
#endif /* !_SHA256_H_ */
#endif /* !_YESPOWERR8G_H_ */

View File

@@ -95,11 +95,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "utils/insecure_memzero.h"
#include "utils/sysendian.h"
#include "crypto/blake2b-yp.h"
#include "yespower.h"
#ifdef __unix__
@@ -952,7 +948,7 @@ static void smix1(uint8_t *B, size_t r, uint32_t N,
salsa20_blk_t *dst = &X[i];
size_t k;
for (k = 0; k < 16; k++)
tmp->w[k] = le32dec(&src->w[k]);
tmp->w[k] = src->w[k];
salsa20_simd_shuffle(tmp, dst);
}
@@ -999,7 +995,7 @@ static void smix1(uint8_t *B, size_t r, uint32_t N,
salsa20_blk_t *dst = (salsa20_blk_t *)&B[i * 64];
size_t k;
for (k = 0; k < 16; k++)
le32enc(&tmp->w[k], src->w[k]);
tmp->w[k] = src->w[k];
salsa20_simd_unshuffle(tmp, dst);
}
}
@@ -1025,7 +1021,7 @@ static void smix2(uint8_t *B, size_t r, uint32_t N, uint32_t Nloop,
salsa20_blk_t *dst = &X[i];
size_t k;
for (k = 0; k < 16; k++)
tmp->w[k] = le32dec(&src->w[k]);
tmp->w[k] = src->w[k];
salsa20_simd_shuffle(tmp, dst);
}
@@ -1055,7 +1051,7 @@ static void smix2(uint8_t *B, size_t r, uint32_t N, uint32_t Nloop,
salsa20_blk_t *dst = (salsa20_blk_t *)&B[i * 64];
size_t k;
for (k = 0; k < 16; k++)
le32enc(&tmp->w[k], src->w[k]);
tmp->w[k] = src->w[k];
salsa20_simd_unshuffle(tmp, dst);
}
}

View File

@@ -32,6 +32,8 @@
static yespower_params_t yespower_params;
// YESPOWER
void yespower_hash( const char *input, char *output, uint32_t len )
{
yespower_tls( input, len, &yespower_params, (yespower_binary_t*)output );
@@ -44,32 +46,29 @@ int scanhash_yespower( struct work *work, uint32_t max_nonce,
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];
const uint32_t last_nonce = max_nonce;
uint32_t n = first_nonce;
int thr_id = mythr->id; // thr_id arg is deprecated
const int thr_id = mythr->id;
for (int k = 0; k < 19; k++)
be32enc(&endiandata[k], pdata[k]);
for ( int k = 0; k < 19; k++ )
be32enc( &endiandata[k], pdata[k] );
endiandata[19] = n;
do {
be32enc(&endiandata[19], n);
yespower_hash((char*) endiandata, (char*) vhash, 80);
if ( vhash[7] <= Htarg && fulltest( vhash, ptarget )
&& !opt_benchmark )
yespower_hash( (char*)endiandata, (char*)vhash, 80 );
if unlikely( valid_hash( vhash, ptarget ) && !opt_benchmark )
{
pdata[19] = n;
be32enc( pdata+19, n );
submit_solution( work, vhash, mythr );
}
n++;
} while (n < max_nonce && !work_restart[thr_id].restart);
*hashes_done = n - first_nonce + 1;
endiandata[19] = ++n;
} while ( n < last_nonce && !work_restart[thr_id].restart );
*hashes_done = n - first_nonce;
pdata[19] = n;
return 0;
}
// YESPOWER-B2B
void yespower_b2b_hash( const char *input, char *output, uint32_t len )
{
@@ -83,29 +82,25 @@ int scanhash_yespower_b2b( struct work *work, uint32_t max_nonce,
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 n = first_nonce;
int thr_id = mythr->id; // thr_id arg is deprecated
const uint32_t last_nonce = max_nonce;
const int thr_id = mythr->id; // thr_id arg is deprecated
for (int k = 0; k < 19; k++)
be32enc(&endiandata[k], pdata[k]);
for ( int k = 0; k < 19; k++ )
be32enc( &endiandata[k], pdata[k] );
endiandata[19] = n;
do {
be32enc(&endiandata[19], n);
yespower_b2b_hash((char*) endiandata, (char*) vhash, 80);
if ( vhash[7] < Htarg && fulltest( vhash, ptarget )
&& !opt_benchmark )
yespower_b2b_hash( (char*) endiandata, (char*) vhash, 80 );
if unlikely( valid_hash( vhash, ptarget ) && !opt_benchmark )
{
pdata[19] = n;
be32enc( pdata+19, n );
submit_solution( work, vhash, mythr );
}
n++;
} while (n < max_nonce && !work_restart[thr_id].restart);
*hashes_done = n - first_nonce + 1;
endiandata[19] = ++n;
} while ( n < last_nonce && !work_restart[thr_id].restart );
*hashes_done = n - first_nonce;
pdata[19] = n;
return 0;
}
@@ -135,7 +130,7 @@ bool register_yespower_algo( algo_gate_t* gate )
if ( yespower_params.pers )
applog( LOG_NOTICE,"Key= \"%s\"\n", yespower_params.pers );
gate->optimizations = SSE2_OPT;
gate->optimizations = SSE2_OPT | SHA_OPT;
gate->scanhash = (void*)&scanhash_yespower;
gate->hash = (void*)&yespower_hash;
opt_target_factor = 65536.0;
@@ -149,14 +144,14 @@ bool register_yespowerr16_algo( algo_gate_t* gate )
yespower_params.r = 16;
yespower_params.pers = NULL;
yespower_params.perslen = 0;
gate->optimizations = SSE2_OPT;
gate->optimizations = SSE2_OPT | SHA_OPT;
gate->scanhash = (void*)&scanhash_yespower;
gate->hash = (void*)&yespower_hash;
opt_target_factor = 65536.0;
return true;
};
/* not used
bool register_yescrypt_05_algo( algo_gate_t* gate )
{
gate->optimizations = SSE2_OPT | SHA_OPT;
@@ -208,6 +203,9 @@ bool register_yescryptr32_05_algo( algo_gate_t* gate )
opt_target_factor = 65536.0;
return true;
}
*/
// POWER2B
bool register_power2b_algo( algo_gate_t* gate )
{
@@ -223,7 +221,7 @@ bool register_power2b_algo( algo_gate_t* gate )
applog( LOG_NOTICE,"Key= \"%s\"", yespower_params.pers );
applog( LOG_NOTICE,"Key length= %d\n", yespower_params.perslen );
gate->optimizations = SSE2_OPT;
gate->optimizations = SSE2_OPT | SHA_OPT;
gate->scanhash = (void*)&scanhash_yespower_b2b;
gate->hash = (void*)&yespower_b2b_hash;
opt_target_factor = 65536.0;

View File

@@ -95,13 +95,8 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "insecure_memzero.h"
#include "sha256_p.h"
#include "sysendian.h"
#include "algo/sha/hmac-sha256-hash.h"
#include "yespower.h"
#include "yespower-platform.c"
#if __STDC_VERSION__ >= 199901L
@@ -861,7 +856,7 @@ static void smix1(uint8_t *B, size_t r, uint32_t N,
salsa20_blk_t *dst = &X[i];
size_t k;
for (k = 0; k < 16; k++)
tmp->w[k] = le32dec(&src->w[k]);
tmp->w[k] = src->w[k];
salsa20_simd_shuffle(tmp, dst);
}
@@ -908,7 +903,7 @@ static void smix1(uint8_t *B, size_t r, uint32_t N,
salsa20_blk_t *dst = (salsa20_blk_t *)&B[i * 64];
size_t k;
for (k = 0; k < 16; k++)
le32enc(&tmp->w[k], src->w[k]);
tmp->w[k] = src->w[k];
salsa20_simd_unshuffle(tmp, dst);
}
}
@@ -934,7 +929,7 @@ static void smix2(uint8_t *B, size_t r, uint32_t N, uint32_t Nloop,
salsa20_blk_t *dst = &X[i];
size_t k;
for (k = 0; k < 16; k++)
tmp->w[k] = le32dec(&src->w[k]);
tmp->w[k] = src->w[k];
salsa20_simd_shuffle(tmp, dst);
}
@@ -966,7 +961,7 @@ static void smix2(uint8_t *B, size_t r, uint32_t N, uint32_t Nloop,
salsa20_blk_t *dst = (salsa20_blk_t *)&B[i * 64];
size_t k;
for (k = 0; k < 16; k++)
le32enc(&tmp->w[k], src->w[k]);
tmp->w[k] = src->w[k];
salsa20_simd_unshuffle(tmp, dst);
}
}

View File

@@ -51,8 +51,8 @@
#include <stdlib.h>
#include <string.h>
#include "sha256_p.h"
#include "sysendian.h"
#include "algo/sha/hmac-sha256-hash.h"
//#include "sysendian.h"
#include "yespower.h"
@@ -346,7 +346,7 @@ static void smix1(uint32_t *B, size_t r, uint32_t N,
/* 1: X <-- B */
for (k = 0; k < 2 * r; k++)
for (i = 0; i < 16; i++)
X[k * 16 + i] = le32dec(&B[k * 16 + (i * 5 % 16)]);
X[k * 16 + i] = B[k * 16 + (i * 5 % 16)];
if (ctx->version != YESPOWER_0_5) {
for (k = 1; k < r; k++) {
@@ -378,7 +378,7 @@ static void smix1(uint32_t *B, size_t r, uint32_t N,
/* B' <-- X */
for (k = 0; k < 2 * r; k++)
for (i = 0; i < 16; i++)
le32enc(&B[k * 16 + (i * 5 % 16)], X[k * 16 + i]);
B[k * 16 + (i * 5 % 16)] = X[k * 16 + i];
}
/**
@@ -398,7 +398,7 @@ static void smix2(uint32_t *B, size_t r, uint32_t N, uint32_t Nloop,
/* X <-- B */
for (k = 0; k < 2 * r; k++)
for (i = 0; i < 16; i++)
X[k * 16 + i] = le32dec(&B[k * 16 + (i * 5 % 16)]);
X[k * 16 + i] = B[k * 16 + (i * 5 % 16)];
/* 6: for i = 0 to N - 1 do */
for (i = 0; i < Nloop; i++) {
@@ -418,7 +418,7 @@ static void smix2(uint32_t *B, size_t r, uint32_t N, uint32_t Nloop,
/* 10: B' <-- X */
for (k = 0; k < 2 * r; k++)
for (i = 0; i < 16; i++)
le32enc(&B[k * 16 + (i * 5 % 16)], X[k * 16 + i]);
B[k * 16 + (i * 5 % 16)] = X[k * 16 + i];
}
/**

View File

@@ -71,7 +71,7 @@ typedef struct {
*/
typedef struct {
unsigned char uc[32];
} yespower_binary_t;
} yespower_binary_t __attribute__ ((aligned (64)));
/**
* yespower_init_local(local):

20
configure vendored
View File

@@ -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.11.5.
# Generated by GNU Autoconf 2.69 for cpuminer-opt 3.11.7.
#
#
# 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.11.5'
PACKAGE_STRING='cpuminer-opt 3.11.5'
PACKAGE_VERSION='3.11.7'
PACKAGE_STRING='cpuminer-opt 3.11.7'
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.11.5 to adapt to many kinds of systems.
\`configure' configures cpuminer-opt 3.11.7 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.11.5:";;
short | recursive ) echo "Configuration of cpuminer-opt 3.11.7:";;
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.11.5
cpuminer-opt configure 3.11.7
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.11.5, which was
It was created by cpuminer-opt $as_me 3.11.7, 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.11.5'
VERSION='3.11.7'
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.11.5, which was
This file was extended by cpuminer-opt $as_me 3.11.7, 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.11.5
cpuminer-opt config.status 3.11.7
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"

View File

@@ -1,4 +1,4 @@
AC_INIT([cpuminer-opt], [3.11.5])
AC_INIT([cpuminer-opt], [3.11.7])
AC_PREREQ([2.59c])
AC_CANONICAL_SYSTEM

View File

@@ -506,6 +506,7 @@ static bool gbt_work_decode( const json_t *val, struct work *work )
uint32_t version, curtime, bits;
uint32_t prevhash[8];
uint32_t target[8];
unsigned char final_sapling_hash[32];
int cbtx_size;
uchar *cbtx = NULL;
int tx_count, tx_size;
@@ -550,12 +551,13 @@ static bool gbt_work_decode( const json_t *val, struct work *work )
goto out;
}
version = (uint32_t) json_integer_value( tmp );
if ( (version & 0xffU) > BLOCK_VERSION_CURRENT )
if ( version == 5 )
work->sapling = true;
else if ( version > 4 )
// if ( (version & 0xffU) > BLOCK_VERSION_CURRENT )
{
if ( version_reduce )
{
version = ( version & ~0xffU ) | BLOCK_VERSION_CURRENT;
}
else if ( have_gbt && allow_getwork && !version_force )
{
applog( LOG_DEBUG, "Switching to getwork, gbt version %d", version );
@@ -590,6 +592,16 @@ static bool gbt_work_decode( const json_t *val, struct work *work )
goto out;
}
if ( work->sapling )
{
if ( unlikely( !jobj_binary( val, "finalsaplingroothash",
final_sapling_hash, sizeof(final_sapling_hash) ) ) )
{
applog( LOG_ERR, "JSON invalid finalsaplingroothash" );
goto out;
}
}
/* find count and size of transactions */
txa = json_object_get(val, "transactions" );
if ( !txa || !json_is_array( txa ) )
@@ -772,7 +784,8 @@ static bool gbt_work_decode( const json_t *val, struct work *work )
/* assemble block header */
algo_gate.build_block_header( work, swab32( version ),
(uint32_t*) prevhash, (uint32_t*) merkle_tree,
swab32( curtime ), le32dec( &bits ) );
swab32( curtime ), le32dec( &bits ),
final_sapling_hash );
if ( unlikely( !jobj_binary(val, "target", target, sizeof(target)) ) )
{
@@ -820,20 +833,15 @@ out:
// returns the unit prefix and the hashrate appropriately scaled.
void scale_hash_for_display ( double* hashrate, char* prefix )
{
if ( *hashrate < 1e4 ) // 0 H/s to 9999 h/s
*prefix = 0;
else if ( *hashrate < 1e7 ) // 10 kH/s to 9999 kh/s
{ *prefix = 'k'; *hashrate /= 1e3; }
else if ( *hashrate < 1e10 ) // 10 Mh/s to 9999 Mh/s
{ *prefix = 'M'; *hashrate /= 1e6; }
else if ( *hashrate < 1e13 ) // 10 Gh/s to 9999 Gh/s
{ *prefix = 'G'; *hashrate /= 1e9; }
else if ( *hashrate < 1e16 ) // 10 Th/s to 9999 Th/s
{ *prefix = 'T'; *hashrate /= 1e12; }
else if ( *hashrate < 1e19 ) // 10 Ph/s to 9999 Ph
{ *prefix = 'P'; *hashrate /= 1e15; }
else // 10 Eh/s and higher
{ *prefix = 'E'; *hashrate /= 1e18; }
if ( *hashrate < 1e4 ) *prefix = 0;
else if ( *hashrate < 1e7 ) { *prefix = 'k'; *hashrate /= 1e3; }
else if ( *hashrate < 1e10 ) { *prefix = 'M'; *hashrate /= 1e6; }
else if ( *hashrate < 1e13 ) { *prefix = 'G'; *hashrate /= 1e9; }
else if ( *hashrate < 1e16 ) { *prefix = 'T'; *hashrate /= 1e12; }
else if ( *hashrate < 1e19 ) { *prefix = 'P'; *hashrate /= 1e15; }
else if ( *hashrate < 1e22 ) { *prefix = 'E'; *hashrate /= 1e18; }
else if ( *hashrate < 1e25 ) { *prefix = 'Z'; *hashrate /= 1e21; }
else { *prefix = 'Y'; *hashrate /= 1e24; }
}
static inline void sprintf_et( char *str, int seconds )
@@ -842,10 +850,13 @@ static inline void sprintf_et( char *str, int seconds )
unsigned int min = seconds / 60;
unsigned int sec = seconds % 60;
unsigned int hrs = min / 60;
if ( hrs )
if ( unlikely( hrs ) )
{
unsigned int years = hrs / (24*365);
unsigned int days = hrs / 24;
if ( days ) //0d00h
if ( years )
sprintf( str, "%uy%ud", years, years % 365 );
else if ( days ) //0d00h
sprintf( str, "%ud%02uh", days, hrs % 24 );
else // 0h00m
sprintf( str, "%uh%02um", hrs, min % 60 );
@@ -867,6 +878,7 @@ const double diff_to_hash = 4294967296.;
static struct timeval session_start;
static struct timeval five_min_start;
static uint64_t session_first_block = 0;
static double latency_sum = 0.;
static uint64_t submit_sum = 0;
static uint64_t accept_sum = 0;
@@ -874,7 +886,7 @@ static uint64_t stale_sum = 0;
static uint64_t reject_sum = 0;
static double norm_diff_sum = 0.;
static uint32_t last_block_height = 0;
static bool new_job = false;
//static bool new_job = false;
static double last_targetdiff = 0.;
static double ref_rate_hi = 0.;
static double ref_rate_lo = 1e100;
@@ -1019,15 +1031,18 @@ static int share_result( int result, struct work *null_work,
int latency = 0;
struct share_stats_t my_stats = {0};
struct timeval ack_time, latency_tv, et;
const char *sres = NULL;
char job_id[48];
char ares[48];
char sres[48];
char rres[48];
char bres[48];
// char job_id[48];
bool solved = false;
bool stale = false;
char *acol = NULL, *bcol = NULL, *scol = NULL, *rcol = NULL;
// Mutex while we grab a snapshot of the stats.
pthread_mutex_lock( &stats_lock );
if ( share_stats[ s_get_ptr ].submit_time.tv_sec )
if ( likely( share_stats[ s_get_ptr ].submit_time.tv_sec ) )
{
memcpy( &my_stats, &share_stats[ s_get_ptr], sizeof my_stats );
memset( &share_stats[ s_get_ptr ], 0, sizeof my_stats );
@@ -1077,7 +1092,6 @@ static int share_result( int result, struct work *null_work,
rejected_share_count++;
}
// update global counters for summary report
pthread_mutex_lock( &stats_lock );
@@ -1102,8 +1116,39 @@ static int share_result( int result, struct work *null_work,
pthread_mutex_unlock( &stats_lock );
sprintf( job_id, "job %s", my_stats.job_id );
bcol = acol = scol = rcol = "\0";
if ( likely( result ) )
{
if ( unlikely( solved ) )
{
sprintf( bres, "BLOCK SOLVED %d", solved_block_count );
sprintf( ares, "A%d", accepted_share_count );
}
else
{
sprintf( bres, "B%d", solved_block_count );
sprintf( ares, "Accepted %d", accepted_share_count );
}
sprintf( sres, "S%d", stale_share_count );
sprintf( rres, "R%d", rejected_share_count );
}
else
{
sprintf( ares, "A%d", accepted_share_count );
sprintf( bres, "B%d", solved_block_count );
if ( stale )
{
sprintf( sres, "Stale job %d", stale_share_count );
sprintf( rres, "R%d", rejected_share_count );
}
else
{
sprintf( sres, "S%d", stale_share_count );
sprintf( rres, "Rejected %d" , rejected_share_count );
}
}
bcol = acol = scol = rcol = CL_WHT;
if ( use_colors )
{
@@ -1111,56 +1156,30 @@ static int share_result( int result, struct work *null_work,
{
if ( unlikely( solved ) )
{
sres = CL_MAG "BLOCK SOLVED" CL_WHT;
bcol = CL_MAG;
acol = CL_GRN;
}
else
sres = CL_GRN "Accepted" CL_WHT;
acol = CL_GRN;
}
/*
if ( unlikely( solved ) )
{
sres = CL_MAG "BLOCK SOLVED" CL_WHT;
bcol = CL_MAG;
acol = CL_GRN;
}
else if ( likely( result ) )
{
sres = CL_GRN "Accepted" CL_WHT;
acol = CL_GRN;
}
*/
else if ( stale )
{
sres = CL_YL2 "Stale share" CL_WHT;
scol = CL_YL2;
sprintf( job_id, "%sjob %s%s", CL_YL2, my_stats.job_id, CL_N );
}
else
{
sres = CL_RED "Rejected" CL_WHT;
rcol = CL_RED;
}
}
else // monochrome
sres = solved ? "BLOCK SOLVED"
: ( result ? "Accepted"
: stale ? "Stale share" : "Rejected" );
applog( LOG_NOTICE, "%d: %s, %.3f secs (%dms), %sA:%d" CL_WHT " %sS:%d" CL_WHT " %sR:%d" CL_WHT " %sB:%d" CL_WHT,
my_stats.share_count, sres, share_time, latency, acol,
accepted_share_count, scol, stale_share_count, rcol,
rejected_share_count, bcol, solved_block_count );
applog( LOG_NOTICE, "%d %s%s %s%s %s%s %s%s" CL_WHT ", %.3f sec (%dms)",
my_stats.share_count, acol, ares, scol, sres, rcol, rres, bcol,
bres, share_time, latency );
if ( have_stratum && !opt_quiet )
applog2( LOG_INFO, "Share diff %.3g (%5f%%), block %d, %s",
my_stats.share_diff, share_ratio, stratum.block_height,
job_id );
applog2( LOG_NOTICE, "Diff %.3g (%.3g%), %sBlock %d, %sJob %s" CL_WHT,
my_stats.share_diff, share_ratio, bcol, stratum.block_height,
scol, my_stats.job_id );
if ( unlikely( reason && !result ) )
{
if ( !opt_quiet && !stale )
if ( !( opt_quiet || stale ) )
applog( LOG_WARNING, "Reject reason: %s", reason );
if ( opt_debug )
@@ -1169,13 +1188,13 @@ static int share_result( int result, struct work *null_work,
char str3[65];
// display share hash and target for troubleshooting
diff_to_target( str1, my_stats.share_diff );
diff_to_target( (uint64_t*)str1, my_stats.share_diff );
for ( int i = 0; i < 8; i++ )
be32enc( str2 + i, str1[7 - i] );
bin2hex( str3, (unsigned char*)str2, 12 );
applog2( LOG_INFO, "Hash: %s...", str3 );
diff_to_target( str1, my_stats.target_diff );
diff_to_target( (uint64_t*)str1, my_stats.target_diff );
for ( int i = 0; i < 8; i++ )
be32enc( str2 + i, str1[7 - i] );
bin2hex( str3, (unsigned char*)str2, 12 );
@@ -1358,9 +1377,11 @@ char* std_malloc_txs_request( struct work *work )
char data_str[2 * sizeof(work->data) + 1];
int i;
int datasize = work->sapling ? 112 : 80;
for ( i = 0; i < ARRAY_SIZE(work->data); i++ )
be32enc( work->data + i, work->data[i] );
bin2hex( data_str, (unsigned char *)work->data, 80 );
bin2hex( data_str, (unsigned char *)work->data, datasize );
if ( work->workid )
{
char *params;
@@ -1368,7 +1389,7 @@ char* std_malloc_txs_request( struct work *work )
json_object_set_new( val, "workid", json_string( work->workid ) );
params = json_dumps( val, 0 );
json_decref( val );
req = (char*) malloc( 128 + 2 * 80 + strlen( work->txs )
req = (char*) malloc( 128 + 2 * datasize + strlen( work->txs )
+ strlen( params ) );
sprintf( req,
"{\"method\": \"submitblock\", \"params\": [\"%s%s\", %s], \"id\":4}\r\n",
@@ -1377,7 +1398,7 @@ char* std_malloc_txs_request( struct work *work )
}
else
{
req = (char*) malloc( 128 + 2 * 80 + strlen( work->txs ) );
req = (char*) malloc( 128 + 2 * datasize + strlen( work->txs ) );
sprintf( req,
"{\"method\": \"submitblock\", \"params\": [\"%s%s\"], \"id\":4}\r\n",
data_str, work->txs);
@@ -1695,7 +1716,7 @@ static void *workio_thread(void *userdata)
if ( jsonrpc_2 && !have_stratum )
ok = rpc2_workio_login( curl );
while (ok)
while ( likely(ok) )
{
struct workio_cmd *wc;
@@ -1771,7 +1792,8 @@ static bool get_work(struct thr_info *thr, struct work *work)
return true;
}
static bool submit_work( struct thr_info *thr, const struct work *work_in )
static bool submit_work( struct thr_info *thr,
const struct work *work_in )
{
struct workio_cmd *wc;
@@ -1795,20 +1817,22 @@ err_out:
return false;
}
// Convert little endian 256 bit unsigned integer to
// double precision floating point.
static inline double u256_to_double( const uint64_t* u )
// __float128?
// Convert little endian 256 bit (38 decimal digits) unsigned integer to
// double precision floating point with 15 decimal digits precision.
// returns u * ( 2**256 )
static inline double u256_to_double( const uint64_t *u )
{
const double f = 4294967296.0 * 4294967296.0; // 2**64
return ( ( u[3] * f + u[2] ) * f + u[1] ) * f + u[0];
const double exp64 = 4294967296.0 * 4294967296.0; // 2**64
return ( ( u[3] * exp64 + u[2] ) * exp64 + u[1] ) * exp64 + u[0];
}
void work_set_target_ratio( struct work* work, uint32_t* hash )
void work_set_target_ratio( struct work* work, const void *hash )
{
double dhash;
dhash = u256_to_double( (const uint64_t*)hash );
if ( dhash > 0. )
if ( likely( dhash > 0. ) )
work->sharediff = work->targetdiff *
u256_to_double( (const uint64_t*)( work->target ) ) / dhash;
else
@@ -1833,38 +1857,38 @@ void work_set_target_ratio( struct work* work, uint32_t* hash )
pthread_mutex_unlock( &stats_lock );
}
bool submit_solution( struct work *work, void *hash,
bool submit_solution( struct work *work, const void *hash,
struct thr_info *thr )
{
if ( submit_work( thr, work ) )
if ( likely( submit_work( thr, work ) ) )
{
submitted_share_count++;
work_set_target_ratio( work, hash );
if ( !opt_quiet )
applog( LOG_NOTICE, "%d: submitted by thread %d, job %s",
applog( LOG_NOTICE, "%d submitted by thread %d, job %s",
submitted_share_count, thr->id, work->job_id );
return true;
}
else
applog( LOG_WARNING, "%d: failed to submit share.",
applog( LOG_WARNING, "%d failed to submit share.",
submitted_share_count );
return false;
}
bool submit_lane_solution( struct work *work, void *hash,
struct thr_info *thr, int lane )
bool submit_lane_solution( struct work *work, const void *hash,
struct thr_info *thr, const int lane )
{
if ( submit_work( thr, work ) )
if ( likely( submit_work( thr, work ) ) )
{
submitted_share_count++;
work_set_target_ratio( work, hash );
if ( !opt_quiet )
applog( LOG_NOTICE, "%d: submitted by thread %d, lane %d, job %s",
applog( LOG_NOTICE, "%d submitted by thread %d, lane %d, job %s",
submitted_share_count, thr->id, lane, work->job_id );
return true;
}
else
applog( LOG_WARNING, "%d: failed to submit share.",
applog( LOG_WARNING, "%d failed to submit share.",
submitted_share_count );
return false;
}
@@ -1971,30 +1995,27 @@ double std_calc_network_diff( struct work* work )
return d;
}
uint32_t* std_get_nonceptr( uint32_t *work_data )
uint32_t *std_get_nonceptr( uint32_t *work_data )
{
return work_data + algo_gate.nonce_index;
}
uint32_t* jr2_get_nonceptr( uint32_t *work_data )
uint32_t *jr2_get_nonceptr( uint32_t *work_data )
{
// nonce is misaligned, use byte offset
return (uint32_t*) ( ((uint8_t*) work_data) + algo_gate.nonce_index );
}
void std_get_new_work( struct work* work, struct work* g_work, int thr_id,
uint32_t *end_nonce_ptr, bool clean_job )
uint32_t *end_nonce_ptr )
{
uint32_t *nonceptr = algo_gate.get_nonceptr( work->data );
bool force_new_work = work->job_id ? strtoul( work->job_id, NULL, 16 )
!= strtoul( g_work->job_id, NULL, 16 )
bool force_new_work = work->job_id ? strtoul( work->job_id, NULL, 16 ) !=
strtoul( g_work->job_id, NULL, 16 )
: true;
if ( force_new_work || *nonceptr >= *end_nonce_ptr
|| ( memcmp( work->data, g_work->data, algo_gate.work_cmp_size )
&& clean_job ) )
if ( force_new_work || *nonceptr >= *end_nonce_ptr )
{
work_free( work );
work_copy( work, g_work );
@@ -2074,29 +2095,20 @@ static void *miner_thread( void *userdata )
#ifndef WIN32
prio = 18;
// note: different behavior on linux (-19 to 19)
switch (opt_priority)
switch ( opt_priority )
{
case 1:
prio = 5;
break;
case 2:
prio = 0;
break;
case 3:
prio = -5;
break;
case 4:
prio = -10;
break;
case 5:
prio = -15;
case 1: prio = 5; break;
case 2: prio = 0; break;
case 3: prio = -5; break;
case 4: prio = -10; break;
case 5: prio = -15;
}
if (opt_debug)
applog(LOG_DEBUG, "Thread %d priority %d (nice %d)", thr_id,
opt_priority, prio );
#endif
setpriority(PRIO_PROCESS, 0, prio);
if (opt_priority == 0)
if ( opt_priority == 0 )
drop_policy();
}
// CPU thread affinity
@@ -2150,7 +2162,7 @@ static void *miner_thread( void *userdata )
}
// wait for stratum to send first job
if ( have_stratum ) while ( !g_work.job_id ) sleep(1);
if ( have_stratum ) while ( unlikely( !g_work.job_id ) ) sleep(1);
while (1)
{
@@ -2159,15 +2171,14 @@ static void *miner_thread( void *userdata )
int64_t max64 = 1000;
int nonce_found = 0;
if ( algo_gate.do_this_thread( thr_id ) )
if ( likely( algo_gate.do_this_thread( thr_id ) ) )
{
if ( have_stratum )
{
pthread_mutex_lock( &g_work_lock );
if ( *algo_gate.get_nonceptr( work.data ) >= end_nonce )
algo_gate.stratum_gen_work( &stratum, &g_work );
algo_gate.get_new_work( &work, &g_work, thr_id, &end_nonce,
stratum.job.clean );
algo_gate.get_new_work( &work, &g_work, thr_id, &end_nonce );
pthread_mutex_unlock( &g_work_lock );
}
else
@@ -2187,17 +2198,17 @@ static void *miner_thread( void *userdata )
}
g_work_time = time(NULL);
}
algo_gate.get_new_work( &work, &g_work, thr_id, &end_nonce, true );
algo_gate.get_new_work( &work, &g_work, thr_id, &end_nonce );
pthread_mutex_unlock( &g_work_lock );
}
} // do_this_thread
algo_gate.resync_threads( &work );
if ( !algo_gate.ready_to_mine( &work, &stratum, thr_id ) )
if ( unlikely( !algo_gate.ready_to_mine( &work, &stratum, thr_id ) ) )
continue;
// conditional mining
if (!wanna_mine(thr_id))
if ( unlikely( !wanna_mine( thr_id ) ) )
{
sleep(5);
continue;
@@ -2209,7 +2220,7 @@ static void *miner_thread( void *userdata )
max64 = g_work_time + ( have_longpoll ? LP_SCANTIME : opt_scantime )
- time(NULL);
// time limit
if ( opt_time_limit && firstwork_time )
if ( unlikely( opt_time_limit && firstwork_time ) )
{
int passed = (int)( time(NULL) - firstwork_time );
int remain = (int)( opt_time_limit - passed );
@@ -2267,7 +2278,7 @@ static void *miner_thread( void *userdata )
pthread_mutex_unlock( &stats_lock );
}
// If unsubmiited nonce(s) found, submit now.
if ( nonce_found && !opt_benchmark )
if ( unlikely( nonce_found && !opt_benchmark ) )
{
applog( LOG_WARNING, "BUG: See RELEASE_NOTES for reporting bugs. Algo = %s.",
algo_names[ opt_algo ] );
@@ -2292,7 +2303,7 @@ static void *miner_thread( void *userdata )
}
}
// display hashrate
if ( opt_hash_meter )
if ( unlikely( opt_hash_meter ) )
{
char hr[16];
char hr_units[2] = {0,0};
@@ -2310,8 +2321,8 @@ static void *miner_thread( void *userdata )
// Display benchmark total
// Update hashrate for API if no shares accepted yet.
if ( ( opt_benchmark || !accepted_share_count )
&& thr_id == opt_n_threads - 1 )
if ( unlikely( ( opt_benchmark || !accepted_share_count )
&& thr_id == opt_n_threads - 1 ) )
{
double hashrate = 0.;
for ( i = 0; i < opt_n_threads; i++ )
@@ -2580,13 +2591,14 @@ out:
// used by stratum and gbt
void std_build_block_header( struct work* g_work, uint32_t version,
uint32_t *prevhash, uint32_t *merkle_tree,
uint32_t ntime, uint32_t nbits )
uint32_t *prevhash, uint32_t *merkle_tree, uint32_t ntime,
uint32_t nbits, unsigned char *final_sapling_hash )
{
int i;
memset( g_work->data, 0, sizeof(g_work->data) );
g_work->data[0] = version;
g_work->sapling = be32dec( &version ) == 5 ? true : false;
if ( have_stratum )
for ( i = 0; i < 8; i++ )
@@ -2600,8 +2612,27 @@ void std_build_block_header( struct work* g_work, uint32_t version,
g_work->data[ algo_gate.ntime_index ] = ntime;
g_work->data[ algo_gate.nbits_index ] = nbits;
if ( g_work->sapling )
{
if ( have_stratum )
for ( i = 0; i < 8; i++ )
g_work->data[20 + i] = le32dec( (uint32_t*)final_sapling_hash + i );
else
{
for ( i = 0; i < 8; i++ )
g_work->data[27 - i] = le32dec( (uint32_t*)final_sapling_hash + i );
g_work->data[19] = 0;
}
g_work->data[28] = 0x80000000;
g_work->data[29] = 0x00000000;
g_work->data[30] = 0x00000000;
g_work->data[31] = 0x00000380;
}
else
{
g_work->data[20] = 0x80000000;
g_work->data[31] = 0x00000280;
}
}
void std_build_extraheader( struct work* g_work, struct stratum_ctx* sctx )
@@ -2615,7 +2646,8 @@ void std_build_extraheader( struct work* g_work, struct stratum_ctx* sctx )
// Assemble block header
algo_gate.build_block_header( g_work, le32dec( sctx->job.version ),
(uint32_t*) sctx->job.prevhash, (uint32_t*) merkle_tree,
le32dec( sctx->job.ntime ), le32dec(sctx->job.nbits) );
le32dec( sctx->job.ntime ), le32dec(sctx->job.nbits),
sctx->job.final_sapling_hash );
}
void std_stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work )
@@ -2630,12 +2662,11 @@ void std_stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work )
algo_gate.build_extraheader( g_work, sctx );
net_diff = algo_gate.calc_network_diff( g_work );
algo_gate.set_work_data_endian( g_work );
pthread_mutex_unlock( &sctx->work_lock );
work_set_target( g_work, sctx->job.diff
/ ( opt_target_factor * opt_diff_factor ) );
pthread_mutex_unlock( &sctx->work_lock );
if ( opt_debug )
{
unsigned char *xnonce2str = abin2hex( g_work->xnonce2,
@@ -2645,12 +2676,7 @@ void std_stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work )
free( xnonce2str );
}
// Log new block and/or stratum difficulty change.
if ( ( stratum_diff != sctx->job.diff )
|| ( last_block_height != sctx->block_height ) )
{
double hr = 0.;
new_job = false;
pthread_mutex_lock( &stats_lock );
for ( int i = 0; i < opt_n_threads; i++ )
@@ -2658,32 +2684,33 @@ void std_stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work )
global_hashrate = hr;
pthread_mutex_unlock( &stats_lock );
if ( !opt_quiet )
{
if ( stratum_diff != sctx->job.diff )
applog( LOG_BLUE, "New stratum diff %g, block %d, job %s",
sctx->job.diff, sctx->block_height, g_work->job_id );
else if ( last_block_height != sctx->block_height )
applog( LOG_BLUE, "New block %d, job %s", sctx->block_height,
g_work->job_id );
applog( LOG_BLUE, "New block %d, job %s",
sctx->block_height, g_work->job_id );
else
applog( LOG_BLUE,"New job %s.", g_work->job_id );
}
applog( LOG_BLUE,"New job %s", g_work->job_id );
// Update data and calculate new estimates.
stratum_diff = sctx->job.diff;
if ( ( stratum_diff != sctx->job.diff )
|| ( last_block_height != sctx->block_height ) )
{
static bool multipool = false;
if ( stratum.block_height < last_block_height ) multipool = true;
if ( unlikely( !session_first_block ) )
session_first_block = stratum.block_height;
last_block_height = stratum.block_height;
stratum_diff = sctx->job.diff;
last_targetdiff = g_work->targetdiff;
if ( !opt_quiet )
{
applog2( LOG_INFO, "%s %s block %d", short_url,
algo_names[opt_algo], stratum.block_height );
applog2( LOG_INFO, "Diff: net %g, stratum %g, target %g",
applog2( LOG_INFO, "%s: %s", algo_names[opt_algo], short_url );
applog2( LOG_INFO, "Diff: Net %.3g, Stratum %.3g, Target %.3g",
net_diff, stratum_diff, last_targetdiff );
}
if ( hr > 0. )
if ( likely( hr > 0. ) )
{
char hr_units[4] = {0};
char block_ttf[32];
@@ -2693,12 +2720,28 @@ void std_stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work )
sprintf_et( share_ttf, last_targetdiff * diff_to_hash / hr );
scale_hash_for_display ( &hr, hr_units );
if ( !opt_quiet )
{
applog2( LOG_INFO, "TTF @ %.2f %sh/s: block %s, share %s",
hr, hr_units, block_ttf, share_ttf );
if ( !multipool && net_diff > 0. )
{
struct timeval now, et;
gettimeofday( &now, NULL );
timeval_subtract( &et, &now, &session_start );
double net_hr = net_diff * diff_to_hash;
char net_ttf[32];
char net_hr_units[4] = {0};
sprintf_et( net_ttf,
( last_block_height - session_first_block ) == 0 ? 0 :
et.tv_sec / ( last_block_height - session_first_block ) );
scale_hash_for_display ( &net_hr, net_hr_units );
applog2( LOG_INFO, "TTF @ %.2f %sh/s: %s",
net_hr, net_hr_units, net_ttf );
}
}
} // hr > 0
} // !quiet
} // new diff/block
}
@@ -2726,7 +2769,7 @@ static void *stratum_thread(void *userdata )
{
int failures = 0;
if ( stratum_need_reset )
if ( unlikely( stratum_need_reset ) )
{
stratum_need_reset = false;
stratum_disconnect( &stratum );
@@ -2763,8 +2806,7 @@ static void *stratum_thread(void *userdata )
applog(LOG_ERR, "...retry after %d seconds", opt_fail_pause);
sleep(opt_fail_pause);
}
if (jsonrpc_2)
if ( unlikely( jsonrpc_2 ) )
{
work_free(&g_work);
work_copy(&g_work, &stratum.work);
@@ -2777,28 +2819,12 @@ static void *stratum_thread(void *userdata )
if ( stratum.job.job_id
&& ( !g_work_time || strcmp( stratum.job.job_id, g_work.job_id ) ) )
{
new_job = true;
pthread_mutex_lock(&g_work_lock);
algo_gate.stratum_gen_work( &stratum, &g_work );
time(&g_work_time);
pthread_mutex_unlock(&g_work_lock);
restart_threads();
if ( stratum.job.clean || jsonrpc_2 )
{
if ( !opt_quiet && last_block_height && new_job
&& ( last_block_height == stratum.block_height ) )
{
new_job = false;
applog( LOG_BLUE,"New job %s", g_work.job_id );
}
}
else if (opt_debug && !opt_quiet)
{
applog( LOG_BLUE, "%s asks job %d for block %d", short_url,
strtoul( stratum.job.job_id, NULL, 16 ), stratum.block_height );
}
} // stratum.job.job_id
if ( stratum_socket_full( &stratum, opt_timeout ) )
{
@@ -3751,6 +3777,7 @@ int main(int argc, char *argv[])
applog(LOG_WARNING,"available on Linux. Using default affinity.");
opt_affinity = -1;
}
/*
else
{
affine_to_cpu_mask( -1, opt_affinity );
@@ -3769,8 +3796,12 @@ int main(int argc, char *argv[])
#endif
}
}
*/
}
applog( LOG_INFO, "Extranonce subscribe: %s",
opt_extranonce ? "YES" : "NO" );
#ifdef HAVE_SYSLOG_H
if (use_syslog)
openlog("cpuminer", LOG_PID, LOG_USER);

25
miner.h
View File

@@ -313,12 +313,14 @@ size_t address_to_script( unsigned char *out, size_t outsz, const char *addr );
int timeval_subtract( struct timeval *result, struct timeval *x,
struct timeval *y);
bool fulltest( const uint32_t *hash, const uint32_t *target );
bool valid_hash( const void*, const void* );
void work_set_target( struct work* work, double diff );
double target_to_diff( uint32_t* target );
extern void diff_to_target(uint32_t *target, double diff);
extern void diff_to_target( uint64_t *target, double diff );
double hash_target_ratio( uint32_t* hash, uint32_t* target );
void work_set_target_ratio( struct work* work, uint32_t* hash );
void work_set_target_ratio( struct work* work, const void *hash );
struct thr_info {
int id;
@@ -330,10 +332,10 @@ struct thr_info {
//struct thr_info *thr_info;
bool submit_solution( struct work *work, void *hash,
bool submit_solution( struct work *work, const void *hash,
struct thr_info *thr );
bool submit_lane_solution( struct work *work, void *hash,
struct thr_info *thr, int lane );
bool submit_lane_solution( struct work *work, const void *hash,
struct thr_info *thr, const int lane );
//bool submit_work( struct thr_info *thr, const struct work *work_in );
@@ -361,7 +363,7 @@ float cpu_temp( int core );
struct work {
uint32_t data[48] __attribute__ ((aligned (64)));
uint32_t target[8];
uint32_t target[8] __attribute__ ((aligned (64)));
double targetdiff;
// double shareratio;
@@ -374,6 +376,8 @@ struct work {
char *job_id;
size_t xnonce2_len;
unsigned char *xnonce2;
bool sapling;
// x16rt
uint32_t merkleroothash[8];
uint32_t witmerkleroothash[8];
@@ -385,8 +389,9 @@ struct work {
} __attribute__ ((aligned (64)));
struct stratum_job {
char *job_id;
unsigned char prevhash[32];
unsigned char final_sapling_hash[32];
char *job_id;
size_t coinbase_size;
unsigned char *coinbase;
unsigned char *xnonce2;
@@ -569,6 +574,7 @@ enum algos {
ALGO_SHA256D,
ALGO_SHA256Q,
ALGO_SHA256T,
ALGO_SHA3D,
ALGO_SHAVITE3,
ALGO_SKEIN,
ALGO_SKEIN2,
@@ -602,6 +608,7 @@ enum algos {
ALGO_XEVAN,
ALGO_YESCRYPT,
ALGO_YESCRYPTR8,
ALGO_YESCRYPTR8G,
ALGO_YESCRYPTR16,
ALGO_YESCRYPTR32,
ALGO_YESPOWER,
@@ -667,6 +674,7 @@ static const char* const algo_names[] = {
"sha256d",
"sha256q",
"sha256t",
"sha3d",
"shavite3",
"skein",
"skein2",
@@ -700,6 +708,7 @@ static const char* const algo_names[] = {
"xevan",
"yescrypt",
"yescryptr8",
"yescryptr8g",
"yescryptr16",
"yescryptr32",
"yespower",
@@ -832,6 +841,7 @@ Options:\n\
sha256d Double SHA-256\n\
sha256q Quad SHA-256, Pyrite (PYE)\n\
sha256t Triple SHA-256, Onecoin (OC)\n\
sha3d Double Keccak256 (BSHA3)\n\
shavite3 Shavite3\n\
skein Skein+Sha (Skeincoin)\n\
skein2 Double Skein (Woodcoin)\n\
@@ -865,6 +875,7 @@ Options:\n\
xevan Bitsend (BSD)\n\
yescrypt Globalboost-Y (BSTY)\n\
yescryptr8 BitZeny (ZNY)\n\
yescryptr8g Koto (KOTO)\n\
yescryptr16 Eli\n\
yescryptr32 WAVI\n\
yespower Cryply\n\

View File

@@ -46,10 +46,11 @@
#define HWMON_PATH \
"/sys/class/hwmon/hwmon2/temp1_input"
/*
// need this for Ryzen
#define HWMON_ALT \
"/sys/class/hwmon/hwmon0/temp1_input"
/*
#define HWMON_ALT1 \
"/sys/devices/platform/coretemp.0/hwmon/hwmon1/temp1_input"
*/
@@ -84,6 +85,9 @@ static inline float linux_cputemp(int core)
if (!fd)
fd = fopen(HWMON_PATH, "r");
if (!fd)
fd = fopen(HWMON_ALT, "r");
if (!fd)
return tc;

163
util.c
View File

@@ -923,7 +923,7 @@ bool jobj_binary(const json_t *obj, const char *key, void *buf, size_t buflen)
size_t address_to_script(unsigned char *out, size_t outsz, const char *addr)
{
unsigned char addrbin[25];
unsigned char addrbin[26];
int addrver;
size_t rv;
@@ -982,64 +982,89 @@ int timeval_subtract(struct timeval *result, struct timeval *x,
return x->tv_sec < y->tv_sec;
}
bool fulltest(const uint32_t *hash, const uint32_t *target)
// Use this when deinterleaved
// do 64 bit test 4 iterations
inline bool valid_hash( const void *hash, const void *target )
{
const uint64_t *h = (const uint64_t*)hash;
const uint64_t *t = (const uint64_t*)target;
if ( h[3] > t[3] ) return false;
if ( h[3] < t[3] ) return true;
if ( h[2] > t[2] ) return false;
if ( h[2] < t[2] ) return true;
if ( h[1] > t[1] ) return false;
if ( h[1] < t[1] ) return true;
if ( h[0] > t[0] ) return false;
return true;
}
bool fulltest( const uint32_t *hash, const uint32_t *target )
{
int i;
bool rc = true;
for (i = 7; i >= 0; i--) {
if (hash[i] > target[i]) {
for ( i = 7; i >= 0; i-- )
{
if ( hash[i] > target[i] )
{
rc = false;
break;
}
if (hash[i] < target[i]) {
if ( hash[i] < target[i] )
{
rc = true;
break;
}
}
if (opt_debug) {
if ( opt_debug )
{
uint32_t hash_be[8], target_be[8];
char hash_str[65], target_str[65];
for (i = 0; i < 8; i++) {
be32enc(hash_be + i, hash[7 - i]);
be32enc(target_be + i, target[7 - i]);
for ( i = 0; i < 8; i++ )
{
be32enc( hash_be + i, hash[7 - i] );
be32enc( target_be + i, target[7 - i] );
}
bin2hex(hash_str, (unsigned char *)hash_be, 32);
bin2hex(target_str, (unsigned char *)target_be, 32);
bin2hex( hash_str, (unsigned char *)hash_be, 32 );
bin2hex( target_str, (unsigned char *)target_be, 32 );
applog(LOG_DEBUG, "DEBUG: %s\nHash: %s\nTarget: %s",
applog( LOG_DEBUG, "DEBUG: %s\nHash: %s\nTarget: %s",
rc ? "hash <= target"
: "hash > target (false positive)",
hash_str,
target_str);
hash_str, target_str );
}
return rc;
}
void diff_to_target(uint32_t *target, double diff)
void diff_to_target(uint64_t *target, double diff)
{
uint64_t m;
int k;
for (k = 6; k > 0 && diff > 1.0; k--)
diff /= 4294967296.0;
m = (uint64_t)(4294901760.0 / diff);
if (m == 0 && k == 6)
memset(target, 0xff, 32);
else {
memset(target, 0, 32);
target[k] = (uint32_t)m;
target[k + 1] = (uint32_t)(m >> 32);
const double exp64 = (double)0xffffffffffffffff + 1.;
for ( k = 3; k > 0 && diff > 1.0; k-- )
diff /= exp64;
// for (k = 6; k > 0 && diff > 1.0; k--)
// diff /= 4294967296.0;
m = (uint64_t)( 0xffff0000 / diff );
if unlikely( m == 0 && k == 3 )
memset( target, 0xff, 32 );
else
{
memset( target, 0, 32 );
target[k] = m;
// target[k] = (uint32_t)m;
// target[k + 1] = (uint32_t)(m >> 32);
}
}
// Only used by stratum pools
void work_set_target(struct work* work, double diff)
{
diff_to_target(work->target, diff);
diff_to_target( (uint64_t*)work->target, diff );
work->targetdiff = diff;
}
@@ -1811,6 +1836,7 @@ static uint32_t getblocheight(struct stratum_ctx *sctx)
static bool stratum_notify(struct stratum_ctx *sctx, json_t *params)
{
const char *job_id, *prevhash, *coinb1, *coinb2, *version, *nbits, *stime;
const char *finalsaplinghash = NULL;
const char *denom10 = NULL, *denom100 = NULL, *denom1000 = NULL,
*denom10000 = NULL, *prooffullnode = NULL;
const char *extradata = NULL;
@@ -1871,6 +1897,18 @@ static bool stratum_notify(struct stratum_ctx *sctx, json_t *params)
goto out;
}
hex2bin( sctx->job.version, version, 4 );
int ver = be32dec( sctx->job.version );
if ( ver == 5 )
{
finalsaplinghash = json_string_value( json_array_get( params, 9 ) );
if ( !finalsaplinghash || strlen(finalsaplinghash) != 64 )
{
applog( LOG_ERR, "Stratum notify: invalid version 5 parameters" );
goto out;
}
}
if ( is_veil )
{
if ( !denom10 || !denom100 || !denom1000 || !denom10000
@@ -1884,66 +1922,69 @@ static bool stratum_notify(struct stratum_ctx *sctx, json_t *params)
}
if ( merkle_count )
merkle = (uchar**) malloc(merkle_count * sizeof(char *));
merkle = (uchar**) malloc( merkle_count * sizeof(char *) );
for ( i = 0; i < merkle_count; i++ )
{
const char *s = json_string_value(json_array_get(merkle_arr, i));
if (!s || strlen(s) != 64) {
while (i--)
free(merkle[i]);
free(merkle);
applog(LOG_ERR, "Stratum notify: invalid Merkle branch");
const char *s = json_string_value( json_array_get( merkle_arr, i ) );
if ( !s || strlen(s) != 64 )
{
while ( i-- ) free( merkle[i] );
free( merkle );
applog( LOG_ERR, "Stratum notify: invalid Merkle branch" );
goto out;
}
merkle[i] = (uchar*) malloc(32);
hex2bin(merkle[i], s, 32);
merkle[i] = (uchar*) malloc( 32 );
hex2bin( merkle[i], s, 32 );
}
pthread_mutex_lock(&sctx->work_lock);
pthread_mutex_lock( &sctx->work_lock );
coinb1_size = strlen(coinb1) / 2;
coinb2_size = strlen(coinb2) / 2;
coinb1_size = strlen( coinb1 ) / 2;
coinb2_size = strlen( coinb2 ) / 2;
sctx->job.coinbase_size = coinb1_size + sctx->xnonce1_size +
sctx->xnonce2_size + coinb2_size;
sctx->job.coinbase = (uchar*) realloc(sctx->job.coinbase, sctx->job.coinbase_size);
sctx->job.coinbase = (uchar*) realloc( sctx->job.coinbase,
sctx->job.coinbase_size );
sctx->job.xnonce2 = sctx->job.coinbase + coinb1_size + sctx->xnonce1_size;
hex2bin(sctx->job.coinbase, coinb1, coinb1_size);
memcpy(sctx->job.coinbase + coinb1_size, sctx->xnonce1, sctx->xnonce1_size);
if (!sctx->job.job_id || strcmp(sctx->job.job_id, job_id))
hex2bin( sctx->job.coinbase, coinb1, coinb1_size );
memcpy( sctx->job.coinbase + coinb1_size,
sctx->xnonce1, sctx->xnonce1_size );
if ( !sctx->job.job_id || strcmp( sctx->job.job_id, job_id ) )
memset(sctx->job.xnonce2, 0, sctx->xnonce2_size);
hex2bin(sctx->job.xnonce2 + sctx->xnonce2_size, coinb2, coinb2_size);
free(sctx->job.job_id);
sctx->job.job_id = strdup(job_id);
hex2bin(sctx->job.prevhash, prevhash, 32);
if (has_claim) hex2bin(sctx->job.extra, extradata, 32);
if (has_roots) hex2bin(sctx->job.extra, extradata, 64);
hex2bin( sctx->job.xnonce2 + sctx->xnonce2_size, coinb2, coinb2_size );
free( sctx->job.job_id );
sctx->job.job_id = strdup( job_id );
hex2bin( sctx->job.prevhash, prevhash, 32 );
if ( has_claim ) hex2bin( sctx->job.extra, extradata, 32 );
if ( has_roots ) hex2bin( sctx->job.extra, extradata, 64 );
if ( ver == 5 )
hex2bin( sctx->job.final_sapling_hash, finalsaplinghash, 32 );
if ( is_veil )
{
hex2bin(sctx->job.denom10, denom10, 32);
hex2bin(sctx->job.denom100, denom100, 32);
hex2bin(sctx->job.denom1000, denom1000, 32);
hex2bin(sctx->job.denom10000, denom10000, 32);
hex2bin(sctx->job.proofoffullnode, prooffullnode, 32);
hex2bin( sctx->job.denom10, denom10, 32 );
hex2bin( sctx->job.denom100, denom100, 32 );
hex2bin( sctx->job.denom1000, denom1000, 32 );
hex2bin( sctx->job.denom10000, denom10000, 32 );
hex2bin( sctx->job.proofoffullnode, prooffullnode, 32 );
}
sctx->block_height = getblocheight(sctx);
sctx->block_height = getblocheight( sctx );
for (i = 0; i < sctx->job.merkle_count; i++)
free(sctx->job.merkle[i]);
for ( i = 0; i < sctx->job.merkle_count; i++ )
free( sctx->job.merkle[i] );
free(sctx->job.merkle);
free( sctx->job.merkle );
sctx->job.merkle = merkle;
sctx->job.merkle_count = merkle_count;
hex2bin(sctx->job.version, version, 4);
hex2bin(sctx->job.nbits, nbits, 4);
hex2bin(sctx->job.ntime, stime, 4);
hex2bin( sctx->job.nbits, nbits, 4 );
hex2bin( sctx->job.ntime, stime, 4 );
sctx->job.clean = clean;
sctx->job.diff = sctx->next_diff;
pthread_mutex_unlock(&sctx->work_lock);
pthread_mutex_unlock( &sctx->work_lock );
ret = true;