diff --git a/Makefile.am b/Makefile.am index 0583339..850c4b7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -53,6 +53,7 @@ cpuminer_SOURCES = \ crypto/c_skein.c \ crypto/hash.c \ crypto/aesb.c \ + crypto/magimath.cpp \ algo/argon2/argon2a.c \ algo/argon2/ar2/argon2.c \ algo/argon2/ar2/opt.c \ @@ -66,7 +67,6 @@ cpuminer_SOURCES = \ algo/blake/decred.c \ algo/blake/pentablake.c \ algo/bmw/bmw256.c \ - algo/c11.c \ algo/cubehash/sse2/cubehash_sse2.c\ algo/cryptolight.c \ algo/cryptonight/cryptonight-common.c\ @@ -76,6 +76,7 @@ cpuminer_SOURCES = \ algo/echo/aes_ni/hash.c\ algo/fresh.c \ algo/groestl/groestl.c \ + algo/groestl/myr-groestl.c \ algo/groestl/sse2/grso.c\ algo/groestl/sse2/grso-asm.c\ algo/groestl/aes_ni/hash-groestl.c \ @@ -99,23 +100,26 @@ cpuminer_SOURCES = \ algo/lyra2/sponge.c \ algo/lyra2/lyra2rev2.c \ algo/lyra2/lyra2re.c \ - algo/myr-groestl.c \ algo/keccak/sse2/keccak.c \ - algo/quark/quark.c \ - algo/qubit/qubit.c \ + algo/m7m.c \ algo/neoscrypt.c \ algo/nist5.c \ algo/pluck.c \ + algo/quark/quark.c \ + algo/qubit/qubit.c \ + algo/ripemd/sph_ripemd.c \ algo/scrypt.c \ algo/scryptjane/scrypt-jane.c \ - algo/sha2.c \ - algo/sibcoin.c \ + algo/sha2/sha2.c \ algo/simd/sse2/nist.c \ algo/simd/sse2/vector.c \ algo/skein/skein.c \ algo/skein/skein2.c \ algo/s3.c \ + algo/tiger/sph_tiger.c \ algo/x11/x11.c \ + algo/x11/x11gost.c \ + algo/x11/c11.c \ algo/x13/x13.c \ algo/x14/x14.c \ algo/x15/x15.c \ @@ -152,7 +156,7 @@ if HAVE_WINDOWS endif cpuminer_LDFLAGS = @LDFLAGS@ -cpuminer_LDADD = @LIBCURL@ @JANSSON_LIBS@ @PTHREAD_LIBS@ @WS2_LIBS@ -lssl -lcrypto +cpuminer_LDADD = @LIBCURL@ @JANSSON_LIBS@ @PTHREAD_LIBS@ @WS2_LIBS@ -lssl -lcrypto -lgmp cpuminer_CPPFLAGS = @LIBCURL_CPPFLAGS@ $(ALL_INCLUDES) cpuminer_CFLAGS = -Wno-pointer-sign -Wno-pointer-to-int-cast $(disable_flags) diff --git a/RELEASE_ANNOUNCEMENT b/RELEASE_ANNOUNCEMENT index a605e91..0c2eece 100644 --- a/RELEASE_ANNOUNCEMENT +++ b/RELEASE_ANNOUNCEMENT @@ -1,50 +1,48 @@ - Release 3.1.14 of cpuminer-opt is available for download. + Release 3.1.16 of cpuminer-opt is available for download. All users are encouraged to upgrade. -New in 3.1.14 +cpuminer-opt now supports 32 algorithms on CPUs with at least SSE2 +capabilities including Intel Core2 and AMD equivalent. See the +performance chart below for details. -Algos - - cryptonight algo is now supported on CPUs without AES_NI. - All algos now support both CPU architectures. - - jane added as an alias for scryptjane with default N-factor 16 +In addition 13 algorithms have optimizations to take advantage of +CPUs with AES_NI for even greater performance, including the Intel +Sandy Bridge (Core-i 2xxx) and AMD equivalent. -Build enhancements, see details in README.md +New in v3.1.16 + + - added m7m algo + - new dependency on gmp + +New in v3.1.15 + + - unified build procedure fixed - build.sh now works for CPUs with and without AES_NI - - it is no longer necessary to add -DNO_AES_NI CFLAG to + - it is no longer necessary to add -DNO_AES_NI CFLAG to the configure command when building for CPUs without AES_NI. -UI enhancements - - enhanced capabilities check will now check CPU architecture - SW build and algo for AES_NI and SSE2 capabilities. - - a warning is displayed if mining an untested algo. +Recently added dependencies: -Code cleanup - - removed a few more compiler warnings - - removed dead code - -Algo gate enhancements (for devs) - - replaced algo specific null gate functions with generic null - functions + - gmp + - libboost-dev + - libboost-system-dev + - libboost-thread-dev Recently added algos: - hodl added with support for CPUs with and without AES_NI - Note: Compiling requires some additional libraries not included - in the default instalation of most Linux distributions: - libboost-dev, libboost-system-dev, libboost-thread-dev. - - argon2 added, 6% faster than encel version + - argon2 - decred (blake256r14) - vanilla (blake256r8vnl) - - x14 added with AES_NI and SSE2 optimisations + - x14 added with AES_NI and SSE2 optimizations - blake - blake2s - yescrypt - scryptjane - scrypt - sha256d - - pluck, drop and bastion added, benchmark tested only Recently improved algos: @@ -60,59 +58,60 @@ Recently improved algos: +45% SSE2 - myr-gr optimized for AES_NI, marginal increase in hashrate -Starting in release 3.1 a CPU with a minimum of SSE2 is required. -This includes core2 and newer CPUs. Some algos also require AES_NI, -see chart below. - -Users with non-SSE2 CPUs or who desire to mine algos not supported by +Users with non-SSE2 CPUs or whoi want to mine algos not supported by cpuminer-opt may find cpuminer-multi by TPruvot useful. -Performance chart for Intel i7-6700K @ 4 GHz, 16 GB mem. +The performance chart below is for an Intel i7-6700K @ 4 GHz, 16 GB mem. -The normalisation rates have ben added to the chart to help with profit +Normalization rates have ben added to the chart to help with profit switching pools. Reference algo x11 = 1. -Normalised profitability = algo profitability * normalisation rate +Due to the peculiarities of some algorithms their performance on other CPU +architectures may not scale equally. Their normalizations rates will also +differ from those listed below. YMMV. + +Normalized profitability = algo profitability * normalization rate AES_NI SSE2(1) norm rate(5) ------ ---- --------- -quark 1195 K 924 K 1.61 -qubit 1090 765 1.45 -x11 740 525 1 +x11 740 K 525 K 1 x13 373 298 0.50 x14 357 271 0.48 x15 333 270 0.45 x17(2) 317 248 0.43 +quark 1195 924 1.61 +qubit 1090 765 1.45 nist5 2000 1592 3.37 zr5 850 650 1.15 x11gost 540 404 0.73 c11 733 475 0.99 myr-gr 1572 1560 2.12 cryptonight 290 H 165 H 0.00039 -hodl 275 200 0.00037 +hodl 275 200 H 0.00037 neoscrypt (4) 32 K 0.043 lyra2re (4) 930 1.25 lyra2rev2 (4) 495 0.65 +argon2 (4) 33.7 0.045 +m7m (4) 48.7 0.066 +groestl (4) 931 1.26 +skein (4) 5747 7.77 +skein2 (4) 8675 11.7 +pentablake (4) 3960 5.35 +keccak (4) 7790 10.5 +scrypt (4) 113 0.153 +sha256d (4) 62.5 0.084 blake (4) 22.4 M 30.4 blake2s (4) 17.5 23.6 vanilla (4) 33.0 44.6 decred (4) 22.6 30.5 -pentablake (4) 3960 K 5.35 -keccak (4) 7790 10.5 axiom (4) 72 H 0.098 -groestl (4) 931 1.26 -skein (4) 5747 7.77 -skein2 (4) 8675 11.7 -argon2 (4) 33.7 K 0.045 -yescrypt (4) 3760 H 0.0051 +yescrypt (4) 3760 0.0051 scryptjane (4) 250 0.00034 -scrypt (4) 113 K 0.153 -sha256d (4) 62.5 M 0.084 blakecoin(2) (4) 33.9 M 45.8 -fresh(2) (4) 528 K 0.71 cryptolight(2) (4) 685 H 0.00093 -pluck(2) (4) 1925 0.0026 +pluck(2) (4) 1925 H 0.0026 drop(2) (4) 934 K 1.26 +fresh(2) (4) 528 K 0.71 Footnotes: (1) SSE2 rates are simulated in software. diff --git a/algo-gate-api.c b/algo-gate-api.c index b905a81..9796e95 100644 --- a/algo-gate-api.c +++ b/algo-gate-api.c @@ -17,19 +17,49 @@ #include "miner.h" #include "algo-gate-api.h" -// define null functions - -// null vs default: strictly speaking a null function should do nothing -// and a default function should do what satisfies the most clients (algos). -// This distinction is blurred and the two function types are combined. -// A null function is either a true do-nothing or it is the default -// action. The only rule is that if even a single client requires a do-nothing -// function it must be the null function. This will require every other -// client to define and register a custom function. In some cases where -// many clients require the same action it may be desireable to define -// an explicit default do-something function here that will eliminate -// the need for those clients to each define their own. The must still -// register the default. +// Define null and standard functions. +// +// Generic null functions do nothing except satisfy the syntax and +// can be used for optional safe gate functions. +// +// null gate functions are genarally used for mandatory and unsafe functions +// and will usually display an error massage and/or return a fail code. +// They are registered by default and are expected to be overwritten. +// +// std functions are non-null functions used by the most number of algos +// are are default. +// +// aux functions are functions used by many, but not most, algos and must +// be registered by eech algo using them. They usually have descriptive +// names. +// +// custom functions are algo spefic and are defined and registered in the +// algo's source file and are usually named [algo]_[function]. +// +// In most cases the default is a null or std function. However in some +// cases, for convenience when the null function is not the most popular, +// the std function will be defined as default and the algo must register +// an appropriate null function. +// +// similar algos may share a gate function that may be defined here or +// in a source file common to the similar algos. +// +// gate functions may call other gate functions under the following +// restrictions. Any gate function defined here or used by more than one +// algo must call other functions using the gate: algo_gate.[function]. +// custom functions may call other custom functions directly using +// [algo]_[function], howver it is recommended to alway use the gate. +// +// If, under rare circumstances, an algo with a custom gate function +// needs to call a function of another algo it must define and register +// a private gate from its rgistration function and use it to call +// forein functions: [private_gate].[function]. If the algo needs to call +// a utility function defined here it may do so directly. +// +// The algo's gate registration function is caled once from the main thread +// and can do other intialization in addition such as setting options or +// other global or local (to the algo) variables. + // As algo-gate evolves some function are taking on multiple personalities. // The same function could perform completely unrelated actions for // different algos, they jut happen to require that action at the same @@ -38,8 +68,8 @@ // of aggo-gate, whether to have many smaller, unique gate functions or // fewer, larger functions with more code duplication. -// A handy predefined generic null function that can be as any null gate -// function with the samesignature. +// A set of predefined generic null functions that can be used as any null +// gate function with the same signature. void do_nothing () {} bool return_true () { return true; } @@ -57,11 +87,13 @@ void algo_not_implemented() applog(LOG_ERR,"Algo %s has not been Implemented.",algo_names[opt_algo]); } +// default null functions + int null_scanhash(int thr_id, struct work* work, uint32_t max_nonce, uint64_t *hashes_done, unsigned char* scratchbuf ) { applog(LOG_WARNING,"SWERR: undefined scanhash function in algo_gate"); - return false; + return 0; } void null_hash( void *output, const void *pdata, uint32_t len ) @@ -71,38 +103,66 @@ void null_hash( void *output, const void *pdata, uint32_t len ) void null_hash_suw( void *output, const void *pdata ) { - applog(LOG_WARNING,"SWERR: null_hash unsafe null function"); + applog(LOG_WARNING,"SWERR: null_hash_suw unsafe null function"); }; -double null_get_max64() -{ - return 0x1fffffLL; -} - void null_hash_alt ( void *output, const void *pdata, uint32_t len ) { applog(LOG_WARNING,"SWERR: null_hash_alt unsafe null function"); }; -// This is the value for most, make it the default -void null_gen_merkle_root( char* merkle_root, struct stratum_ctx* sctx, +// Standard functions (default) + +// pick your favorite or define your own +int64_t get_max64_0x1fffffLL() { return 0x1fffffLL; } // default +int64_t get_max64_0x40LL() { return 0x40LL; } +int64_t get_max64_0x3ffff() { return 0x3ffff; } +int64_t get_max64_0x3fffffLL() { return 0x3fffffLL; } +int64_t get_max64_0x1ffff() { return 0x1ffff; } + +// This is the default +void sha256d_gen_merkle_root( char* merkle_root, struct stratum_ctx* sctx, int* headersize, uint32_t* extraheader, int extraheader_size ) { sha256d(merkle_root, sctx->job.coinbase, (int) sctx->job.coinbase_size); } -// This is the value for most, make it default -void null_set_target( struct work* work, double job_diff ) +void SHA256_gen_merkle_root ( char* merkle_root, struct stratum_ctx* sctx ) +{ + SHA256( sctx->job.coinbase, (int)sctx->job.coinbase_size, merkle_root ); +} + +// default +void std_set_target( struct work* work, double job_diff ) { work_set_target( work, job_diff / opt_diff_factor ); } -void null_set_data_size( uint32_t* data_size, uint32_t* adata_sz ) -{ - *adata_sz = *data_size / sizeof(uint32_t); +// most scrypt based algos +void scrypt_set_target( struct work* work, double job_diff ) +{ + work_set_target( work, job_diff / (65536.0 * opt_diff_factor) ); } -void null_build_stratum_request( char* req, struct work* work, +// default +int set_data_size_128() { return 128; } +int set_data_size_80 () { return 80; } + +// default +int suw_build_hex_string_128( struct work *work ) +{ + for ( int i = 0; i < 128 / sizeof(uint32_t); i++ ) + le32enc( &work->data[i], work->data[i] ); + return 128; +} +int suw_build_hex_string_80( struct work *work ) +{ + for ( int i = 0; i < 80 / sizeof(uint32_t); i++ ) + le32enc( &work->data[i], work->data[i] ); + return 80; +} + +void std_build_stratum_request( char* req, struct work* work, unsigned char *xnonce2str, char* ntimestr, char* noncestr ) { snprintf( req, JSON_BUF_LEN, @@ -110,15 +170,41 @@ void null_build_stratum_request( char* req, struct work* work, rpc_user, work->job_id, xnonce2str, ntimestr, noncestr ); } -void null_reverse_endian_17_19 ( uint32_t* ntime, uint32_t* nonce, +// default +void std_set_work_data_endian( struct work *work ) +{ + work->data[20] = 0x80000000; + work->data[31] = 0x00000280; +} +void swab_work_data( struct work *work ) +{ + for ( int i = 0; i <= 18; i++ ) + work->data[i] = swab32( work->data[i] ); + work->data[20] = 0x80000000; + work->data[31] = 0x00000280; +} + +void reverse_endian( struct work* work ) +{ + for ( int i = 0; i <= 18; i++ ) + work->data[i] = swab32( work->data[i] ); +} + +// default +void encode_little_endian_17_19 ( uint32_t* ntime, uint32_t* nonce, struct work* work ) { le32enc( ntime, work->data[17] ); le32enc( nonce, work->data[19] ); } +void encode_big_endian_17_19( uint32_t* ntime, uint32_t* nonce, + struct work* work ) +{ + be32enc( ntime, work->data[17] ); + be32enc( nonce, work->data[19] ); +} -// used by most algos -void null_calc_network_diff ( struct work* work ) +void std_calc_network_diff ( struct work* work ) { // sample for diff 43.281 : 1c05ea29 // todo: endian reversed on longpoll could be zr5 specific... @@ -134,18 +220,50 @@ void null_calc_network_diff ( struct work* work ) net_diff /= 256.0; } -unsigned char* null_get_xnonce2str( struct work* work, size_t xnonce1_size ) +bool std_work_decode( const json_t *val, struct work *work) +{ + int i; + int data_size = sizeof(work->data); + int target_size = sizeof(work->target); + int adata_sz = ARRAY_SIZE(work->data); + int atarget_sz = ARRAY_SIZE(work->target); + + algo_gate.set_data_and_target_size( &data_size, &target_size, + &adata_sz, &atarget_sz, &allow_mininginfo ); + + if (jsonrpc_2) + return rpc2_job_decode(val, work); + + if (unlikely(!jobj_binary(val, "data", work->data, data_size))) + { + applog(LOG_ERR, "JSON invalid data"); + return false; + } + if (unlikely(!jobj_binary(val, "target", work->target, target_size))) + { + applog(LOG_ERR, "JSON invalid target"); + return false; + } + + for (i = 0; i < adata_sz; i++) + work->data[i] = le32dec(work->data + i); + for (i = 0; i < atarget_sz; i++) + work->target[i] = le32dec(work->target + i); + return true; +} + +unsigned char* std_get_xnonce2str( struct work* work, size_t xnonce1_size ) { return abin2hex(work->xnonce2, work->xnonce2_len); } -void null_set_benchmark_work_data( struct work* work ) +void std_set_benchmark_work_data( struct work* work ) { work->data[20] = 0x80000000; work->data[31] = 0x00000280; } -void null_build_extraheader( struct work* work, struct stratum_ctx* sctx, +void std_build_extraheader( struct work* work, struct stratum_ctx* sctx, uint32_t* extraheader, int headersize ) { work->data[17] = le32dec(sctx->job.ntime); @@ -185,19 +303,19 @@ void init_null_algo_gate( algo_gate_t* gate ) gate->ignore_pok = (void*)&return_false; gate->display_pok = (void*)&do_nothing; gate->wait_for_diff = (void*)&do_nothing; - gate->get_max64 = (void*)&null_get_max64; + gate->get_max64 = (void*)&get_max64_0x1fffffLL; gate->get_scratchbuf = (void*)&return_true; - gate->gen_merkle_root = (void*)&null_gen_merkle_root; - gate->build_stratum_request = (void*)&null_build_stratum_request; - gate->set_target = (void*)&null_set_target; - gate->set_data_size = (void*)&null_set_data_size; + gate->gen_merkle_root = (void*)&sha256d_gen_merkle_root; + gate->build_stratum_request = (void*)&std_build_stratum_request; + gate->set_target = (void*)&std_set_target; + gate->suw_build_hex_string = (void*)&suw_build_hex_string_128; gate->set_data_and_target_size = (void*)&do_nothing; - gate->reverse_endian = (void*)&do_nothing; - gate->reverse_endian_17_19 = (void*)&null_reverse_endian_17_19; - gate->calc_network_diff = (void*)&null_calc_network_diff; - gate->get_xnonce2str = (void*)&null_get_xnonce2str; - gate->set_benchmark_work_data = (void*)&null_set_benchmark_work_data; - gate->build_extraheader = (void*)&null_build_extraheader; + gate->set_work_data_endian = (void*)&std_set_work_data_endian; + gate->encode_endian_17_19 = (void*)&encode_little_endian_17_19; + gate->calc_network_diff = (void*)&std_calc_network_diff; + gate->get_xnonce2str = (void*)&std_get_xnonce2str; + gate->set_benchmark_work_data = (void*)&std_set_benchmark_work_data; + gate->build_extraheader = (void*)&std_build_extraheader; gate->prevent_dupes = (void*)&return_false; gate->thread_barrier_init = (void*)&do_nothing; gate->thread_barrier_wait = (void*)&do_nothing; @@ -245,6 +363,7 @@ bool register_algo_gate( int algo, algo_gate_t *gate ) case ALGO_LUFFA: register_luffa_algo ( gate ); break; case ALGO_LYRA2RE: register_lyra2re_algo ( gate ); break; case ALGO_LYRA2REV2: register_lyra2rev2_algo ( gate ); break; + case ALGO_M7M: register_m7m_algo ( gate ); break; case ALGO_MYR_GR: register_myriad_algo ( gate ); break; case ALGO_NEOSCRYPT: register_neoscrypt_algo ( gate ); break; case ALGO_NIST5: register_nist5_algo ( gate ); break; diff --git a/algo-gate-api.h b/algo-gate-api.h index 14c51ab..fa0bf7b 100644 --- a/algo-gate-api.h +++ b/algo-gate-api.h @@ -83,28 +83,29 @@ int *( *scanhash ) ( int, struct work*, uint32_t, uint64_t*, // optional unsafe, must be overwritten if algo uses function void *( *hash ) ( void*, const void*, uint32_t ) ; void *( *hash_alt ) ( void*, const void*, uint32_t ); -void *( *hash_suw ) ( void*, const void*, uint32_t ); +void *( *hash_suw ) ( void*, const void* ); void *( *init_ctx ) (); //optional, safe to use default null instance bool *( *aes_ni_optimized ) (); // regen_work for decred -bool *( *ignore_pok ) ( int*, int*, int* ); +bool *( *ignore_pok ) ( int*, int*, int* ); // decode_extra_data for decred -void *( *display_pok ) ( struct work*, uint64_t* ); -void *( *wait_for_diff ) ( struct stratum_ctx* ); -double *( *get_max64 ) (); -void *( *set_target) ( struct work*, double ); -bool *( *get_scratchbuf ) ( unsigned char** ); -void *( *set_data_size ) ( uint32_t*, uint32_t*, struct work* ); -int *( *set_data_and_target_size ) ( int*, int*, int*, int*, bool* ); -void *( *gen_merkle_root ) ( char*, struct stratum_ctx*, int*, - uint32_t*, int ); -void *( *build_stratum_request ) ( char*, struct work*, unsigned char*, +void *( *display_pok ) ( struct work*, uint64_t* ); +void *( *wait_for_diff ) ( struct stratum_ctx* ); +int64_t *( *get_max64 ) (); +bool *( *work_decode ) ( const struct json_t*, struct work* ); +void *( *set_target) ( struct work*, double ); +bool *( *get_scratchbuf ) ( unsigned char** ); +int *( *suw_build_hex_string ) ( ); +int *( *set_data_and_target_size )( int*, int*, int*, int*, bool* ); +void *( *gen_merkle_root ) ( char*, struct stratum_ctx*, int*, + uint32_t*, int ); +void *( *build_stratum_request ) ( char*, struct work*, unsigned char*, char*, char* ); -void *( *reverse_endian ) ( struct work* ); +void *( *set_work_data_endian ) ( struct work* ); // reverse_endian_34_35 for decred -void *( *reverse_endian_17_19 ) ( uint32_t*, uint32_t*, struct work* ); +void *( *encode_endian_17_19 ) ( uint32_t*, uint32_t*, struct work* ); void *( *calc_network_diff ) ( struct work* ); unsigned char* *( *get_xnonce2str ) ( struct work*, size_t ); void *( *set_benchmark_work_data ) ( struct work* ); @@ -124,6 +125,8 @@ void *( *init_nonceptr ) ( struct work*, struct work* ,uint32_t**, int, int, int, int ); } algo_gate_t; +extern algo_gate_t algo_gate; + // Declare null instances void do_nothing(); @@ -133,43 +136,65 @@ void *return_null(); void algo_not_tested(); // allways returns failure -int null_scanhash ( int thr_id, struct work* work, uint32_t max_nonce, +int null_scanhash ( int thr_id, struct work* work, uint32_t max_nonce, uint64_t *hashes_done, unsigned char* scratchbuf ); -// just a stub that returns success -void null_hash ( void *output, const void *pdata, uint32_t len ); +// displays warning +void null_hash ( void *output, const void *pdata, uint32_t len ); +void null_hash_alt ( void *output, const void *pdata, uint32_t len ); +void null_hash_suw ( void *output, const void *pdata ); -// not truly null, but default, used to simplify algo registration by -// allowing algos to avoid needing to implement their own custom -// functions if the default works in their case. -void null_gen_merkle_root( char*, struct stratum_ctx* sctx, +// default +void sha256_gen_merkle_root( char*, struct stratum_ctx* sctx, int* headersize, uint32_t* extraheader, int extraheader_size ); -double null_get_max64 (); -void null_set_target ( struct work* work, double job_diff ); -bool null_get_scratchbuf( char** scratchbuf ); -void null_set_data_size ( uint32_t* data_size, uint32_t* adata_sz ); -void null_build_stratum_request( char* req, struct work* work, +void SHA256_gen_merkle_root ( char* merkle_root, struct stratum_ctx* sctx ); + +// pick your favorite or define your own +int64_t get_max64_0x1fffffLL(); // default +int64_t get_max64_0x40LL(); +int64_t get_max64_0x3ffff(); +int64_t get_max64_0x3fffffLL(); +int64_t get_max64_0x1ffff(); + +void std_set_target ( struct work* work, double job_diff ); +void scrypt_set_target( struct work* work, double job_diff ); + +// default +bool std_work_decode( const json_t *val, struct work *work); + +// default +int suw_build_hex_string_128(); +int suw_build_hex_string_80(); +int set_data_size_128(); +int set_data_size_80 (); + +void std_build_stratum_request( char* req, struct work* work, unsigned char *xnonce2str, char* ntimestr, char* noncestr ); -void null_reverse_endian_17_19( uint32_t* ntime , uint32_t* nonce, - struct work* work ); -void null_calc_network_diff( struct work* work ); -unsigned char* null_get_xnonce2str( struct work* work, size_t xnonce1_size ); -void null_set_benchmark_work_data( struct work* work ); -void null_build_extraheader( struct work* work, struct stratum_ctx* sctx, + +// default +void std_set_work_data_endian( struct work *work ); +void swab_work_data( struct work *work ); + +// default +void encode_little_endian_17_19( uint32_t* ntime , uint32_t* nonce, + struct work* work ); +void encode_big_endian_17_19( uint32_t* ntime , uint32_t* nonce, + struct work* work ); + +void std_calc_network_diff( struct work* work ); + +unsigned char* std_get_xnonce2str( struct work* work, size_t xnonce1_size ); +void std_set_benchmark_work_data( struct work* work ); +void std_build_extraheader( struct work* work, struct stratum_ctx* sctx, uint32_t* extraheader, int headersize ); -// In a reversal of logic the true null_init_nonce is used by only one -// algo, so far. Every other algo uses the same standard function. -// Both are defined here, the standard is the default initialised below -// and the null is registered only by algo hodl. -//void null_init_nonceptr( struct work* work, struct work* g_work, -// uint32_t **nonceptr, int wkcmp_offset, -// int wkcmp_sz, int nonce_oft, int thr_id ); +// This is the default, if you need null do it yourself. void std_init_nonceptr ( struct work* work, struct work* g_work, uint32_t **nonceptr, int wkcmp_offset, int wkcmp_sz, int nonce_oft, int thr_id ); -char* null_get_nonce2str ( struct work* work ); +// Gate admin functions +bool register_algo_gate( int algo, algo_gate_t *gate ); // The register functions for all the algos can be declared here to reduce // compiler warnings but that's just more work for devs adding new algos. diff --git a/algo/axiom.c b/algo/axiom.c index 3b999c1..613ea8e 100644 --- a/algo/axiom.c +++ b/algo/axiom.c @@ -79,10 +79,12 @@ int scanhash_axiom(int thr_id, struct work *work, return 0; } +/* int64_t axiom_get_max64() { return 0x40LL; } +*/ bool register_axiom_algo( algo_gate_t* gate ) { @@ -90,6 +92,7 @@ bool register_axiom_algo( algo_gate_t* gate ) gate->scanhash = (void*)&scanhash_axiom; gate->hash = (void*)&axiomhash; gate->hash_alt = (void*)&axiomhash; - gate->get_max64 = (void*)&axiom_get_max64; +// gate->get_max64 = (void*)&axiom_get_max64; + gate->get_max64 = (void*)&get_max64_0x40LL; return true; } diff --git a/algo/blake/blake.c b/algo/blake/blake.c index d3ef1fb..b29f1f7 100644 --- a/algo/blake/blake.c +++ b/algo/blake/blake.c @@ -94,6 +94,7 @@ int scanhash_blake( int thr_id, struct work *work, uint32_t max_nonce, return 0; } +// changed to get_max64_0x3fffffLL in cpuminer-multi-decred int64_t blake_get_max64 () { return 0x7ffffLL; diff --git a/algo/blake/blake2.c b/algo/blake/blake2.c index f7d4400..8353dbf 100644 --- a/algo/blake/blake2.c +++ b/algo/blake/blake2.c @@ -54,6 +54,7 @@ int scanhash_blake2s(int thr_id, struct work *work, return 0; } +// changed to get_max64_0x3fffffLL in cpuminer-multi-decred int64_t blake2s_get_max64 () { return 0x7ffffLL; diff --git a/algo/blake/blakecoin.c b/algo/blake/blakecoin.c index 1bb5c63..ed0dbae 100644 --- a/algo/blake/blakecoin.c +++ b/algo/blake/blakecoin.c @@ -102,6 +102,7 @@ void blakecoin_gen_merkle_root ( char* merkle_root, struct stratum_ctx* sctx ) SHA256( sctx->job.coinbase, (int)sctx->job.coinbase_size, merkle_root ); } +// changed to get_max64_0x3fffffLL in cpuminer-multi-decred int64_t blakecoin_get_max64 () { return 0x7ffffLL; @@ -114,7 +115,8 @@ bool register_blakecoin_algo( algo_gate_t* gate ) gate->scanhash = (void*)&scanhash_blakecoin; gate->hash = (void*)&blakecoinhash; gate->hash_alt = (void*)&blakecoinhash; - gate->gen_merkle_root = (void*)&blakecoin_gen_merkle_root; +// gate->gen_merkle_root = (void*)&blakecoin_gen_merkle_root; + gate->gen_merkle_root = (void*)&SHA256_gen_merkle_root; gate->get_max64 = (void*)&blakecoin_get_max64; return true; } diff --git a/algo/blake/decred.c b/algo/blake/decred.c index 2aa0d32..f27b947 100644 --- a/algo/blake/decred.c +++ b/algo/blake/decred.c @@ -157,11 +157,20 @@ unsigned char* decred_get_xnonce2str( struct work* work, size_t xnonce1_size ) return abin2hex((unsigned char*)(&work->data[36]), xnonce1_size ); } +/* void decred_set_data_size( int* data_size, int* adata_sz ) { *data_size = 192; *adata_sz = 180 / 4; } +*/ + +int decred_suw_build_hex_string( struct work *work ) +{ + for ( int i = 0; i < 180 / sizeof(uint32_t); i++ ) + le32enc( &work->data[i], work->data[i] ); + return 192; +} void decred_gen_merkle_root( char* merkle_root, struct stratum_ctx* sctx, int* headersize, uint32_t* extraheader, int extraheader_size ) @@ -216,10 +225,12 @@ bool decred_prevent_dupes( uint32_t* nonceptr, struct work* work, struct stratum return false; } +/* int64_t decred_get_max64 () { return 0x3fffffLL; } +*/ bool register_decred_algo( algo_gate_t* gate ) { @@ -227,12 +238,14 @@ bool register_decred_algo( algo_gate_t* gate ) gate->scanhash = (void*)&scanhash_decred; gate->hash = (void*)&decred_hash; gate->hash_alt = (void*)&decred_hash; - gate->get_max64 = (void*)&decred_get_max64; +// gate->get_max64 = (void*)&decred_get_max64; + gate->get_max64 = (void*)&get_max64_0x3fffffLL; gate->set_data_and_target_size = (void*)&decred_set_data_and_target_size; gate->display_pok = (void*)&decred_decode_extradata; gate->get_xnonce2str = (void*)&decred_get_xnonce2str; - gate->reverse_endian_17_19 = (void*)&decred_reverse_endian_34_35; - gate->set_data_size = (void*)&decred_set_data_size; + gate->encode_endian_17_19 = (void*)&decred_reverse_endian_34_35; +// gate->set_data_size = (void*)&decred_set_data_size; + gate->suw_build_hex_string = (void*)&decred_suw_build_hex_string; gate->gen_merkle_root = (void*)&decred_gen_merkle_root; gate->build_extraheader = (void*)&decred_build_extraheader; gate->ignore_pok = (void*)&decred_regen_work; diff --git a/algo/blake/pentablake.c b/algo/blake/pentablake.c index 54f53eb..317703f 100644 --- a/algo/blake/pentablake.c +++ b/algo/blake/pentablake.c @@ -108,17 +108,20 @@ int scanhash_pentablake(int thr_id, struct work *work, uint32_t max_nonce, return 0; } +/* int64_t pentablake_get_max64 () { return 0x3ffffLL; } +*/ bool register_pentablake_algo( algo_gate_t* gate ) { // gate->init_ctx = init_pentablake_ctx; gate->scanhash = (void*)&scanhash_pentablake; gate->hash = (void*)&pentablakehash; - gate->get_max64 = (void*)&pentablake_get_max64; +// gate->get_max64 = (void*)&pentablake_get_max64; + gate->get_max64 = (void*)&get_max64_0x3ffff; return true; }; diff --git a/algo/cryptolight.c b/algo/cryptolight.c index 5fd5cd1..5d4817b 100644 --- a/algo/cryptolight.c +++ b/algo/cryptolight.c @@ -363,6 +363,7 @@ bool register_cryptolight_algo( algo_gate_t* gate ) gate->scanhash = (void*)&scanhash_cryptolight; gate->hash = (void*)&cryptolight_hash; gate->hash_suw = (void*)&cryptolight_hash; // submit_upstream woek + gate->get_max64 = (void*)&get_max64_0x40LL; jsonrpc_2 = true; return true; }; diff --git a/algo/cryptonight/cryptonight-aesni.c b/algo/cryptonight/cryptonight-aesni.c index 1753958..baea68e 100644 --- a/algo/cryptonight/cryptonight-aesni.c +++ b/algo/cryptonight/cryptonight-aesni.c @@ -1,5 +1,6 @@ #include #include "cryptonight.h" +#include "miner.h" void aesni_parallel_noxor(uint8_t *long_state, uint8_t *text, uint8_t *ExpandedKey); void aesni_parallel_xor(uint8_t *text, uint8_t *ExpandedKey, uint8_t *long_state); diff --git a/algo/cryptonight/cryptonight-common.c b/algo/cryptonight/cryptonight-common.c index 6b36bea..ce72443 100644 --- a/algo/cryptonight/cryptonight-common.c +++ b/algo/cryptonight/cryptonight-common.c @@ -86,10 +86,12 @@ int scanhash_cryptonight( int thr_id, struct work *work, uint32_t max_nonce, return 0; } +/* int64_t cryptonight_get_max64 () { return 0x40LL; } +*/ bool register_cryptonight_algo( algo_gate_t* gate ) { @@ -97,7 +99,8 @@ bool register_cryptonight_algo( algo_gate_t* gate ) gate->scanhash = (void*)&scanhash_cryptonight; gate->hash = (void*)&cryptonight_hash; gate->hash_suw = (void*)&cryptonight_hash_suw; - gate->get_max64 = (void*)&cryptonight_get_max64; +// gate->get_max64 = (void*)&cryptonight_get_max64; + gate->get_max64 = (void*)&get_max64_0x40LL; jsonrpc_2 = true; return true; }; diff --git a/algo/drop.c b/algo/drop.c index 9e3ddce..aecef42 100644 --- a/algo/drop.c +++ b/algo/drop.c @@ -224,12 +224,14 @@ bool drop_ignore_pok( int* wkcmp_sz, int* wkcmp_offset ) return false; } +/* void drop_set_data_size( uint32_t* data_size, uint32_t* adata_sz ) { *data_size = 80; *adata_sz = *data_size / sizeof(uint32_t); } +*/ void reverse_drop_endian( struct work* work ) { @@ -238,12 +240,14 @@ void reverse_drop_endian( struct work* work ) work->data[i] = swab32( work->data[i] ); } +/* void reverse_drop_endian_17_19( uint32_t* ntime, uint32_t* nonce, struct work* work ) { be32enc( ntime, work->data[17] ); be32enc( nonce, work->data[19] ); } +*/ void display_drop_pok ( struct work* work ) { @@ -268,11 +272,13 @@ bool register_drop_algo( algo_gate_t* gate ) gate->hash = (void*)&droplp_hash_pok; gate->hash_alt = (void*)&droplp_hash_pok; gate->hash_suw = (void*)&droplp_hash_pok; - gate->set_target = (void*)&drop_set_target; +// gate->set_target = (void*)&drop_set_target; + gate->set_target = (void*)&scrypt_set_target; gate->ignore_pok = (void*)&drop_ignore_pok; - gate->set_data_size = (void*)&drop_set_data_size; - gate->reverse_endian = (void*)&reverse_drop_endian; - gate->reverse_endian_17_19 = (void*)&reverse_drop_endian_17_19; + gate->suw_build_hex_string = (void*)&suw_build_hex_string_80; +// gate->set_data_size = (void*)&set_data_size_80; + gate->set_work_data_endian = (void*)&swab_work_data; + gate->encode_endian_17_19 = (void*)&encode_big_endian_17_19; gate->display_pok = (void*)&display_drop_pok; gate->set_data_and_target_size = (void*)&drop_set_data_and_target_size; return true; diff --git a/algo/echo/aes_ni/hash.c b/algo/echo/aes_ni/hash.c index e4fac3d..074506c 100644 --- a/algo/echo/aes_ni/hash.c +++ b/algo/echo/aes_ni/hash.c @@ -19,8 +19,6 @@ #include "hash_api.h" #include "vperm.h" -//#ifdef AES_NI - #ifndef NO_AES_NI #include #else diff --git a/algo/fresh.c b/algo/fresh.c index a4d3e80..c83784c 100644 --- a/algo/fresh.c +++ b/algo/fresh.c @@ -134,6 +134,7 @@ bool register_fresh_algo( algo_gate_t* gate ) gate->hash = (void*)&freshhash; gate->hash_alt = (void*)&freshhash; gate->set_target = (void*)&fresh_set_target; + gate->get_max64 = (void*)&get_max64_0x3ffff; return true; }; diff --git a/algo/groestl/aes_ni/hash-groestl.c b/algo/groestl/aes_ni/hash-groestl.c index 5ff075e..47c6a12 100644 --- a/algo/groestl/aes_ni/hash-groestl.c +++ b/algo/groestl/aes_ni/hash-groestl.c @@ -9,9 +9,6 @@ #include "hash-groestl.h" #include "miner.h" -//#define AES_NI -//#ifdef AES_NI - #ifndef NO_AES_NI #include "groestl-version.h" diff --git a/algo/groestl/groestl.c b/algo/groestl/groestl.c index 1ad7e3e..fc27276 100644 --- a/algo/groestl/groestl.c +++ b/algo/groestl/groestl.c @@ -97,10 +97,12 @@ int scanhash_groestl(int thr_id, struct work *work, return 0; } +/* unsigned char groestl_gen_merkle_root ( char* merkle_root, struct stratum_ctx* sctx ) { SHA256( sctx->job.coinbase, (int)sctx->job.coinbase_size, merkle_root ); } +*/ void groestl_set_target( struct work* work, double job_diff ) { @@ -115,7 +117,9 @@ bool register_groestl_algo( algo_gate_t* gate ) gate->hash = (void*)&groestlhash; gate->hash_alt = (void*)&groestlhash; gate->set_target = (void*)&groestl_set_target; - gate->gen_merkle_root = (void*)&groestl_gen_merkle_root; +// gate->gen_merkle_root = (void*)&groestl_gen_merkle_root; + gate->gen_merkle_root = (void*)&SHA256_gen_merkle_root; + gate->get_max64 = (void*)&get_max64_0x3ffff; return true; }; diff --git a/algo/groestl/myr-groestl.c b/algo/groestl/myr-groestl.c new file mode 100644 index 0000000..bad2deb --- /dev/null +++ b/algo/groestl/myr-groestl.c @@ -0,0 +1,111 @@ +#include "miner.h" +#include "algo-gate-api.h" + +#include +#include +#include +#include + +#ifdef NO_AES_NI + #include "sph_groestl.h" +#else + #include "aes_ni/hash-groestl.h" +#endif +#include "algo/sha3/sph_sha2.h" + +typedef struct { +#ifdef NO_AES_NI + sph_groestl512_context groestl; +#else + hashState_groestl groestl; +#endif + sph_sha256_context sha; +} myrgr_ctx_holder; + +myrgr_ctx_holder myrgr_ctx; + +void init_myrgr_ctx() +{ +#ifdef NO_AES_NI + sph_groestl512_init( &myrgr_ctx.groestl ); +#else + init_groestl (&myrgr_ctx.groestl ); +#endif + sph_sha256_init(&myrgr_ctx.sha); +} + +void myriadhash(void *output, const void *input) +{ + myrgr_ctx_holder ctx; + memcpy( &ctx, &myrgr_ctx, sizeof(myrgr_ctx) ); + + uint32_t _ALIGN(32) hash[16]; +// sph_groestl512_context ctx; +// sph_sha256_context sha_ctx; + + // memset(&hash[0], 0, sizeof(hash)); + +// sph_groestl512_init(&ctx); +#ifdef NO_AES_NI + sph_groestl512(&ctx.groestl, input, 80); + sph_groestl512_close(&ctx.groestl, hash); +#else + update_groestl( &ctx.groestl, (char*)hash,512); + final_groestl( &ctx.groestl, (char*)hash); +#endif + +// sph_sha256_init(&sha_ctx); + sph_sha256(&ctx.sha, hash, 64); + sph_sha256_close(&ctx.sha, hash); + + memcpy(output, hash, 32); + +} + +int scanhash_myriad(int thr_id, struct work *work, + uint32_t max_nonce, uint64_t *hashes_done) +{ + uint32_t *pdata = work->data; + uint32_t *ptarget = work->target; + + uint32_t _ALIGN(64) endiandata[20]; + const uint32_t first_nonce = pdata[19]; + uint32_t nonce = first_nonce; + + if (opt_benchmark) + ((uint32_t*)ptarget)[7] = 0x0000ff; + + for (int k=0; k < 20; k++) + be32enc(&endiandata[k], ((uint32_t*)pdata)[k]); + + do { + const uint32_t Htarg = ptarget[7]; + uint32_t hash[8]; + be32enc(&endiandata[19], nonce); + myriadhash(hash, endiandata); + + if (hash[7] <= Htarg && fulltest(hash, ptarget)) { + pdata[19] = nonce; + *hashes_done = pdata[19] - first_nonce; + return 1; + } + nonce++; + + } while (nonce < max_nonce && !work_restart[thr_id].restart); + + pdata[19] = nonce; + *hashes_done = pdata[19] - first_nonce + 1; + return 0; +} + +bool register_myriad_algo( algo_gate_t* gate ) +{ + gate->aes_ni_optimized = (void*)&return_true; + gate->init_ctx = (void*)&init_myrgr_ctx; + gate->scanhash = (void*)&scanhash_myriad; + gate->hash = (void*)&myriadhash; + gate->hash_alt = (void*)&myriadhash; + gate->get_max64 = (void*)&get_max64_0x3ffff; + return true; +}; + diff --git a/algo/hodl/aes.c b/algo/hodl/aes.c index 6f1f901..b481c7d 100644 --- a/algo/hodl/aes.c +++ b/algo/hodl/aes.c @@ -1,5 +1,6 @@ #include #include +#include "miner.h" #include "miner.h" diff --git a/algo/hodl/hodl-gate.c b/algo/hodl/hodl-gate.c index 38975e7..56544e3 100644 --- a/algo/hodl/hodl-gate.c +++ b/algo/hodl/hodl-gate.c @@ -34,12 +34,14 @@ bool hodl_get_scratchbuf( unsigned char** scratchbuf ) return ( *scratchbuf != NULL ); } +/* void hodl_reverse_endian_17_19( uint32_t* ntime, uint32_t* nonce, struct work* work ) { le32enc(ntime, work->data[17]); le32enc(nonce, work->data[19]); } +*/ char *hodl_build_stratum_request( char* req, struct work* work, unsigned char *xnonce2str, char* ntimestr, char* noncestr ) @@ -134,7 +136,7 @@ bool register_hodl_algo ( algo_gate_t* gate ) #endif gate->set_target = (void*)&hodl_set_target; gate->get_scratchbuf = (void*)&hodl_get_scratchbuf; - gate->reverse_endian_17_19 = (void*)&hodl_reverse_endian_17_19; +// gate->reverse_endian_17_19 = (void*)&hodl_reverse_endian_17_19; gate->build_stratum_request = (void*)&hodl_build_stratum_request; // gate->set_data_size = (void*)&hodl_set_data_size; gate->build_extraheader = (void*)&hodl_build_extraheader; @@ -143,8 +145,8 @@ bool register_hodl_algo ( algo_gate_t* gate ) gate->backup_work_data = (void*)&hodl_backup_work_data; gate->restore_work_data = (void*)&hodl_restore_work_data; gate->init_nonceptr = (void*)&do_nothing; - gate->do_all_threads = (void*)&hodl_do_all_threads; gate->get_pseudo_random_data = (void*)&hodl_get_pseudo_random_data; + gate->do_all_threads = (void*)&hodl_do_all_threads; return true; } diff --git a/algo/keccak/keccak.c b/algo/keccak/keccak.c index 46de9d7..87a32d4 100644 --- a/algo/keccak/keccak.c +++ b/algo/keccak/keccak.c @@ -54,10 +54,12 @@ int scanhash_keccak(int thr_id, struct work *work, return 0; } +/* void keccak_gen_merkle_root ( char* merkle_root, struct stratum_ctx* sctx ) { SHA256( sctx->job.coinbase, (int)sctx->job.coinbase_size, merkle_root ); } +*/ void keccak_set_target( struct work* work, double job_diff ) { @@ -69,7 +71,8 @@ bool register_keccak_algo( algo_gate_t* gate ) // gate->init_ctx = &init_keccak_aes_ctx; gate->scanhash = (void*)&scanhash_keccak; gate->hash = (void*)&keccakhash; - gate->gen_merkle_root = (void*)&keccak_gen_merkle_root; +// gate->gen_merkle_root = (void*)&keccak_gen_merkle_root; + gate->gen_merkle_root = (void*)&SHA256_gen_merkle_root; gate->set_target = (void*)&keccak_set_target; return true; }; diff --git a/algo/m7m.c b/algo/m7m.c new file mode 100644 index 0000000..b03e8bf --- /dev/null +++ b/algo/m7m.c @@ -0,0 +1,403 @@ +#include "miner.h" +#include "algo-gate-api.h" +#include /* user MPIR lib for vstudio */ +#include +#include +#include +#include +#include +#include + +#include "algo/sha2/sph-sha2.h" +#include "algo/keccak/sph_keccak.h" +#include "algo/haval/sph-haval.h" +#include "algo/tiger/sph_tiger.h" +#include "algo/whirlpool/sph_whirlpool.h" +#include "algo/ripemd/sph_ripemd.h" + +#include "crypto/magimath.h" + + +static bool cputest = false; +static uint32_t* hashtest = NULL; + +static inline void mpz_set_uint256(mpz_t r, uint8_t *u) +{ + mpz_import(r, 32 / sizeof(unsigned long), -1, sizeof(unsigned long), -1, 0, u); +} + +static inline void mpz_set_uint512(mpz_t r, uint8_t *u) +{ + mpz_import(r, 64 / sizeof(unsigned long), -1, sizeof(unsigned long), -1, 0, u); +} + +static inline void set_one_if_zero(uint8_t *hash512) { + for (int i = 0; i < 32; i++) { + if (hash512[i] != 0) { + return; + } + } + hash512[0] = 1; +} + +static bool fulltest_m7hash(const uint32_t *hash32, const uint32_t *target32) +{ + int i; + bool rc = true; + + const unsigned char *hash = (const unsigned char *)hash32; + const unsigned char *target = (const unsigned char *)target32; + for (i = 31; i >= 0; i--) { + if (hash[i] != target[i]) { + rc = hash[i] < target[i]; + break; + } + } + + return rc; +} + +static __thread mpf_t mpsqrt; +static __thread int s_digits = -1; + +#define BITS_PER_DIGIT 3.32192809488736234787 +#define EPS (DBL_EPSILON) + +#define NM7M 5 +#define SW_DIVS 5 +#define M7_MIDSTATE_LEN 76 + +typedef struct { + sph_sha256_context sha256; + sph_sha512_context sha512; + sph_keccak512_context keccak; + sph_whirlpool_context whirlpool; + sph_haval256_5_context haval; + sph_tiger_context tiger; + sph_ripemd160_context ripemd; +} m7m_ctx_holder; + +sph_sha256_context m7m_ctx_final_sha256; +m7m_ctx_holder m7m_ctx1, m7m_ctx2; + +void init_m7m_ctx() +{ + sph_sha256_init(&m7m_ctx_final_sha256); + sph_sha256_init(&m7m_ctx1.sha256); + sph_sha512_init(&m7m_ctx1.sha512); + sph_keccak512_init(&m7m_ctx1.keccak); + sph_whirlpool_init(&m7m_ctx1.whirlpool); + sph_haval256_5_init(&m7m_ctx1.haval); + sph_tiger_init(&m7m_ctx1.tiger); + sph_ripemd160_init(&m7m_ctx1.ripemd); +} + +int scanhash_m7m(int thr_id, struct work *work, uint64_t max_nonce, uint64_t *hashes_done) +{ + uint32_t _ALIGN(128) data[32]; + uint8_t _ALIGN(128) bhash[7][64]; + uint32_t _ALIGN(128) hash[8]; + uint32_t *pdata = work->data; + uint32_t *ptarget = work->target; + uint32_t *data_p64 = data + (M7_MIDSTATE_LEN / sizeof(data[0])); + uint32_t n = pdata[19]; + const uint32_t first_nonce = pdata[19]; + char data_str[161], hash_str[65], target_str[65]; + uint8_t *bdata = 0; + mpz_t bns[8]; + int rc = 0; + int bytes, nnNonce2; + + m7m_ctx_holder ctx, ctx2; + memcpy( &ctx, &m7m_ctx1, sizeof(m7m_ctx1) ); + sph_sha256_context ctxf_sha256; + memcpy( &ctxf_sha256, &m7m_ctx_final_sha256, sizeof(sph_sha256_context) ); + + mpz_t product; + mpz_init(product); + + for(int i=0; i < 8; i++){ + mpz_init(bns[i]); + } + + memcpy(data, pdata, 80); + + sph_sha256 (&ctx.sha256, data, M7_MIDSTATE_LEN); + sph_sha512 (&ctx.sha512, data, M7_MIDSTATE_LEN); + sph_keccak512 (&ctx.keccak, data, M7_MIDSTATE_LEN); + sph_whirlpool (&ctx.whirlpool, data, M7_MIDSTATE_LEN); + sph_haval256_5 (&ctx.haval, data, M7_MIDSTATE_LEN); + sph_tiger (&ctx.tiger, data, M7_MIDSTATE_LEN); + sph_ripemd160 (&ctx.ripemd, data, M7_MIDSTATE_LEN); + + mpf_t mpa1, mpb1, mpt1; + mpf_t mpa2, mpb2, mpt2; + mpf_t magifpi; + mpf_t mpsft; + + mpz_t magipi; + mpz_t magisw; + mpz_init(magipi); + mpz_init(magisw); + + do { + + if (!cputest) + data[19] = n++; + else + hashtest = hash; + + nnNonce2 = (int)(data[19]/2); + //memset(bhash, 0, 7 * 64); + memset(&bhash[0][32], 0, 32); // sha256 + memset(&bhash[4][32], 0, 32 + 64*2); // haval/tiger/ripemd + + memcpy( &ctx2, &ctx, sizeof(m7m_ctx1) ); + + sph_sha256 (&ctx2.sha256, data_p64, 80 - M7_MIDSTATE_LEN); + sph_sha256_close(&ctx2.sha256, (void*)(bhash[0])); + + sph_sha512 (&ctx2.sha512, data_p64, 80 - M7_MIDSTATE_LEN); + sph_sha512_close(&ctx2.sha512, (void*)(bhash[1])); + + sph_keccak512 (&ctx2.keccak, data_p64, 80 - M7_MIDSTATE_LEN); + sph_keccak512_close(&ctx2.keccak, (void*)(bhash[2])); + + sph_whirlpool (&ctx2.whirlpool, data_p64, 80 - M7_MIDSTATE_LEN); + sph_whirlpool_close(&ctx2.whirlpool, (void*)(bhash[3])); + + sph_haval256_5 (&ctx2.haval, data_p64, 80 - M7_MIDSTATE_LEN); + sph_haval256_5_close(&ctx2.haval, (void*)(bhash[4])); + + sph_tiger (&ctx2.tiger, data_p64, 80 - M7_MIDSTATE_LEN); + sph_tiger_close(&ctx2.tiger, (void*)(bhash[5])); + + sph_ripemd160 (&ctx2.ripemd, data_p64, 80 - M7_MIDSTATE_LEN); + sph_ripemd160_close(&ctx2.ripemd, (void*)(bhash[6])); + + for(int i=0; i < 7; i++){ + set_one_if_zero(bhash[i]); + mpz_set_uint512(bns[i], bhash[i]); + } + + mpz_set_ui(bns[7],0); + + for(int i=0; i < 7; i++){ + mpz_add(bns[7], bns[7], bns[i]); + } + + mpz_set_ui(product,1); + + for(int i=0; i < 8; i++){ + mpz_mul(product,product,bns[i]); + } + + mpz_pow_ui(product, product, 2); + + bytes = mpz_sizeinbase(product, 256); + bdata = (uint8_t *)realloc(bdata, bytes); + mpz_export((void *)bdata, NULL, -1, 1, 0, 0, product); + + sph_sha256 (&ctxf_sha256, bdata, bytes); + sph_sha256_close(&ctxf_sha256, (void*)(hash)); + + const int digits=(int)((sqrt((double)(nnNonce2))*(1.+EPS))/9000+75); + if (digits != s_digits) { + int prec = (int)(digits*BITS_PER_DIGIT+16); + mpf_set_default_prec(prec); + if (s_digits == -1) mpf_init(mpsqrt); + s_digits = digits; + mpf_set_ui(mpsqrt, 2); + mpf_sqrt(mpsqrt, mpsqrt); + mpf_ui_div(mpsqrt, 1, mpsqrt); // 1 / √2 + } + + mpf_init(magifpi); + mpf_init(mpsft); + mpf_init(mpa1); + mpf_init(mpb1); + mpf_init(mpt1); + + mpf_init(mpa2); + mpf_init(mpb2); + mpf_init(mpt2); + + uint32_t usw_ = sw_(nnNonce2, SW_DIVS); + if (usw_ < 1) usw_ = 1; + mpz_set_ui(magisw, usw_); + uint32_t mpzscale = (uint32_t) mpz_size(magisw); + + for(int i=0; i < NM7M; i++) + { + const int iterations = 20; + + if (mpzscale > 1000) mpzscale = 1000; + else if (mpzscale < 1) mpzscale = 1; + + mpf_set_d(mpt1, 0.25*mpzscale); + + mpf_set(mpb1, mpsqrt); // B' = 1 / √2 => pow(2, -0.5) + + mpf_set_ui(mpa1, 1); // A' = 1 + uint32_t p = 1; + + for(int j=0; j <= iterations; j++){ + // A = AVG(A',B') + mpf_add(mpa2, mpa1, mpb1); // A = A' + B' + mpf_div_ui(mpa2, mpa2, 2); // A /= 2 + + // B = √(A'B') + mpf_mul(mpb2, mpa1, mpb1); // B = A' * B' + mpf_abs(mpb2, mpb2); // B = ABS(B) + mpf_sqrt(mpb2, mpb2); // B = √B + mpf_swap(mpb1, mpb2); + + // T = √(A'-A) + mpf_sub(mpt2, mpa1, mpa2); // T = A' - A + mpf_abs(mpt2, mpt2); // T = ABS(T) + mpf_sqrt(mpt2, mpt2); // T = √T + mpf_swap(mpa1, mpa2); + + // T = T' - T*P + mpf_mul_ui(mpt2, mpt2, p); // T *= P + mpf_sub(mpt1, mpt1, mpt2); // T = T' - T + + p <<= 1; + } + + // PI = (A + B)²/4 + mpf_add(magifpi, mpa1, mpb1); + mpf_pow_ui(magifpi, magifpi, 2); + mpf_div_ui(magifpi, magifpi, 4); + + // PI = PI / |T| + mpf_abs(mpt1, mpt1); + mpf_div(magifpi, magifpi, mpt1); + + // PI = Extract float part digits + mpf_set_ui(mpsft, 10); + mpf_pow_ui(mpsft, mpsft, digits/2); + mpf_mul(magifpi, magifpi, mpsft); + mpz_set_f(magipi, magifpi); + + mpz_add(product,product,magipi); + mpz_add(product,product,magisw); + + mpz_set_uint256(bns[0], (void*)(hash)); + mpz_add(bns[7], bns[7], bns[0]); + + mpz_mul(product,product,bns[7]); + mpz_cdiv_q (product, product, bns[0]); + if (mpz_sgn(product) <= 0) mpz_set_ui(product,1); + + bytes = mpz_sizeinbase(product, 256); + mpzscale = bytes; + bdata = (uint8_t *)realloc(bdata, bytes); + mpz_export(bdata, NULL, -1, 1, 0, 0, product); + + memcpy( &ctxf_sha256, &m7m_ctx_final_sha256, + sizeof(sph_sha256_context) ); + sph_sha256 (&ctxf_sha256, bdata, bytes); + sph_sha256_close(&ctxf_sha256, (void*)(hash)); + } + + mpf_clear(magifpi); + mpf_clear(mpsft); + mpf_clear(mpa1); + mpf_clear(mpb1); + mpf_clear(mpt1); + + mpf_clear(mpa2); + mpf_clear(mpb2); + mpf_clear(mpt2); + + rc = fulltest_m7hash(hash, ptarget); + if (rc) { + work_set_target_ratio(work, hash); + if (opt_debug) { + bin2hex(hash_str, (unsigned char *)hash, 32); + bin2hex(target_str, (unsigned char *)ptarget, 32); + bin2hex(data_str, (unsigned char *)data, 80); + applog(LOG_DEBUG, "DEBUG: [%d thread] Found share!\ndata %s\nhash %s\ntarget %s", thr_id, + data_str, + hash_str, + target_str); + } + + pdata[19] = data[19]; + + goto out; + } + } while (n < max_nonce && !work_restart[thr_id].restart); + + pdata[19] = n; + +out: + mpz_clear(magipi); + mpz_clear(magisw); + for(int i=0; i < 8; i++) { + mpz_clear(bns[i]); + } + mpz_clear(product); + free(bdata); + + *hashes_done = n - first_nonce + 1; + return rc; +} + +/* --cputest */ +void m7mhash(void *output, const void *input) +{ + uint64_t hashes_done = 0; + struct work work; + memset(&work, 0, sizeof(struct work)); + memcpy(work.data, input, 80); + cputest = true; + scanhash_m7m(0, &work, 0, &hashes_done); + if (hashtest) + memcpy(output, hashtest, 32); + cputest = false; +} + +bool m7m_work_decode( const json_t *val, struct work *work ) +{ + int i; + int data_size = sizeof(work->data); + int target_size = sizeof(work->target); + int adata_sz = ARRAY_SIZE(work->data); + int atarget_sz = ARRAY_SIZE(work->target); + + algo_gate.set_data_and_target_size( &data_size, &target_size, + &adata_sz, &atarget_sz, &allow_mininginfo ); + + if ( unlikely(!jobj_binary( val, "data", work->data, data_size )) ) + { + applog(LOG_ERR, "JSON invalid data"); + return false; + } + if ( unlikely(!jobj_binary( val, "target", work->target, target_size )) ) + { + applog(LOG_ERR, "JSON invalid target"); + return false; + } + return true; +} + +void m7m_reverse_endian( struct work *work ) +{ + for ( int i = 0; i < 32; i++ ) + be32enc( &work->data[i], work->data[i] ); +} + +bool register_m7m_algo( algo_gate_t *gate ) +{ + gate->init_ctx = (void*)&init_m7m_ctx; + gate->scanhash = (void*)&scanhash_m7m; + gate->hash = (void*)&m7mhash; + gate->hash_alt = (void*)&m7mhash; + gate->encode_endian_17_19 = (void*)&encode_big_endian_17_19; + gate->suw_build_hex_string = (void*)&set_data_size_80; + gate->set_target = (void*)&scrypt_set_target; + gate->get_max64 = (void*)&get_max64_0x1ffff; + gate->set_work_data_endian = (void*)&m7m_reverse_endian; +} diff --git a/algo/neoscrypt.c b/algo/neoscrypt.c index 24c70d0..249b312 100644 --- a/algo/neoscrypt.c +++ b/algo/neoscrypt.c @@ -1094,25 +1094,30 @@ void neoscrypt_wait_for_diff( struct stratum_ctx *stratum ) } } +/* void reverse_neoscrypt_endian( struct work* work ) { int i; for (i = 0; i <= 18; i++) work->data[i] = swab32( work->data[i] ); } +*/ +/* void reverse_neoscrypt_endian_17_19( uint32_t* ntime, uint32_t* nonce, struct work* work ) { be32enc( ntime, work->data[17] ); be32enc( nonce, work->data[19] ); } - +*/ +/* void neoscrypt_set_data_size( uint32_t* data_size, uint32_t* adata_sz ) { *data_size = 80; *adata_sz = *data_size / sizeof(uint32_t); } +*/ void neoscrypt_set_data_and_target_size( int *data_size, int *target_size, int *adata_sz, int *atarget_sz ) @@ -1129,12 +1134,14 @@ bool register_neoscrypt_algo( algo_gate_t* gate ) gate->hash = (void*)&neoscrypt; gate->hash_alt = (void*)&neoscrypt; gate->get_max64 = (void*)&get_neoscrypt_max64; - gate->set_target = (void*)&neoscrypt_set_target; +// gate->set_target = (void*)&neoscrypt_set_target; + gate->set_target = (void*)&scrypt_set_target; gate->wait_for_diff = (void*)&neoscrypt_wait_for_diff; - gate->set_data_size = (void*)&neoscrypt_set_data_size; + gate->suw_build_hex_string = (void*)&suw_build_hex_string_80; +// gate->set_data_size = (void*)&set_data_size_80; gate->set_data_and_target_size = (void*)&neoscrypt_set_data_and_target_size; - gate->reverse_endian = (void*)&reverse_neoscrypt_endian; - gate->reverse_endian_17_19 = (void*)&reverse_neoscrypt_endian_17_19; + gate->set_work_data_endian = (void*)&swab_work_data; + gate->encode_endian_17_19 = (void*)&encode_big_endian_17_19; return true; }; diff --git a/algo/pluck.c b/algo/pluck.c index e9c133c..5dff2cf 100644 --- a/algo/pluck.c +++ b/algo/pluck.c @@ -502,7 +502,8 @@ bool register_pluck_algo( algo_gate_t* gate ) algo_not_tested(); gate->scanhash = (void*)&scanhash_pluck; gate->hash = (void*)&pluck_hash; - gate->set_target = (void*)&pluck_set_target; +// gate->set_target = (void*)&pluck_set_target; + gate->set_target = (void*)&scrypt_set_target; gate->get_scratchbuf = (void*)&get_pluck_scratchbuf; gate->get_max64 = (void*)&pluck_get_max64; return true; diff --git a/algo/ripemd/sph_ripemd.c b/algo/ripemd/sph_ripemd.c new file mode 100644 index 0000000..10c6ad0 --- /dev/null +++ b/algo/ripemd/sph_ripemd.c @@ -0,0 +1,834 @@ +/* $Id: ripemd.c 216 2010-06-08 09:46:57Z tp $ */ +/* + * RIPEMD-160 implementation. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @author Thomas Pornin + */ + +#include +#include + +#include "sph_ripemd.h" + +/* + * Round functions for RIPEMD (original). + */ +#define F(x, y, z) ((((y) ^ (z)) & (x)) ^ (z)) +#define G(x, y, z) (((x) & (y)) | (((x) | (y)) & (z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) + +static const sph_u32 oIV[5] = { + SPH_C32(0x67452301), SPH_C32(0xEFCDAB89), + SPH_C32(0x98BADCFE), SPH_C32(0x10325476) +}; + +/* + * Round functions for RIPEMD-128 and RIPEMD-160. + */ +#define F1(x, y, z) ((x) ^ (y) ^ (z)) +#define F2(x, y, z) ((((y) ^ (z)) & (x)) ^ (z)) +#define F3(x, y, z) (((x) | ~(y)) ^ (z)) +#define F4(x, y, z) ((((x) ^ (y)) & (z)) ^ (y)) +#define F5(x, y, z) ((x) ^ ((y) | ~(z))) + +static const sph_u32 IV[5] = { + SPH_C32(0x67452301), SPH_C32(0xEFCDAB89), SPH_C32(0x98BADCFE), + SPH_C32(0x10325476), SPH_C32(0xC3D2E1F0) +}; + +#define ROTL SPH_ROTL32 + +/* ===================================================================== */ +/* + * RIPEMD (original hash, deprecated). + */ + +#define FF1(A, B, C, D, X, s) do { \ + sph_u32 tmp = SPH_T32((A) + F(B, C, D) + (X)); \ + (A) = ROTL(tmp, (s)); \ + } while (0) + +#define GG1(A, B, C, D, X, s) do { \ + sph_u32 tmp = SPH_T32((A) + G(B, C, D) \ + + (X) + SPH_C32(0x5A827999)); \ + (A) = ROTL(tmp, (s)); \ + } while (0) + +#define HH1(A, B, C, D, X, s) do { \ + sph_u32 tmp = SPH_T32((A) + H(B, C, D) \ + + (X) + SPH_C32(0x6ED9EBA1)); \ + (A) = ROTL(tmp, (s)); \ + } while (0) + +#define FF2(A, B, C, D, X, s) do { \ + sph_u32 tmp = SPH_T32((A) + F(B, C, D) \ + + (X) + SPH_C32(0x50A28BE6)); \ + (A) = ROTL(tmp, (s)); \ + } while (0) + +#define GG2(A, B, C, D, X, s) do { \ + sph_u32 tmp = SPH_T32((A) + G(B, C, D) + (X)); \ + (A) = ROTL(tmp, (s)); \ + } while (0) + +#define HH2(A, B, C, D, X, s) do { \ + sph_u32 tmp = SPH_T32((A) + H(B, C, D) \ + + (X) + SPH_C32(0x5C4DD124)); \ + (A) = ROTL(tmp, (s)); \ + } while (0) + +#define RIPEMD_ROUND_BODY(in, h) do { \ + sph_u32 A1, B1, C1, D1; \ + sph_u32 A2, B2, C2, D2; \ + sph_u32 tmp; \ + \ + A1 = A2 = (h)[0]; \ + B1 = B2 = (h)[1]; \ + C1 = C2 = (h)[2]; \ + D1 = D2 = (h)[3]; \ + \ + FF1(A1, B1, C1, D1, in( 0), 11); \ + FF1(D1, A1, B1, C1, in( 1), 14); \ + FF1(C1, D1, A1, B1, in( 2), 15); \ + FF1(B1, C1, D1, A1, in( 3), 12); \ + FF1(A1, B1, C1, D1, in( 4), 5); \ + FF1(D1, A1, B1, C1, in( 5), 8); \ + FF1(C1, D1, A1, B1, in( 6), 7); \ + FF1(B1, C1, D1, A1, in( 7), 9); \ + FF1(A1, B1, C1, D1, in( 8), 11); \ + FF1(D1, A1, B1, C1, in( 9), 13); \ + FF1(C1, D1, A1, B1, in(10), 14); \ + FF1(B1, C1, D1, A1, in(11), 15); \ + FF1(A1, B1, C1, D1, in(12), 6); \ + FF1(D1, A1, B1, C1, in(13), 7); \ + FF1(C1, D1, A1, B1, in(14), 9); \ + FF1(B1, C1, D1, A1, in(15), 8); \ + \ + GG1(A1, B1, C1, D1, in( 7), 7); \ + GG1(D1, A1, B1, C1, in( 4), 6); \ + GG1(C1, D1, A1, B1, in(13), 8); \ + GG1(B1, C1, D1, A1, in( 1), 13); \ + GG1(A1, B1, C1, D1, in(10), 11); \ + GG1(D1, A1, B1, C1, in( 6), 9); \ + GG1(C1, D1, A1, B1, in(15), 7); \ + GG1(B1, C1, D1, A1, in( 3), 15); \ + GG1(A1, B1, C1, D1, in(12), 7); \ + GG1(D1, A1, B1, C1, in( 0), 12); \ + GG1(C1, D1, A1, B1, in( 9), 15); \ + GG1(B1, C1, D1, A1, in( 5), 9); \ + GG1(A1, B1, C1, D1, in(14), 7); \ + GG1(D1, A1, B1, C1, in( 2), 11); \ + GG1(C1, D1, A1, B1, in(11), 13); \ + GG1(B1, C1, D1, A1, in( 8), 12); \ + \ + HH1(A1, B1, C1, D1, in( 3), 11); \ + HH1(D1, A1, B1, C1, in(10), 13); \ + HH1(C1, D1, A1, B1, in( 2), 14); \ + HH1(B1, C1, D1, A1, in( 4), 7); \ + HH1(A1, B1, C1, D1, in( 9), 14); \ + HH1(D1, A1, B1, C1, in(15), 9); \ + HH1(C1, D1, A1, B1, in( 8), 13); \ + HH1(B1, C1, D1, A1, in( 1), 15); \ + HH1(A1, B1, C1, D1, in(14), 6); \ + HH1(D1, A1, B1, C1, in( 7), 8); \ + HH1(C1, D1, A1, B1, in( 0), 13); \ + HH1(B1, C1, D1, A1, in( 6), 6); \ + HH1(A1, B1, C1, D1, in(11), 12); \ + HH1(D1, A1, B1, C1, in(13), 5); \ + HH1(C1, D1, A1, B1, in( 5), 7); \ + HH1(B1, C1, D1, A1, in(12), 5); \ + \ + FF2(A2, B2, C2, D2, in( 0), 11); \ + FF2(D2, A2, B2, C2, in( 1), 14); \ + FF2(C2, D2, A2, B2, in( 2), 15); \ + FF2(B2, C2, D2, A2, in( 3), 12); \ + FF2(A2, B2, C2, D2, in( 4), 5); \ + FF2(D2, A2, B2, C2, in( 5), 8); \ + FF2(C2, D2, A2, B2, in( 6), 7); \ + FF2(B2, C2, D2, A2, in( 7), 9); \ + FF2(A2, B2, C2, D2, in( 8), 11); \ + FF2(D2, A2, B2, C2, in( 9), 13); \ + FF2(C2, D2, A2, B2, in(10), 14); \ + FF2(B2, C2, D2, A2, in(11), 15); \ + FF2(A2, B2, C2, D2, in(12), 6); \ + FF2(D2, A2, B2, C2, in(13), 7); \ + FF2(C2, D2, A2, B2, in(14), 9); \ + FF2(B2, C2, D2, A2, in(15), 8); \ + \ + GG2(A2, B2, C2, D2, in( 7), 7); \ + GG2(D2, A2, B2, C2, in( 4), 6); \ + GG2(C2, D2, A2, B2, in(13), 8); \ + GG2(B2, C2, D2, A2, in( 1), 13); \ + GG2(A2, B2, C2, D2, in(10), 11); \ + GG2(D2, A2, B2, C2, in( 6), 9); \ + GG2(C2, D2, A2, B2, in(15), 7); \ + GG2(B2, C2, D2, A2, in( 3), 15); \ + GG2(A2, B2, C2, D2, in(12), 7); \ + GG2(D2, A2, B2, C2, in( 0), 12); \ + GG2(C2, D2, A2, B2, in( 9), 15); \ + GG2(B2, C2, D2, A2, in( 5), 9); \ + GG2(A2, B2, C2, D2, in(14), 7); \ + GG2(D2, A2, B2, C2, in( 2), 11); \ + GG2(C2, D2, A2, B2, in(11), 13); \ + GG2(B2, C2, D2, A2, in( 8), 12); \ + \ + HH2(A2, B2, C2, D2, in( 3), 11); \ + HH2(D2, A2, B2, C2, in(10), 13); \ + HH2(C2, D2, A2, B2, in( 2), 14); \ + HH2(B2, C2, D2, A2, in( 4), 7); \ + HH2(A2, B2, C2, D2, in( 9), 14); \ + HH2(D2, A2, B2, C2, in(15), 9); \ + HH2(C2, D2, A2, B2, in( 8), 13); \ + HH2(B2, C2, D2, A2, in( 1), 15); \ + HH2(A2, B2, C2, D2, in(14), 6); \ + HH2(D2, A2, B2, C2, in( 7), 8); \ + HH2(C2, D2, A2, B2, in( 0), 13); \ + HH2(B2, C2, D2, A2, in( 6), 6); \ + HH2(A2, B2, C2, D2, in(11), 12); \ + HH2(D2, A2, B2, C2, in(13), 5); \ + HH2(C2, D2, A2, B2, in( 5), 7); \ + HH2(B2, C2, D2, A2, in(12), 5); \ + \ + tmp = SPH_T32((h)[1] + C1 + D2); \ + (h)[1] = SPH_T32((h)[2] + D1 + A2); \ + (h)[2] = SPH_T32((h)[3] + A1 + B2); \ + (h)[3] = SPH_T32((h)[0] + B1 + C2); \ + (h)[0] = tmp; \ + } while (0) + +/* + * One round of RIPEMD. The data must be aligned for 32-bit access. + */ +static void +ripemd_round(const unsigned char *data, sph_u32 r[5]) +{ +#if SPH_LITTLE_FAST + +#define RIPEMD_IN(x) sph_dec32le_aligned(data + (4 * (x))) + +#else + + sph_u32 X_var[16]; + int i; + + for (i = 0; i < 16; i ++) + X_var[i] = sph_dec32le_aligned(data + 4 * i); +#define RIPEMD_IN(x) X_var[x] + +#endif + RIPEMD_ROUND_BODY(RIPEMD_IN, r); +#undef RIPEMD_IN +} + +/* see sph_ripemd.h */ +void +sph_ripemd_init(void *cc) +{ + sph_ripemd_context *sc; + + sc = (sph_ripemd_context*)cc; + memcpy(sc->val, oIV, sizeof sc->val); +#if SPH_64 + sc->count = 0; +#else + sc->count_high = sc->count_low = 0; +#endif +} + +#define RFUN ripemd_round +#define HASH ripemd +#define LE32 1 +#include "algo/sha3/md_helper.c" +#undef RFUN +#undef HASH +#undef LE32 + +/* see sph_ripemd.h */ +void +sph_ripemd_close(void *cc, void *dst) +{ + ripemd_close(cc, dst, 4); + sph_ripemd_init(cc); +} + +/* see sph_ripemd.h */ +void +sph_ripemd_comp(const sph_u32 msg[16], sph_u32 val[4]) +{ +#define RIPEMD_IN(x) msg[x] + RIPEMD_ROUND_BODY(RIPEMD_IN, val); +#undef RIPEMD_IN +} + +/* ===================================================================== */ +/* + * RIPEMD-128. + */ + +/* + * Round constants for RIPEMD-128. + */ +#define sK11 SPH_C32(0x00000000) +#define sK12 SPH_C32(0x5A827999) +#define sK13 SPH_C32(0x6ED9EBA1) +#define sK14 SPH_C32(0x8F1BBCDC) + +#define sK21 SPH_C32(0x50A28BE6) +#define sK22 SPH_C32(0x5C4DD124) +#define sK23 SPH_C32(0x6D703EF3) +#define sK24 SPH_C32(0x00000000) + +#define sRR(a, b, c, d, f, s, r, k) do { \ + a = ROTL(SPH_T32(a + f(b, c, d) + r + k), s); \ + } while (0) + +#define sROUND1(a, b, c, d, f, s, r, k) \ + sRR(a ## 1, b ## 1, c ## 1, d ## 1, f, s, r, sK1 ## k) + +#define sROUND2(a, b, c, d, f, s, r, k) \ + sRR(a ## 2, b ## 2, c ## 2, d ## 2, f, s, r, sK2 ## k) + +/* + * This macro defines the body for a RIPEMD-128 compression function + * implementation. The "in" parameter should evaluate, when applied to a + * numerical input parameter from 0 to 15, to an expression which yields + * the corresponding input block. The "h" parameter should evaluate to + * an array or pointer expression designating the array of 4 words which + * contains the input and output of the compression function. + */ + +#define RIPEMD128_ROUND_BODY(in, h) do { \ + sph_u32 A1, B1, C1, D1; \ + sph_u32 A2, B2, C2, D2; \ + sph_u32 tmp; \ + \ + A1 = A2 = (h)[0]; \ + B1 = B2 = (h)[1]; \ + C1 = C2 = (h)[2]; \ + D1 = D2 = (h)[3]; \ + \ + sROUND1(A, B, C, D, F1, 11, in( 0), 1); \ + sROUND1(D, A, B, C, F1, 14, in( 1), 1); \ + sROUND1(C, D, A, B, F1, 15, in( 2), 1); \ + sROUND1(B, C, D, A, F1, 12, in( 3), 1); \ + sROUND1(A, B, C, D, F1, 5, in( 4), 1); \ + sROUND1(D, A, B, C, F1, 8, in( 5), 1); \ + sROUND1(C, D, A, B, F1, 7, in( 6), 1); \ + sROUND1(B, C, D, A, F1, 9, in( 7), 1); \ + sROUND1(A, B, C, D, F1, 11, in( 8), 1); \ + sROUND1(D, A, B, C, F1, 13, in( 9), 1); \ + sROUND1(C, D, A, B, F1, 14, in(10), 1); \ + sROUND1(B, C, D, A, F1, 15, in(11), 1); \ + sROUND1(A, B, C, D, F1, 6, in(12), 1); \ + sROUND1(D, A, B, C, F1, 7, in(13), 1); \ + sROUND1(C, D, A, B, F1, 9, in(14), 1); \ + sROUND1(B, C, D, A, F1, 8, in(15), 1); \ + \ + sROUND1(A, B, C, D, F2, 7, in( 7), 2); \ + sROUND1(D, A, B, C, F2, 6, in( 4), 2); \ + sROUND1(C, D, A, B, F2, 8, in(13), 2); \ + sROUND1(B, C, D, A, F2, 13, in( 1), 2); \ + sROUND1(A, B, C, D, F2, 11, in(10), 2); \ + sROUND1(D, A, B, C, F2, 9, in( 6), 2); \ + sROUND1(C, D, A, B, F2, 7, in(15), 2); \ + sROUND1(B, C, D, A, F2, 15, in( 3), 2); \ + sROUND1(A, B, C, D, F2, 7, in(12), 2); \ + sROUND1(D, A, B, C, F2, 12, in( 0), 2); \ + sROUND1(C, D, A, B, F2, 15, in( 9), 2); \ + sROUND1(B, C, D, A, F2, 9, in( 5), 2); \ + sROUND1(A, B, C, D, F2, 11, in( 2), 2); \ + sROUND1(D, A, B, C, F2, 7, in(14), 2); \ + sROUND1(C, D, A, B, F2, 13, in(11), 2); \ + sROUND1(B, C, D, A, F2, 12, in( 8), 2); \ + \ + sROUND1(A, B, C, D, F3, 11, in( 3), 3); \ + sROUND1(D, A, B, C, F3, 13, in(10), 3); \ + sROUND1(C, D, A, B, F3, 6, in(14), 3); \ + sROUND1(B, C, D, A, F3, 7, in( 4), 3); \ + sROUND1(A, B, C, D, F3, 14, in( 9), 3); \ + sROUND1(D, A, B, C, F3, 9, in(15), 3); \ + sROUND1(C, D, A, B, F3, 13, in( 8), 3); \ + sROUND1(B, C, D, A, F3, 15, in( 1), 3); \ + sROUND1(A, B, C, D, F3, 14, in( 2), 3); \ + sROUND1(D, A, B, C, F3, 8, in( 7), 3); \ + sROUND1(C, D, A, B, F3, 13, in( 0), 3); \ + sROUND1(B, C, D, A, F3, 6, in( 6), 3); \ + sROUND1(A, B, C, D, F3, 5, in(13), 3); \ + sROUND1(D, A, B, C, F3, 12, in(11), 3); \ + sROUND1(C, D, A, B, F3, 7, in( 5), 3); \ + sROUND1(B, C, D, A, F3, 5, in(12), 3); \ + \ + sROUND1(A, B, C, D, F4, 11, in( 1), 4); \ + sROUND1(D, A, B, C, F4, 12, in( 9), 4); \ + sROUND1(C, D, A, B, F4, 14, in(11), 4); \ + sROUND1(B, C, D, A, F4, 15, in(10), 4); \ + sROUND1(A, B, C, D, F4, 14, in( 0), 4); \ + sROUND1(D, A, B, C, F4, 15, in( 8), 4); \ + sROUND1(C, D, A, B, F4, 9, in(12), 4); \ + sROUND1(B, C, D, A, F4, 8, in( 4), 4); \ + sROUND1(A, B, C, D, F4, 9, in(13), 4); \ + sROUND1(D, A, B, C, F4, 14, in( 3), 4); \ + sROUND1(C, D, A, B, F4, 5, in( 7), 4); \ + sROUND1(B, C, D, A, F4, 6, in(15), 4); \ + sROUND1(A, B, C, D, F4, 8, in(14), 4); \ + sROUND1(D, A, B, C, F4, 6, in( 5), 4); \ + sROUND1(C, D, A, B, F4, 5, in( 6), 4); \ + sROUND1(B, C, D, A, F4, 12, in( 2), 4); \ + \ + sROUND2(A, B, C, D, F4, 8, in( 5), 1); \ + sROUND2(D, A, B, C, F4, 9, in(14), 1); \ + sROUND2(C, D, A, B, F4, 9, in( 7), 1); \ + sROUND2(B, C, D, A, F4, 11, in( 0), 1); \ + sROUND2(A, B, C, D, F4, 13, in( 9), 1); \ + sROUND2(D, A, B, C, F4, 15, in( 2), 1); \ + sROUND2(C, D, A, B, F4, 15, in(11), 1); \ + sROUND2(B, C, D, A, F4, 5, in( 4), 1); \ + sROUND2(A, B, C, D, F4, 7, in(13), 1); \ + sROUND2(D, A, B, C, F4, 7, in( 6), 1); \ + sROUND2(C, D, A, B, F4, 8, in(15), 1); \ + sROUND2(B, C, D, A, F4, 11, in( 8), 1); \ + sROUND2(A, B, C, D, F4, 14, in( 1), 1); \ + sROUND2(D, A, B, C, F4, 14, in(10), 1); \ + sROUND2(C, D, A, B, F4, 12, in( 3), 1); \ + sROUND2(B, C, D, A, F4, 6, in(12), 1); \ + \ + sROUND2(A, B, C, D, F3, 9, in( 6), 2); \ + sROUND2(D, A, B, C, F3, 13, in(11), 2); \ + sROUND2(C, D, A, B, F3, 15, in( 3), 2); \ + sROUND2(B, C, D, A, F3, 7, in( 7), 2); \ + sROUND2(A, B, C, D, F3, 12, in( 0), 2); \ + sROUND2(D, A, B, C, F3, 8, in(13), 2); \ + sROUND2(C, D, A, B, F3, 9, in( 5), 2); \ + sROUND2(B, C, D, A, F3, 11, in(10), 2); \ + sROUND2(A, B, C, D, F3, 7, in(14), 2); \ + sROUND2(D, A, B, C, F3, 7, in(15), 2); \ + sROUND2(C, D, A, B, F3, 12, in( 8), 2); \ + sROUND2(B, C, D, A, F3, 7, in(12), 2); \ + sROUND2(A, B, C, D, F3, 6, in( 4), 2); \ + sROUND2(D, A, B, C, F3, 15, in( 9), 2); \ + sROUND2(C, D, A, B, F3, 13, in( 1), 2); \ + sROUND2(B, C, D, A, F3, 11, in( 2), 2); \ + \ + sROUND2(A, B, C, D, F2, 9, in(15), 3); \ + sROUND2(D, A, B, C, F2, 7, in( 5), 3); \ + sROUND2(C, D, A, B, F2, 15, in( 1), 3); \ + sROUND2(B, C, D, A, F2, 11, in( 3), 3); \ + sROUND2(A, B, C, D, F2, 8, in( 7), 3); \ + sROUND2(D, A, B, C, F2, 6, in(14), 3); \ + sROUND2(C, D, A, B, F2, 6, in( 6), 3); \ + sROUND2(B, C, D, A, F2, 14, in( 9), 3); \ + sROUND2(A, B, C, D, F2, 12, in(11), 3); \ + sROUND2(D, A, B, C, F2, 13, in( 8), 3); \ + sROUND2(C, D, A, B, F2, 5, in(12), 3); \ + sROUND2(B, C, D, A, F2, 14, in( 2), 3); \ + sROUND2(A, B, C, D, F2, 13, in(10), 3); \ + sROUND2(D, A, B, C, F2, 13, in( 0), 3); \ + sROUND2(C, D, A, B, F2, 7, in( 4), 3); \ + sROUND2(B, C, D, A, F2, 5, in(13), 3); \ + \ + sROUND2(A, B, C, D, F1, 15, in( 8), 4); \ + sROUND2(D, A, B, C, F1, 5, in( 6), 4); \ + sROUND2(C, D, A, B, F1, 8, in( 4), 4); \ + sROUND2(B, C, D, A, F1, 11, in( 1), 4); \ + sROUND2(A, B, C, D, F1, 14, in( 3), 4); \ + sROUND2(D, A, B, C, F1, 14, in(11), 4); \ + sROUND2(C, D, A, B, F1, 6, in(15), 4); \ + sROUND2(B, C, D, A, F1, 14, in( 0), 4); \ + sROUND2(A, B, C, D, F1, 6, in( 5), 4); \ + sROUND2(D, A, B, C, F1, 9, in(12), 4); \ + sROUND2(C, D, A, B, F1, 12, in( 2), 4); \ + sROUND2(B, C, D, A, F1, 9, in(13), 4); \ + sROUND2(A, B, C, D, F1, 12, in( 9), 4); \ + sROUND2(D, A, B, C, F1, 5, in( 7), 4); \ + sROUND2(C, D, A, B, F1, 15, in(10), 4); \ + sROUND2(B, C, D, A, F1, 8, in(14), 4); \ + \ + tmp = SPH_T32((h)[1] + C1 + D2); \ + (h)[1] = SPH_T32((h)[2] + D1 + A2); \ + (h)[2] = SPH_T32((h)[3] + A1 + B2); \ + (h)[3] = SPH_T32((h)[0] + B1 + C2); \ + (h)[0] = tmp; \ + } while (0) + +/* + * One round of RIPEMD-128. The data must be aligned for 32-bit access. + */ +static void +ripemd128_round(const unsigned char *data, sph_u32 r[5]) +{ +#if SPH_LITTLE_FAST + +#define RIPEMD128_IN(x) sph_dec32le_aligned(data + (4 * (x))) + +#else + + sph_u32 X_var[16]; + int i; + + for (i = 0; i < 16; i ++) + X_var[i] = sph_dec32le_aligned(data + 4 * i); +#define RIPEMD128_IN(x) X_var[x] + +#endif + RIPEMD128_ROUND_BODY(RIPEMD128_IN, r); +#undef RIPEMD128_IN +} + +/* see sph_ripemd.h */ +void +sph_ripemd128_init(void *cc) +{ + sph_ripemd128_context *sc; + + sc = (sph_ripemd128_context*)cc; + memcpy(sc->val, IV, sizeof sc->val); +#if SPH_64 + sc->count = 0; +#else + sc->count_high = sc->count_low = 0; +#endif +} + +#define RFUN ripemd128_round +#define HASH ripemd128 +#define LE32 1 +#include "algo/sha3/md_helper.c" +#undef RFUN +#undef HASH +#undef LE32 + +/* see sph_ripemd.h */ +void +sph_ripemd128_close(void *cc, void *dst) +{ + ripemd128_close(cc, dst, 4); + sph_ripemd128_init(cc); +} + +/* see sph_ripemd.h */ +void +sph_ripemd128_comp(const sph_u32 msg[16], sph_u32 val[4]) +{ +#define RIPEMD128_IN(x) msg[x] + RIPEMD128_ROUND_BODY(RIPEMD128_IN, val); +#undef RIPEMD128_IN +} + +/* ===================================================================== */ +/* + * RIPEMD-160. + */ + +/* + * Round constants for RIPEMD-160. + */ +#define K11 SPH_C32(0x00000000) +#define K12 SPH_C32(0x5A827999) +#define K13 SPH_C32(0x6ED9EBA1) +#define K14 SPH_C32(0x8F1BBCDC) +#define K15 SPH_C32(0xA953FD4E) + +#define K21 SPH_C32(0x50A28BE6) +#define K22 SPH_C32(0x5C4DD124) +#define K23 SPH_C32(0x6D703EF3) +#define K24 SPH_C32(0x7A6D76E9) +#define K25 SPH_C32(0x00000000) + +#define RR(a, b, c, d, e, f, s, r, k) do { \ + a = SPH_T32(ROTL(SPH_T32(a + f(b, c, d) + r + k), s) + e); \ + c = ROTL(c, 10); \ + } while (0) + +#define ROUND1(a, b, c, d, e, f, s, r, k) \ + RR(a ## 1, b ## 1, c ## 1, d ## 1, e ## 1, f, s, r, K1 ## k) + +#define ROUND2(a, b, c, d, e, f, s, r, k) \ + RR(a ## 2, b ## 2, c ## 2, d ## 2, e ## 2, f, s, r, K2 ## k) + +/* + * This macro defines the body for a RIPEMD-160 compression function + * implementation. The "in" parameter should evaluate, when applied to a + * numerical input parameter from 0 to 15, to an expression which yields + * the corresponding input block. The "h" parameter should evaluate to + * an array or pointer expression designating the array of 5 words which + * contains the input and output of the compression function. + */ + +#define RIPEMD160_ROUND_BODY(in, h) do { \ + sph_u32 A1, B1, C1, D1, E1; \ + sph_u32 A2, B2, C2, D2, E2; \ + sph_u32 tmp; \ + \ + A1 = A2 = (h)[0]; \ + B1 = B2 = (h)[1]; \ + C1 = C2 = (h)[2]; \ + D1 = D2 = (h)[3]; \ + E1 = E2 = (h)[4]; \ + \ + ROUND1(A, B, C, D, E, F1, 11, in( 0), 1); \ + ROUND1(E, A, B, C, D, F1, 14, in( 1), 1); \ + ROUND1(D, E, A, B, C, F1, 15, in( 2), 1); \ + ROUND1(C, D, E, A, B, F1, 12, in( 3), 1); \ + ROUND1(B, C, D, E, A, F1, 5, in( 4), 1); \ + ROUND1(A, B, C, D, E, F1, 8, in( 5), 1); \ + ROUND1(E, A, B, C, D, F1, 7, in( 6), 1); \ + ROUND1(D, E, A, B, C, F1, 9, in( 7), 1); \ + ROUND1(C, D, E, A, B, F1, 11, in( 8), 1); \ + ROUND1(B, C, D, E, A, F1, 13, in( 9), 1); \ + ROUND1(A, B, C, D, E, F1, 14, in(10), 1); \ + ROUND1(E, A, B, C, D, F1, 15, in(11), 1); \ + ROUND1(D, E, A, B, C, F1, 6, in(12), 1); \ + ROUND1(C, D, E, A, B, F1, 7, in(13), 1); \ + ROUND1(B, C, D, E, A, F1, 9, in(14), 1); \ + ROUND1(A, B, C, D, E, F1, 8, in(15), 1); \ + \ + ROUND1(E, A, B, C, D, F2, 7, in( 7), 2); \ + ROUND1(D, E, A, B, C, F2, 6, in( 4), 2); \ + ROUND1(C, D, E, A, B, F2, 8, in(13), 2); \ + ROUND1(B, C, D, E, A, F2, 13, in( 1), 2); \ + ROUND1(A, B, C, D, E, F2, 11, in(10), 2); \ + ROUND1(E, A, B, C, D, F2, 9, in( 6), 2); \ + ROUND1(D, E, A, B, C, F2, 7, in(15), 2); \ + ROUND1(C, D, E, A, B, F2, 15, in( 3), 2); \ + ROUND1(B, C, D, E, A, F2, 7, in(12), 2); \ + ROUND1(A, B, C, D, E, F2, 12, in( 0), 2); \ + ROUND1(E, A, B, C, D, F2, 15, in( 9), 2); \ + ROUND1(D, E, A, B, C, F2, 9, in( 5), 2); \ + ROUND1(C, D, E, A, B, F2, 11, in( 2), 2); \ + ROUND1(B, C, D, E, A, F2, 7, in(14), 2); \ + ROUND1(A, B, C, D, E, F2, 13, in(11), 2); \ + ROUND1(E, A, B, C, D, F2, 12, in( 8), 2); \ + \ + ROUND1(D, E, A, B, C, F3, 11, in( 3), 3); \ + ROUND1(C, D, E, A, B, F3, 13, in(10), 3); \ + ROUND1(B, C, D, E, A, F3, 6, in(14), 3); \ + ROUND1(A, B, C, D, E, F3, 7, in( 4), 3); \ + ROUND1(E, A, B, C, D, F3, 14, in( 9), 3); \ + ROUND1(D, E, A, B, C, F3, 9, in(15), 3); \ + ROUND1(C, D, E, A, B, F3, 13, in( 8), 3); \ + ROUND1(B, C, D, E, A, F3, 15, in( 1), 3); \ + ROUND1(A, B, C, D, E, F3, 14, in( 2), 3); \ + ROUND1(E, A, B, C, D, F3, 8, in( 7), 3); \ + ROUND1(D, E, A, B, C, F3, 13, in( 0), 3); \ + ROUND1(C, D, E, A, B, F3, 6, in( 6), 3); \ + ROUND1(B, C, D, E, A, F3, 5, in(13), 3); \ + ROUND1(A, B, C, D, E, F3, 12, in(11), 3); \ + ROUND1(E, A, B, C, D, F3, 7, in( 5), 3); \ + ROUND1(D, E, A, B, C, F3, 5, in(12), 3); \ + \ + ROUND1(C, D, E, A, B, F4, 11, in( 1), 4); \ + ROUND1(B, C, D, E, A, F4, 12, in( 9), 4); \ + ROUND1(A, B, C, D, E, F4, 14, in(11), 4); \ + ROUND1(E, A, B, C, D, F4, 15, in(10), 4); \ + ROUND1(D, E, A, B, C, F4, 14, in( 0), 4); \ + ROUND1(C, D, E, A, B, F4, 15, in( 8), 4); \ + ROUND1(B, C, D, E, A, F4, 9, in(12), 4); \ + ROUND1(A, B, C, D, E, F4, 8, in( 4), 4); \ + ROUND1(E, A, B, C, D, F4, 9, in(13), 4); \ + ROUND1(D, E, A, B, C, F4, 14, in( 3), 4); \ + ROUND1(C, D, E, A, B, F4, 5, in( 7), 4); \ + ROUND1(B, C, D, E, A, F4, 6, in(15), 4); \ + ROUND1(A, B, C, D, E, F4, 8, in(14), 4); \ + ROUND1(E, A, B, C, D, F4, 6, in( 5), 4); \ + ROUND1(D, E, A, B, C, F4, 5, in( 6), 4); \ + ROUND1(C, D, E, A, B, F4, 12, in( 2), 4); \ + \ + ROUND1(B, C, D, E, A, F5, 9, in( 4), 5); \ + ROUND1(A, B, C, D, E, F5, 15, in( 0), 5); \ + ROUND1(E, A, B, C, D, F5, 5, in( 5), 5); \ + ROUND1(D, E, A, B, C, F5, 11, in( 9), 5); \ + ROUND1(C, D, E, A, B, F5, 6, in( 7), 5); \ + ROUND1(B, C, D, E, A, F5, 8, in(12), 5); \ + ROUND1(A, B, C, D, E, F5, 13, in( 2), 5); \ + ROUND1(E, A, B, C, D, F5, 12, in(10), 5); \ + ROUND1(D, E, A, B, C, F5, 5, in(14), 5); \ + ROUND1(C, D, E, A, B, F5, 12, in( 1), 5); \ + ROUND1(B, C, D, E, A, F5, 13, in( 3), 5); \ + ROUND1(A, B, C, D, E, F5, 14, in( 8), 5); \ + ROUND1(E, A, B, C, D, F5, 11, in(11), 5); \ + ROUND1(D, E, A, B, C, F5, 8, in( 6), 5); \ + ROUND1(C, D, E, A, B, F5, 5, in(15), 5); \ + ROUND1(B, C, D, E, A, F5, 6, in(13), 5); \ + \ + ROUND2(A, B, C, D, E, F5, 8, in( 5), 1); \ + ROUND2(E, A, B, C, D, F5, 9, in(14), 1); \ + ROUND2(D, E, A, B, C, F5, 9, in( 7), 1); \ + ROUND2(C, D, E, A, B, F5, 11, in( 0), 1); \ + ROUND2(B, C, D, E, A, F5, 13, in( 9), 1); \ + ROUND2(A, B, C, D, E, F5, 15, in( 2), 1); \ + ROUND2(E, A, B, C, D, F5, 15, in(11), 1); \ + ROUND2(D, E, A, B, C, F5, 5, in( 4), 1); \ + ROUND2(C, D, E, A, B, F5, 7, in(13), 1); \ + ROUND2(B, C, D, E, A, F5, 7, in( 6), 1); \ + ROUND2(A, B, C, D, E, F5, 8, in(15), 1); \ + ROUND2(E, A, B, C, D, F5, 11, in( 8), 1); \ + ROUND2(D, E, A, B, C, F5, 14, in( 1), 1); \ + ROUND2(C, D, E, A, B, F5, 14, in(10), 1); \ + ROUND2(B, C, D, E, A, F5, 12, in( 3), 1); \ + ROUND2(A, B, C, D, E, F5, 6, in(12), 1); \ + \ + ROUND2(E, A, B, C, D, F4, 9, in( 6), 2); \ + ROUND2(D, E, A, B, C, F4, 13, in(11), 2); \ + ROUND2(C, D, E, A, B, F4, 15, in( 3), 2); \ + ROUND2(B, C, D, E, A, F4, 7, in( 7), 2); \ + ROUND2(A, B, C, D, E, F4, 12, in( 0), 2); \ + ROUND2(E, A, B, C, D, F4, 8, in(13), 2); \ + ROUND2(D, E, A, B, C, F4, 9, in( 5), 2); \ + ROUND2(C, D, E, A, B, F4, 11, in(10), 2); \ + ROUND2(B, C, D, E, A, F4, 7, in(14), 2); \ + ROUND2(A, B, C, D, E, F4, 7, in(15), 2); \ + ROUND2(E, A, B, C, D, F4, 12, in( 8), 2); \ + ROUND2(D, E, A, B, C, F4, 7, in(12), 2); \ + ROUND2(C, D, E, A, B, F4, 6, in( 4), 2); \ + ROUND2(B, C, D, E, A, F4, 15, in( 9), 2); \ + ROUND2(A, B, C, D, E, F4, 13, in( 1), 2); \ + ROUND2(E, A, B, C, D, F4, 11, in( 2), 2); \ + \ + ROUND2(D, E, A, B, C, F3, 9, in(15), 3); \ + ROUND2(C, D, E, A, B, F3, 7, in( 5), 3); \ + ROUND2(B, C, D, E, A, F3, 15, in( 1), 3); \ + ROUND2(A, B, C, D, E, F3, 11, in( 3), 3); \ + ROUND2(E, A, B, C, D, F3, 8, in( 7), 3); \ + ROUND2(D, E, A, B, C, F3, 6, in(14), 3); \ + ROUND2(C, D, E, A, B, F3, 6, in( 6), 3); \ + ROUND2(B, C, D, E, A, F3, 14, in( 9), 3); \ + ROUND2(A, B, C, D, E, F3, 12, in(11), 3); \ + ROUND2(E, A, B, C, D, F3, 13, in( 8), 3); \ + ROUND2(D, E, A, B, C, F3, 5, in(12), 3); \ + ROUND2(C, D, E, A, B, F3, 14, in( 2), 3); \ + ROUND2(B, C, D, E, A, F3, 13, in(10), 3); \ + ROUND2(A, B, C, D, E, F3, 13, in( 0), 3); \ + ROUND2(E, A, B, C, D, F3, 7, in( 4), 3); \ + ROUND2(D, E, A, B, C, F3, 5, in(13), 3); \ + \ + ROUND2(C, D, E, A, B, F2, 15, in( 8), 4); \ + ROUND2(B, C, D, E, A, F2, 5, in( 6), 4); \ + ROUND2(A, B, C, D, E, F2, 8, in( 4), 4); \ + ROUND2(E, A, B, C, D, F2, 11, in( 1), 4); \ + ROUND2(D, E, A, B, C, F2, 14, in( 3), 4); \ + ROUND2(C, D, E, A, B, F2, 14, in(11), 4); \ + ROUND2(B, C, D, E, A, F2, 6, in(15), 4); \ + ROUND2(A, B, C, D, E, F2, 14, in( 0), 4); \ + ROUND2(E, A, B, C, D, F2, 6, in( 5), 4); \ + ROUND2(D, E, A, B, C, F2, 9, in(12), 4); \ + ROUND2(C, D, E, A, B, F2, 12, in( 2), 4); \ + ROUND2(B, C, D, E, A, F2, 9, in(13), 4); \ + ROUND2(A, B, C, D, E, F2, 12, in( 9), 4); \ + ROUND2(E, A, B, C, D, F2, 5, in( 7), 4); \ + ROUND2(D, E, A, B, C, F2, 15, in(10), 4); \ + ROUND2(C, D, E, A, B, F2, 8, in(14), 4); \ + \ + ROUND2(B, C, D, E, A, F1, 8, in(12), 5); \ + ROUND2(A, B, C, D, E, F1, 5, in(15), 5); \ + ROUND2(E, A, B, C, D, F1, 12, in(10), 5); \ + ROUND2(D, E, A, B, C, F1, 9, in( 4), 5); \ + ROUND2(C, D, E, A, B, F1, 12, in( 1), 5); \ + ROUND2(B, C, D, E, A, F1, 5, in( 5), 5); \ + ROUND2(A, B, C, D, E, F1, 14, in( 8), 5); \ + ROUND2(E, A, B, C, D, F1, 6, in( 7), 5); \ + ROUND2(D, E, A, B, C, F1, 8, in( 6), 5); \ + ROUND2(C, D, E, A, B, F1, 13, in( 2), 5); \ + ROUND2(B, C, D, E, A, F1, 6, in(13), 5); \ + ROUND2(A, B, C, D, E, F1, 5, in(14), 5); \ + ROUND2(E, A, B, C, D, F1, 15, in( 0), 5); \ + ROUND2(D, E, A, B, C, F1, 13, in( 3), 5); \ + ROUND2(C, D, E, A, B, F1, 11, in( 9), 5); \ + ROUND2(B, C, D, E, A, F1, 11, in(11), 5); \ + \ + tmp = SPH_T32((h)[1] + C1 + D2); \ + (h)[1] = SPH_T32((h)[2] + D1 + E2); \ + (h)[2] = SPH_T32((h)[3] + E1 + A2); \ + (h)[3] = SPH_T32((h)[4] + A1 + B2); \ + (h)[4] = SPH_T32((h)[0] + B1 + C2); \ + (h)[0] = tmp; \ + } while (0) + +/* + * One round of RIPEMD-160. The data must be aligned for 32-bit access. + */ +static void +ripemd160_round(const unsigned char *data, sph_u32 r[5]) +{ +#if SPH_LITTLE_FAST + +#define RIPEMD160_IN(x) sph_dec32le_aligned(data + (4 * (x))) + +#else + + sph_u32 X_var[16]; + int i; + + for (i = 0; i < 16; i ++) + X_var[i] = sph_dec32le_aligned(data + 4 * i); +#define RIPEMD160_IN(x) X_var[x] + +#endif + RIPEMD160_ROUND_BODY(RIPEMD160_IN, r); +#undef RIPEMD160_IN +} + +/* see sph_ripemd.h */ +void +sph_ripemd160_init(void *cc) +{ + sph_ripemd160_context *sc; + + sc = (sph_ripemd160_context*)cc; + memcpy(sc->val, IV, sizeof sc->val); +#if SPH_64 + sc->count = 0; +#else + sc->count_high = sc->count_low = 0; +#endif +} + +#define RFUN ripemd160_round +#define HASH ripemd160 +#define LE32 1 +#include "algo/sha3/md_helper.c" +#undef RFUN +#undef HASH +#undef LE32 + +/* see sph_ripemd.h */ +void +sph_ripemd160_close(void *cc, void *dst) +{ + ripemd160_close(cc, dst, 5); + sph_ripemd160_init(cc); +} + +/* see sph_ripemd.h */ +void +sph_ripemd160_comp(const sph_u32 msg[16], sph_u32 val[5]) +{ +#define RIPEMD160_IN(x) msg[x] + RIPEMD160_ROUND_BODY(RIPEMD160_IN, val); +#undef RIPEMD160_IN +} + diff --git a/algo/ripemd/sph_ripemd.h b/algo/ripemd/sph_ripemd.h new file mode 100644 index 0000000..37405d3 --- /dev/null +++ b/algo/ripemd/sph_ripemd.h @@ -0,0 +1,274 @@ +/* $Id: sph_ripemd.h 216 2010-06-08 09:46:57Z tp $ */ +/** + * RIPEMD, RIPEMD-128 and RIPEMD-160 interface. + * + * RIPEMD was first described in: Research and Development in Advanced + * Communication Technologies in Europe, "RIPE Integrity Primitives: + * Final Report of RACE Integrity Primitives Evaluation (R1040)", RACE, + * June 1992. + * + * A new, strengthened version, dubbed RIPEMD-160, was published in: H. + * Dobbertin, A. Bosselaers, and B. Preneel, "RIPEMD-160, a strengthened + * version of RIPEMD", Fast Software Encryption - FSE'96, LNCS 1039, + * Springer (1996), pp. 71--82. + * + * This article describes both RIPEMD-160, with a 160-bit output, and a + * reduced version called RIPEMD-128, which has a 128-bit output. RIPEMD-128 + * was meant as a "drop-in" replacement for any hash function with 128-bit + * output, especially the original RIPEMD. + * + * @warning Collisions, and an efficient method to build other collisions, + * have been published for the original RIPEMD, which is thus considered as + * cryptographically broken. It is also very rarely encountered, and there + * seems to exist no free description or implementation of RIPEMD (except + * the sphlib code, of course). As of january 2007, RIPEMD-128 and RIPEMD-160 + * seem as secure as their output length allows. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @file sph_ripemd.h + * @author Thomas Pornin + */ + +#ifndef SPH_RIPEMD_H__ +#define SPH_RIPEMD_H__ + +#include +#include "algo/sha3/sph_types.h" + +/** + * Output size (in bits) for RIPEMD. + */ +#define SPH_SIZE_ripemd 128 + +/** + * Output size (in bits) for RIPEMD-128. + */ +#define SPH_SIZE_ripemd128 128 + +/** + * Output size (in bits) for RIPEMD-160. + */ +#define SPH_SIZE_ripemd160 160 + +/** + * This structure is a context for RIPEMD computations: it contains the + * intermediate values and some data from the last entered block. Once + * a RIPEMD computation has been performed, the context can be reused for + * another computation. + * + * The contents of this structure are private. A running RIPEMD computation + * can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[64]; /* first field, for alignment */ + sph_u32 val[4]; +#if SPH_64 + sph_u64 count; +#else + sph_u32 count_high, count_low; +#endif +#endif +} sph_ripemd_context; + +/** + * Initialize a RIPEMD context. This process performs no memory allocation. + * + * @param cc the RIPEMD context (pointer to + * a sph_ripemd_context) + */ +void sph_ripemd_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the RIPEMD context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_ripemd(void *cc, const void *data, size_t len); + +/** + * Terminate the current RIPEMD computation and output the result into the + * provided buffer. The destination buffer must be wide enough to + * accomodate the result (16 bytes). The context is automatically + * reinitialized. + * + * @param cc the RIPEMD context + * @param dst the destination buffer + */ +void sph_ripemd_close(void *cc, void *dst); + +/** + * Apply the RIPEMD compression function on the provided data. The + * msg parameter contains the 16 32-bit input blocks, + * as numerical values (hence after the little-endian decoding). The + * val parameter contains the 5 32-bit input blocks for + * the compression function; the output is written in place in this + * array. + * + * @param msg the message block (16 values) + * @param val the function 128-bit input and output + */ +void sph_ripemd_comp(const sph_u32 msg[16], sph_u32 val[4]); + +/* ===================================================================== */ + +/** + * This structure is a context for RIPEMD-128 computations: it contains the + * intermediate values and some data from the last entered block. Once + * a RIPEMD-128 computation has been performed, the context can be reused for + * another computation. + * + * The contents of this structure are private. A running RIPEMD-128 computation + * can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[64]; /* first field, for alignment */ + sph_u32 val[4]; +#if SPH_64 + sph_u64 count; +#else + sph_u32 count_high, count_low; +#endif +#endif +} sph_ripemd128_context; + +/** + * Initialize a RIPEMD-128 context. This process performs no memory allocation. + * + * @param cc the RIPEMD-128 context (pointer to + * a sph_ripemd128_context) + */ +void sph_ripemd128_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the RIPEMD-128 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_ripemd128(void *cc, const void *data, size_t len); + +/** + * Terminate the current RIPEMD-128 computation and output the result into the + * provided buffer. The destination buffer must be wide enough to + * accomodate the result (16 bytes). The context is automatically + * reinitialized. + * + * @param cc the RIPEMD-128 context + * @param dst the destination buffer + */ +void sph_ripemd128_close(void *cc, void *dst); + +/** + * Apply the RIPEMD-128 compression function on the provided data. The + * msg parameter contains the 16 32-bit input blocks, + * as numerical values (hence after the little-endian decoding). The + * val parameter contains the 5 32-bit input blocks for + * the compression function; the output is written in place in this + * array. + * + * @param msg the message block (16 values) + * @param val the function 128-bit input and output + */ +void sph_ripemd128_comp(const sph_u32 msg[16], sph_u32 val[4]); + +/* ===================================================================== */ + +/** + * This structure is a context for RIPEMD-160 computations: it contains the + * intermediate values and some data from the last entered block. Once + * a RIPEMD-160 computation has been performed, the context can be reused for + * another computation. + * + * The contents of this structure are private. A running RIPEMD-160 computation + * can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[64]; /* first field, for alignment */ + sph_u32 val[5]; +#if SPH_64 + sph_u64 count; +#else + sph_u32 count_high, count_low; +#endif +#endif +} sph_ripemd160_context; + +/** + * Initialize a RIPEMD-160 context. This process performs no memory allocation. + * + * @param cc the RIPEMD-160 context (pointer to + * a sph_ripemd160_context) + */ +void sph_ripemd160_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the RIPEMD-160 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_ripemd160(void *cc, const void *data, size_t len); + +/** + * Terminate the current RIPEMD-160 computation and output the result into the + * provided buffer. The destination buffer must be wide enough to + * accomodate the result (20 bytes). The context is automatically + * reinitialized. + * + * @param cc the RIPEMD-160 context + * @param dst the destination buffer + */ +void sph_ripemd160_close(void *cc, void *dst); + +/** + * Apply the RIPEMD-160 compression function on the provided data. The + * msg parameter contains the 16 32-bit input blocks, + * as numerical values (hence after the little-endian decoding). The + * val parameter contains the 5 32-bit input blocks for + * the compression function; the output is written in place in this + * array. + * + * @param msg the message block (16 values) + * @param val the function 160-bit input and output + */ +void sph_ripemd160_comp(const sph_u32 msg[16], sph_u32 val[5]); + +#endif + diff --git a/algo/scrypt.c b/algo/scrypt.c index baa539a..24efb45 100644 --- a/algo/scrypt.c +++ b/algo/scrypt.c @@ -772,10 +772,12 @@ int64_t scrypt_get_max64() return max64; } +/* void scrypt_set_target( struct work* work, double job_diff ) { work_set_target( work, job_diff / (65536.0 * opt_diff_factor) ); } +*/ bool get_scrypt_scratchbuf( char** scratchbuf ) { @@ -791,7 +793,7 @@ bool register_scrypt_algo( algo_gate_t* gate ) gate->set_target = (void*)&scrypt_set_target; gate->get_scratchbuf = (void*)&get_scrypt_scratchbuf; gate->get_max64 = (void*)&scrypt_get_max64; - if ( opt_nfactor = 0 ) + if ( opt_nfactor == 0 ) opt_nfactor = 6; return true; }; diff --git a/algo/scryptjane/scrypt-jane.c b/algo/scryptjane/scrypt-jane.c index 8ce290f..1b79a6d 100644 --- a/algo/scryptjane/scrypt-jane.c +++ b/algo/scryptjane/scrypt-jane.c @@ -229,11 +229,12 @@ void scryptjane_set_target( struct work* work, double job_diff ) { work_set_target( work, job_diff / (65536.0 * opt_diff_factor) ); } - +/* int64_t scryptjane_get_max64() { return 0x40LL; } +*/ bool register_scryptjane_algo( algo_gate_t* gate ) { @@ -241,8 +242,10 @@ bool register_scryptjane_algo( algo_gate_t* gate ) gate->scanhash = (void*)&scanhash_scryptjane; gate->hash = (void*)&scryptjanehash; gate->hash_alt = (void*)&scryptjanehash; - gate->set_target = (void*)&scryptjane_set_target; - gate->get_max64 = (void*)&scryptjane_get_max64; +// gate->set_target = (void*)&scryptjane_set_target; + gate->set_target = (void*)&scrypt_set_target; + gate->get_max64 = (void*)&get_max64_0x40LL; +// gate->get_max64 = (void*)&scryptjane_get_max64; if ( opt_nfactor == 0 ) opt_nfactor = 16; return true; diff --git a/algo/sha2/sha2.c b/algo/sha2/sha2.c new file mode 100644 index 0000000..d7af63b --- /dev/null +++ b/algo/sha2/sha2.c @@ -0,0 +1,647 @@ +/* + * Copyright 2011 ArtForz + * Copyright 2011-2013 pooler + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. See COPYING for more details. + */ + +#include "miner.h" +#include "algo-gate-api.h" + +#include +#include + +#if defined(USE_ASM) && defined(__arm__) && defined(__APCS_32__) +#define EXTERN_SHA256 +#endif + +static const uint32_t sha256_h[8] = { + 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, + 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 +}; + +static const uint32_t sha256_k[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +void sha256_init(uint32_t *state) +{ + memcpy(state, sha256_h, 32); +} + +/* 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 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) ^ (x >> 3)) +#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ (x >> 10)) + +/* SHA256 round function */ +#define RND(a, b, c, d, e, f, g, h, k) \ + do { \ + t0 = h + S1(e) + Ch(e, f, g) + k; \ + t1 = S0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; \ + } while (0) + +/* Adjusted round function for rotating state */ +#define RNDr(S, W, i) \ + 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] + sha256_k[i]) + +#ifndef EXTERN_SHA256 + +/* + * SHA256 block compression function. The 256-bit state is transformed via + * the 512-bit input block to produce a new state. + */ +void sha256_transform(uint32_t *state, const uint32_t *block, int swap) +{ + uint32_t W[64]; + uint32_t S[8]; + uint32_t t0, t1; + int i; + + /* 1. Prepare message schedule W. */ + if (swap) { + for (i = 0; i < 16; i++) + W[i] = swab32(block[i]); + } else + memcpy(W, block, 64); + for (i = 16; i < 64; i += 2) { + W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; + W[i+1] = s1(W[i - 1]) + W[i - 6] + s0(W[i - 14]) + W[i - 15]; + } + + /* 2. Initialize working variables. */ + memcpy(S, state, 32); + + /* 3. Mix. */ + RNDr(S, W, 0); + RNDr(S, W, 1); + RNDr(S, W, 2); + RNDr(S, W, 3); + RNDr(S, W, 4); + RNDr(S, W, 5); + RNDr(S, W, 6); + RNDr(S, W, 7); + RNDr(S, W, 8); + RNDr(S, W, 9); + RNDr(S, W, 10); + RNDr(S, W, 11); + RNDr(S, W, 12); + RNDr(S, W, 13); + RNDr(S, W, 14); + RNDr(S, W, 15); + RNDr(S, W, 16); + RNDr(S, W, 17); + RNDr(S, W, 18); + RNDr(S, W, 19); + RNDr(S, W, 20); + RNDr(S, W, 21); + RNDr(S, W, 22); + RNDr(S, W, 23); + RNDr(S, W, 24); + RNDr(S, W, 25); + RNDr(S, W, 26); + RNDr(S, W, 27); + RNDr(S, W, 28); + RNDr(S, W, 29); + RNDr(S, W, 30); + RNDr(S, W, 31); + RNDr(S, W, 32); + RNDr(S, W, 33); + RNDr(S, W, 34); + RNDr(S, W, 35); + RNDr(S, W, 36); + RNDr(S, W, 37); + RNDr(S, W, 38); + RNDr(S, W, 39); + RNDr(S, W, 40); + RNDr(S, W, 41); + RNDr(S, W, 42); + RNDr(S, W, 43); + RNDr(S, W, 44); + RNDr(S, W, 45); + RNDr(S, W, 46); + RNDr(S, W, 47); + RNDr(S, W, 48); + RNDr(S, W, 49); + RNDr(S, W, 50); + RNDr(S, W, 51); + RNDr(S, W, 52); + RNDr(S, W, 53); + RNDr(S, W, 54); + RNDr(S, W, 55); + RNDr(S, W, 56); + RNDr(S, W, 57); + RNDr(S, W, 58); + RNDr(S, W, 59); + RNDr(S, W, 60); + RNDr(S, W, 61); + RNDr(S, W, 62); + RNDr(S, W, 63); + + /* 4. Mix local working variables into global state */ + for (i = 0; i < 8; i++) + state[i] += S[i]; +} + +#endif /* EXTERN_SHA256 */ + + +static const uint32_t sha256d_hash1[16] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x80000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000100 +}; + +static void sha256d_80_swap(uint32_t *hash, const uint32_t *data) +{ + uint32_t S[16]; + int i; + + sha256_init(S); + sha256_transform(S, data, 0); + sha256_transform(S, data + 16, 0); + memcpy(S + 8, sha256d_hash1 + 8, 32); + sha256_init(hash); + sha256_transform(hash, S, 0); + for (i = 0; i < 8; i++) + hash[i] = swab32(hash[i]); +} + +extern void sha256d(unsigned char *hash, const unsigned char *data, int len) +{ + uint32_t S[16], T[16]; + int i, r; + + sha256_init(S); + for (r = len; r > -9; r -= 64) { + if (r < 64) + memset(T, 0, 64); + memcpy(T, data + len - r, r > 64 ? 64 : (r < 0 ? 0 : r)); + if (r >= 0 && r < 64) + ((unsigned char *)T)[r] = 0x80; + for (i = 0; i < 16; i++) + T[i] = be32dec(T + i); + if (r < 56) + T[15] = 8 * len; + sha256_transform(S, T, 0); + } + memcpy(S + 8, sha256d_hash1 + 8, 32); + sha256_init(T); + sha256_transform(T, S, 0); + for (i = 0; i < 8; i++) + be32enc((uint32_t *)hash + i, T[i]); +} + +static inline void sha256d_preextend(uint32_t *W) +{ + W[16] = s1(W[14]) + W[ 9] + s0(W[ 1]) + W[ 0]; + W[17] = s1(W[15]) + W[10] + s0(W[ 2]) + W[ 1]; + W[18] = s1(W[16]) + W[11] + W[ 2]; + W[19] = s1(W[17]) + W[12] + s0(W[ 4]); + W[20] = W[13] + s0(W[ 5]) + W[ 4]; + W[21] = W[14] + s0(W[ 6]) + W[ 5]; + W[22] = W[15] + s0(W[ 7]) + W[ 6]; + W[23] = W[16] + s0(W[ 8]) + W[ 7]; + W[24] = W[17] + s0(W[ 9]) + W[ 8]; + W[25] = s0(W[10]) + W[ 9]; + W[26] = s0(W[11]) + W[10]; + W[27] = s0(W[12]) + W[11]; + W[28] = s0(W[13]) + W[12]; + W[29] = s0(W[14]) + W[13]; + W[30] = s0(W[15]) + W[14]; + W[31] = s0(W[16]) + W[15]; +} + +static inline void sha256d_prehash(uint32_t *S, const uint32_t *W) +{ + uint32_t t0, t1; + RNDr(S, W, 0); + RNDr(S, W, 1); + RNDr(S, W, 2); +} + +#ifdef EXTERN_SHA256 + +void sha256d_ms(uint32_t *hash, uint32_t *W, + const uint32_t *midstate, const uint32_t *prehash); + +#else + +static inline void sha256d_ms(uint32_t *hash, uint32_t *W, + const uint32_t *midstate, const uint32_t *prehash) +{ + uint32_t S[64]; + uint32_t t0, t1; + int i; + + S[18] = W[18]; + S[19] = W[19]; + S[20] = W[20]; + S[22] = W[22]; + S[23] = W[23]; + S[24] = W[24]; + S[30] = W[30]; + S[31] = W[31]; + + W[18] += s0(W[3]); + W[19] += W[3]; + W[20] += s1(W[18]); + W[21] = s1(W[19]); + W[22] += s1(W[20]); + W[23] += s1(W[21]); + W[24] += s1(W[22]); + W[25] = s1(W[23]) + W[18]; + W[26] = s1(W[24]) + W[19]; + W[27] = s1(W[25]) + W[20]; + W[28] = s1(W[26]) + W[21]; + W[29] = s1(W[27]) + W[22]; + W[30] += s1(W[28]) + W[23]; + W[31] += s1(W[29]) + W[24]; + for (i = 32; i < 64; i += 2) { + W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; + W[i+1] = s1(W[i - 1]) + W[i - 6] + s0(W[i - 14]) + W[i - 15]; + } + + memcpy(S, prehash, 32); + + RNDr(S, W, 3); + RNDr(S, W, 4); + RNDr(S, W, 5); + RNDr(S, W, 6); + RNDr(S, W, 7); + RNDr(S, W, 8); + RNDr(S, W, 9); + RNDr(S, W, 10); + RNDr(S, W, 11); + RNDr(S, W, 12); + RNDr(S, W, 13); + RNDr(S, W, 14); + RNDr(S, W, 15); + RNDr(S, W, 16); + RNDr(S, W, 17); + RNDr(S, W, 18); + RNDr(S, W, 19); + RNDr(S, W, 20); + RNDr(S, W, 21); + RNDr(S, W, 22); + RNDr(S, W, 23); + RNDr(S, W, 24); + RNDr(S, W, 25); + RNDr(S, W, 26); + RNDr(S, W, 27); + RNDr(S, W, 28); + RNDr(S, W, 29); + RNDr(S, W, 30); + RNDr(S, W, 31); + RNDr(S, W, 32); + RNDr(S, W, 33); + RNDr(S, W, 34); + RNDr(S, W, 35); + RNDr(S, W, 36); + RNDr(S, W, 37); + RNDr(S, W, 38); + RNDr(S, W, 39); + RNDr(S, W, 40); + RNDr(S, W, 41); + RNDr(S, W, 42); + RNDr(S, W, 43); + RNDr(S, W, 44); + RNDr(S, W, 45); + RNDr(S, W, 46); + RNDr(S, W, 47); + RNDr(S, W, 48); + RNDr(S, W, 49); + RNDr(S, W, 50); + RNDr(S, W, 51); + RNDr(S, W, 52); + RNDr(S, W, 53); + RNDr(S, W, 54); + RNDr(S, W, 55); + RNDr(S, W, 56); + RNDr(S, W, 57); + RNDr(S, W, 58); + RNDr(S, W, 59); + RNDr(S, W, 60); + RNDr(S, W, 61); + RNDr(S, W, 62); + RNDr(S, W, 63); + + for (i = 0; i < 8; i++) + S[i] += midstate[i]; + + W[18] = S[18]; + W[19] = S[19]; + W[20] = S[20]; + W[22] = S[22]; + W[23] = S[23]; + W[24] = S[24]; + W[30] = S[30]; + W[31] = S[31]; + + memcpy(S + 8, sha256d_hash1 + 8, 32); + S[16] = s1(sha256d_hash1[14]) + sha256d_hash1[ 9] + s0(S[ 1]) + S[ 0]; + S[17] = s1(sha256d_hash1[15]) + sha256d_hash1[10] + s0(S[ 2]) + S[ 1]; + S[18] = s1(S[16]) + sha256d_hash1[11] + s0(S[ 3]) + S[ 2]; + S[19] = s1(S[17]) + sha256d_hash1[12] + s0(S[ 4]) + S[ 3]; + S[20] = s1(S[18]) + sha256d_hash1[13] + s0(S[ 5]) + S[ 4]; + S[21] = s1(S[19]) + sha256d_hash1[14] + s0(S[ 6]) + S[ 5]; + S[22] = s1(S[20]) + sha256d_hash1[15] + s0(S[ 7]) + S[ 6]; + S[23] = s1(S[21]) + S[16] + s0(sha256d_hash1[ 8]) + S[ 7]; + S[24] = s1(S[22]) + S[17] + s0(sha256d_hash1[ 9]) + sha256d_hash1[ 8]; + S[25] = s1(S[23]) + S[18] + s0(sha256d_hash1[10]) + sha256d_hash1[ 9]; + S[26] = s1(S[24]) + S[19] + s0(sha256d_hash1[11]) + sha256d_hash1[10]; + S[27] = s1(S[25]) + S[20] + s0(sha256d_hash1[12]) + sha256d_hash1[11]; + S[28] = s1(S[26]) + S[21] + s0(sha256d_hash1[13]) + sha256d_hash1[12]; + S[29] = s1(S[27]) + S[22] + s0(sha256d_hash1[14]) + sha256d_hash1[13]; + S[30] = s1(S[28]) + S[23] + s0(sha256d_hash1[15]) + sha256d_hash1[14]; + S[31] = s1(S[29]) + S[24] + s0(S[16]) + sha256d_hash1[15]; + for (i = 32; i < 60; i += 2) { + S[i] = s1(S[i - 2]) + S[i - 7] + s0(S[i - 15]) + S[i - 16]; + S[i+1] = s1(S[i - 1]) + S[i - 6] + s0(S[i - 14]) + S[i - 15]; + } + S[60] = s1(S[58]) + S[53] + s0(S[45]) + S[44]; + + sha256_init(hash); + + RNDr(hash, S, 0); + RNDr(hash, S, 1); + RNDr(hash, S, 2); + RNDr(hash, S, 3); + RNDr(hash, S, 4); + RNDr(hash, S, 5); + RNDr(hash, S, 6); + RNDr(hash, S, 7); + RNDr(hash, S, 8); + RNDr(hash, S, 9); + RNDr(hash, S, 10); + RNDr(hash, S, 11); + RNDr(hash, S, 12); + RNDr(hash, S, 13); + RNDr(hash, S, 14); + RNDr(hash, S, 15); + RNDr(hash, S, 16); + RNDr(hash, S, 17); + RNDr(hash, S, 18); + RNDr(hash, S, 19); + RNDr(hash, S, 20); + RNDr(hash, S, 21); + RNDr(hash, S, 22); + RNDr(hash, S, 23); + RNDr(hash, S, 24); + RNDr(hash, S, 25); + RNDr(hash, S, 26); + RNDr(hash, S, 27); + RNDr(hash, S, 28); + RNDr(hash, S, 29); + RNDr(hash, S, 30); + RNDr(hash, S, 31); + RNDr(hash, S, 32); + RNDr(hash, S, 33); + RNDr(hash, S, 34); + RNDr(hash, S, 35); + RNDr(hash, S, 36); + RNDr(hash, S, 37); + RNDr(hash, S, 38); + RNDr(hash, S, 39); + RNDr(hash, S, 40); + RNDr(hash, S, 41); + RNDr(hash, S, 42); + RNDr(hash, S, 43); + RNDr(hash, S, 44); + RNDr(hash, S, 45); + RNDr(hash, S, 46); + RNDr(hash, S, 47); + RNDr(hash, S, 48); + RNDr(hash, S, 49); + RNDr(hash, S, 50); + RNDr(hash, S, 51); + RNDr(hash, S, 52); + RNDr(hash, S, 53); + RNDr(hash, S, 54); + RNDr(hash, S, 55); + RNDr(hash, S, 56); + + hash[2] += hash[6] + S1(hash[3]) + Ch(hash[3], hash[4], hash[5]) + + S[57] + sha256_k[57]; + hash[1] += hash[5] + S1(hash[2]) + Ch(hash[2], hash[3], hash[4]) + + S[58] + sha256_k[58]; + hash[0] += hash[4] + S1(hash[1]) + Ch(hash[1], hash[2], hash[3]) + + S[59] + sha256_k[59]; + hash[7] += hash[3] + S1(hash[0]) + Ch(hash[0], hash[1], hash[2]) + + S[60] + sha256_k[60] + + sha256_h[7]; +} + +#endif /* EXTERN_SHA256 */ + +#ifdef HAVE_SHA256_4WAY + +void sha256d_ms_4way(uint32_t *hash, uint32_t *data, + const uint32_t *midstate, const uint32_t *prehash); + +static inline int scanhash_sha256d_4way(int thr_id, struct work *work, + uint32_t max_nonce, uint64_t *hashes_done) +{ + uint32_t *pdata = work->data; + uint32_t *ptarget = work->target; + + uint32_t _ALIGN(128) data[4 * 64]; + uint32_t _ALIGN(32) hash[4 * 8]; + uint32_t _ALIGN(32) midstate[4 * 8]; + uint32_t _ALIGN(32) prehash[4 * 8]; + uint32_t n = pdata[19] - 1; + const uint32_t first_nonce = pdata[19]; + const uint32_t Htarg = ptarget[7]; + int i, j; + + memcpy(data, pdata + 16, 64); + sha256d_preextend(data); + for (i = 31; i >= 0; i--) + for (j = 0; j < 4; j++) + data[i * 4 + j] = data[i]; + + sha256_init(midstate); + sha256_transform(midstate, pdata, 0); + memcpy(prehash, midstate, 32); + sha256d_prehash(prehash, pdata + 16); + for (i = 7; i >= 0; i--) { + for (j = 0; j < 4; j++) { + midstate[i * 4 + j] = midstate[i]; + prehash[i * 4 + j] = prehash[i]; + } + } + + do { + for (i = 0; i < 4; i++) + data[4 * 3 + i] = ++n; + + sha256d_ms_4way(hash, data, midstate, prehash); + + for (i = 0; i < 4; i++) { + if (swab32(hash[4 * 7 + i]) <= Htarg) { + pdata[19] = data[4 * 3 + i]; + sha256d_80_swap(hash, pdata); + if (fulltest(hash, ptarget)) { + *hashes_done = n - first_nonce + 1; + return 1; + } + } + } + } while (n < max_nonce && !work_restart[thr_id].restart); + + *hashes_done = n - first_nonce + 1; + pdata[19] = n; + return 0; +} + +#endif /* HAVE_SHA256_4WAY */ + +#ifdef HAVE_SHA256_8WAY + +void sha256d_ms_8way(uint32_t *hash, uint32_t *data, + const uint32_t *midstate, const uint32_t *prehash); + +static inline int scanhash_sha256d_8way(int thr_id, struct work *work, + uint32_t max_nonce, uint64_t *hashes_done) +{ + uint32_t *pdata = work->data; + uint32_t *ptarget = work->target; + + uint32_t _ALIGN(128) data[8 * 64]; + uint32_t _ALIGN(32) hash[8 * 8]; + uint32_t _ALIGN(32) midstate[8 * 8]; + uint32_t _ALIGN(32) prehash[8 * 8]; + uint32_t n = pdata[19] - 1; + const uint32_t first_nonce = pdata[19]; + const uint32_t Htarg = ptarget[7]; + int i, j; + + memcpy(data, pdata + 16, 64); + sha256d_preextend(data); + for (i = 31; i >= 0; i--) + for (j = 0; j < 8; j++) + data[i * 8 + j] = data[i]; + + sha256_init(midstate); + sha256_transform(midstate, pdata, 0); + memcpy(prehash, midstate, 32); + sha256d_prehash(prehash, pdata + 16); + for (i = 7; i >= 0; i--) { + for (j = 0; j < 8; j++) { + midstate[i * 8 + j] = midstate[i]; + prehash[i * 8 + j] = prehash[i]; + } + } + + do { + for (i = 0; i < 8; i++) + data[8 * 3 + i] = ++n; + + sha256d_ms_8way(hash, data, midstate, prehash); + + for (i = 0; i < 8; i++) { + if (swab32(hash[8 * 7 + i]) <= Htarg) { + pdata[19] = data[8 * 3 + i]; + sha256d_80_swap(hash, pdata); + if (fulltest(hash, ptarget)) { + *hashes_done = n - first_nonce + 1; + return 1; + } + } + } + } while (n < max_nonce && !work_restart[thr_id].restart); + + *hashes_done = n - first_nonce + 1; + pdata[19] = n; + return 0; +} + +#endif /* HAVE_SHA256_8WAY */ + +int scanhash_sha256d(int thr_id, struct work *work, + uint32_t max_nonce, uint64_t *hashes_done) +{ + uint32_t *pdata = work->data; + uint32_t *ptarget = work->target; + uint32_t _ALIGN(128) data[64]; + uint32_t _ALIGN(32) hash[8]; + uint32_t _ALIGN(32) midstate[8]; + uint32_t _ALIGN(32) prehash[8]; + uint32_t n = pdata[19] - 1; + const uint32_t first_nonce = pdata[19]; + const uint32_t Htarg = ptarget[7]; + +#ifdef HAVE_SHA256_8WAY + if (sha256_use_8way()) + return scanhash_sha256d_8way(thr_id, work, + max_nonce, hashes_done); +#endif +#ifdef HAVE_SHA256_4WAY + if (sha256_use_4way()) + return scanhash_sha256d_4way(thr_id, work, + max_nonce, hashes_done); +#endif + + memcpy(data, pdata + 16, 64); + sha256d_preextend(data); + + sha256_init(midstate); + sha256_transform(midstate, pdata, 0); + memcpy(prehash, midstate, 32); + sha256d_prehash(prehash, pdata + 16); + + do { + data[3] = ++n; + sha256d_ms(hash, data, midstate, prehash); + if (unlikely(swab32(hash[7]) <= Htarg)) { + pdata[19] = data[3]; + sha256d_80_swap(hash, pdata); + if (fulltest(hash, ptarget)) { + *hashes_done = n - first_nonce + 1; + return 1; + } + } + } while (likely(n < max_nonce && !work_restart[thr_id].restart)); + + *hashes_done = n - first_nonce + 1; + pdata[19] = n; + return 0; +} + +bool register_sha256d_algo( algo_gate_t* gate ) +{ + gate->scanhash = (void*)&scanhash_sha256d; + gate->hash_alt = (void*)&sha256d; + gate->hash = (void*)&sha256d; + return true; +}; + diff --git a/algo/tiger/sph_tiger.c b/algo/tiger/sph_tiger.c new file mode 100644 index 0000000..12ec2a8 --- /dev/null +++ b/algo/tiger/sph_tiger.c @@ -0,0 +1,698 @@ +/* $Id: tiger.c 216 2010-06-08 09:46:57Z tp $ */ +/* + * Tiger / Tiger2 implementation. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @author Thomas Pornin + */ + +#include +#include + +#include "sph_tiger.h" + +#if SPH_64 + +static const sph_u64 T1[256] = { + SPH_C64(0x02AAB17CF7E90C5E), SPH_C64(0xAC424B03E243A8EC), + SPH_C64(0x72CD5BE30DD5FCD3), SPH_C64(0x6D019B93F6F97F3A), + SPH_C64(0xCD9978FFD21F9193), SPH_C64(0x7573A1C9708029E2), + SPH_C64(0xB164326B922A83C3), SPH_C64(0x46883EEE04915870), + SPH_C64(0xEAACE3057103ECE6), SPH_C64(0xC54169B808A3535C), + SPH_C64(0x4CE754918DDEC47C), SPH_C64(0x0AA2F4DFDC0DF40C), + SPH_C64(0x10B76F18A74DBEFA), SPH_C64(0xC6CCB6235AD1AB6A), + SPH_C64(0x13726121572FE2FF), SPH_C64(0x1A488C6F199D921E), + SPH_C64(0x4BC9F9F4DA0007CA), SPH_C64(0x26F5E6F6E85241C7), + SPH_C64(0x859079DBEA5947B6), SPH_C64(0x4F1885C5C99E8C92), + SPH_C64(0xD78E761EA96F864B), SPH_C64(0x8E36428C52B5C17D), + SPH_C64(0x69CF6827373063C1), SPH_C64(0xB607C93D9BB4C56E), + SPH_C64(0x7D820E760E76B5EA), SPH_C64(0x645C9CC6F07FDC42), + SPH_C64(0xBF38A078243342E0), SPH_C64(0x5F6B343C9D2E7D04), + SPH_C64(0xF2C28AEB600B0EC6), SPH_C64(0x6C0ED85F7254BCAC), + SPH_C64(0x71592281A4DB4FE5), SPH_C64(0x1967FA69CE0FED9F), + SPH_C64(0xFD5293F8B96545DB), SPH_C64(0xC879E9D7F2A7600B), + SPH_C64(0x860248920193194E), SPH_C64(0xA4F9533B2D9CC0B3), + SPH_C64(0x9053836C15957613), SPH_C64(0xDB6DCF8AFC357BF1), + SPH_C64(0x18BEEA7A7A370F57), SPH_C64(0x037117CA50B99066), + SPH_C64(0x6AB30A9774424A35), SPH_C64(0xF4E92F02E325249B), + SPH_C64(0x7739DB07061CCAE1), SPH_C64(0xD8F3B49CECA42A05), + SPH_C64(0xBD56BE3F51382F73), SPH_C64(0x45FAED5843B0BB28), + SPH_C64(0x1C813D5C11BF1F83), SPH_C64(0x8AF0E4B6D75FA169), + SPH_C64(0x33EE18A487AD9999), SPH_C64(0x3C26E8EAB1C94410), + SPH_C64(0xB510102BC0A822F9), SPH_C64(0x141EEF310CE6123B), + SPH_C64(0xFC65B90059DDB154), SPH_C64(0xE0158640C5E0E607), + SPH_C64(0x884E079826C3A3CF), SPH_C64(0x930D0D9523C535FD), + SPH_C64(0x35638D754E9A2B00), SPH_C64(0x4085FCCF40469DD5), + SPH_C64(0xC4B17AD28BE23A4C), SPH_C64(0xCAB2F0FC6A3E6A2E), + SPH_C64(0x2860971A6B943FCD), SPH_C64(0x3DDE6EE212E30446), + SPH_C64(0x6222F32AE01765AE), SPH_C64(0x5D550BB5478308FE), + SPH_C64(0xA9EFA98DA0EDA22A), SPH_C64(0xC351A71686C40DA7), + SPH_C64(0x1105586D9C867C84), SPH_C64(0xDCFFEE85FDA22853), + SPH_C64(0xCCFBD0262C5EEF76), SPH_C64(0xBAF294CB8990D201), + SPH_C64(0xE69464F52AFAD975), SPH_C64(0x94B013AFDF133E14), + SPH_C64(0x06A7D1A32823C958), SPH_C64(0x6F95FE5130F61119), + SPH_C64(0xD92AB34E462C06C0), SPH_C64(0xED7BDE33887C71D2), + SPH_C64(0x79746D6E6518393E), SPH_C64(0x5BA419385D713329), + SPH_C64(0x7C1BA6B948A97564), SPH_C64(0x31987C197BFDAC67), + SPH_C64(0xDE6C23C44B053D02), SPH_C64(0x581C49FED002D64D), + SPH_C64(0xDD474D6338261571), SPH_C64(0xAA4546C3E473D062), + SPH_C64(0x928FCE349455F860), SPH_C64(0x48161BBACAAB94D9), + SPH_C64(0x63912430770E6F68), SPH_C64(0x6EC8A5E602C6641C), + SPH_C64(0x87282515337DDD2B), SPH_C64(0x2CDA6B42034B701B), + SPH_C64(0xB03D37C181CB096D), SPH_C64(0xE108438266C71C6F), + SPH_C64(0x2B3180C7EB51B255), SPH_C64(0xDF92B82F96C08BBC), + SPH_C64(0x5C68C8C0A632F3BA), SPH_C64(0x5504CC861C3D0556), + SPH_C64(0xABBFA4E55FB26B8F), SPH_C64(0x41848B0AB3BACEB4), + SPH_C64(0xB334A273AA445D32), SPH_C64(0xBCA696F0A85AD881), + SPH_C64(0x24F6EC65B528D56C), SPH_C64(0x0CE1512E90F4524A), + SPH_C64(0x4E9DD79D5506D35A), SPH_C64(0x258905FAC6CE9779), + SPH_C64(0x2019295B3E109B33), SPH_C64(0xF8A9478B73A054CC), + SPH_C64(0x2924F2F934417EB0), SPH_C64(0x3993357D536D1BC4), + SPH_C64(0x38A81AC21DB6FF8B), SPH_C64(0x47C4FBF17D6016BF), + SPH_C64(0x1E0FAADD7667E3F5), SPH_C64(0x7ABCFF62938BEB96), + SPH_C64(0xA78DAD948FC179C9), SPH_C64(0x8F1F98B72911E50D), + SPH_C64(0x61E48EAE27121A91), SPH_C64(0x4D62F7AD31859808), + SPH_C64(0xECEBA345EF5CEAEB), SPH_C64(0xF5CEB25EBC9684CE), + SPH_C64(0xF633E20CB7F76221), SPH_C64(0xA32CDF06AB8293E4), + SPH_C64(0x985A202CA5EE2CA4), SPH_C64(0xCF0B8447CC8A8FB1), + SPH_C64(0x9F765244979859A3), SPH_C64(0xA8D516B1A1240017), + SPH_C64(0x0BD7BA3EBB5DC726), SPH_C64(0xE54BCA55B86ADB39), + SPH_C64(0x1D7A3AFD6C478063), SPH_C64(0x519EC608E7669EDD), + SPH_C64(0x0E5715A2D149AA23), SPH_C64(0x177D4571848FF194), + SPH_C64(0xEEB55F3241014C22), SPH_C64(0x0F5E5CA13A6E2EC2), + SPH_C64(0x8029927B75F5C361), SPH_C64(0xAD139FABC3D6E436), + SPH_C64(0x0D5DF1A94CCF402F), SPH_C64(0x3E8BD948BEA5DFC8), + SPH_C64(0xA5A0D357BD3FF77E), SPH_C64(0xA2D12E251F74F645), + SPH_C64(0x66FD9E525E81A082), SPH_C64(0x2E0C90CE7F687A49), + SPH_C64(0xC2E8BCBEBA973BC5), SPH_C64(0x000001BCE509745F), + SPH_C64(0x423777BBE6DAB3D6), SPH_C64(0xD1661C7EAEF06EB5), + SPH_C64(0xA1781F354DAACFD8), SPH_C64(0x2D11284A2B16AFFC), + SPH_C64(0xF1FC4F67FA891D1F), SPH_C64(0x73ECC25DCB920ADA), + SPH_C64(0xAE610C22C2A12651), SPH_C64(0x96E0A810D356B78A), + SPH_C64(0x5A9A381F2FE7870F), SPH_C64(0xD5AD62EDE94E5530), + SPH_C64(0xD225E5E8368D1427), SPH_C64(0x65977B70C7AF4631), + SPH_C64(0x99F889B2DE39D74F), SPH_C64(0x233F30BF54E1D143), + SPH_C64(0x9A9675D3D9A63C97), SPH_C64(0x5470554FF334F9A8), + SPH_C64(0x166ACB744A4F5688), SPH_C64(0x70C74CAAB2E4AEAD), + SPH_C64(0xF0D091646F294D12), SPH_C64(0x57B82A89684031D1), + SPH_C64(0xEFD95A5A61BE0B6B), SPH_C64(0x2FBD12E969F2F29A), + SPH_C64(0x9BD37013FEFF9FE8), SPH_C64(0x3F9B0404D6085A06), + SPH_C64(0x4940C1F3166CFE15), SPH_C64(0x09542C4DCDF3DEFB), + SPH_C64(0xB4C5218385CD5CE3), SPH_C64(0xC935B7DC4462A641), + SPH_C64(0x3417F8A68ED3B63F), SPH_C64(0xB80959295B215B40), + SPH_C64(0xF99CDAEF3B8C8572), SPH_C64(0x018C0614F8FCB95D), + SPH_C64(0x1B14ACCD1A3ACDF3), SPH_C64(0x84D471F200BB732D), + SPH_C64(0xC1A3110E95E8DA16), SPH_C64(0x430A7220BF1A82B8), + SPH_C64(0xB77E090D39DF210E), SPH_C64(0x5EF4BD9F3CD05E9D), + SPH_C64(0x9D4FF6DA7E57A444), SPH_C64(0xDA1D60E183D4A5F8), + SPH_C64(0xB287C38417998E47), SPH_C64(0xFE3EDC121BB31886), + SPH_C64(0xC7FE3CCC980CCBEF), SPH_C64(0xE46FB590189BFD03), + SPH_C64(0x3732FD469A4C57DC), SPH_C64(0x7EF700A07CF1AD65), + SPH_C64(0x59C64468A31D8859), SPH_C64(0x762FB0B4D45B61F6), + SPH_C64(0x155BAED099047718), SPH_C64(0x68755E4C3D50BAA6), + SPH_C64(0xE9214E7F22D8B4DF), SPH_C64(0x2ADDBF532EAC95F4), + SPH_C64(0x32AE3909B4BD0109), SPH_C64(0x834DF537B08E3450), + SPH_C64(0xFA209DA84220728D), SPH_C64(0x9E691D9B9EFE23F7), + SPH_C64(0x0446D288C4AE8D7F), SPH_C64(0x7B4CC524E169785B), + SPH_C64(0x21D87F0135CA1385), SPH_C64(0xCEBB400F137B8AA5), + SPH_C64(0x272E2B66580796BE), SPH_C64(0x3612264125C2B0DE), + SPH_C64(0x057702BDAD1EFBB2), SPH_C64(0xD4BABB8EACF84BE9), + SPH_C64(0x91583139641BC67B), SPH_C64(0x8BDC2DE08036E024), + SPH_C64(0x603C8156F49F68ED), SPH_C64(0xF7D236F7DBEF5111), + SPH_C64(0x9727C4598AD21E80), SPH_C64(0xA08A0896670A5FD7), + SPH_C64(0xCB4A8F4309EBA9CB), SPH_C64(0x81AF564B0F7036A1), + SPH_C64(0xC0B99AA778199ABD), SPH_C64(0x959F1EC83FC8E952), + SPH_C64(0x8C505077794A81B9), SPH_C64(0x3ACAAF8F056338F0), + SPH_C64(0x07B43F50627A6778), SPH_C64(0x4A44AB49F5ECCC77), + SPH_C64(0x3BC3D6E4B679EE98), SPH_C64(0x9CC0D4D1CF14108C), + SPH_C64(0x4406C00B206BC8A0), SPH_C64(0x82A18854C8D72D89), + SPH_C64(0x67E366B35C3C432C), SPH_C64(0xB923DD61102B37F2), + SPH_C64(0x56AB2779D884271D), SPH_C64(0xBE83E1B0FF1525AF), + SPH_C64(0xFB7C65D4217E49A9), SPH_C64(0x6BDBE0E76D48E7D4), + SPH_C64(0x08DF828745D9179E), SPH_C64(0x22EA6A9ADD53BD34), + SPH_C64(0xE36E141C5622200A), SPH_C64(0x7F805D1B8CB750EE), + SPH_C64(0xAFE5C7A59F58E837), SPH_C64(0xE27F996A4FB1C23C), + SPH_C64(0xD3867DFB0775F0D0), SPH_C64(0xD0E673DE6E88891A), + SPH_C64(0x123AEB9EAFB86C25), SPH_C64(0x30F1D5D5C145B895), + SPH_C64(0xBB434A2DEE7269E7), SPH_C64(0x78CB67ECF931FA38), + SPH_C64(0xF33B0372323BBF9C), SPH_C64(0x52D66336FB279C74), + SPH_C64(0x505F33AC0AFB4EAA), SPH_C64(0xE8A5CD99A2CCE187), + SPH_C64(0x534974801E2D30BB), SPH_C64(0x8D2D5711D5876D90), + SPH_C64(0x1F1A412891BC038E), SPH_C64(0xD6E2E71D82E56648), + SPH_C64(0x74036C3A497732B7), SPH_C64(0x89B67ED96361F5AB), + SPH_C64(0xFFED95D8F1EA02A2), SPH_C64(0xE72B3BD61464D43D), + SPH_C64(0xA6300F170BDC4820), SPH_C64(0xEBC18760ED78A77A), +}; + +static const sph_u64 T2[256] = { + SPH_C64(0xE6A6BE5A05A12138), SPH_C64(0xB5A122A5B4F87C98), + SPH_C64(0x563C6089140B6990), SPH_C64(0x4C46CB2E391F5DD5), + SPH_C64(0xD932ADDBC9B79434), SPH_C64(0x08EA70E42015AFF5), + SPH_C64(0xD765A6673E478CF1), SPH_C64(0xC4FB757EAB278D99), + SPH_C64(0xDF11C6862D6E0692), SPH_C64(0xDDEB84F10D7F3B16), + SPH_C64(0x6F2EF604A665EA04), SPH_C64(0x4A8E0F0FF0E0DFB3), + SPH_C64(0xA5EDEEF83DBCBA51), SPH_C64(0xFC4F0A2A0EA4371E), + SPH_C64(0xE83E1DA85CB38429), SPH_C64(0xDC8FF882BA1B1CE2), + SPH_C64(0xCD45505E8353E80D), SPH_C64(0x18D19A00D4DB0717), + SPH_C64(0x34A0CFEDA5F38101), SPH_C64(0x0BE77E518887CAF2), + SPH_C64(0x1E341438B3C45136), SPH_C64(0xE05797F49089CCF9), + SPH_C64(0xFFD23F9DF2591D14), SPH_C64(0x543DDA228595C5CD), + SPH_C64(0x661F81FD99052A33), SPH_C64(0x8736E641DB0F7B76), + SPH_C64(0x15227725418E5307), SPH_C64(0xE25F7F46162EB2FA), + SPH_C64(0x48A8B2126C13D9FE), SPH_C64(0xAFDC541792E76EEA), + SPH_C64(0x03D912BFC6D1898F), SPH_C64(0x31B1AAFA1B83F51B), + SPH_C64(0xF1AC2796E42AB7D9), SPH_C64(0x40A3A7D7FCD2EBAC), + SPH_C64(0x1056136D0AFBBCC5), SPH_C64(0x7889E1DD9A6D0C85), + SPH_C64(0xD33525782A7974AA), SPH_C64(0xA7E25D09078AC09B), + SPH_C64(0xBD4138B3EAC6EDD0), SPH_C64(0x920ABFBE71EB9E70), + SPH_C64(0xA2A5D0F54FC2625C), SPH_C64(0xC054E36B0B1290A3), + SPH_C64(0xF6DD59FF62FE932B), SPH_C64(0x3537354511A8AC7D), + SPH_C64(0xCA845E9172FADCD4), SPH_C64(0x84F82B60329D20DC), + SPH_C64(0x79C62CE1CD672F18), SPH_C64(0x8B09A2ADD124642C), + SPH_C64(0xD0C1E96A19D9E726), SPH_C64(0x5A786A9B4BA9500C), + SPH_C64(0x0E020336634C43F3), SPH_C64(0xC17B474AEB66D822), + SPH_C64(0x6A731AE3EC9BAAC2), SPH_C64(0x8226667AE0840258), + SPH_C64(0x67D4567691CAECA5), SPH_C64(0x1D94155C4875ADB5), + SPH_C64(0x6D00FD985B813FDF), SPH_C64(0x51286EFCB774CD06), + SPH_C64(0x5E8834471FA744AF), SPH_C64(0xF72CA0AEE761AE2E), + SPH_C64(0xBE40E4CDAEE8E09A), SPH_C64(0xE9970BBB5118F665), + SPH_C64(0x726E4BEB33DF1964), SPH_C64(0x703B000729199762), + SPH_C64(0x4631D816F5EF30A7), SPH_C64(0xB880B5B51504A6BE), + SPH_C64(0x641793C37ED84B6C), SPH_C64(0x7B21ED77F6E97D96), + SPH_C64(0x776306312EF96B73), SPH_C64(0xAE528948E86FF3F4), + SPH_C64(0x53DBD7F286A3F8F8), SPH_C64(0x16CADCE74CFC1063), + SPH_C64(0x005C19BDFA52C6DD), SPH_C64(0x68868F5D64D46AD3), + SPH_C64(0x3A9D512CCF1E186A), SPH_C64(0x367E62C2385660AE), + SPH_C64(0xE359E7EA77DCB1D7), SPH_C64(0x526C0773749ABE6E), + SPH_C64(0x735AE5F9D09F734B), SPH_C64(0x493FC7CC8A558BA8), + SPH_C64(0xB0B9C1533041AB45), SPH_C64(0x321958BA470A59BD), + SPH_C64(0x852DB00B5F46C393), SPH_C64(0x91209B2BD336B0E5), + SPH_C64(0x6E604F7D659EF19F), SPH_C64(0xB99A8AE2782CCB24), + SPH_C64(0xCCF52AB6C814C4C7), SPH_C64(0x4727D9AFBE11727B), + SPH_C64(0x7E950D0C0121B34D), SPH_C64(0x756F435670AD471F), + SPH_C64(0xF5ADD442615A6849), SPH_C64(0x4E87E09980B9957A), + SPH_C64(0x2ACFA1DF50AEE355), SPH_C64(0xD898263AFD2FD556), + SPH_C64(0xC8F4924DD80C8FD6), SPH_C64(0xCF99CA3D754A173A), + SPH_C64(0xFE477BACAF91BF3C), SPH_C64(0xED5371F6D690C12D), + SPH_C64(0x831A5C285E687094), SPH_C64(0xC5D3C90A3708A0A4), + SPH_C64(0x0F7F903717D06580), SPH_C64(0x19F9BB13B8FDF27F), + SPH_C64(0xB1BD6F1B4D502843), SPH_C64(0x1C761BA38FFF4012), + SPH_C64(0x0D1530C4E2E21F3B), SPH_C64(0x8943CE69A7372C8A), + SPH_C64(0xE5184E11FEB5CE66), SPH_C64(0x618BDB80BD736621), + SPH_C64(0x7D29BAD68B574D0B), SPH_C64(0x81BB613E25E6FE5B), + SPH_C64(0x071C9C10BC07913F), SPH_C64(0xC7BEEB7909AC2D97), + SPH_C64(0xC3E58D353BC5D757), SPH_C64(0xEB017892F38F61E8), + SPH_C64(0xD4EFFB9C9B1CC21A), SPH_C64(0x99727D26F494F7AB), + SPH_C64(0xA3E063A2956B3E03), SPH_C64(0x9D4A8B9A4AA09C30), + SPH_C64(0x3F6AB7D500090FB4), SPH_C64(0x9CC0F2A057268AC0), + SPH_C64(0x3DEE9D2DEDBF42D1), SPH_C64(0x330F49C87960A972), + SPH_C64(0xC6B2720287421B41), SPH_C64(0x0AC59EC07C00369C), + SPH_C64(0xEF4EAC49CB353425), SPH_C64(0xF450244EEF0129D8), + SPH_C64(0x8ACC46E5CAF4DEB6), SPH_C64(0x2FFEAB63989263F7), + SPH_C64(0x8F7CB9FE5D7A4578), SPH_C64(0x5BD8F7644E634635), + SPH_C64(0x427A7315BF2DC900), SPH_C64(0x17D0C4AA2125261C), + SPH_C64(0x3992486C93518E50), SPH_C64(0xB4CBFEE0A2D7D4C3), + SPH_C64(0x7C75D6202C5DDD8D), SPH_C64(0xDBC295D8E35B6C61), + SPH_C64(0x60B369D302032B19), SPH_C64(0xCE42685FDCE44132), + SPH_C64(0x06F3DDB9DDF65610), SPH_C64(0x8EA4D21DB5E148F0), + SPH_C64(0x20B0FCE62FCD496F), SPH_C64(0x2C1B912358B0EE31), + SPH_C64(0xB28317B818F5A308), SPH_C64(0xA89C1E189CA6D2CF), + SPH_C64(0x0C6B18576AAADBC8), SPH_C64(0xB65DEAA91299FAE3), + SPH_C64(0xFB2B794B7F1027E7), SPH_C64(0x04E4317F443B5BEB), + SPH_C64(0x4B852D325939D0A6), SPH_C64(0xD5AE6BEEFB207FFC), + SPH_C64(0x309682B281C7D374), SPH_C64(0xBAE309A194C3B475), + SPH_C64(0x8CC3F97B13B49F05), SPH_C64(0x98A9422FF8293967), + SPH_C64(0x244B16B01076FF7C), SPH_C64(0xF8BF571C663D67EE), + SPH_C64(0x1F0D6758EEE30DA1), SPH_C64(0xC9B611D97ADEB9B7), + SPH_C64(0xB7AFD5887B6C57A2), SPH_C64(0x6290AE846B984FE1), + SPH_C64(0x94DF4CDEACC1A5FD), SPH_C64(0x058A5BD1C5483AFF), + SPH_C64(0x63166CC142BA3C37), SPH_C64(0x8DB8526EB2F76F40), + SPH_C64(0xE10880036F0D6D4E), SPH_C64(0x9E0523C9971D311D), + SPH_C64(0x45EC2824CC7CD691), SPH_C64(0x575B8359E62382C9), + SPH_C64(0xFA9E400DC4889995), SPH_C64(0xD1823ECB45721568), + SPH_C64(0xDAFD983B8206082F), SPH_C64(0xAA7D29082386A8CB), + SPH_C64(0x269FCD4403B87588), SPH_C64(0x1B91F5F728BDD1E0), + SPH_C64(0xE4669F39040201F6), SPH_C64(0x7A1D7C218CF04ADE), + SPH_C64(0x65623C29D79CE5CE), SPH_C64(0x2368449096C00BB1), + SPH_C64(0xAB9BF1879DA503BA), SPH_C64(0xBC23ECB1A458058E), + SPH_C64(0x9A58DF01BB401ECC), SPH_C64(0xA070E868A85F143D), + SPH_C64(0x4FF188307DF2239E), SPH_C64(0x14D565B41A641183), + SPH_C64(0xEE13337452701602), SPH_C64(0x950E3DCF3F285E09), + SPH_C64(0x59930254B9C80953), SPH_C64(0x3BF299408930DA6D), + SPH_C64(0xA955943F53691387), SPH_C64(0xA15EDECAA9CB8784), + SPH_C64(0x29142127352BE9A0), SPH_C64(0x76F0371FFF4E7AFB), + SPH_C64(0x0239F450274F2228), SPH_C64(0xBB073AF01D5E868B), + SPH_C64(0xBFC80571C10E96C1), SPH_C64(0xD267088568222E23), + SPH_C64(0x9671A3D48E80B5B0), SPH_C64(0x55B5D38AE193BB81), + SPH_C64(0x693AE2D0A18B04B8), SPH_C64(0x5C48B4ECADD5335F), + SPH_C64(0xFD743B194916A1CA), SPH_C64(0x2577018134BE98C4), + SPH_C64(0xE77987E83C54A4AD), SPH_C64(0x28E11014DA33E1B9), + SPH_C64(0x270CC59E226AA213), SPH_C64(0x71495F756D1A5F60), + SPH_C64(0x9BE853FB60AFEF77), SPH_C64(0xADC786A7F7443DBF), + SPH_C64(0x0904456173B29A82), SPH_C64(0x58BC7A66C232BD5E), + SPH_C64(0xF306558C673AC8B2), SPH_C64(0x41F639C6B6C9772A), + SPH_C64(0x216DEFE99FDA35DA), SPH_C64(0x11640CC71C7BE615), + SPH_C64(0x93C43694565C5527), SPH_C64(0xEA038E6246777839), + SPH_C64(0xF9ABF3CE5A3E2469), SPH_C64(0x741E768D0FD312D2), + SPH_C64(0x0144B883CED652C6), SPH_C64(0xC20B5A5BA33F8552), + SPH_C64(0x1AE69633C3435A9D), SPH_C64(0x97A28CA4088CFDEC), + SPH_C64(0x8824A43C1E96F420), SPH_C64(0x37612FA66EEEA746), + SPH_C64(0x6B4CB165F9CF0E5A), SPH_C64(0x43AA1C06A0ABFB4A), + SPH_C64(0x7F4DC26FF162796B), SPH_C64(0x6CBACC8E54ED9B0F), + SPH_C64(0xA6B7FFEFD2BB253E), SPH_C64(0x2E25BC95B0A29D4F), + SPH_C64(0x86D6A58BDEF1388C), SPH_C64(0xDED74AC576B6F054), + SPH_C64(0x8030BDBC2B45805D), SPH_C64(0x3C81AF70E94D9289), + SPH_C64(0x3EFF6DDA9E3100DB), SPH_C64(0xB38DC39FDFCC8847), + SPH_C64(0x123885528D17B87E), SPH_C64(0xF2DA0ED240B1B642), + SPH_C64(0x44CEFADCD54BF9A9), SPH_C64(0x1312200E433C7EE6), + SPH_C64(0x9FFCC84F3A78C748), SPH_C64(0xF0CD1F72248576BB), + SPH_C64(0xEC6974053638CFE4), SPH_C64(0x2BA7B67C0CEC4E4C), + SPH_C64(0xAC2F4DF3E5CE32ED), SPH_C64(0xCB33D14326EA4C11), + SPH_C64(0xA4E9044CC77E58BC), SPH_C64(0x5F513293D934FCEF), + SPH_C64(0x5DC9645506E55444), SPH_C64(0x50DE418F317DE40A), + SPH_C64(0x388CB31A69DDE259), SPH_C64(0x2DB4A83455820A86), + SPH_C64(0x9010A91E84711AE9), SPH_C64(0x4DF7F0B7B1498371), + SPH_C64(0xD62A2EABC0977179), SPH_C64(0x22FAC097AA8D5C0E), +}; + +static const sph_u64 T3[256] = { + SPH_C64(0xF49FCC2FF1DAF39B), SPH_C64(0x487FD5C66FF29281), + SPH_C64(0xE8A30667FCDCA83F), SPH_C64(0x2C9B4BE3D2FCCE63), + SPH_C64(0xDA3FF74B93FBBBC2), SPH_C64(0x2FA165D2FE70BA66), + SPH_C64(0xA103E279970E93D4), SPH_C64(0xBECDEC77B0E45E71), + SPH_C64(0xCFB41E723985E497), SPH_C64(0xB70AAA025EF75017), + SPH_C64(0xD42309F03840B8E0), SPH_C64(0x8EFC1AD035898579), + SPH_C64(0x96C6920BE2B2ABC5), SPH_C64(0x66AF4163375A9172), + SPH_C64(0x2174ABDCCA7127FB), SPH_C64(0xB33CCEA64A72FF41), + SPH_C64(0xF04A4933083066A5), SPH_C64(0x8D970ACDD7289AF5), + SPH_C64(0x8F96E8E031C8C25E), SPH_C64(0xF3FEC02276875D47), + SPH_C64(0xEC7BF310056190DD), SPH_C64(0xF5ADB0AEBB0F1491), + SPH_C64(0x9B50F8850FD58892), SPH_C64(0x4975488358B74DE8), + SPH_C64(0xA3354FF691531C61), SPH_C64(0x0702BBE481D2C6EE), + SPH_C64(0x89FB24057DEDED98), SPH_C64(0xAC3075138596E902), + SPH_C64(0x1D2D3580172772ED), SPH_C64(0xEB738FC28E6BC30D), + SPH_C64(0x5854EF8F63044326), SPH_C64(0x9E5C52325ADD3BBE), + SPH_C64(0x90AA53CF325C4623), SPH_C64(0xC1D24D51349DD067), + SPH_C64(0x2051CFEEA69EA624), SPH_C64(0x13220F0A862E7E4F), + SPH_C64(0xCE39399404E04864), SPH_C64(0xD9C42CA47086FCB7), + SPH_C64(0x685AD2238A03E7CC), SPH_C64(0x066484B2AB2FF1DB), + SPH_C64(0xFE9D5D70EFBF79EC), SPH_C64(0x5B13B9DD9C481854), + SPH_C64(0x15F0D475ED1509AD), SPH_C64(0x0BEBCD060EC79851), + SPH_C64(0xD58C6791183AB7F8), SPH_C64(0xD1187C5052F3EEE4), + SPH_C64(0xC95D1192E54E82FF), SPH_C64(0x86EEA14CB9AC6CA2), + SPH_C64(0x3485BEB153677D5D), SPH_C64(0xDD191D781F8C492A), + SPH_C64(0xF60866BAA784EBF9), SPH_C64(0x518F643BA2D08C74), + SPH_C64(0x8852E956E1087C22), SPH_C64(0xA768CB8DC410AE8D), + SPH_C64(0x38047726BFEC8E1A), SPH_C64(0xA67738B4CD3B45AA), + SPH_C64(0xAD16691CEC0DDE19), SPH_C64(0xC6D4319380462E07), + SPH_C64(0xC5A5876D0BA61938), SPH_C64(0x16B9FA1FA58FD840), + SPH_C64(0x188AB1173CA74F18), SPH_C64(0xABDA2F98C99C021F), + SPH_C64(0x3E0580AB134AE816), SPH_C64(0x5F3B05B773645ABB), + SPH_C64(0x2501A2BE5575F2F6), SPH_C64(0x1B2F74004E7E8BA9), + SPH_C64(0x1CD7580371E8D953), SPH_C64(0x7F6ED89562764E30), + SPH_C64(0xB15926FF596F003D), SPH_C64(0x9F65293DA8C5D6B9), + SPH_C64(0x6ECEF04DD690F84C), SPH_C64(0x4782275FFF33AF88), + SPH_C64(0xE41433083F820801), SPH_C64(0xFD0DFE409A1AF9B5), + SPH_C64(0x4325A3342CDB396B), SPH_C64(0x8AE77E62B301B252), + SPH_C64(0xC36F9E9F6655615A), SPH_C64(0x85455A2D92D32C09), + SPH_C64(0xF2C7DEA949477485), SPH_C64(0x63CFB4C133A39EBA), + SPH_C64(0x83B040CC6EBC5462), SPH_C64(0x3B9454C8FDB326B0), + SPH_C64(0x56F56A9E87FFD78C), SPH_C64(0x2DC2940D99F42BC6), + SPH_C64(0x98F7DF096B096E2D), SPH_C64(0x19A6E01E3AD852BF), + SPH_C64(0x42A99CCBDBD4B40B), SPH_C64(0xA59998AF45E9C559), + SPH_C64(0x366295E807D93186), SPH_C64(0x6B48181BFAA1F773), + SPH_C64(0x1FEC57E2157A0A1D), SPH_C64(0x4667446AF6201AD5), + SPH_C64(0xE615EBCACFB0F075), SPH_C64(0xB8F31F4F68290778), + SPH_C64(0x22713ED6CE22D11E), SPH_C64(0x3057C1A72EC3C93B), + SPH_C64(0xCB46ACC37C3F1F2F), SPH_C64(0xDBB893FD02AAF50E), + SPH_C64(0x331FD92E600B9FCF), SPH_C64(0xA498F96148EA3AD6), + SPH_C64(0xA8D8426E8B6A83EA), SPH_C64(0xA089B274B7735CDC), + SPH_C64(0x87F6B3731E524A11), SPH_C64(0x118808E5CBC96749), + SPH_C64(0x9906E4C7B19BD394), SPH_C64(0xAFED7F7E9B24A20C), + SPH_C64(0x6509EADEEB3644A7), SPH_C64(0x6C1EF1D3E8EF0EDE), + SPH_C64(0xB9C97D43E9798FB4), SPH_C64(0xA2F2D784740C28A3), + SPH_C64(0x7B8496476197566F), SPH_C64(0x7A5BE3E6B65F069D), + SPH_C64(0xF96330ED78BE6F10), SPH_C64(0xEEE60DE77A076A15), + SPH_C64(0x2B4BEE4AA08B9BD0), SPH_C64(0x6A56A63EC7B8894E), + SPH_C64(0x02121359BA34FEF4), SPH_C64(0x4CBF99F8283703FC), + SPH_C64(0x398071350CAF30C8), SPH_C64(0xD0A77A89F017687A), + SPH_C64(0xF1C1A9EB9E423569), SPH_C64(0x8C7976282DEE8199), + SPH_C64(0x5D1737A5DD1F7ABD), SPH_C64(0x4F53433C09A9FA80), + SPH_C64(0xFA8B0C53DF7CA1D9), SPH_C64(0x3FD9DCBC886CCB77), + SPH_C64(0xC040917CA91B4720), SPH_C64(0x7DD00142F9D1DCDF), + SPH_C64(0x8476FC1D4F387B58), SPH_C64(0x23F8E7C5F3316503), + SPH_C64(0x032A2244E7E37339), SPH_C64(0x5C87A5D750F5A74B), + SPH_C64(0x082B4CC43698992E), SPH_C64(0xDF917BECB858F63C), + SPH_C64(0x3270B8FC5BF86DDA), SPH_C64(0x10AE72BB29B5DD76), + SPH_C64(0x576AC94E7700362B), SPH_C64(0x1AD112DAC61EFB8F), + SPH_C64(0x691BC30EC5FAA427), SPH_C64(0xFF246311CC327143), + SPH_C64(0x3142368E30E53206), SPH_C64(0x71380E31E02CA396), + SPH_C64(0x958D5C960AAD76F1), SPH_C64(0xF8D6F430C16DA536), + SPH_C64(0xC8FFD13F1BE7E1D2), SPH_C64(0x7578AE66004DDBE1), + SPH_C64(0x05833F01067BE646), SPH_C64(0xBB34B5AD3BFE586D), + SPH_C64(0x095F34C9A12B97F0), SPH_C64(0x247AB64525D60CA8), + SPH_C64(0xDCDBC6F3017477D1), SPH_C64(0x4A2E14D4DECAD24D), + SPH_C64(0xBDB5E6D9BE0A1EEB), SPH_C64(0x2A7E70F7794301AB), + SPH_C64(0xDEF42D8A270540FD), SPH_C64(0x01078EC0A34C22C1), + SPH_C64(0xE5DE511AF4C16387), SPH_C64(0x7EBB3A52BD9A330A), + SPH_C64(0x77697857AA7D6435), SPH_C64(0x004E831603AE4C32), + SPH_C64(0xE7A21020AD78E312), SPH_C64(0x9D41A70C6AB420F2), + SPH_C64(0x28E06C18EA1141E6), SPH_C64(0xD2B28CBD984F6B28), + SPH_C64(0x26B75F6C446E9D83), SPH_C64(0xBA47568C4D418D7F), + SPH_C64(0xD80BADBFE6183D8E), SPH_C64(0x0E206D7F5F166044), + SPH_C64(0xE258A43911CBCA3E), SPH_C64(0x723A1746B21DC0BC), + SPH_C64(0xC7CAA854F5D7CDD3), SPH_C64(0x7CAC32883D261D9C), + SPH_C64(0x7690C26423BA942C), SPH_C64(0x17E55524478042B8), + SPH_C64(0xE0BE477656A2389F), SPH_C64(0x4D289B5E67AB2DA0), + SPH_C64(0x44862B9C8FBBFD31), SPH_C64(0xB47CC8049D141365), + SPH_C64(0x822C1B362B91C793), SPH_C64(0x4EB14655FB13DFD8), + SPH_C64(0x1ECBBA0714E2A97B), SPH_C64(0x6143459D5CDE5F14), + SPH_C64(0x53A8FBF1D5F0AC89), SPH_C64(0x97EA04D81C5E5B00), + SPH_C64(0x622181A8D4FDB3F3), SPH_C64(0xE9BCD341572A1208), + SPH_C64(0x1411258643CCE58A), SPH_C64(0x9144C5FEA4C6E0A4), + SPH_C64(0x0D33D06565CF620F), SPH_C64(0x54A48D489F219CA1), + SPH_C64(0xC43E5EAC6D63C821), SPH_C64(0xA9728B3A72770DAF), + SPH_C64(0xD7934E7B20DF87EF), SPH_C64(0xE35503B61A3E86E5), + SPH_C64(0xCAE321FBC819D504), SPH_C64(0x129A50B3AC60BFA6), + SPH_C64(0xCD5E68EA7E9FB6C3), SPH_C64(0xB01C90199483B1C7), + SPH_C64(0x3DE93CD5C295376C), SPH_C64(0xAED52EDF2AB9AD13), + SPH_C64(0x2E60F512C0A07884), SPH_C64(0xBC3D86A3E36210C9), + SPH_C64(0x35269D9B163951CE), SPH_C64(0x0C7D6E2AD0CDB5FA), + SPH_C64(0x59E86297D87F5733), SPH_C64(0x298EF221898DB0E7), + SPH_C64(0x55000029D1A5AA7E), SPH_C64(0x8BC08AE1B5061B45), + SPH_C64(0xC2C31C2B6C92703A), SPH_C64(0x94CC596BAF25EF42), + SPH_C64(0x0A1D73DB22540456), SPH_C64(0x04B6A0F9D9C4179A), + SPH_C64(0xEFFDAFA2AE3D3C60), SPH_C64(0xF7C8075BB49496C4), + SPH_C64(0x9CC5C7141D1CD4E3), SPH_C64(0x78BD1638218E5534), + SPH_C64(0xB2F11568F850246A), SPH_C64(0xEDFABCFA9502BC29), + SPH_C64(0x796CE5F2DA23051B), SPH_C64(0xAAE128B0DC93537C), + SPH_C64(0x3A493DA0EE4B29AE), SPH_C64(0xB5DF6B2C416895D7), + SPH_C64(0xFCABBD25122D7F37), SPH_C64(0x70810B58105DC4B1), + SPH_C64(0xE10FDD37F7882A90), SPH_C64(0x524DCAB5518A3F5C), + SPH_C64(0x3C9E85878451255B), SPH_C64(0x4029828119BD34E2), + SPH_C64(0x74A05B6F5D3CECCB), SPH_C64(0xB610021542E13ECA), + SPH_C64(0x0FF979D12F59E2AC), SPH_C64(0x6037DA27E4F9CC50), + SPH_C64(0x5E92975A0DF1847D), SPH_C64(0xD66DE190D3E623FE), + SPH_C64(0x5032D6B87B568048), SPH_C64(0x9A36B7CE8235216E), + SPH_C64(0x80272A7A24F64B4A), SPH_C64(0x93EFED8B8C6916F7), + SPH_C64(0x37DDBFF44CCE1555), SPH_C64(0x4B95DB5D4B99BD25), + SPH_C64(0x92D3FDA169812FC0), SPH_C64(0xFB1A4A9A90660BB6), + SPH_C64(0x730C196946A4B9B2), SPH_C64(0x81E289AA7F49DA68), + SPH_C64(0x64669A0F83B1A05F), SPH_C64(0x27B3FF7D9644F48B), + SPH_C64(0xCC6B615C8DB675B3), SPH_C64(0x674F20B9BCEBBE95), + SPH_C64(0x6F31238275655982), SPH_C64(0x5AE488713E45CF05), + SPH_C64(0xBF619F9954C21157), SPH_C64(0xEABAC46040A8EAE9), + SPH_C64(0x454C6FE9F2C0C1CD), SPH_C64(0x419CF6496412691C), + SPH_C64(0xD3DC3BEF265B0F70), SPH_C64(0x6D0E60F5C3578A9E), +}; + +static const sph_u64 T4[256] = { + SPH_C64(0x5B0E608526323C55), SPH_C64(0x1A46C1A9FA1B59F5), + SPH_C64(0xA9E245A17C4C8FFA), SPH_C64(0x65CA5159DB2955D7), + SPH_C64(0x05DB0A76CE35AFC2), SPH_C64(0x81EAC77EA9113D45), + SPH_C64(0x528EF88AB6AC0A0D), SPH_C64(0xA09EA253597BE3FF), + SPH_C64(0x430DDFB3AC48CD56), SPH_C64(0xC4B3A67AF45CE46F), + SPH_C64(0x4ECECFD8FBE2D05E), SPH_C64(0x3EF56F10B39935F0), + SPH_C64(0x0B22D6829CD619C6), SPH_C64(0x17FD460A74DF2069), + SPH_C64(0x6CF8CC8E8510ED40), SPH_C64(0xD6C824BF3A6ECAA7), + SPH_C64(0x61243D581A817049), SPH_C64(0x048BACB6BBC163A2), + SPH_C64(0xD9A38AC27D44CC32), SPH_C64(0x7FDDFF5BAAF410AB), + SPH_C64(0xAD6D495AA804824B), SPH_C64(0xE1A6A74F2D8C9F94), + SPH_C64(0xD4F7851235DEE8E3), SPH_C64(0xFD4B7F886540D893), + SPH_C64(0x247C20042AA4BFDA), SPH_C64(0x096EA1C517D1327C), + SPH_C64(0xD56966B4361A6685), SPH_C64(0x277DA5C31221057D), + SPH_C64(0x94D59893A43ACFF7), SPH_C64(0x64F0C51CCDC02281), + SPH_C64(0x3D33BCC4FF6189DB), SPH_C64(0xE005CB184CE66AF1), + SPH_C64(0xFF5CCD1D1DB99BEA), SPH_C64(0xB0B854A7FE42980F), + SPH_C64(0x7BD46A6A718D4B9F), SPH_C64(0xD10FA8CC22A5FD8C), + SPH_C64(0xD31484952BE4BD31), SPH_C64(0xC7FA975FCB243847), + SPH_C64(0x4886ED1E5846C407), SPH_C64(0x28CDDB791EB70B04), + SPH_C64(0xC2B00BE2F573417F), SPH_C64(0x5C9590452180F877), + SPH_C64(0x7A6BDDFFF370EB00), SPH_C64(0xCE509E38D6D9D6A4), + SPH_C64(0xEBEB0F00647FA702), SPH_C64(0x1DCC06CF76606F06), + SPH_C64(0xE4D9F28BA286FF0A), SPH_C64(0xD85A305DC918C262), + SPH_C64(0x475B1D8732225F54), SPH_C64(0x2D4FB51668CCB5FE), + SPH_C64(0xA679B9D9D72BBA20), SPH_C64(0x53841C0D912D43A5), + SPH_C64(0x3B7EAA48BF12A4E8), SPH_C64(0x781E0E47F22F1DDF), + SPH_C64(0xEFF20CE60AB50973), SPH_C64(0x20D261D19DFFB742), + SPH_C64(0x16A12B03062A2E39), SPH_C64(0x1960EB2239650495), + SPH_C64(0x251C16FED50EB8B8), SPH_C64(0x9AC0C330F826016E), + SPH_C64(0xED152665953E7671), SPH_C64(0x02D63194A6369570), + SPH_C64(0x5074F08394B1C987), SPH_C64(0x70BA598C90B25CE1), + SPH_C64(0x794A15810B9742F6), SPH_C64(0x0D5925E9FCAF8C6C), + SPH_C64(0x3067716CD868744E), SPH_C64(0x910AB077E8D7731B), + SPH_C64(0x6A61BBDB5AC42F61), SPH_C64(0x93513EFBF0851567), + SPH_C64(0xF494724B9E83E9D5), SPH_C64(0xE887E1985C09648D), + SPH_C64(0x34B1D3C675370CFD), SPH_C64(0xDC35E433BC0D255D), + SPH_C64(0xD0AAB84234131BE0), SPH_C64(0x08042A50B48B7EAF), + SPH_C64(0x9997C4EE44A3AB35), SPH_C64(0x829A7B49201799D0), + SPH_C64(0x263B8307B7C54441), SPH_C64(0x752F95F4FD6A6CA6), + SPH_C64(0x927217402C08C6E5), SPH_C64(0x2A8AB754A795D9EE), + SPH_C64(0xA442F7552F72943D), SPH_C64(0x2C31334E19781208), + SPH_C64(0x4FA98D7CEAEE6291), SPH_C64(0x55C3862F665DB309), + SPH_C64(0xBD0610175D53B1F3), SPH_C64(0x46FE6CB840413F27), + SPH_C64(0x3FE03792DF0CFA59), SPH_C64(0xCFE700372EB85E8F), + SPH_C64(0xA7BE29E7ADBCE118), SPH_C64(0xE544EE5CDE8431DD), + SPH_C64(0x8A781B1B41F1873E), SPH_C64(0xA5C94C78A0D2F0E7), + SPH_C64(0x39412E2877B60728), SPH_C64(0xA1265EF3AFC9A62C), + SPH_C64(0xBCC2770C6A2506C5), SPH_C64(0x3AB66DD5DCE1CE12), + SPH_C64(0xE65499D04A675B37), SPH_C64(0x7D8F523481BFD216), + SPH_C64(0x0F6F64FCEC15F389), SPH_C64(0x74EFBE618B5B13C8), + SPH_C64(0xACDC82B714273E1D), SPH_C64(0xDD40BFE003199D17), + SPH_C64(0x37E99257E7E061F8), SPH_C64(0xFA52626904775AAA), + SPH_C64(0x8BBBF63A463D56F9), SPH_C64(0xF0013F1543A26E64), + SPH_C64(0xA8307E9F879EC898), SPH_C64(0xCC4C27A4150177CC), + SPH_C64(0x1B432F2CCA1D3348), SPH_C64(0xDE1D1F8F9F6FA013), + SPH_C64(0x606602A047A7DDD6), SPH_C64(0xD237AB64CC1CB2C7), + SPH_C64(0x9B938E7225FCD1D3), SPH_C64(0xEC4E03708E0FF476), + SPH_C64(0xFEB2FBDA3D03C12D), SPH_C64(0xAE0BCED2EE43889A), + SPH_C64(0x22CB8923EBFB4F43), SPH_C64(0x69360D013CF7396D), + SPH_C64(0x855E3602D2D4E022), SPH_C64(0x073805BAD01F784C), + SPH_C64(0x33E17A133852F546), SPH_C64(0xDF4874058AC7B638), + SPH_C64(0xBA92B29C678AA14A), SPH_C64(0x0CE89FC76CFAADCD), + SPH_C64(0x5F9D4E0908339E34), SPH_C64(0xF1AFE9291F5923B9), + SPH_C64(0x6E3480F60F4A265F), SPH_C64(0xEEBF3A2AB29B841C), + SPH_C64(0xE21938A88F91B4AD), SPH_C64(0x57DFEFF845C6D3C3), + SPH_C64(0x2F006B0BF62CAAF2), SPH_C64(0x62F479EF6F75EE78), + SPH_C64(0x11A55AD41C8916A9), SPH_C64(0xF229D29084FED453), + SPH_C64(0x42F1C27B16B000E6), SPH_C64(0x2B1F76749823C074), + SPH_C64(0x4B76ECA3C2745360), SPH_C64(0x8C98F463B91691BD), + SPH_C64(0x14BCC93CF1ADE66A), SPH_C64(0x8885213E6D458397), + SPH_C64(0x8E177DF0274D4711), SPH_C64(0xB49B73B5503F2951), + SPH_C64(0x10168168C3F96B6B), SPH_C64(0x0E3D963B63CAB0AE), + SPH_C64(0x8DFC4B5655A1DB14), SPH_C64(0xF789F1356E14DE5C), + SPH_C64(0x683E68AF4E51DAC1), SPH_C64(0xC9A84F9D8D4B0FD9), + SPH_C64(0x3691E03F52A0F9D1), SPH_C64(0x5ED86E46E1878E80), + SPH_C64(0x3C711A0E99D07150), SPH_C64(0x5A0865B20C4E9310), + SPH_C64(0x56FBFC1FE4F0682E), SPH_C64(0xEA8D5DE3105EDF9B), + SPH_C64(0x71ABFDB12379187A), SPH_C64(0x2EB99DE1BEE77B9C), + SPH_C64(0x21ECC0EA33CF4523), SPH_C64(0x59A4D7521805C7A1), + SPH_C64(0x3896F5EB56AE7C72), SPH_C64(0xAA638F3DB18F75DC), + SPH_C64(0x9F39358DABE9808E), SPH_C64(0xB7DEFA91C00B72AC), + SPH_C64(0x6B5541FD62492D92), SPH_C64(0x6DC6DEE8F92E4D5B), + SPH_C64(0x353F57ABC4BEEA7E), SPH_C64(0x735769D6DA5690CE), + SPH_C64(0x0A234AA642391484), SPH_C64(0xF6F9508028F80D9D), + SPH_C64(0xB8E319A27AB3F215), SPH_C64(0x31AD9C1151341A4D), + SPH_C64(0x773C22A57BEF5805), SPH_C64(0x45C7561A07968633), + SPH_C64(0xF913DA9E249DBE36), SPH_C64(0xDA652D9B78A64C68), + SPH_C64(0x4C27A97F3BC334EF), SPH_C64(0x76621220E66B17F4), + SPH_C64(0x967743899ACD7D0B), SPH_C64(0xF3EE5BCAE0ED6782), + SPH_C64(0x409F753600C879FC), SPH_C64(0x06D09A39B5926DB6), + SPH_C64(0x6F83AEB0317AC588), SPH_C64(0x01E6CA4A86381F21), + SPH_C64(0x66FF3462D19F3025), SPH_C64(0x72207C24DDFD3BFB), + SPH_C64(0x4AF6B6D3E2ECE2EB), SPH_C64(0x9C994DBEC7EA08DE), + SPH_C64(0x49ACE597B09A8BC4), SPH_C64(0xB38C4766CF0797BA), + SPH_C64(0x131B9373C57C2A75), SPH_C64(0xB1822CCE61931E58), + SPH_C64(0x9D7555B909BA1C0C), SPH_C64(0x127FAFDD937D11D2), + SPH_C64(0x29DA3BADC66D92E4), SPH_C64(0xA2C1D57154C2ECBC), + SPH_C64(0x58C5134D82F6FE24), SPH_C64(0x1C3AE3515B62274F), + SPH_C64(0xE907C82E01CB8126), SPH_C64(0xF8ED091913E37FCB), + SPH_C64(0x3249D8F9C80046C9), SPH_C64(0x80CF9BEDE388FB63), + SPH_C64(0x1881539A116CF19E), SPH_C64(0x5103F3F76BD52457), + SPH_C64(0x15B7E6F5AE47F7A8), SPH_C64(0xDBD7C6DED47E9CCF), + SPH_C64(0x44E55C410228BB1A), SPH_C64(0xB647D4255EDB4E99), + SPH_C64(0x5D11882BB8AAFC30), SPH_C64(0xF5098BBB29D3212A), + SPH_C64(0x8FB5EA14E90296B3), SPH_C64(0x677B942157DD025A), + SPH_C64(0xFB58E7C0A390ACB5), SPH_C64(0x89D3674C83BD4A01), + SPH_C64(0x9E2DA4DF4BF3B93B), SPH_C64(0xFCC41E328CAB4829), + SPH_C64(0x03F38C96BA582C52), SPH_C64(0xCAD1BDBD7FD85DB2), + SPH_C64(0xBBB442C16082AE83), SPH_C64(0xB95FE86BA5DA9AB0), + SPH_C64(0xB22E04673771A93F), SPH_C64(0x845358C9493152D8), + SPH_C64(0xBE2A488697B4541E), SPH_C64(0x95A2DC2DD38E6966), + SPH_C64(0xC02C11AC923C852B), SPH_C64(0x2388B1990DF2A87B), + SPH_C64(0x7C8008FA1B4F37BE), SPH_C64(0x1F70D0C84D54E503), + SPH_C64(0x5490ADEC7ECE57D4), SPH_C64(0x002B3C27D9063A3A), + SPH_C64(0x7EAEA3848030A2BF), SPH_C64(0xC602326DED2003C0), + SPH_C64(0x83A7287D69A94086), SPH_C64(0xC57A5FCB30F57A8A), + SPH_C64(0xB56844E479EBE779), SPH_C64(0xA373B40F05DCBCE9), + SPH_C64(0xD71A786E88570EE2), SPH_C64(0x879CBACDBDE8F6A0), + SPH_C64(0x976AD1BCC164A32F), SPH_C64(0xAB21E25E9666D78B), + SPH_C64(0x901063AAE5E5C33C), SPH_C64(0x9818B34448698D90), + SPH_C64(0xE36487AE3E1E8ABB), SPH_C64(0xAFBDF931893BDCB4), + SPH_C64(0x6345A0DC5FBBD519), SPH_C64(0x8628FE269B9465CA), + SPH_C64(0x1E5D01603F9C51EC), SPH_C64(0x4DE44006A15049B7), + SPH_C64(0xBF6C70E5F776CBB1), SPH_C64(0x411218F2EF552BED), + SPH_C64(0xCB0C0708705A36A3), SPH_C64(0xE74D14754F986044), + SPH_C64(0xCD56D9430EA8280E), SPH_C64(0xC12591D7535F5065), + SPH_C64(0xC83223F1720AEF96), SPH_C64(0xC3A0396F7363A51F), +}; + +#define PASS(a, b, c, mul) do { \ + ROUND(a, b, c, X0, mul); \ + ROUND(b, c, a, X1, mul); \ + ROUND(c, a, b, X2, mul); \ + ROUND(a, b, c, X3, mul); \ + ROUND(b, c, a, X4, mul); \ + ROUND(c, a, b, X5, mul); \ + ROUND(a, b, c, X6, mul); \ + ROUND(b, c, a, X7, mul); \ + } while (0) + +#define ROUND(a, b, c, x, mul) do { \ + c ^= x; \ + a = SPH_T64(a - (T1[c & 0xFF] ^ T2[(c >> 16) & 0xFF] \ + ^ T3[(c >> 32) & 0xFF] ^ T4[(c >> 48) & 0xFF])); \ + b = SPH_T64(b + (T4[(c >> 8) & 0xFF] ^ T3[(c >> 24) & 0xFF] \ + ^ T2[(c >> 40) & 0xFF] ^ T1[(c >> 56) & 0xFF])); \ + b = mul(b); \ + } while (0) + +#define MUL5(x) SPH_T64((x) * SPH_C64(5)) +#define MUL7(x) SPH_T64((x) * SPH_C64(7)) +#define MUL9(x) SPH_T64((x) * SPH_C64(9)) + +#define KSCHED do { \ + X0 = SPH_T64(X0 - (X7 ^ SPH_C64(0xA5A5A5A5A5A5A5A5))); \ + X1 ^= X0; \ + X2 = SPH_T64(X2 + X1); \ + X3 = SPH_T64(X3 - (X2 ^ (~X1 << 19))); \ + X4 ^= X3; \ + X5 = SPH_T64(X5 + X4); \ + X6 = SPH_T64(X6 - (X5 ^ (~X4 >> 23))); \ + X7 ^= X6; \ + X0 = SPH_T64(X0 + X7); \ + X1 = SPH_T64(X1 - (X0 ^ (~X7 << 19))); \ + X2 ^= X1; \ + X3 = SPH_T64(X3 + X2); \ + X4 = SPH_T64(X4 - (X3 ^ (~X2 >> 23))); \ + X5 ^= X4; \ + X6 = SPH_T64(X6 + X5); \ + X7 = SPH_T64(X7 - (X6 ^ SPH_C64(0x0123456789ABCDEF))); \ + } while (0) + +#define TIGER_ROUND_BODY(in, r) do { \ + sph_u64 A, B, C; \ + sph_u64 X0, X1, X2, X3, X4, X5, X6, X7; \ + \ + A = (r)[0]; \ + B = (r)[1]; \ + C = (r)[2]; \ + \ + X0 = (in(0)); \ + X1 = (in(1)); \ + X2 = (in(2)); \ + X3 = (in(3)); \ + X4 = (in(4)); \ + X5 = (in(5)); \ + X6 = (in(6)); \ + X7 = (in(7)); \ + PASS(A, B, C, MUL5); \ + KSCHED; \ + PASS(C, A, B, MUL7); \ + KSCHED; \ + PASS(B, C, A, MUL9); \ + \ + (r)[0] ^= A; \ + (r)[1] = SPH_T64(B - (r)[1]); \ + (r)[2] = SPH_T64(C + (r)[2]); \ + } while (0) + +/* + * One round of Tiger. The data must be aligned for 64-bit access. + */ +static void +tiger_round(const unsigned char *data, sph_u64 r[3]) +{ +#define TIGER_IN(i) sph_dec64le_aligned(data + 8 * (i)) + TIGER_ROUND_BODY(TIGER_IN, r); +#undef TIGER_IN +} + +/* see sph_tiger.h */ +void +sph_tiger_init(void *cc) +{ + sph_tiger_context *sc; + + sc = (sph_tiger_context*)cc; + sc->val[0] = SPH_C64(0x0123456789ABCDEF); + sc->val[1] = SPH_C64(0xFEDCBA9876543210); + sc->val[2] = SPH_C64(0xF096A5B4C3B2E187); + sc->count = 0; +} + +#define RFUN tiger_round +#define HASH tiger +#define LE64 1 +#define BLEN 64U +#define PW01 1 +#define PLW1 1 +#include "algo/sha3/md_helper.c" + +/* see sph_tiger.h */ +void +sph_tiger_close(void *cc, void *dst) +{ + tiger_close(cc, dst, 3); + sph_tiger_init(cc); +} + +/* see sph_tiger.h */ +void +sph_tiger_comp(const sph_u64 msg[8], sph_u64 val[3]) +{ +#define TIGER_IN(i) msg[i] + TIGER_ROUND_BODY(TIGER_IN, val); +#undef TIGER_IN +} + +#undef HASH +#define HASH tiger2 +#undef PW01 +#define CLOSE_ONLY 1 +#include "algo/sha3/md_helper.c" + +/* see sph_tiger.h */ +void +sph_tiger2_close(void *cc, void *dst) +{ + tiger2_close(cc, dst, 3); + sph_tiger2_init(cc); +} + +#endif + diff --git a/algo/tiger/sph_tiger.h b/algo/tiger/sph_tiger.h new file mode 100644 index 0000000..23ed069 --- /dev/null +++ b/algo/tiger/sph_tiger.h @@ -0,0 +1,192 @@ +/* $Id: sph_tiger.h 216 2010-06-08 09:46:57Z tp $ */ +/** + * Tiger / Tiger-2 interface. + * + * Tiger has been published in: R. Anderson, E. Biham, "Tiger: A Fast + * New Hash Function", Fast Software Encryption - FSE'96, LNCS 1039, + * Springer (1996), pp. 89--97. + * + * Tiger2 has never been formally published, but it was described as + * identical to Tiger, except for the padding which is the same in + * Tiger2 as it is in MD4. Fortunately, an implementation of Tiger2 + * was submitted to NESSIE, which produced test vectors; the sphlib + * implementation of Tiger2 is compatible with the NESSIE test vectors. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @file sph_tiger.h + * @author Thomas Pornin + */ + +#ifndef SPH_TIGER_H__ +#define SPH_TIGER_H__ + +#include +#include "algo/sha3/sph_types.h" + +#if SPH_64 + +/** + * Output size (in bits) for Tiger. + */ +#define SPH_SIZE_tiger 192 + +/** + * Output size (in bits) for Tiger2. + */ +#define SPH_SIZE_tiger2 192 + +/** + * This structure is a context for Tiger computations: it contains the + * intermediate values and some data from the last entered block. Once + * a Tiger computation has been performed, the context can be reused for + * another computation. + * + * The contents of this structure are private. A running Tiger computation + * can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[64]; /* first field, for alignment */ + sph_u64 val[3]; + sph_u64 count; +#endif +} sph_tiger_context; + +/** + * Initialize a Tiger context. This process performs no memory allocation. + * + * @param cc the Tiger context (pointer to + * a sph_tiger_context) + */ +void sph_tiger_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Tiger context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_tiger(void *cc, const void *data, size_t len); + +/** + * Terminate the current Tiger computation and output the result into the + * provided buffer. The destination buffer must be wide enough to + * accomodate the result (24 bytes). The context is automatically + * reinitialized. + * + * @param cc the Tiger context + * @param dst the destination buffer + */ +void sph_tiger_close(void *cc, void *dst); + +/** + * Apply the Tiger compression function on the provided data. The + * msg parameter contains the 8 64-bit input blocks, + * as numerical values (hence after the little-endian decoding). The + * val parameter contains the 3 64-bit input blocks for + * the compression function; the output is written in place in this + * array. + * + * @param msg the message block (8 values) + * @param val the function 192-bit input and output + */ +void sph_tiger_comp(const sph_u64 msg[8], sph_u64 val[3]); + +/** + * This structure is a context for Tiger2 computations. It is identical + * to the Tiger context, and they may be freely exchanged, since the + * difference between Tiger and Tiger2 resides solely in the padding, which + * is computed only in the last computation step. + */ +typedef sph_tiger_context sph_tiger2_context; + +#ifdef DOXYGEN_IGNORE +/** + * Initialize a Tiger2 context. This function is identical to + * sph_tiger_init(). + * + * @param cc the Tiger2 context (pointer to + * a sph_tiger2_context) + */ +void sph_tiger2_init(void *cc); +#endif + +#ifndef DOXYGEN_IGNORE +#define sph_tiger2_init sph_tiger_init +#endif + +#ifdef DOXYGEN_IGNORE +/** + * Process some data bytes. This function is identical to + * sph_tiger(). + * + * @param cc the Tiger2 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_tiger2(void *cc, const void *data, size_t len); +#endif + +#ifndef DOXYGEN_IGNORE +#define sph_tiger2 sph_tiger +#endif + +/** + * Terminate the current Tiger2 computation and output the result into the + * provided buffer. The destination buffer must be wide enough to + * accomodate the result (24 bytes). The context is automatically + * reinitialized. Note that this function is NOT identical to + * sph_tiger2_close(): this is the exact and unique point + * where Tiger and Tiger2 differ. + * + * @param cc the Tiger context + * @param dst the destination buffer + */ +void sph_tiger2_close(void *cc, void *dst); + +#ifdef DOXYGEN_IGNORE +/** + * Apply the Tiger2 compression function, which is identical to the Tiger + * compression function. + * + * @param msg the message block (8 values) + * @param val the function 192-bit input and output + */ +void sph_tiger2_comp(const sph_u64 msg[8], sph_u64 val[3]); +#endif + +#ifndef DOXYGEN_IGNORE +#define sph_tiger2_comp sph_tiger_comp +#endif + +#endif + +#endif + diff --git a/algo/x11/c11.c b/algo/x11/c11.c new file mode 100644 index 0000000..5909001 --- /dev/null +++ b/algo/x11/c11.c @@ -0,0 +1,259 @@ +#include "miner.h" +#include "algo-gate-api.h" + +#include +#include +#include +#include + +//#include "algo/blake/sph_blake.h" +//#include "algo/bmw/sph_bmw.h" +//#include "algo/groestl/sph_groestl.h" +//#include "algo/jh/sph_jh.h" +//#include "algo/keccak/sph_keccak.h" +//#include "algo/skein/sph_skein.h" +//#include "algo/luffa/sph_luffa.h" +//#include "algo/cubehash/sph_cubehash.h" +#include "algo/shavite/sph_shavite.h" +//#include "algo/simd/sph_simd.h" +//#include "algo/echo/sph_echo.h" + +#ifdef NO_AES_NI + #include "algo/echo/sph_echo.h" + #include "algo/groestl/sph_groestl.h" +#else + #include "algo/groestl/aes_ni/hash-groestl.h" + #include "algo/echo/aes_ni/hash_api.h" +#endif + +#include "algo/luffa/sse2/luffa_for_sse2.h" +#include "algo/cubehash/sse2/cubehash_sse2.h" +#include "algo/simd/sse2/nist.h" +#include "algo/blake/sse2/blake.c" +#include "algo/keccak/sse2/keccak.c" +#include "algo/bmw/sse2/bmw.c" +#include "algo/skein/sse2/skein.c" +#include "algo/jh/sse2/jh_sse2_opt64.h" + + +typedef struct { + sph_shavite512_context shavite; +// sph_groestl512_context groestl; + sph_skein512_context skein; +// sph_jh512_context jh; +// sph_keccak512_context keccak; +#ifdef NO_AES_NI + sph_groestl512_context groestl; + sph_echo512_context echo; +#else + hashState_echo echo; + hashState_groestl groestl; +#endif + hashState_luffa luffa; + cubehashParam cube; + hashState_sd simd; +} c11_ctx_holder; + +c11_ctx_holder c11_ctx; + +void init_c11_ctx() +{ + init_luffa( &c11_ctx.luffa, 512 ); + cubehashInit( &c11_ctx.cube, 512, 16, 32 ); + sph_shavite512_init( &c11_ctx.shavite ); + init_sd( &c11_ctx.simd, 512 ); +// sph_jh512_init(&c11_ctx.jh); +// sph_keccak512_init(&c11_ctx.keccak); +// sph_skein512_init(&c11_ctx.skein); +// sph_groestl512_init( &c11_ctx.groestl ); +#ifdef NO_AES_NI + sph_groestl512_init( &c11_ctx.groestl ); + sph_echo512_init( &c11_ctx.echo ); +#else + init_echo( &c11_ctx.echo, 512 ); + init_groestl( &c11_ctx.groestl ); +#endif +} + +void c11hash(void *output, const void *input) +{ + unsigned char hash[128]; // uint32_t hashA[16], hashB[16]; +// uint32_t _ALIGN(64) hash[16]; + + c11_ctx_holder ctx; + memcpy( &ctx, &c11_ctx, sizeof(c11_ctx) ); + + size_t hashptr; + unsigned char hashbuf[128]; + sph_u64 hashctA; + sph_u64 hashctB; + + DECL_BLK; + BLK_I; + BLK_W; + BLK_C; + + DECL_BMW; + BMW_I; + BMW_U; + #define M(x) sph_dec64le_aligned(data + 8 * (x)) + #define H(x) (h[x]) + #define dH(x) (dh[x]) + BMW_C; + #undef M + #undef H + #undef dH + +#ifdef NO_AES_NI +// grsoState sts_grs; +// GRS_I; +// GRS_U; +// GRS_C; +// + sph_groestl512 (&ctx.groestl, hash, 64); + sph_groestl512_close(&ctx.groestl, hash); +#else + update_groestl( &ctx.groestl, (char*)hash,512); + final_groestl( &ctx.groestl, (char*)hash); +#endif + + DECL_JH; + JH_H; + + DECL_KEC; + KEC_I; + KEC_U; + KEC_C; + + DECL_SKN; + SKN_I; + SKN_U; + SKN_C; +/* + sph_jh512 (&ctx.jh, hash, 64); + sph_jh512_close(&ctx.jh, hash+64); + + sph_keccak512 (&ctx.keccak, hash+64, 64); + sph_keccak512_close(&ctx.keccak, hash); + + sph_skein512 (&ctx.skein, hash, 64); + sph_skein512_close (&ctx.skein, hash); +*/ + update_luffa( &ctx.luffa, (const BitSequence*)hash,512); + final_luffa( &ctx.luffa, (BitSequence*)hash+64); + + cubehashUpdate( &ctx.cube, (const byte*) hash+64,64); + cubehashDigest( &ctx.cube, (byte*)hash); + + sph_shavite512( &ctx.shavite, hash, 64); + sph_shavite512_close( &ctx.shavite, hash+64); + + update_sd( &ctx.simd, (const BitSequence *)hash+64,512); + final_sd( &ctx.simd, (BitSequence *)hash); + +#ifdef NO_AES_NI + sph_echo512 (&ctx.echo, hash, 64); + sph_echo512_close(&ctx.echo, hash+64); +#else + update_echo ( &ctx.echo, (const BitSequence *) hash, 512); + final_echo( &ctx.echo, (BitSequence *) hash+64 ); +#endif + + +/* + sph_blake512_init(&ctx_blake); + sph_blake512 (&ctx_blake, input, 80); + sph_blake512_close (&ctx_blake, hash); + + sph_bmw512_init(&ctx_bmw); + sph_bmw512 (&ctx_bmw, hash, 64); + sph_bmw512_close(&ctx_bmw, hash); + + sph_groestl512_init(&ctx_groestl); + sph_groestl512 (&ctx_groestl, hash, 64); + sph_groestl512_close(&ctx_groestl, hash); + + sph_jh512_init(&ctx_jh); + sph_jh512 (&ctx_jh, hash, 64); + sph_jh512_close(&ctx_jh, hash); + + sph_keccak512_init(&ctx_keccak); + sph_keccak512 (&ctx_keccak, hash, 64); + sph_keccak512_close(&ctx_keccak, hash); + + sph_skein512_init(&ctx_skein); + sph_skein512 (&ctx_skein, hash, 64); + sph_skein512_close (&ctx_skein, hash); + + sph_luffa512_init (&ctx_luffa1); + sph_luffa512 (&ctx_luffa1, hash, 64); + sph_luffa512_close (&ctx_luffa1, hash); + + sph_cubehash512_init (&ctx_cubehash1); + sph_cubehash512 (&ctx_cubehash1, hash, 64); + sph_cubehash512_close(&ctx_cubehash1, hash); + + sph_shavite512_init (&ctx_shavite1); + sph_shavite512 (&ctx_shavite1, hash, 64); + sph_shavite512_close(&ctx_shavite1, hash); + + sph_simd512_init (&ctx_simd1); + sph_simd512 (&ctx_simd1, hash, 64); + sph_simd512_close(&ctx_simd1, hash); + + sph_echo512_init (&ctx_echo1); + sph_echo512 (&ctx_echo1, hash, 64); + sph_echo512_close(&ctx_echo1, hash); +*/ + memcpy(output, hash+64, 32); +} + +int scanhash_c11(int thr_id, struct work *work, + uint32_t max_nonce, uint64_t *hashes_done) +{ + uint32_t *pdata = work->data; + uint32_t *ptarget = work->target; + const uint32_t first_nonce = pdata[19]; + uint32_t _ALIGN(64) endiandata[20]; + uint32_t nonce = first_nonce; + volatile uint8_t *restart = &(work_restart[thr_id].restart); + +// init_c11_ctx(); + + if (opt_benchmark) + ((uint32_t*)ptarget)[7] = 0x0cff; + + for (int k=0; k < 19; k++) + be32enc(&endiandata[k], pdata[k]); + + const uint32_t Htarg = ptarget[7]; + do { + uint32_t hash[8]; + be32enc(&endiandata[19], nonce); + c11hash(hash, endiandata); + + if (hash[7] <= Htarg && fulltest(hash, ptarget)) { + pdata[19] = nonce; + *hashes_done = pdata[19] - first_nonce; + return 1; + } + nonce++; + + } while (nonce < max_nonce && !(*restart)); + + pdata[19] = nonce; + *hashes_done = pdata[19] - first_nonce + 1; + return 0; +} + +bool register_c11_algo( algo_gate_t* gate ) +{ + gate->aes_ni_optimized = (void*)&return_true; + gate->scanhash = (void*)&scanhash_c11; + gate->hash = (void*)&c11hash; + gate->hash_alt = (void*)&c11hash; + gate->init_ctx = (void*)&init_c11_ctx; + gate->get_max64 = (void*)&get_max64_0x3ffff; + return true; +}; + diff --git a/algo/x11/x11.c b/algo/x11/x11.c index ca7b797..38fd82c 100644 --- a/algo/x11/x11.c +++ b/algo/x11/x11.c @@ -428,8 +428,10 @@ int scanhash_x11(int thr_id, struct work *work, return 0; } +/* int64_t get_x11_max64 () { return 0x3ffffLL; } +*/ bool register_x11_algo( algo_gate_t* gate ) { @@ -437,7 +439,8 @@ bool register_x11_algo( algo_gate_t* gate ) gate->init_ctx = (void*)&init_x11_ctx; gate->scanhash = (void*)&scanhash_x11; gate->hash = (void*)&x11_hash; - gate->get_max64 = (void*)&get_x11_max64; +// gate->get_max64 = (void*)&get_x11_max64; + gate->get_max64 = (void*)&get_max64_0x3ffff; gate->hash_alt = (void*)&x11hash_alt; return true; }; diff --git a/algo/x11/x11gost.c b/algo/x11/x11gost.c new file mode 100644 index 0000000..f7bc5a3 --- /dev/null +++ b/algo/x11/x11gost.c @@ -0,0 +1,190 @@ +#include "miner.h" +#include "algo-gate-api.h" + +#include +#include +#include +#include + +#include "algo/gost/sph_gost.h" +#include "algo/shavite/sph_shavite.h" +#include "algo/echo/sph_echo.h" + +#include "algo/luffa/sse2/luffa_for_sse2.h" +#include "algo/cubehash/sse2/cubehash_sse2.h" +#include "algo/simd/sse2/nist.h" +#include "algo/blake/sse2/blake.c" +#include "algo/keccak/sse2/keccak.c" +#include "algo/bmw/sse2/bmw.c" +#include "algo/skein/sse2/skein.c" +#include "algo/jh/sse2/jh_sse2_opt64.h" + +#ifdef NO_AES_NI + #include "algo/groestl/sse2/grso.h" + #include "algo/groestl/sse2/grso-macro.c" +#else + #include "algo/groestl/aes_ni/hash-groestl.h" + #include "algo/echo/aes_ni/hash_api.h" +#endif + +typedef struct { + sph_gost512_context gost; + sph_shavite512_context shavite; + hashState_luffa luffa; + cubehashParam cube; + hashState_sd simd; +#ifdef NO_AES_NI + sph_echo512_context echo; +#else + hashState_echo echo; + hashState_groestl groestl; +#endif +} sib_ctx_holder; + +sib_ctx_holder sib_ctx; + +void init_sib_ctx() +{ + sph_gost512_init(&sib_ctx.gost); + sph_shavite512_init(&sib_ctx.shavite); + init_luffa( &sib_ctx.luffa, 512 ); + cubehashInit( &sib_ctx.cube, 512, 16, 32 ); + init_sd( &sib_ctx.simd, 512 ); +#ifdef NO_AES_NI + sph_echo512_init( &sib_ctx.echo ); +#else + init_echo( &sib_ctx.echo, 512 ); + init_groestl( &sib_ctx.groestl ); +#endif + +} + + +void sibhash(void *output, const void *input) +{ + unsigned char hash[128]; // uint32_t hashA[16], hashB[16]; + #define hashA hash + #define hashB hash+64 + + #ifdef NO_AES_NI + grsoState sts_grs; + #endif + + size_t hashptr; + unsigned char hashbuf[128]; + sph_u64 hashctA; + sph_u64 hashctB; + + sib_ctx_holder ctx; + memcpy( &ctx, &sib_ctx, sizeof(sib_ctx) ); + + DECL_BLK; + BLK_I; + BLK_W; + BLK_C; + + DECL_BMW; + BMW_I; + BMW_U; + #define M(x) sph_dec64le_aligned(data + 8 * (x)) + #define H(x) (h[x]) + #define dH(x) (dh[x]) + BMW_C; + #undef M + #undef H + #undef dH + + #ifdef NO_AES_NI + GRS_I; + GRS_U; + GRS_C; + #else + update_groestl( &ctx.groestl, (char*)hash,512); + final_groestl( &ctx.groestl, (char*)hash); + #endif + + DECL_SKN; + SKN_I; + SKN_U; + SKN_C; + + DECL_JH; + JH_H; + + DECL_KEC; + KEC_I; + KEC_U; + KEC_C; + + sph_gost512(&ctx.gost, hashA, 64); + sph_gost512_close(&ctx.gost, hashB); + + update_luffa( &ctx.luffa, (const BitSequence*)hashB,512); + final_luffa( &ctx.luffa, (BitSequence*)hashA); + + cubehashUpdate( &ctx.cube, (const byte*) hashA,64); + cubehashDigest( &ctx.cube, (byte*)hashB); + + sph_shavite512(&ctx.shavite, hashB, 64); + sph_shavite512_close(&ctx.shavite, hashA); + + update_sd( &ctx.simd, (const BitSequence *)hashA,512); + final_sd( &ctx.simd, (BitSequence *)hashB); + +#ifdef NO_AES_NI + sph_echo512(&ctx.echo, hashB, 64); + sph_echo512_close(&ctx.echo, hashA); +#else + update_echo ( &ctx.echo, (const BitSequence *) hashB, 512); + final_echo( &ctx.echo, (BitSequence *) hashA ); +#endif + + memcpy(output, hashA, 32); +} + +int scanhash_sib(int thr_id, struct work *work, + uint32_t max_nonce, uint64_t *hashes_done) +{ + uint32_t *pdata = work->data; + uint32_t *ptarget = work->target; + + const uint32_t first_nonce = pdata[19]; + uint32_t _ALIGN(64) endiandata[20]; + uint32_t nonce = first_nonce; + volatile uint8_t *restart = &(work_restart[thr_id].restart); + + if (opt_benchmark) + ((uint32_t*)ptarget)[7] = 0x0cff; + + for (int k = 0; k < 19; k++) + be32enc(&endiandata[k], pdata[k]); + + const uint32_t Htarg = ptarget[7]; + do { + uint32_t hash[8]; + be32enc(&endiandata[19], nonce); + sibhash(hash, endiandata); + + if (hash[7] <= Htarg && fulltest(hash, ptarget)) { + pdata[19] = nonce; + *hashes_done = pdata[19] - first_nonce; + return 1; + } + nonce++; + + } while (nonce < max_nonce && !(*restart)); + + pdata[19] = nonce; + *hashes_done = pdata[19] - first_nonce + 1; + return 0; +} + +bool register_sib_algo( algo_gate_t* gate ) +{ + gate->aes_ni_optimized = (void*)&return_true; + gate->scanhash = (void*)&scanhash_sib; + gate->hash = (void*)&sibhash; + gate->hash_alt = (void*)&sibhash; + gate->init_ctx = (void*)&init_sib_ctx; + gate->get_max64 = (void*)&get_max64_0x3ffff; +} diff --git a/algo/x13/x13.c b/algo/x13/x13.c index 31f02ea..20ea1fd 100644 --- a/algo/x13/x13.c +++ b/algo/x13/x13.c @@ -383,6 +383,7 @@ bool register_x13_algo( algo_gate_t* gate ) gate->scanhash = (void*)&scanhash_x13; gate->hash = (void*)&x13hash; gate->hash_alt = (void*)&x13hash_alt; + gate->get_max64 = (void*)&get_max64_0x3ffff; return true; }; diff --git a/algo/x14/x14.c b/algo/x14/x14.c index bcc72cf..533f711 100644 --- a/algo/x14/x14.c +++ b/algo/x14/x14.c @@ -381,10 +381,12 @@ int scanhash_x14(int thr_id, struct work *work, return 0; } +/* int64_t x14_get_max64 () { return 0x3ffffLL; } +*/ bool register_x14_algo( algo_gate_t* gate ) { @@ -393,7 +395,8 @@ bool register_x14_algo( algo_gate_t* gate ) gate->scanhash = (void*)&scanhash_x14; gate->hash = (void*)&x14hash; gate->hash_alt = (void*)&x14hash_alt; - gate->get_max64 = (void*)&x14_get_max64; +// gate->get_max64 = (void*)&x14_get_max64; + gate->get_max64 = (void*)&get_max64_0x3ffff; return true; }; diff --git a/algo/yescrypt/yescrypt.c b/algo/yescrypt/yescrypt.c index 5cc14f8..3a99aa2 100644 --- a/algo/yescrypt/yescrypt.c +++ b/algo/yescrypt/yescrypt.c @@ -56,12 +56,14 @@ void yescrypt_set_target( struct work* work, double job_diff ) work_set_target( work, job_diff / (65536.0 * opt_diff_factor) ); } + bool register_yescrypt_algo ( algo_gate_t* gate ) { gate->scanhash = (void*)&scanhash_yescrypt; gate->hash = (void*)&yescrypt_hash; gate->hash_alt = (void*)&yescrypthash; - gate->set_target = (void*)&yescrypt_set_target; +// gate->set_target = (void*)&yescrypt_set_target; + gate->set_target = (void*)&scrypt_set_target; gate->get_max64 = (void*)&yescrypt_get_max64; return true; } diff --git a/algo/zr5.c b/algo/zr5.c index 68e3b40..0ce7aaa 100644 --- a/algo/zr5.c +++ b/algo/zr5.c @@ -212,11 +212,13 @@ void zr5_display_pok ( struct work* work ) applog(LOG_BLUE, "POK received: %08xx", work->data[0] ); } +/* void zr5_set_data_size( uint32_t* data_size, uint32_t* adata_sz ) { *data_size = 80; *adata_sz = *data_size / sizeof(uint32_t); } +*/ void zr5_set_data_and_target_size( int *data_size, int *target_size, int *adata_sz, int *atarget_sz ) @@ -234,12 +236,14 @@ void zr5_reverse_endian( struct work* work ) work->data[i] = swab32( work->data[i] ); } +/* void zr5_reverse_endian_17_19( uint32_t* ntime, uint32_t* nonce, struct work* work ) { be32enc( ntime, work->data[17] ); be32enc( nonce, work->data[19] ); } +*/ bool register_zr5_algo( algo_gate_t* gate ) { @@ -251,10 +255,11 @@ bool register_zr5_algo( algo_gate_t* gate ) gate->get_max64 = (void*)&zr5_get_max64; gate->ignore_pok = (void*)&zr5_ignore_pok; gate->display_pok = (void*)&zr5_display_pok; - gate->set_data_size = (void*)&zr5_set_data_size; + gate->suw_build_hex_string = (void*)&suw_build_hex_string_80; +// gate->set_data_size = (void*)&set_data_size_80; gate->set_data_and_target_size = (void*)&zr5_set_data_and_target_size; - gate->reverse_endian = (void*)&zr5_reverse_endian; - gate->reverse_endian_17_19 = (void*)&zr5_reverse_endian_17_19; + gate->set_work_data_endian = (void*)&swab_work_data; + gate->encode_endian_17_19 = (void*)&encode_big_endian_17_19; return true; }; diff --git a/api.c b/api.c index d504785..933f16a 100644 --- a/api.c +++ b/api.c @@ -27,7 +27,7 @@ #include #include #include - +#include #include #include @@ -314,8 +314,6 @@ static size_t base64_encode(const uchar *indata, size_t insize, char *outptr, si return len; } -#include - /* websocket handshake (tested in Chrome) */ static int websocket_handshake(SOCKETTYPE c, char *result, char *clientkey) { diff --git a/cpu-miner.c b/cpu-miner.c index 0a36f5e..41dc859 100644 --- a/cpu-miner.c +++ b/cpu-miner.c @@ -72,7 +72,7 @@ #define LP_SCANTIME 60 -static algo_gate_t algo_gate; +algo_gate_t algo_gate; bool opt_debug = false; bool opt_debug_diff = false; @@ -155,14 +155,11 @@ uint64_t net_blocks = 0; int opt_api_remote = 0; int opt_api_listen = 4048; - pthread_mutex_t rpc2_job_lock; pthread_mutex_t rpc2_login_lock; pthread_mutex_t applog_lock; pthread_mutex_t stats_lock; - - static char const short_options[] = #ifdef HAVE_SYSLOG_H "S" @@ -170,7 +167,7 @@ static char const short_options[] = "a:b:Bc:CDf:hm:n:p:Px:qr:R:s:t:T:o:u:O:V"; static struct work g_work = {{ 0 }}; -static struct work tmp_work; +//static struct work tmp_work; static time_t g_work_time = 0; static pthread_mutex_t g_work_lock; static bool submit_old = false; @@ -269,65 +266,21 @@ void work_copy(struct work *dest, const struct work *src) } } -/* compute nbits to get the network diff */ - -static void calc_network_diff(struct work *work) -{ - // sample for diff 43.281 : 1c05ea29 - // todo: endian reversed on longpoll could be zr5 specific... - uint32_t nbits = have_longpoll ? work->data[18] : swab32(work->data[18]); - uint32_t bits = (nbits & 0xffffff); - int16_t shift = (swab32(nbits) & 0xff); // 0x1c = 28 - - double d = (double)0x0000ffff / (double)bits; - - for (int m=shift; m < 29; m++) d *= 256.0; - for (int m=29; m < shift; m++) d /= 256.0; - if (opt_debug_diff) - applog(LOG_DEBUG, "net diff: %f -> shift %u, bits %08x", - d, shift, bits); - net_diff = d; -} - static bool work_decode(const json_t *val, struct work *work) { - int i; - int data_size = sizeof(work->data); - int target_size = sizeof(work->target); - int adata_sz = ARRAY_SIZE(work->data); - int atarget_sz = ARRAY_SIZE(work->target); - - algo_gate.set_data_and_target_size( &data_size, &target_size, - &adata_sz, &atarget_sz, &allow_mininginfo ); - - if (jsonrpc_2) - return rpc2_job_decode(val, work); - - if (unlikely(!jobj_binary(val, "data", work->data, data_size))) - { - applog(LOG_ERR, "JSON invalid data"); - return false; - } - if (unlikely(!jobj_binary(val, "target", work->target, target_size))) - { - applog(LOG_ERR, "JSON invalid target"); - return false; - } - for (i = 0; i < adata_sz; i++) - work->data[i] = le32dec(work->data + i); - for (i = 0; i < atarget_sz; i++) - work->target[i] = le32dec(work->target + i); + if ( !algo_gate.work_decode( val, work ) ) + return false; - if ((opt_showdiff || opt_max_diff > 0.) && !allow_mininginfo) - algo_gate.calc_network_diff( work ); + if ((opt_showdiff || opt_max_diff > 0.) && !allow_mininginfo) + algo_gate.calc_network_diff( work ); - work->targetdiff = target_to_diff(work->target); - // for api stats, on longpoll pools - stratum_diff = work->targetdiff; - algo_gate.display_pok( work, &net_blocks ); + work->targetdiff = target_to_diff(work->target); + // for api stats, on longpoll pools + stratum_diff = work->targetdiff; + algo_gate.display_pok( work, &net_blocks ); - return true; + return true; } // good alternative for wallet mining, difficulty and net hashrate @@ -814,9 +767,7 @@ static bool submit_upstream_work(CURL *curl, struct work *work) uchar hash[32]; bin2hex(noncestr, (const unsigned char *)work->data + 39, 4); - // len arg is ignoree by the functions, they know, they - // don't need to be told. - algo_gate.hash_suw( hash, work->data, 0 ); + algo_gate.hash_suw( hash, work->data ); char *hashhex = abin2hex(hash, 32); snprintf(s, JSON_BUF_LEN, "{\"method\": \"submit\", \"params\": {\"id\": \"%s\", \"job_id\": \"%s\", \"nonce\": \"%s\", \"result\": \"%s\"}, \"id\":4}\r\n", @@ -825,10 +776,10 @@ static bool submit_upstream_work(CURL *curl, struct work *work) } else { - bool rc = false; +// bool rc = false; unsigned char *xnonce2str; - algo_gate.reverse_endian_17_19( &ntime, &nonce, work ); + algo_gate.encode_endian_17_19( &ntime, &nonce, work ); bin2hex( ntimestr, (const unsigned char *)(&ntime), 4 ); bin2hex( noncestr, (const unsigned char *)(&nonce), 4 ); xnonce2str = algo_gate.get_xnonce2str( work, @@ -908,10 +859,6 @@ static bool submit_upstream_work(CURL *curl, struct work *work) } else { - char* gw_str = NULL; - int data_size = 128; - int adata_sz; - if (jsonrpc_2) { char noncestr[9]; @@ -920,7 +867,7 @@ static bool submit_upstream_work(CURL *curl, struct work *work) bin2hex(noncestr, (const unsigned char *)work->data + 39, 4); - algo_gate.hash_suw( hash, work->data, 0 ); + algo_gate.hash_suw( hash, work->data ); hashhex = abin2hex(&hash[0], 32); snprintf(s, JSON_BUF_LEN, "{\"method\": \"submit\", \"params\": " @@ -958,12 +905,9 @@ static bool submit_upstream_work(CURL *curl, struct work *work) return true; } // jsonrpc_2 - - algo_gate.set_data_size( &data_size, &adata_sz, work ); - - /* build hex string */ - for (i = 0; i < adata_sz; i++) - le32enc(&work->data[i], work->data[i]); + + char* gw_str = NULL; + int data_size = algo_gate.suw_build_hex_string( work ); gw_str = abin2hex((uchar*)work->data, data_size); @@ -1129,6 +1073,10 @@ static bool workio_submit_work(struct workio_cmd *wc, CURL *curl) /* submit solution to bitcoin via JSON-RPC */ while (!submit_upstream_work(curl, wc->u.work)) { +// Use 2 2D arrsy of function pointers to select stratum or gbt in one +// D and JSONRPC2 or not in the other. +// submit_upstream_work[protocol][jsonrpc_2]( ); + if (unlikely((opt_retries >= 0) && (++failures > opt_retries))) { applog(LOG_ERR, "...terminating workio thread"); @@ -1385,7 +1333,7 @@ static void stratum_gen_work(struct stratum_ctx *sctx, struct work *work, int th if (opt_showdiff || opt_max_diff > 0.) algo_gate.calc_network_diff( work ); - algo_gate.reverse_endian( work ); + algo_gate.set_work_data_endian( work ); pthread_mutex_unlock(&sctx->work_lock); @@ -1468,7 +1416,7 @@ static void *miner_thread(void *userdata) uint32_t end_nonce = 0xffffffffU / opt_n_threads * (thr_id + 1) - 0x20; time_t firstwork_time = 0; unsigned char *scratchbuf = NULL; - char s[16]; +// char s[16]; int i; memset(&work, 0, sizeof(work)); @@ -1696,9 +1644,9 @@ static void *miner_thread(void *userdata) // firstwork_time = time(NULL); /** Scanhash **/ - if ( algo_gate.scanhash != null_scanhash ) + if ( algo_gate.scanhash != (void*)null_scanhash ) - rc = algo_gate.scanhash( thr_id, &work, max_nonce, &hashes_done, + rc = (int) algo_gate.scanhash( thr_id, &work, max_nonce, &hashes_done, scratchbuf ); else applog(LOG_ERR,"FAIL: %s has no scanhash function registered.\n", @@ -2629,20 +2577,16 @@ void check_cpu_capability () unsigned int nExIds; char CPUBrandString[0x40]; bool algo_has_aes = algo_gate.aes_ni_optimized(); - char* grn_yes; - char* ylw_no; - char* red; + char* grn_yes = CL_GRN "YES." CL_N; + char* ylw_no = CL_YLW "NO." CL_N; + char* ylo = CL_YLW; + char* red = CL_RED; - if ( use_colors ) - { - grn_yes = CL_GRN "YES." CL_N; - ylw_no = CL_YLW "NO." CL_N; - red = CL_RED; - } - else + if ( !use_colors ) { - grn_yes = "YES"; - ylw_no = "NO"; + grn_yes = "YES."; + ylw_no = "NO."; + ylo = 0; red = 0; } diff --git a/crypto/magimath.cpp b/crypto/magimath.cpp new file mode 100644 index 0000000..c8c64e2 --- /dev/null +++ b/crypto/magimath.cpp @@ -0,0 +1,75 @@ +// Copyright (c) 2014 The Magi developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include +#include +#include +#include +#include +#include + +#include "magimath.h" + +#define EPS1 (std::numeric_limits::epsilon()) +#define EPS2 3.0e-11 + +static void gauleg(double x1, double x2, double x[], double w[], const int n) +{ + int m,j,i; + double z1, z, xm, xl, pp, p3, p2, p1; + m=(n+1)/2; + xm=0.5*(x2+x1); + xl=0.5*(x2-x1); + for (i=1;i<=m;i++) { + z=cos(3.141592654*(i-0.25)/(n+0.5)); + do { + p1=1.0; + p2=0.0; + for (j=1;j<=n;j++) { + p3=p2; + p2=p1; + p1=((2.0*j-1.0)*z*p2-(j-1.0)*p3)/j; + } + pp=n*(z*p1-p2)/(z*z-1.0); + z1=z; + z=z1-p1/pp; + } while (fabs(z-z1) > EPS2); + x[i]=xm-xl*z; + x[n+1-i]=xm+xl*z; + w[i]=2.0*xl/((1.0-z*z)*pp*pp); + w[n+1-i]=w[i]; + } +} + +static double GaussianQuad_N(double func(const double), const double a2, const double b2, const int NptGQ) +{ + double s=0.0; +#ifdef _MSC_VER +#define SW_DIVS 23 + double x[SW_DIVS+1], w[SW_DIVS+1]; +#else + double x[NptGQ+1], w[NptGQ+1]; +#endif + + gauleg(a2, b2, x, w, NptGQ); + + for (int j=1; j<=NptGQ; j++) { + s += w[j]*func(x[j]); + } + + return s; +} + +static double swit_(double wvnmb) +{ + return pow( (5.55243*(exp_n(-0.3*wvnmb/15.762) - exp_n(-0.6*wvnmb/15.762)))*wvnmb, 0.5) + / 1034.66 * pow(sin(wvnmb/65.), 2.); +} + +uint32_t sw_(int nnounce, int divs) +{ + double wmax = ((sqrt((double)(nnounce))*(1.+EPS1))/450+100); + return ((uint32_t)(GaussianQuad_N(swit_, 0., wmax, divs)*(1.+EPS1)*1.e6)); +} diff --git a/crypto/magimath.h b/crypto/magimath.h new file mode 100644 index 0000000..b57eb80 --- /dev/null +++ b/crypto/magimath.h @@ -0,0 +1,54 @@ +// Copyright (c) 2014 The Magi developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef MAGI_MATH_H +#define MAGI_MATH_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t sw_(int nnounce, int divs); + +#ifdef __cplusplus +} +#endif + + +inline double exp_n(double xt) +{ + double p1 = -700.0, p3 = -0.8e-8, p4 = 0.8e-8, p6 = 700.0; + if(xt < p1) + return 0; + else if(xt > p6) + return 1e200; + else if(xt > p3 && xt < p4) + return (1.0 + xt); + else + return exp(xt); +} + +// 1 / (1 + exp(x1-x2)) +inline double exp_n2(double x1, double x2) +{ + double p1 = -700., p2 = -37., p3 = -0.8e-8, p4 = 0.8e-8, p5 = 37., p6 = 700.; + double xt = x1 - x2; + if (xt < p1+1.e-200) + return 1.; + else if (xt > p1 && xt < p2 + 1.e-200) + return ( 1. - exp(xt) ); + else if (xt > p2 && xt < p3 + 1.e-200) + return ( 1. / (1. + exp(xt)) ); + else if (xt > p3 && xt < p4) + return ( 1. / (2. + xt) ); + else if (xt > p4 - 1.e-200 && xt < p5) + return ( exp(-xt) / (1. + exp(-xt)) ); + else if (xt > p5 - 1.e-200 && xt < p6) + return ( exp(-xt) ); + else //if (xt > p6 - 1.e-200) + return 0.; +} + +#endif diff --git a/import_cleanup.sh b/import_cleanup.sh index 057cb78..46a5a9f 100755 --- a/import_cleanup.sh +++ b/import_cleanup.sh @@ -9,3 +9,4 @@ find . -name '*.old' -print0 | xargs -0 rm -rvf find . -name '*.fail' -print0 | xargs -0 rm -rvf find . -name '*.del' -print0 | xargs -0 rm -rvf find . -name '*.swo' -print0 | xargs -0 rm -rvf +find . -name '*.wtf' -print0 | xargs -0 rm -rvf diff --git a/miner.h b/miner.h index 34e50ae..8bd0d00 100644 --- a/miner.h +++ b/miner.h @@ -450,6 +450,7 @@ enum algos { ALGO_LUFFA, ALGO_LYRA2RE, ALGO_LYRA2REV2, + ALGO_M7M, ALGO_MYR_GR, ALGO_NEOSCRYPT, ALGO_NIST5, @@ -497,6 +498,7 @@ static const char *algo_names[] = { "luffa", "lyra2re", "lyra2rev2", + "m7m", "myr-gr", "neoscrypt", "nist5", @@ -562,6 +564,8 @@ extern int opt_scrypt_n; extern double opt_diff_factor; extern unsigned int opt_nfactor; extern bool opt_randomize; +extern bool allow_mininginfo; + extern pthread_mutex_t rpc2_job_lock; extern pthread_mutex_t rpc2_login_lock; @@ -593,6 +597,7 @@ Options:\n\ luffa Luffa\n\ lyra2re lyra2\n\ lyra2rev2 lyrav2\n\ + m7m\n\ myr-gr Myriad-Groestl\n\ neoscrypt NeoScrypt(128, 2, 1)\n\ nist5 Nist5\n\