Compare commits

..

13 Commits

Author SHA1 Message Date
Jay D Dee
7544cb956c v3.6.5 2017-05-19 16:38:26 -04:00
Jay D Dee
e7dbd27636 v3.6.4 2017-05-02 10:28:19 -04:00
Jay D Dee
0155cd1bfe v3.6.3 2017-04-17 14:35:18 -04:00
Jay D Dee
53259692eb v3.6.2 2017-04-16 12:55:19 -04:00
Jay D Dee
9afa0d9820 v3.6.1 2017-03-31 11:59:04 -04:00
Jay D Dee
2dcc4821b6 v3.6.0 2017-03-15 13:21:18 -04:00
Jay D Dee
200b06f369 I have no idea why I need to do this except git told me to. I hope
it doesn't break anything, I just want to update the master branch.
2017-03-10 11:52:49 -05:00
Jay D Dee
f1f9e821a2 v3.5.13 2017-03-10 11:38:58 -05:00
JayDDee
6431c25293 Merge pull request #6 from felixbrucker/felixbrucker/update-dockerfile
Update Dockerfile for cpuminer-opt
2017-03-04 11:29:25 -05:00
Felix Brucker
e1742be8c4 Update Dockerfile for cpuminer-opt 2017-03-04 11:31:19 +01:00
Jay D Dee
38c6f23b66 v3.5.12 2017-03-03 13:55:00 -05:00
Jay D Dee
1b288b1209 v3.5.11 2017-02-28 17:15:39 -05:00
Jay D Dee
f7865ae9f9 v3.5.10 2017-02-26 13:37:00 -05:00
147 changed files with 2193 additions and 11355 deletions

View File

@@ -41,8 +41,8 @@ cpuminer_SOURCES = \
algo/jh/sph_jh.c \
algo/keccak/sph_keccak.c \
algo/keccak/keccak.c\
algo/sha3/sph_sha2.c \
algo/sha3/sph_sha2big.c \
algo/sha/sph_sha2.c \
algo/sha/sph_sha2big.c \
algo/shabal/sph_shabal.c \
algo/whirlpool/sph_whirlpool.c\
crypto/blake2s.c \
@@ -81,25 +81,16 @@ cpuminer_SOURCES = \
algo/groestl/myr-groestl.c \
algo/groestl/aes_ni/hash-groestl.c \
algo/groestl/aes_ni/hash-groestl256.c \
algo/groestl/sse2/grso.c \
algo/groestl/sse2/grso-asm.c \
algo/haval/haval.c \
algo/haval/haval.c\
algo/heavy/heavy.c \
algo/heavy/bastion.c \
algo/hmq1725.c \
algo/hodl/hodl.cpp \
algo/hodl/hodl-gate.c \
algo/hodl/hodl_arith_uint256.cpp \
algo/hodl/hodl_uint256.cpp \
algo/hodl/hash.cpp \
algo/hodl/hmac_sha512.cpp \
algo/hodl/sha256.cpp \
algo/hodl/sha512.cpp \
algo/hodl/utilstrencodings.cpp \
algo/hodl/hodl-wolf.c \
algo/hodl/aes.c \
algo/hodl/hodl-gate.c \
algo/hodl/hodl-wolf.c \
algo/hodl/sha512_avx.c \
algo/hodl/sha512_avx2.c \
algo/jh/jha.c \
algo/lbry.c \
algo/luffa/luffa.c \
algo/luffa/sse2/luffa_for_sse2.c \
@@ -108,7 +99,7 @@ cpuminer_SOURCES = \
algo/lyra2/lyra2rev2.c \
algo/lyra2/lyra2re.c \
algo/lyra2/zcoin.c \
algo/lyra2/zoin.c \
algo/lyra2/lyra2z330.c \
algo/keccak/sse2/keccak.c \
algo/m7m.c \
algo/neoscrypt.c \
@@ -120,8 +111,8 @@ cpuminer_SOURCES = \
algo/ripemd/sph_ripemd.c \
algo/scrypt.c \
algo/scryptjane/scrypt-jane.c \
algo/sha2/sha2.c \
algo/sha2/sha256t.c \
algo/sha/sha2.c \
algo/sha/sha256t.c \
algo/simd/sse2/nist.c \
algo/simd/sse2/vector.c \
algo/skein/skein.c \
@@ -129,6 +120,7 @@ cpuminer_SOURCES = \
algo/s3.c \
algo/tiger/sph_tiger.c \
algo/timetravel.c \
algo/timetravel10.c \
algo/veltor.c \
algo/whirlpool/whirlpool.c \
algo/whirlpool/whirlpoolx.c \

View File

@@ -23,23 +23,26 @@ Supported Algorithms
blakecoin blake256r8
blake2s Blake-2 S
bmw BMW 256
c11 Flax
c11 Chaincoin
cryptolight Cryptonight-light
cryptonight cryptonote, Monero (XMR)
decred
deep Deepcoin (DCN)
dmd-gr Diamond-Groestl
drop Dropcoin
fresh Fresh
groestl groestl
groestl Groestl coin
heavy Heavy
hmq1725 Espers
hodl Hodlcoin
jha jackpotcoin
keccak Keccak
lbry LBC, LBRY Credits
luffa Luffa
lyra2re lyra2
lyra2rev2 lyrav2
lyra2rev2 lyrav2, Vertcoin
lyra2z Zcoin (XZC)
lyra2zoin Zoin (ZOI)
lyra2z330 Lyra2 330 rows, Zoin (ZOI)
m7m Magi (XMG)
myr-gr Myriad-Groestl
neoscrypt NeoScrypt(128, 2, 1)
@@ -51,16 +54,18 @@ Supported Algorithms
scrypt scrypt(1024, 1, 1) (default)
scrypt:N scrypt(N, 1, 1)
scryptjane:nf
sha256d SHA-256d
sha256d Double SHA-256
sha256t Triple SHA-256, Onecoin (OC)
shavite3 Shavite3
skein Skein+Sha (Skeincoin)
skein2 Double Skein (Woodcoin)
timetravel Machinecoin (MAC)
timetravel10 Bitcore
vanilla blake256r8vnl (VCash)
veltor
whirlpool
whirlpoolx
x11 X11
x11 Dash
x11evo Revolvercoin
x11gost sib (SibCoin)
x13 X13
@@ -94,6 +99,11 @@ may work wallet mining but there are no guarantees.
Errata
------
AMD CPUs older than Piledriver, including Athlon x2 and Phenom II x4, are not
supported by cpuminer-opt due to an incompatible implementation of SSE2 on
these CPUs. Some algos may crash the miner with an invalid instruction.
Users are recommended to use an unoptimized miner such as cpuminer-multi.
cpuminer-opt does not work mining Decred algo at Nicehash and produces
only "invalid extranonce2 size" rejects.

View File

@@ -1,8 +1,190 @@
Compile instruction for Linux and Windows are at the bottom of this file.
cpuminer-opt now supports HW SHA acceleration available on AMD Ryzen CPUs.
This feature requires recent SW including GCC version 5 or higher and
openssl version 1.1 or higher. It may also require using "-march=znver1"
compile flag.
HW SHA support is only available when compiled from source, Windows binaries
are not yet available.
cpuminer-opt is a console program, if you're using a mouse you're doing it
wrong.
Compile Instructions
--------------------
Requirements:
Intel Core2 or newer, or AMD Steamroller or newer CPU.
64 bit Linux or Windows operating system.
Building on linux prerequisites:
It is assumed users know how to install packages on their system and
be able to compile standard source packages. This is basic Linux and
beyond the scope of cpuminer-opt.
Make sure you have the basic development packages installed.
Here is a good start:
http://askubuntu.com/questions/457526/how-to-install-cpuminer-in-ubuntu
Install any additional dependencies needed by cpuminer-opt. The list below
are some of the ones that may not be in the default install and need to
be installed manually. There may be others, read the error messages they
will give a clue as to the missing package.
The following command should install everything you need on Debian based
distributions such as Ubuntu:
sudo apt-get install build-essential libssl-dev libcurl4-openssl-dev libjansson-dev libgmp-dev automake
build-essential (for Ubuntu, Development Tools package group on Fedora)
automake
libjansson-dev
libgmp-dev
libcurl4-openssl-dev
libssl-dev
pthreads
zlib
SHA support on AMD Ryzen CPUs requires gcc version 5 or higher and openssl 1.1
or higher. Additional compile options may also be required such as
"-march-znver1" or "-msha".
Extract cpuminer source.
tar xvzf cpuminer-opt-x.y.z.tar.gz
cd cpuminer-opt-x.y.z
Run ./build.sh to build on Linux or execute the following commands.
./autogen.sh
CFLAGS="-O3 -march=native -Wall" CXXFLAGS="$CFLAGS -std=gnu++11" ./configure --with-curl
make
Start mining.
./cpuminer -a algo -o url -u username -p password
Building on Windows prerequisites:
msys
mingw_w64
Visual C++ redistributable 2008 X64
openssl
Install msys and mingw_w64, only needed once.
Unpack msys into C:\msys or your preferred directory.
Install mingw_w64 from win-builds.
Follow instructions, check "msys or cygwin" and "x86_64" and accept default
existing msys instalation.
Open a msys shell by double clicking on msys.bat.
Note that msys shell uses linux syntax for file specifications, "C:\" is
mounted at "/c/".
Add mingw bin directory to PATH variable
PATH="/c/msys/opt/windows_64/bin/:$PATH"
Instalation complete, compile cpuminer-opt.
Unpack cpuminer-opt source files using tar from msys shell, or using 7zip
or similar Windows program.
In msys shell cd to miner directory.
cd /c/path/to/cpuminer-opt
Run winbuild.sh to build on Windows or execute the following commands.
./autogen.sh
CFLAGS="-O3 -march=native -Wall" CXXFLAGS="$CFLAGS -std=gnu++11 -fpermissive" ./configure --with-curl
make
The following tips may be useful for older AMD CPUs.
AMD CPUs older than Piledriver, including Athlon x2 and Phenom II x4, are not
supported by cpuminer-opt due to an incompatible implementation of SSE2 on
these CPUs. Some algos may crash the miner with an invalid instruction.
Users are recommended to use an unoptimized miner such as cpuminer-multi.
Some users with AMD CPUs without AES_NI have reported problems compiling
with build.sh or "-march=native". Problems have included compile errors
and poor performance. These users are recommended to compile manually
specifying "-march=btver1" on the configure command line.
Support for even older x86_64 without AES_NI or SSE2 is not availble.
Change Log
----------
v3.6.5
Cryptonight a little faster.
Added jha algo (Jackpotcoin) with AES optimizations.
v3.6.4
Added support for Bitcore (BTX) using the timetravel10 algo, optimized for
AES and AVX2.
"-a bitcore" works as an alias and is less typing that "-a timetravel10".
v3.6.3
Fixed all known issues with SHA support on AMD Ryzen CPUs, still no
Windows binaries.
v3.6.2
SHA accceleration is now supported on AMD Ryzen CPUs when compiled from source,
Windows binaries not yet available.
Fixed groestl algo.
Fixed dmd-gr (Diamond) algo.
Fixed lbry compile error on Ryzen.
Added SHA support to m7m algo.
Hodl support for CPUs without AES has been removed, use legacy version.
v3.6.1
Fixed data alignment issue that broke lyra2rev2 AVX2 on Windows.
Added preliminary support for HW accelerated SHA.
Solo mining most algos should now work, cryptonight confirmed exception.
v3.6.0
Preliminary support for solo mining using getwork.
v3.5.13
Found more speed in Cubehash, algo improvement depends on chain length,
deep +8%, timetravel +1% , xevan +1%
Fixed a getwork bug, solo mining is not yet supported but testing is encouraged
v3.5.12
New algo sha256t for Onecoin (OC), 29% faster than ocminer version.
lyra2zoin algo renamed to lyra2z330, lyra2zoin and zoin still work
as aliases.
v3.5.11
Fixed hmq1725 crash on Ubuntu 16.04
Fixed compile error in hodl.cpp with gcc 6.3
Fixed x11 crash on Windows with AVX2
v3.5.10
Some AVX2 optimizations introduced for Luffa, shorter chained algos such
as Qubit and Deep should see the biggest gains, but many other algos should
also see improvement, longer chains like xevan not so much.
Rewrite of Groestl AES, now 100% vectorized, small improvement.
build.sh and winbuild.sh initialize with distclean instead of clean.
Implemented a workaround for a compile error in hodl code when compiling
with gcc 6.3.
V3.5.9
Reduced stack usage for hmq1725 and small speedup.
@@ -168,98 +350,3 @@ AVX2 optimizations improving many algos:
- x17 +2.8%
- qubit +8.4%
Compile Instructions
--------------------
Building on linux prerequisites:
It is assumed users know how to install packages on their system and
be able to compile standard source packages. This is basic Linux and
beyond the scope of cpuminer-opt.
Make sure you have the basic development packages installed.
Here is a good start:
http://askubuntu.com/questions/457526/how-to-install-cpuminer-in-ubuntu
Install any additional dependencies needed by cpuminer-opt. The list below
are some of the ones that may not be in the default install and need to
be installed manually. There may be others, read the error messages they
will give a clue as to the missing package.
The folliwing command should install everything you need on Debian based
packages:
sudo apt-get install build-essential libssl-dev libcurl4-openssl-dev libjansson-dev libgmp-dev automake
Building on Linux, see below for Windows.
Dependencies
build-essential (for Ubuntu, Development Tools package group on Fedora)
automake
libjansson-dev
libgmp-dev
libcurl4-openssl-dev
libssl-dev
pthreads
zlib
tar xvzf [file.tar.gz]
cd [file]
Run build.sh to build on Linux or execute the following commands.
./autogen.sh
CFLAGS="-O3 -march=native -Wall" CXXFLAGS="$CFLAGS -std=gnu++11" ./configure --with-curl
make
Start mining.
./cpuminer -a algo ...
Building on Windows prerequisites:
msys
mingw_w64
Visual C++ redistributable 2008 X64
openssl, not sure about this
Install msys and mingw_w64, only needed once.
Unpack msys into C:\msys or your preferred directory.
Install mingw__w64 from win-builds.
Follow instructions, check "msys or cygwin" and "x86_64" and accept default
existing msys instalation.
Open a msys shell by double clicking on msys.bat.
Note that msys shell uses linux syntax for file specifications, "C:\" is
mounted at "/c/".
Add mingw bin directory to PATH variable
PATH="/c/msys/opt/windows_64/bin/:$PATH"
Instalation complete, compile cpuminer-opt
Unpack cpuminer-opt source files using tar from msys shell, or using 7zip
or similar Windows program.
In msys shell cd to miner directory.
cd /c/path/to/cpuminer-opt
Run winbuild.sh to build on Windows or execute the following commands.
./autogen.sh
CFLAGS="-O3 -march=native -Wall" CXXFLAGS="$CFLAGS -std=gnu++11 -fpermissive" ./configure --with-curl
make
The following tips may be useful for older AMD CPUs.
Some users with AMD CPUs without AES_NI have reported problems compiling
with build.sh or "-march=native". Problems have included compile errors
and poor performance. These users are recommended to compile manually
specifying "-march=btver1" on the configure command line.
Support for even older x86_64 without AES_NI or SSE2 is not availble.

View File

@@ -98,17 +98,12 @@ void null_hash_suw()
{
applog(LOG_WARNING,"SWERR: null_hash_suw unsafe null function");
};
void null_hash_alt()
{
applog(LOG_WARNING,"SWERR: null_hash_alt unsafe null function");
};
void init_algo_gate( algo_gate_t* gate )
{
gate->miner_thread_init = (void*)&return_true;
gate->scanhash = (void*)&null_scanhash;
gate->hash = (void*)&null_hash;
gate->hash_alt = (void*)&null_hash_alt;
gate->hash_suw = (void*)&null_hash_suw;
gate->get_new_work = (void*)&std_get_new_work;
gate->get_nonceptr = (void*)&std_get_nonceptr;
@@ -119,11 +114,11 @@ void init_algo_gate( algo_gate_t* gate )
gate->stratum_gen_work = (void*)&std_stratum_gen_work;
gate->build_stratum_request = (void*)&std_le_build_stratum_request;
gate->set_target = (void*)&std_set_target;
gate->work_decode = (void*)&std_work_decode;
gate->submit_getwork_result = (void*)&std_submit_getwork_result;
gate->build_extraheader = (void*)&std_build_extraheader;
gate->set_work_data_endian = (void*)&do_nothing;
gate->calc_network_diff = (void*)&std_calc_network_diff;
// gate->prevent_dupes = (void*)&return_false;
gate->ready_to_mine = (void*)&std_ready_to_mine;
gate->resync_threads = (void*)&do_nothing;
gate->do_this_thread = (void*)&return_true;
@@ -155,62 +150,65 @@ bool register_algo_gate( int algo, algo_gate_t *gate )
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
case ALGO_ARGON2: register_argon2_algo ( gate ); break;
case ALGO_AXIOM: register_axiom_algo ( gate ); break;
case ALGO_BASTION: register_bastion_algo ( gate ); break;
case ALGO_BLAKE: register_blake_algo ( gate ); break;
case ALGO_BLAKECOIN: register_blakecoin_algo ( gate ); break;
// case ALGO_BLAKE2B: register_blake2b_algo ( gate ); break;
case ALGO_BLAKE2S: register_blake2s_algo ( gate ); break;
case ALGO_C11: register_c11_algo ( gate ); break;
case ALGO_CRYPTOLIGHT: register_cryptolight_algo( gate ); break;
case ALGO_CRYPTONIGHT: register_cryptonight_algo( gate ); break;
case ALGO_DECRED: register_decred_algo ( gate ); break;
case ALGO_DEEP: register_deep_algo ( gate ); break;
case ALGO_DROP: register_drop_algo ( gate ); break;
case ALGO_FRESH: register_fresh_algo ( gate ); break;
case ALGO_GROESTL: register_groestl_algo ( gate ); break;
case ALGO_HEAVY: register_heavy_algo ( gate ); break;
case ALGO_HMQ1725: register_hmq1725_algo ( gate ); break;
case ALGO_HODL: register_hodl_algo ( gate ); break;
case ALGO_KECCAK: register_keccak_algo ( gate ); break;
case ALGO_LBRY: register_lbry_algo ( gate ); break;
case ALGO_LUFFA: register_luffa_algo ( gate ); break;
case ALGO_LYRA2RE: register_lyra2re_algo ( gate ); break;
case ALGO_LYRA2REV2: register_lyra2rev2_algo ( gate ); break;
case ALGO_LYRA2Z: register_zcoin_algo ( gate ); break;
case ALGO_LYRA2Z330: register_lyra2z330_algo ( gate ); break;
case ALGO_M7M: register_m7m_algo ( gate ); break;
case ALGO_MYR_GR: register_myriad_algo ( gate ); break;
case ALGO_NEOSCRYPT: register_neoscrypt_algo ( gate ); break;
case ALGO_NIST5: register_nist5_algo ( gate ); break;
case ALGO_PENTABLAKE: register_pentablake_algo ( gate ); break;
case ALGO_PLUCK: register_pluck_algo ( gate ); break;
case ALGO_QUARK: register_quark_algo ( gate ); break;
case ALGO_QUBIT: register_qubit_algo ( gate ); break;
case ALGO_SCRYPT: register_scrypt_algo ( gate ); break;
case ALGO_SCRYPTJANE: register_scryptjane_algo ( gate ); break;
case ALGO_SHA256D: register_sha256d_algo ( gate ); break;
case ALGO_SHA256T: register_sha256t_algo ( gate ); break;
case ALGO_SHAVITE3: register_shavite_algo ( gate ); break;
case ALGO_SKEIN: register_skein_algo ( gate ); break;
case ALGO_SKEIN2: register_skein2_algo ( gate ); break;
case ALGO_S3: register_s3_algo ( gate ); break;
case ALGO_TIMETRAVEL: register_timetravel_algo ( gate ); break;
case ALGO_VANILLA: register_vanilla_algo ( gate ); break;
case ALGO_VELTOR: register_veltor_algo ( gate ); break;
case ALGO_WHIRLPOOL: register_whirlpool_algo ( gate ); break;
case ALGO_WHIRLPOOLX: register_whirlpoolx_algo ( gate ); break;
case ALGO_X11: register_x11_algo ( gate ); break;
case ALGO_X11EVO: register_x11evo_algo ( gate ); break;
case ALGO_X11GOST: register_sib_algo ( gate ); break;
case ALGO_X13: register_x13_algo ( gate ); break;
case ALGO_X14: register_x14_algo ( gate ); break;
case ALGO_X15: register_x15_algo ( gate ); break;
case ALGO_X17: register_x17_algo ( gate ); break;
case ALGO_XEVAN: register_xevan_algo ( gate ); break;
case ALGO_YESCRYPT: register_yescrypt_algo ( gate ); break;
case ALGO_ZR5: register_zr5_algo ( gate ); break;
case ALGO_ARGON2: register_argon2_algo ( gate ); break;
case ALGO_AXIOM: register_axiom_algo ( gate ); break;
case ALGO_BASTION: register_bastion_algo ( gate ); break;
case ALGO_BLAKE: register_blake_algo ( gate ); break;
case ALGO_BLAKECOIN: register_blakecoin_algo ( gate ); break;
// case ALGO_BLAKE2B: register_blake2b_algo ( gate ); break;
case ALGO_BLAKE2S: register_blake2s_algo ( gate ); break;
case ALGO_C11: register_c11_algo ( gate ); break;
case ALGO_CRYPTOLIGHT: register_cryptolight_algo ( gate ); break;
case ALGO_CRYPTONIGHT: register_cryptonight_algo ( gate ); break;
case ALGO_DECRED: register_decred_algo ( gate ); break;
case ALGO_DEEP: register_deep_algo ( gate ); break;
case ALGO_DMD_GR: register_dmd_gr_algo ( gate ); break;
case ALGO_DROP: register_drop_algo ( gate ); break;
case ALGO_FRESH: register_fresh_algo ( gate ); break;
case ALGO_GROESTL: register_groestl_algo ( gate ); break;
case ALGO_HEAVY: register_heavy_algo ( gate ); break;
case ALGO_HMQ1725: register_hmq1725_algo ( gate ); break;
case ALGO_HODL: register_hodl_algo ( gate ); break;
case ALGO_JHA: register_jha_algo ( gate ); break;
case ALGO_KECCAK: register_keccak_algo ( gate ); break;
case ALGO_LBRY: register_lbry_algo ( gate ); break;
case ALGO_LUFFA: register_luffa_algo ( gate ); break;
case ALGO_LYRA2RE: register_lyra2re_algo ( gate ); break;
case ALGO_LYRA2REV2: register_lyra2rev2_algo ( gate ); break;
case ALGO_LYRA2Z: register_zcoin_algo ( gate ); break;
case ALGO_LYRA2Z330: register_lyra2z330_algo ( gate ); break;
case ALGO_M7M: register_m7m_algo ( gate ); break;
case ALGO_MYR_GR: register_myriad_algo ( gate ); break;
case ALGO_NEOSCRYPT: register_neoscrypt_algo ( gate ); break;
case ALGO_NIST5: register_nist5_algo ( gate ); break;
case ALGO_PENTABLAKE: register_pentablake_algo ( gate ); break;
case ALGO_PLUCK: register_pluck_algo ( gate ); break;
case ALGO_QUARK: register_quark_algo ( gate ); break;
case ALGO_QUBIT: register_qubit_algo ( gate ); break;
case ALGO_SCRYPT: register_scrypt_algo ( gate ); break;
case ALGO_SCRYPTJANE: register_scryptjane_algo ( gate ); break;
case ALGO_SHA256D: register_sha256d_algo ( gate ); break;
case ALGO_SHA256T: register_sha256t_algo ( gate ); break;
case ALGO_SHAVITE3: register_shavite_algo ( gate ); break;
case ALGO_SKEIN: register_skein_algo ( gate ); break;
case ALGO_SKEIN2: register_skein2_algo ( gate ); break;
case ALGO_S3: register_s3_algo ( gate ); break;
case ALGO_TIMETRAVEL: register_timetravel_algo ( gate ); break;
case ALGO_TIMETRAVEL10: register_timetravel10_algo( gate ); break;
case ALGO_VANILLA: register_vanilla_algo ( gate ); break;
case ALGO_VELTOR: register_veltor_algo ( gate ); break;
case ALGO_WHIRLPOOL: register_whirlpool_algo ( gate ); break;
case ALGO_WHIRLPOOLX: register_whirlpoolx_algo ( gate ); break;
case ALGO_X11: register_x11_algo ( gate ); break;
case ALGO_X11EVO: register_x11evo_algo ( gate ); break;
case ALGO_X11GOST: register_sib_algo ( gate ); break;
case ALGO_X13: register_x13_algo ( gate ); break;
case ALGO_X14: register_x14_algo ( gate ); break;
case ALGO_X15: register_x15_algo ( gate ); break;
case ALGO_X17: register_x17_algo ( gate ); break;
case ALGO_XEVAN: register_xevan_algo ( gate ); break;
case ALGO_YESCRYPT: register_yescrypt_algo ( gate ); break;
case ALGO_ZR5: register_zr5_algo ( gate ); break;
// restore warnings
#pragma GCC diagnostic pop
@@ -244,6 +242,7 @@ bool register_json_rpc2( algo_gate_t *gate )
gate->nonce_index = JR2_NONCE_INDEX;
jsonrpc_2 = true; // still needed
opt_extranonce = false;
// have_gbt = false;
return true;
}
@@ -256,41 +255,43 @@ void exec_hash_function( int algo, void *output, const void *pdata )
gate.hash( output, pdata, 0 );
}
// an algo can have multiple aliases but the aliases must be unique
#define PROPER (1)
#define ALIAS (0)
// The only difference between the alias and the proper algo name is the
// proper name s the one that is defined in ALGO_NAMES, there may be
// proper name is the one that is defined in ALGO_NAMES. There may be
// multiple aliases that map to the same proper name.
// New aliases can be added anywhere in the array as long as NULL is last.
// Alphabetic order of alias is recommended.
const char* const algo_alias_map[][2] =
{
// alias proper
{ "blake256r8", "blakecoin" },
{ "blake256r8vnl", "vanilla" },
{ "sia", "blake2b" },
{ "blake256r14", "blake" },
{ "cryptonote", "cryptonight" },
{ "cryptonight-light", "cryptolight" },
{ "dmd-gr", "groestl" },
{ "droplp", "drop" },
{ "espers", "hmq1725" },
{ "flax", "c11" },
{ "jane", "scryptjane" },
{ "lyra2", "lyra2re" },
{ "lyra2v2", "lyra2rev2" },
{ "lyra2zoin", "lyra2z330" },
{ "myriad", "myr-gr" },
{ "neo", "neoscrypt" },
{ "sib", "x11gost" },
{ "yes", "yescrypt" },
{ "ziftr", "zr5" },
{ "zcoin", "lyra2z" },
{ "zoin", "lyra2z330" },
{ NULL, NULL }
{ "bitcore", "timetravel10" },
{ "blake256r8", "blakecoin" },
{ "blake256r8vnl", "vanilla" },
{ "blake256r14", "blake" },
{ "blake256r14dcr", "decred" },
{ "cryptonote", "cryptonight" },
{ "cryptonight-light", "cryptolight" },
{ "diamond", "dmd-gr" },
{ "droplp", "drop" },
{ "espers", "hmq1725" },
{ "flax", "c11" },
{ "jackpot", "jha" },
{ "jane", "scryptjane" },
{ "lyra2", "lyra2re" },
{ "lyra2v2", "lyra2rev2" },
{ "lyra2zoin", "lyra2z330" },
{ "myriad", "myr-gr" },
{ "neo", "neoscrypt" },
// { "sia", "blake2b" },
{ "sib", "x11gost" },
{ "timetravel8", "timetravel" },
{ "yes", "yescrypt" },
{ "ziftr", "zr5" },
{ "zcoin", "lyra2z" },
{ "zoin", "lyra2z330" },
{ NULL, NULL }
};
// if arg is a valid alias for a known algo it is updated with the proper name.

View File

@@ -86,10 +86,11 @@
typedef uint32_t set_t;
#define EMPTY_SET 0
#define SSE2_OPT 1
#define AES_OPT 2
#define AVX_OPT 4
#define AVX2_OPT 8
#define SSE2_OPT 1
#define AES_OPT 2
#define AVX_OPT 4
#define AVX2_OPT 8
#define SHA_OPT 16
// return set containing all elements from sets a & b
inline set_t set_union ( set_t a, set_t b ) { return a | b; }
@@ -110,7 +111,6 @@ 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* );
//optional, safe to use default in most cases
@@ -130,7 +130,6 @@ void ( *build_extraheader ) ( struct work*, struct stratum_ctx* );
void ( *build_stratum_request ) ( char*, struct work*, struct stratum_ctx* );
void ( *set_work_data_endian ) ( struct work* );
double ( *calc_network_diff ) ( struct work* );
//bool ( *prevent_dupes ) ( struct work*, struct stratum_ctx*, int );
bool ( *ready_to_mine ) ( struct work*, struct stratum_ctx*, int );
void ( *resync_threads ) ( struct work* );
bool ( *do_this_thread ) ( int );
@@ -185,7 +184,6 @@ int null_scanhash();
// displays warning
void null_hash ();
void null_hash_alt();
void null_hash_suw();
// optional safe targets, default listed first unless noted.

View File

@@ -6,11 +6,11 @@
#include "algo/shabal/sph_shabal.h"
static __thread uint32_t _ALIGN(128) M[65536][8];
static __thread uint32_t _ALIGN(64) M[65536][8];
void axiomhash(void *output, const void *input)
{
sph_shabal256_context ctx;
sph_shabal256_context ctx __attribute__ ((aligned (64)));
const int N = 65536;
sph_shabal256_init(&ctx);
@@ -34,7 +34,7 @@ void axiomhash(void *output, const void *input)
sph_shabal256(&ctx, M[p], 32);
sph_shabal256(&ctx, M[j], 32);
#else
uint8_t _ALIGN(128) hash[64];
uint8_t _ALIGN(64) hash[64];
memcpy(hash, M[p], 32);
memcpy(&hash[32], M[j], 32);
sph_shabal256(&ctx, hash, 64);
@@ -49,8 +49,8 @@ int scanhash_axiom(int thr_id, struct work *work,
{
uint32_t *pdata = work->data;
uint32_t *ptarget = work->target;
uint32_t _ALIGN(128) hash64[8];
uint32_t _ALIGN(128) endiandata[20];
uint32_t _ALIGN(64) hash64[8];
uint32_t _ALIGN(64) endiandata[20];
const uint32_t Htarg = ptarget[7];
const uint32_t first_nonce = pdata[19];
@@ -82,7 +82,6 @@ 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*)&get_max64_0x40LL;
return true;
}

View File

@@ -1,203 +0,0 @@
#include <ccminer-config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <inttypes.h>
#include <unistd.h>
#include <math.h>
#include <sys/time.h>
#include <time.h>
#include <signal.h>
#include <curl/curl.h>
#include <miner.h>
#include "sia-rpc.h"
static bool sia_debug_diff = false;
extern int share_result(int result, int pooln, double sharediff, const char *reason);
/* compute nbits to get the network diff */
static void calc_network_diff(struct work *work)
{
uint32_t nbits = work->data[11]; // unsure if correct
uint32_t bits = (nbits & 0xffffff);
int16_t shift = (swab32(nbits) & 0xff); // 0x1c = 28
uint64_t diffone = 0x0000FFFF00000000ull;
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 (sia_debug_diff)
applog(LOG_DEBUG, "net diff: %f -> shift %u, bits %08x", d, shift, bits);
net_diff = d;
}
// ---- SIA LONGPOLL --------------------------------------------------------------------------------
struct data_buffer {
void *buf;
size_t len;
};
static size_t sia_data_cb(const void *ptr, size_t size, size_t nmemb,
void *user_data)
{
struct data_buffer *db = (struct data_buffer *)user_data;
size_t len = size * nmemb;
size_t oldlen, newlen;
void *newmem;
static const uchar zero = 0;
oldlen = db->len;
newlen = oldlen + len;
newmem = realloc(db->buf, newlen + 1);
if (!newmem)
return 0;
db->buf = newmem;
db->len = newlen;
memcpy((char*)db->buf + oldlen, ptr, len);
memcpy((char*)db->buf + newlen, &zero, 1); /* null terminate */
return len;
}
char* sia_getheader(CURL *curl, struct pool_infos *pool)
{
char curl_err_str[CURL_ERROR_SIZE] = { 0 };
struct data_buffer all_data = { 0 };
struct curl_slist *headers = NULL;
char data[256] = { 0 };
char url[512];
// nanopool
snprintf(url, 512, "%s/miner/header?address=%s&worker=%s", //&longpoll
pool->url, pool->user, pool->pass);
if (opt_protocol)
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_POST, 0);
curl_easy_setopt(curl, CURLOPT_ENCODING, "");
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 0);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, opt_timeout);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_err_str);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, sia_data_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &all_data);
headers = curl_slist_append(headers, "Accept: application/octet-stream");
headers = curl_slist_append(headers, "Expect:"); // disable Expect hdr
headers = curl_slist_append(headers, "User-Agent: Sia-Agent"); // required for now
// headers = curl_slist_append(headers, "User-Agent: " USER_AGENT);
// headers = curl_slist_append(headers, "X-Mining-Extensions: longpoll");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
int rc = curl_easy_perform(curl);
if (rc && strlen(curl_err_str)) {
applog(LOG_WARNING, "%s", curl_err_str);
}
if (all_data.len >= 112)
cbin2hex(data, (const char*) all_data.buf, 112);
if (opt_protocol || all_data.len != 112)
applog(LOG_DEBUG, "received %d bytes: %s", (int) all_data.len, data);
curl_slist_free_all(headers);
return rc == 0 && all_data.len ? strdup(data) : NULL;
}
bool sia_work_decode(const char *hexdata, struct work *work)
{
uint8_t target[32];
if (!work) return false;
hex2bin((uchar*)target, &hexdata[0], 32);
swab256(work->target, target);
work->targetdiff = target_to_diff(work->target);
hex2bin((uchar*)work->data, &hexdata[64], 80);
// high 16 bits of the 64 bits nonce
work->data[9] = rand() << 16;
// use work ntime as job id
cbin2hex(work->job_id, (const char*)&work->data[10], 4);
calc_network_diff(work);
if (stratum_diff != work->targetdiff) {
stratum_diff = work->targetdiff;
applog(LOG_WARNING, "Pool diff set to %g", stratum_diff);
}
return true;
}
bool sia_submit(CURL *curl, struct pool_infos *pool, struct work *work)
{
char curl_err_str[CURL_ERROR_SIZE] = { 0 };
struct data_buffer all_data = { 0 };
struct curl_slist *headers = NULL;
char buf[256] = { 0 };
char url[512];
if (opt_protocol)
applog_hex(work->data, 80);
//applog_hex(&work->data[8], 16);
//applog_hex(&work->data[10], 4);
// nanopool
snprintf(url, 512, "%s/miner/header?address=%s&worker=%s",
pool->url, pool->user, pool->pass);
if (opt_protocol)
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_ENCODING, "");
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 0);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 1);
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_err_str);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &all_data);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, sia_data_cb);
memcpy(buf, work->data, 80);
curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 80);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, (void*) buf);
// headers = curl_slist_append(headers, "Content-Type: application/octet-stream");
// headers = curl_slist_append(headers, "Content-Length: 80");
headers = curl_slist_append(headers, "Accept:"); // disable Accept hdr
headers = curl_slist_append(headers, "Expect:"); // disable Expect hdr
headers = curl_slist_append(headers, "User-Agent: Sia-Agent");
// headers = curl_slist_append(headers, "User-Agent: " USER_AGENT);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
int res = curl_easy_perform(curl) == 0;
long errcode;
CURLcode c = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &errcode);
if (errcode != 204) {
if (strlen(curl_err_str))
applog(LOG_ERR, "submit err %ld %s", errcode, curl_err_str);
res = 0;
}
share_result(res, work->pooln, work->sharediff[0], res ? NULL : (char*) all_data.buf);
curl_slist_free_all(headers);
return true;
}
// ---- END SIA LONGPOLL ----------------------------------------------------------------------------

View File

@@ -1,6 +0,0 @@
#include <miner.h>
char* sia_getheader(CURL *curl, struct pool_infos *pool);
bool sia_work_decode(const char *hexdata, struct work *work);
bool sia_submit(CURL *curl, struct pool_infos *pool, struct work *work);

View File

@@ -21,7 +21,7 @@ void blakehash(void *state, const void *input)
{
sph_blake256_context ctx;
uint8_t hash[64];
uint8_t hash[64] __attribute__ ((aligned (32)));
uint8_t *ending = (uint8_t*) input;
ending += 64;
@@ -100,7 +100,6 @@ bool register_blake_algo( algo_gate_t* gate )
{
gate->scanhash = (void*)&scanhash_blake;
gate->hash = (void*)&blakehash;
gate->hash_alt = (void*)&blakehash;
gate->get_max64 = (void*)&blake_get_max64;
return true;
}

View File

@@ -10,6 +10,7 @@
#include "algo/blake/sph_blake2b.h"
static __thread sph_blake2b_ctx s_midstate;
static __thread sph_blake2b_ctx s_ctx;
#define MIDLEN 76
@@ -18,7 +19,7 @@ static __thread sph_blake2b_ctx s_ctx;
void blake2b_hash(void *output, const void *input)
{
uint8_t _ALIGN(A) hash[32];
sph_blake2b_ctx ctx;
sph_blake2b_ctx ctx __attribute__ ((aligned (64)));
sph_blake2b_init(&ctx, 32, NULL, 0);
sph_blake2b_update(&ctx, input, 80);
@@ -44,7 +45,6 @@ int scanhash_blake2b( int thr_id, struct work *work, uint32_t max_nonce,
uint32_t *ptarget = work->target;
const uint32_t Htarg = ptarget[7];
// const uint32_t first_nonce = pdata[19];
const uint32_t first_nonce = pdata[8];
uint32_t n = first_nonce;
@@ -59,7 +59,6 @@ int scanhash_blake2b( int thr_id, struct work *work, uint32_t max_nonce,
//memcpy(&s_ctx, &s_midstate, sizeof(blake2b_ctx));
do {
// be32enc(&endiandata[19], n);
be32enc(&endiandata[8], n);
//blake2b_hash_end(vhashcpu, endiandata);
blake2b_hash(vhashcpu, endiandata);
@@ -67,7 +66,6 @@ int scanhash_blake2b( int thr_id, struct work *work, uint32_t max_nonce,
if (vhashcpu[7] < Htarg && fulltest(vhashcpu, ptarget)) {
work_set_target_ratio(work, vhashcpu);
*hashes_done = n - first_nonce + 1;
// pdata[19] = n;
pdata[8] = n;
return 1;
}
@@ -75,7 +73,6 @@ int scanhash_blake2b( int thr_id, struct work *work, uint32_t max_nonce,
} while (n < max_nonce && !work_restart[thr_id].restart);
*hashes_done = n - first_nonce + 1;
// pdata[19] = n;
pdata[8] = n;
return 0;
@@ -173,8 +170,8 @@ void blake2b_get_new_work( struct work* work, struct work* g_work, int thr_id,
uint32_t *nonceptr = algo_gate.get_nonceptr( work->data );
if ( memcmp( &work->data[ wkcmp_off ], &g_work->data[ wkcmp_off ], wkcmp_sz )
&& ( clean_job || ( *nonceptr >= *end_nonce_ptr ) )
|| strcmp( work->job_id, g_work->job_id ) )
&& ( clean_job || ( *nonceptr >= *end_nonce_ptr )
|| strcmp( work->job_id, g_work->job_id ) ) )
{
work_free( work );
work_copy( work, g_work );

View File

@@ -13,7 +13,7 @@ static __thread blake2s_state s_ctx;
void blake2s_hash(void *output, const void *input)
{
unsigned char _ALIGN(64) hash[BLAKE2S_OUTBYTES];
blake2s_state blake2_ctx;
blake2s_state blake2_ctx __attribute__ ((aligned (64)));
blake2s_init(&blake2_ctx, BLAKE2S_OUTBYTES);
blake2s_update(&blake2_ctx, input, 80);

View File

@@ -30,7 +30,7 @@ static void blake_midstate_init( const void* input )
void blakecoinhash( void *state, const void *input )
{
sph_blake256_context ctx;
uint8_t hash[64];
uint8_t hash[64] __attribute__ ((aligned (32)));
uint8_t *ending = (uint8_t*) input + 64;
// copy cached midstate
@@ -93,10 +93,12 @@ int scanhash_blakecoin( int thr_id, struct work *work, uint32_t max_nonce,
return 0;
}
/*
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 ()
@@ -109,7 +111,6 @@ bool register_vanilla_algo( algo_gate_t* gate )
{
gate->scanhash = (void*)&scanhash_blakecoin;
gate->hash = (void*)&blakecoinhash;
gate->hash_alt = (void*)&blakecoinhash;
gate->get_max64 = (void*)&blakecoin_get_max64;
blakecoin_init( &blake_init_ctx );
return true;

View File

@@ -5,6 +5,8 @@
#include <string.h>
#include <stdint.h>
#include <memory.h>
#include <unistd.h>
/*
#ifndef min
#define min(a,b) (a>b ? b : a)
@@ -27,7 +29,7 @@ static __thread bool ctx_midstate_done = false;
void decred_hash(void *state, const void *input)
{
#define MIDSTATE_LEN 128
sph_blake256_context ctx;
sph_blake256_context ctx __attribute__ ((aligned (64)));
uint8_t *ending = (uint8_t*) input;
ending += MIDSTATE_LEN;
@@ -53,8 +55,8 @@ void decred_hash_simple(void *state, const void *input)
int scanhash_decred(int thr_id, struct work *work, uint32_t max_nonce, uint64_t *hashes_done)
{
uint32_t _ALIGN(128) endiandata[48];
uint32_t _ALIGN(128) hash32[8];
uint32_t _ALIGN(64) endiandata[48];
uint32_t _ALIGN(64) hash32[8];
uint32_t *pdata = work->data;
uint32_t *ptarget = work->target;
@@ -195,6 +197,7 @@ void decred_gen_merkle_root( char* merkle_root, struct stratum_ctx* sctx )
}
*/
#define min(a,b) (a>b ? (b) :(a))
void decred_build_extraheader( struct work* g_work, struct stratum_ctx* sctx )
@@ -244,21 +247,6 @@ void decred_build_extraheader( struct work* g_work, struct stratum_ctx* sctx )
#undef min
/*
bool decred_prevent_dupes( struct work* work, struct stratum_ctx* stratum,
int thr_id )
{
return false;
if ( have_stratum && strcmp(stratum->job.job_id, work->job_id) )
// need to regen g_work..
return true;
// extradata: prevent duplicates
work->data[ DECRED_XNONCE_INDEX ] += 1;
work->data[ DECRED_XNONCE_INDEX + 1 ] |= thr_id;
return false;
}
*/
bool decred_ready_to_mine( struct work* work, struct stratum_ctx* stratum,
int thr_id )
{
@@ -282,14 +270,11 @@ bool register_decred_algo( algo_gate_t* gate )
gate->optimizations = SSE2_OPT;
gate->scanhash = (void*)&scanhash_decred;
gate->hash = (void*)&decred_hash;
gate->hash_alt = (void*)&decred_hash;
gate->get_nonceptr = (void*)&decred_get_nonceptr;
gate->get_max64 = (void*)&get_max64_0x3fffffLL;
gate->display_extra_data = (void*)&decred_decode_extradata;
gate->build_stratum_request = (void*)&decred_be_build_stratum_request;
// gate->gen_merkle_root = (void*)&decred_gen_merkle_root;
gate->build_extraheader = (void*)&decred_build_extraheader;
// gate->prevent_dupes = (void*)&decred_prevent_dupes;
gate->ready_to_mine = (void*)&decred_ready_to_mine;
gate->nbits_index = DECRED_NBITS_INDEX;
gate->ntime_index = DECRED_NTIME_INDEX;

View File

@@ -42,7 +42,7 @@ extern "C"{
#endif
#include <stddef.h>
#include "algo/sha3/sph_types.h"
#include "algo/sha/sph_types.h"
/**
* Output size (in bits) for BLAKE-224.

View File

@@ -31,7 +31,7 @@
#include <stdint.h>
#include <string.h>
#include "algo/sha3/sph_types.h"
#include "algo/sha/sph_types.h"
#include "sph_blake2b.h"
// Cyclic right rotation.

View File

@@ -41,7 +41,7 @@ extern "C"{
#endif
#include <stddef.h>
#include "algo/sha3/sph_types.h"
#include "algo/sha/sph_types.h"
/**
* Output size (in bits) for BMW-224.

View File

@@ -109,43 +109,43 @@ static __thread cryptonight_ctx ctx;
void cryptonight_hash_aes( void *restrict output, const void *input, int len )
{
#ifndef NO_AES_NI
keccak( (const uint8_t*)input, 76, (char*)&ctx.state.hs.b, 200 );
uint8_t ExpandedKey[256] __attribute__((aligned(64)));
__m128i *longoutput, *expkey, *xmminput;
size_t i, j;
memcpy(ctx.text, ctx.state.init, INIT_SIZE_BYTE);
memcpy(ExpandedKey, ctx.state.hs.b, AES_KEY_SIZE);
ExpandAESKey256(ExpandedKey);
keccak( (const uint8_t*)input, 76, (char*)&ctx.state.hs.b, 200 );
memcpy( ExpandedKey, ctx.state.hs.b, AES_KEY_SIZE );
ExpandAESKey256( ExpandedKey );
memcpy( ctx.text, ctx.state.init, INIT_SIZE_BYTE );
__m128i *longoutput, *expkey, *xmminput;
longoutput = (__m128i *)ctx.long_state;
expkey = (__m128i *)ExpandedKey;
xmminput = (__m128i *)ctx.text;
longoutput = (__m128i*)ctx.long_state;
xmminput = (__m128i*)ctx.text;
expkey = (__m128i*)ExpandedKey;
//for (i = 0; likely(i < MEMORY); i += INIT_SIZE_BYTE)
// aesni_parallel_noxor(&ctx->long_state[i], ctx->text, ExpandedKey);
// prefetch expkey, all of xmminput and enough longoutput for 4 loops
// prefetch expkey, xmminput and enough longoutput for 4 iterations
_mm_prefetch( xmminput, _MM_HINT_T0 );
_mm_prefetch( xmminput + 4, _MM_HINT_T0 );
for ( i = 0; i < 64; i += 16 )
{
_mm_prefetch( longoutput + i, _MM_HINT_T0 );
_mm_prefetch( longoutput + i + 4, _MM_HINT_T0 );
_mm_prefetch( longoutput + i + 8, _MM_HINT_T0 );
_mm_prefetch( longoutput + i + 12, _MM_HINT_T0 );
}
_mm_prefetch( expkey, _MM_HINT_T0 );
_mm_prefetch( expkey + 4, _MM_HINT_T0 );
_mm_prefetch( expkey + 8, _MM_HINT_T0 );
for ( i = 0; likely( i < MEMORY_M128I ); i += INIT_SIZE_M128I )
for ( i = 0; i < 64; i += 16 )
{
// prefetch 4 loops ahead,
__builtin_prefetch( longoutput + i, 1, 0 );
__builtin_prefetch( longoutput + i + 4, 1, 0 );
__builtin_prefetch( longoutput + i + 8, 1, 0 );
__builtin_prefetch( longoutput + i + 12, 1, 0 );
}
// n-4 iterations
for ( i = 0; likely( i < MEMORY_M128I - 4*INIT_SIZE_M128I );
i += INIT_SIZE_M128I )
{
// prefetch 4 iterations ahead.
__builtin_prefetch( longoutput + i + 64, 1, 0 );
__builtin_prefetch( longoutput + i + 68, 1, 0 );
for (j = 0; j < 10; j++ )
for ( j = 0; j < 10; j++ )
{
xmminput[0] = _mm_aesenc_si128( xmminput[0], expkey[j] );
xmminput[1] = _mm_aesenc_si128( xmminput[1], expkey[j] );
@@ -165,84 +165,99 @@ void cryptonight_hash_aes( void *restrict output, const void *input, int len )
_mm_store_si128( &( longoutput[i+6] ), xmminput[6] );
_mm_store_si128( &( longoutput[i+7] ), xmminput[7] );
}
// last 4 iterations
for ( ; likely( i < MEMORY_M128I ); i += INIT_SIZE_M128I )
{
for ( j = 0; j < 10; j++ )
{
xmminput[0] = _mm_aesenc_si128( xmminput[0], expkey[j] );
xmminput[1] = _mm_aesenc_si128( xmminput[1], expkey[j] );
xmminput[2] = _mm_aesenc_si128( xmminput[2], expkey[j] );
xmminput[3] = _mm_aesenc_si128( xmminput[3], expkey[j] );
xmminput[4] = _mm_aesenc_si128( xmminput[4], expkey[j] );
xmminput[5] = _mm_aesenc_si128( xmminput[5], expkey[j] );
xmminput[6] = _mm_aesenc_si128( xmminput[6], expkey[j] );
xmminput[7] = _mm_aesenc_si128( xmminput[7], expkey[j] );
}
_mm_store_si128( &( longoutput[i ] ), xmminput[0] );
_mm_store_si128( &( longoutput[i+1] ), xmminput[1] );
_mm_store_si128( &( longoutput[i+2] ), xmminput[2] );
_mm_store_si128( &( longoutput[i+3] ), xmminput[3] );
_mm_store_si128( &( longoutput[i+4] ), xmminput[4] );
_mm_store_si128( &( longoutput[i+5] ), xmminput[5] );
_mm_store_si128( &( longoutput[i+6] ), xmminput[6] );
_mm_store_si128( &( longoutput[i+7] ), xmminput[7] );
}
// cast_m128i( ctx.a ) = _mm_xor_si128( casti_m128i( ctx.state.k, 0 ) ,
// casti_m128i( ctx.state.k, 2 ) );
// cast_m128i( ctx.b ) = _mm_xor_si128( casti_m128i( ctx.state.k, 1 ),
// casti_m128i( ctx.state.k, 3 ) );
ctx.a[0] = ((uint64_t *)ctx.state.k)[0] ^ ((uint64_t *)ctx.state.k)[4];
ctx.b[0] = ((uint64_t *)ctx.state.k)[2] ^ ((uint64_t *)ctx.state.k)[6];
ctx.a[1] = ((uint64_t *)ctx.state.k)[1] ^ ((uint64_t *)ctx.state.k)[5];
ctx.b[1] = ((uint64_t *)ctx.state.k)[3] ^ ((uint64_t *)ctx.state.k)[7];
ctx.a[0] = ((uint64_t *)ctx.state.k)[0] ^ ((uint64_t *)ctx.state.k)[4];
ctx.b[0] = ((uint64_t *)ctx.state.k)[2] ^ ((uint64_t *)ctx.state.k)[6];
ctx.a[1] = ((uint64_t *)ctx.state.k)[1] ^ ((uint64_t *)ctx.state.k)[5];
ctx.b[1] = ((uint64_t *)ctx.state.k)[3] ^ ((uint64_t *)ctx.state.k)[7];
// for (i = 0; i < 2; i++)
// {
// ctx.a[i] = ((uint64_t *)ctx.state.k)[i] ^ ((uint64_t *)ctx.state.k)[i+4];
// ctx.b[i] = ((uint64_t *)ctx.state.k)[i+2] ^ ((uint64_t *)ctx.state.k)[i+6];
// }
__m128i b_x = _mm_load_si128((__m128i *)ctx.b);
uint64_t a[2] __attribute((aligned(16))), b[2] __attribute((aligned(16)));
uint64_t a[2] __attribute((aligned(16))),
b[2] __attribute((aligned(16))),
c[2] __attribute((aligned(16)));
a[0] = ctx.a[0];
a[1] = ctx.a[1];
for(i = 0; __builtin_expect(i < 0x80000, 1); i++)
__m128i b_x = _mm_load_si128( (__m128i*)ctx.b );
__m128i a_x = _mm_load_si128( (__m128i*)a );
__m128i* lsa = (__m128i*)&ctx.long_state[ a[0] & 0x1FFFF0 ];
__m128i c_x = _mm_load_si128( lsa );
uint64_t *nextblock;
uint64_t hi, lo;
// n-1 iterations
for( i = 0; __builtin_expect( i < 0x7ffff, 1 ); i++ )
{
uint64_t c[2];
__builtin_prefetch( &ctx.long_state[c[0] & 0x1FFFF0], 0, 1 );
__m128i c_x = _mm_load_si128(
(__m128i *)&ctx.long_state[a[0] & 0x1FFFF0]);
__m128i a_x = _mm_load_si128((__m128i *)a);
c_x = _mm_aesenc_si128(c_x, a_x);
_mm_store_si128((__m128i *)c, c_x);
b_x = _mm_xor_si128(b_x, c_x);
_mm_store_si128((__m128i *)&ctx.long_state[a[0] & 0x1FFFF0], b_x);
uint64_t *nextblock = (uint64_t *)&ctx.long_state[c[0] & 0x1FFFF0];
// uint64_t b[2];
c_x = _mm_aesenc_si128( c_x, a_x );
_mm_store_si128( (__m128i*)c, c_x );
b_x = _mm_xor_si128( b_x, c_x );
nextblock = (uint64_t *)&ctx.long_state[c[0] & 0x1FFFF0];
_mm_store_si128( lsa, b_x );
b[0] = nextblock[0];
b[1] = nextblock[1];
{
uint64_t hi, lo;
// hi,lo = 64bit x 64bit multiply of c[0] and b[0]
// hi,lo = 64bit x 64bit multiply of c[0] and b[0]
__asm__( "mulq %3\n\t"
: "=d" ( hi ),
"=a" ( lo )
: "%a" ( c[0] ),
"rm" ( b[0] )
: "cc" );
__asm__("mulq %3\n\t"
: "=d" (hi),
"=a" (lo)
: "%a" (c[0]),
"rm" (b[0])
: "cc" );
a[0] += hi;
a[1] += lo;
}
uint64_t *dst = (uint64_t*)&ctx.long_state[c[0] & 0x1FFFF0];
// __m128i *dst = (__m128i*)&ctx.long_state[c[0] & 0x1FFFF0];
// *dst = cast_m128i( a );
dst[0] = a[0];
dst[1] = a[1];
// cast_m128i( a ) = _mm_xor_si128( cast_m128i( a ), cast_m128i( b ) );
a[0] ^= b[0];
a[1] ^= b[1];
b_x = c_x;
__builtin_prefetch( &ctx.long_state[a[0] & 0x1FFFF0], 0, 3 );
b_x = c_x;
nextblock[0] = a[0] + hi;
nextblock[1] = a[1] + lo;
a[0] = b[0] ^ nextblock[0];
a[1] = b[1] ^ nextblock[1];
lsa = (__m128i*)&ctx.long_state[ a[0] & 0x1FFFF0 ];
a_x = _mm_load_si128( (__m128i*)a );
c_x = _mm_load_si128( lsa );
}
// abreviated nth iteration
c_x = _mm_aesenc_si128( c_x, a_x );
_mm_store_si128( (__m128i*)c, c_x );
b_x = _mm_xor_si128( b_x, c_x );
nextblock = (uint64_t *)&ctx.long_state[c[0] & 0x1FFFF0];
_mm_store_si128( lsa, b_x );
b[0] = nextblock[0];
b[1] = nextblock[1];
__asm__( "mulq %3\n\t"
: "=d" ( hi ),
"=a" ( lo )
: "%a" ( c[0] ),
"rm" ( b[0] )
: "cc" );
nextblock[0] = a[0] + hi;
nextblock[1] = a[1] + lo;
memcpy( ctx.text, ctx.state.init, INIT_SIZE_BYTE );
memcpy( ExpandedKey, &ctx.state.hs.b[32], AES_KEY_SIZE );
ExpandAESKey256( ExpandedKey );
//for (i = 0; likely(i < MEMORY); i += INIT_SIZE_BYTE)
// aesni_parallel_xor(&ctx->text, ExpandedKey, &ctx->long_state[i]);
memcpy( ctx.text, ctx.state.init, INIT_SIZE_BYTE );
// prefetch expkey, all of xmminput and enough longoutput for 4 loops
_mm_prefetch( xmminput, _MM_HINT_T0 );
_mm_prefetch( xmminput + 4, _MM_HINT_T0 );
for ( i = 0; i < 64; i += 16 )
@@ -256,9 +271,11 @@ void cryptonight_hash_aes( void *restrict output, const void *input, int len )
_mm_prefetch( expkey + 4, _MM_HINT_T0 );
_mm_prefetch( expkey + 8, _MM_HINT_T0 );
for ( i = 0; likely( i < MEMORY_M128I ); i += INIT_SIZE_M128I )
// n-4 iterations
for ( i = 0; likely( i < MEMORY_M128I - 4*INIT_SIZE_M128I );
i += INIT_SIZE_M128I )
{
// stay 4 loops ahead,
// stay 4 iterations ahead.
_mm_prefetch( longoutput + i + 64, _MM_HINT_T0 );
_mm_prefetch( longoutput + i + 68, _MM_HINT_T0 );
@@ -283,10 +300,34 @@ void cryptonight_hash_aes( void *restrict output, const void *input, int len )
xmminput[7] = _mm_aesenc_si128( xmminput[7], expkey[j] );
}
}
// last 4 iterations
for ( ; likely( i < MEMORY_M128I ); i += INIT_SIZE_M128I )
{
xmminput[0] = _mm_xor_si128( longoutput[i ], xmminput[0] );
xmminput[1] = _mm_xor_si128( longoutput[i+1], xmminput[1] );
xmminput[2] = _mm_xor_si128( longoutput[i+2], xmminput[2] );
xmminput[3] = _mm_xor_si128( longoutput[i+3], xmminput[3] );
xmminput[4] = _mm_xor_si128( longoutput[i+4], xmminput[4] );
xmminput[5] = _mm_xor_si128( longoutput[i+5], xmminput[5] );
xmminput[6] = _mm_xor_si128( longoutput[i+6], xmminput[6] );
xmminput[7] = _mm_xor_si128( longoutput[i+7], xmminput[7] );
for( j = 0; j < 10; j++ )
{
xmminput[0] = _mm_aesenc_si128( xmminput[0], expkey[j] );
xmminput[1] = _mm_aesenc_si128( xmminput[1], expkey[j] );
xmminput[2] = _mm_aesenc_si128( xmminput[2], expkey[j] );
xmminput[3] = _mm_aesenc_si128( xmminput[3], expkey[j] );
xmminput[4] = _mm_aesenc_si128( xmminput[4], expkey[j] );
xmminput[5] = _mm_aesenc_si128( xmminput[5], expkey[j] );
xmminput[6] = _mm_aesenc_si128( xmminput[6], expkey[j] );
xmminput[7] = _mm_aesenc_si128( xmminput[7], expkey[j] );
}
}
memcpy( ctx.state.init, ctx.text, INIT_SIZE_BYTE);
keccakf( (uint64_t*)&ctx.state.hs.w, 24 );
extra_hashes[ctx.state.hs.b[0] & 3](&ctx.state, 200, output);
#endif
}

View File

@@ -42,7 +42,7 @@ extern "C"{
#endif
#include <stddef.h>
#include "algo/sha3/sph_types.h"
#include "algo/sha/sph_types.h"
/**
* Output size (in bits) for CubeHash-224.

View File

@@ -9,11 +9,7 @@
#include <immintrin.h>
#endif
#include "cubehash_sse2.h"
#include "algo/sha3/sha3-defs.h"
//enum { SUCCESS = 0, FAIL = 1, BAD_HASHBITLEN = 2 };
//#if defined(OPTIMIZE_SSE2)
#include "algo/sha/sha3-defs.h"
static void transform( cubehashParam *sp )
{
@@ -143,72 +139,71 @@ int cubehashInit(cubehashParam *sp, int hashbitlen, int rounds, int blockbytes)
if ( blockbytes <= 0 || blockbytes >= 256)
blockbytes = CUBEHASH_BLOCKBYTES;
sp->hashbitlen = hashbitlen;
sp->rounds = rounds;
sp->blockbytes = blockbytes;
// all sizes of __m128i
sp->hashlen = hashbitlen/128;
sp->blocksize = blockbytes/16;
sp->rounds = rounds;
sp->pos = 0;
for ( i = 0; i < 8; ++i )
sp->x[i] = _mm_set_epi32(0, 0, 0, 0);
sp->x[0] = _mm_set_epi32(0, sp->rounds, sp->blockbytes, hashbitlen / 8);
sp->x[0] = _mm_set_epi32( 0, rounds, blockbytes, hashbitlen / 8 );
for ( i = 0; i < 10; ++i )
transform(sp);
sp->pos = 0;
// sp->pos = 0;
return SUCCESS;
}
int
cubehashReset(cubehashParam *sp)
{
return cubehashInit(sp, sp->hashbitlen, sp->rounds, sp->blockbytes);
}
int cubehashUpdate( cubehashParam *sp, const byte *data, size_t size )
{
uint64_t databitlen = 8 * size;
const int len = size / 16;
const __m128i* in = (__m128i*)data;
int i;
/* caller promises us that previous data had integral number of bytes */
/* so sp->pos is a multiple of 8 */
// It is assumed data is aligned to 256 bits and is a multiple of 128 bits.
// Current usage sata is either 64 or 80 bytes.
while ( databitlen >= 8 )
for ( i = 0; i < len; i++ )
{
( (unsigned char *)sp->x )[sp->pos/8] ^= *data;
data += 1;
databitlen -= 8;
sp->pos += 8;
if ( sp->pos == 8 * sp->blockbytes )
sp->x[ sp->pos ] = _mm_xor_si128( sp->x[ sp->pos ], in[i] );
sp->pos++;
if ( sp->pos == sp->blocksize )
{
transform( sp );
sp->pos = 0;
}
}
if ( databitlen > 0 )
{
( (unsigned char *)sp->x )[sp->pos/8] ^= *data;
sp->pos += databitlen;
transform( sp );
sp->pos = 0;
}
}
return SUCCESS;
}
int cubehashDigest( cubehashParam *sp, byte *digest )
{
__m128i* hash = (__m128i*)digest;
int i;
( (unsigned char *)sp->x )[sp->pos/8] ^= ( 128 >> (sp->pos % 8) );
transform(sp);
// pos is zero for 64 byte data, 1 for 80 byte data.
sp->x[ sp->pos ] = _mm_xor_si128( sp->x[ sp->pos ],
_mm_set_epi8( 0,0,0,0, 0,0,0,0,
0,0,0,0, 0,0,0,0x80 ) );
transform( sp );
sp->x[7] = _mm_xor_si128(sp->x[7], _mm_set_epi32(1, 0, 0, 0));
transform(sp);
transform(sp);
transform(sp);
transform(sp);
transform(sp);
transform(sp);
transform(sp);
transform(sp);
transform(sp);
transform(sp);
sp->x[7] = _mm_xor_si128( sp->x[7], _mm_set_epi32( 1,0,0,0 ) );
transform( sp );
transform( sp );
transform( sp );
transform( sp );
transform( sp );
transform( sp );
transform( sp );
transform( sp );
transform( sp );
transform( sp );
for ( i = 0; i < sp->hashbitlen / 8; ++i )
digest[i] = ((unsigned char *) sp->x)[i];
for ( i = 0; i < sp->hashlen; i++ )
hash[i] = sp->x[i];
return SUCCESS;
}
@@ -216,48 +211,45 @@ int cubehashDigest( cubehashParam *sp, byte *digest )
int cubehashUpdateDigest( cubehashParam *sp, byte *digest,
const byte *data, size_t size )
{
uint64_t databitlen = 8 * size;
int hashlen128 = sp->hashbitlen/128;
const int len = size / 16;
const __m128i* in = (__m128i*)data;
__m128i* hash = (__m128i*)digest;
int i;
/* caller promises us that previous data had integral number of bytes */
/* so sp->pos is a multiple of 8 */
// It is assumed data is aligned to 256 bits and is a multiple of 128 bits.
// Current usage sata is either 64 or 80 bytes.
while ( databitlen >= 8 )
for ( i = 0; i < len; i++ )
{
( (unsigned char *)sp->x )[sp->pos/8] ^= *data;
data += 1;
databitlen -= 8;
sp->pos += 8;
if ( sp->pos == 8 * sp->blockbytes )
sp->x[ sp->pos ] = _mm_xor_si128( sp->x[ sp->pos ], in[i] );
sp->pos++;
if ( sp->pos == sp->blocksize )
{
transform(sp);
sp->pos = 0;
transform( sp );
sp->pos = 0;
}
}
if ( databitlen > 0 )
{
( (unsigned char *)sp->x )[sp->pos/8] ^= *data;
sp->pos += databitlen;
}
( (unsigned char *)sp->x )[sp->pos/8] ^= ( 128 >> (sp->pos % 8) );
// pos is zero for 64 byte data, 1 for 80 byte data.
sp->x[ sp->pos ] = _mm_xor_si128( sp->x[ sp->pos ],
_mm_set_epi8( 0,0,0,0, 0,0,0,0,
0,0,0,0, 0,0,0,0x80 ) );
transform( sp );
sp->x[7] = _mm_xor_si128( sp->x[7], _mm_set_epi32(1,0,0,0) );
transform(sp);
transform(sp);
transform(sp);
transform(sp);
transform(sp);
transform(sp);
transform(sp);
transform(sp);
transform(sp);
transform(sp);
sp->x[7] = _mm_xor_si128( sp->x[7], _mm_set_epi32( 1,0,0,0 ) );
transform( sp );
transform( sp );
transform( sp );
transform( sp );
transform( sp );
transform( sp );
transform( sp );
transform( sp );
transform( sp );
transform( sp );
for ( i = 0; i < hashlen128; i++ )
( (__m128i*)digest )[i] = ( (__m128i*)sp->x )[i];
for ( i = 0; i < sp->hashlen; i++ )
hash[i] = sp->x[i];
return SUCCESS;
}

View File

@@ -3,58 +3,35 @@
#include "compat.h"
#include <stdint.h>
#include "algo/sha3/sha3-defs.h"
//#include <beecrypt/beecrypt.h>
#include "algo/sha/sha3-defs.h"
//#if defined(__SSE2__)
#define OPTIMIZE_SSE2
//#endif
#if defined(OPTIMIZE_SSE2)
#include <emmintrin.h>
#endif
/*!\brief Holds all the parameters necessary for the CUBEHASH algorithm.
* \ingroup HASH_cubehash_m
*/
struct _cubehashParam
//#endif
{
int hashbitlen;
int hashlen; // __m128i
int rounds;
int blockbytes;
int pos; /* number of bits read into x from current block */
#if defined(OPTIMIZE_SSE2)
__m128i _ALIGN(256) x[8];
#else
uint32_t x[32];
#endif
int blocksize; // __m128i
int pos; // number of __m128i read into x from current block
__m128i _ALIGN(256) x[8]; // aligned for __m256i
};
//#ifndef __cplusplus
typedef struct _cubehashParam cubehashParam;
//#endif
#ifdef __cplusplus
extern "C" {
#endif
/*!\var cubehash256
* \brief Holds the full API description of the CUBEHASH algorithm.
*/
//extern BEECRYPTAPI const hashFunction cubehash256;
//BEECRYPTAPI
int cubehashInit(cubehashParam* sp, int hashbitlen, int rounds, int blockbytes);
//BEECRYPTAPI
int cubehashReset(cubehashParam* sp);
//BEECRYPTAPI
int cubehashUpdate(cubehashParam* sp, const byte *data, size_t size);
//BEECRYPTAPI
int cubehashDigest(cubehashParam* sp, byte *digest);
int cubehashUpdateDigest( cubehashParam *sp, byte *digest, const byte *data,

View File

@@ -245,8 +245,6 @@ bool register_drop_algo( algo_gate_t* gate )
algo_not_tested();
gate->scanhash = (void*)&scanhash_drop;
gate->hash = (void*)&droplp_hash_pok;
gate->hash_alt = (void*)&droplp_hash_pok;
gate->hash_suw = (void*)&droplp_hash_pok;
gate->get_new_work = (void*)&drop_get_new_work;
gate->set_target = (void*)&scrypt_set_target;
gate->build_stratum_request = (void*)&std_be_build_stratum_request;

View File

@@ -22,7 +22,7 @@
#endif
#include "algo/sha3/sha3_common.h"
#include "algo/sha/sha3_common.h"
#include <emmintrin.h>

View File

@@ -16,7 +16,7 @@
#ifndef VPERM_H
#define VPERM_H
#include "algo/sha3/sha3_common.h"
#include "algo/sha/sha3_common.h"
#include <tmmintrin.h>
/*

View File

@@ -71,7 +71,7 @@ extern "C"{
#endif
#define AES_BIG_ENDIAN 0
#include "algo/sha3/aes_helper.c"
#include "algo/sha/aes_helper.c"
#if SPH_ECHO_64

View File

@@ -41,7 +41,7 @@ extern "C"{
#endif
#include <stddef.h>
#include "algo/sha3/sph_types.h"
#include "algo/sha/sph_types.h"
/**
* Output size (in bits) for ECHO-224.

View File

@@ -41,7 +41,7 @@ extern "C"{
#endif
#include <stddef.h>
#include "algo/sha3/sph_types.h"
#include "algo/sha/sph_types.h"
/**
* Output size (in bits) for ECHO-224.

View File

@@ -131,7 +131,6 @@ bool register_fresh_algo( algo_gate_t* gate )
algo_not_tested();
gate->scanhash = (void*)&scanhash_fresh;
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;

View File

@@ -2,7 +2,7 @@
#define SPH_FUGUE_H__
#include <stddef.h>
#include "algo/sha3/sph_types.h"
#include "algo/sha/sph_types.h"
#ifdef __cplusplus
extern "C"{

View File

@@ -41,7 +41,7 @@ extern "C"{
#endif
#include <stddef.h>
#include "algo/sha3/sph_types.h"
#include "algo/sha/sph_types.h"
/**
* Output size (in bits) for GOST-256.

View File

@@ -13,8 +13,8 @@
/* global constants */
__m128i ROUND_CONST_Lx;
__m128i ROUND_CONST_L0[ROUNDS512];
__m128i ROUND_CONST_L7[ROUNDS512];
//__m128i ROUND_CONST_L0[ROUNDS512];
//__m128i ROUND_CONST_L7[ROUNDS512];
__m128i ROUND_CONST_P[ROUNDS1024];
__m128i ROUND_CONST_Q[ROUNDS1024];
__m128i TRANSP_MASK;
@@ -22,11 +22,9 @@ __m128i SUBSH_MASK[8];
__m128i ALL_1B;
__m128i ALL_FF;
#define tos(a) #a
#define tostr(a) tos(a)
/* xmm[i] will be multiplied by 2
* xmm[j] will be lost
* xmm[k] has to be all 0x1b */
@@ -153,352 +151,6 @@ __m128i ALL_FF;
b1 = _mm_xor_si128(b1, a4);\
}/*MixBytes*/
#if (LENGTH <= 256)
#define SET_CONSTANTS(){\
ALL_1B = _mm_set_epi32(0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b);\
TRANSP_MASK = _mm_set_epi32(0x0f070b03, 0x0e060a02, 0x0d050901, 0x0c040800);\
SUBSH_MASK[0] = _mm_set_epi32(0x03060a0d, 0x08020509, 0x0c0f0104, 0x070b0e00);\
SUBSH_MASK[1] = _mm_set_epi32(0x04070c0f, 0x0a03060b, 0x0e090205, 0x000d0801);\
SUBSH_MASK[2] = _mm_set_epi32(0x05000e09, 0x0c04070d, 0x080b0306, 0x010f0a02);\
SUBSH_MASK[3] = _mm_set_epi32(0x0601080b, 0x0e05000f, 0x0a0d0407, 0x02090c03);\
SUBSH_MASK[4] = _mm_set_epi32(0x0702090c, 0x0f060108, 0x0b0e0500, 0x030a0d04);\
SUBSH_MASK[5] = _mm_set_epi32(0x00030b0e, 0x0907020a, 0x0d080601, 0x040c0f05);\
SUBSH_MASK[6] = _mm_set_epi32(0x01040d08, 0x0b00030c, 0x0f0a0702, 0x050e0906);\
SUBSH_MASK[7] = _mm_set_epi32(0x02050f0a, 0x0d01040e, 0x090c0003, 0x06080b07);\
for(i = 0; i < ROUNDS512; i++)\
{\
ROUND_CONST_L0[i] = _mm_set_epi32(0xffffffff, 0xffffffff, 0x70605040 ^ (i * 0x01010101), 0x30201000 ^ (i * 0x01010101));\
ROUND_CONST_L7[i] = _mm_set_epi32(0x8f9fafbf ^ (i * 0x01010101), 0xcfdfefff ^ (i * 0x01010101), 0x00000000, 0x00000000);\
}\
ROUND_CONST_Lx = _mm_set_epi32(0xffffffff, 0xffffffff, 0x00000000, 0x00000000);\
}while(0); \
/* one round
* i = round number
* a0-a7 = input rows
* b0-b7 = output rows
*/
#define ROUND(i, a0, a1, a2, a3, a4, a5, a6, a7, b0, b1, b2, b3, b4, b5, b6, b7){\
/* AddRoundConstant */\
b1 = ROUND_CONST_Lx;\
a0 = _mm_xor_si128(a0, (ROUND_CONST_L0[i]));\
a1 = _mm_xor_si128(a1, b1);\
a2 = _mm_xor_si128(a2, b1);\
a3 = _mm_xor_si128(a3, b1);\
a4 = _mm_xor_si128(a4, b1);\
a5 = _mm_xor_si128(a5, b1);\
a6 = _mm_xor_si128(a6, b1);\
a7 = _mm_xor_si128(a7, (ROUND_CONST_L7[i]));\
\
/* ShiftBytes + SubBytes (interleaved) */\
b0 = _mm_xor_si128(b0, b0);\
a0 = _mm_shuffle_epi8(a0, (SUBSH_MASK[0]));\
a0 = _mm_aesenclast_si128(a0, b0);\
a1 = _mm_shuffle_epi8(a1, (SUBSH_MASK[1]));\
a1 = _mm_aesenclast_si128(a1, b0);\
a2 = _mm_shuffle_epi8(a2, (SUBSH_MASK[2]));\
a2 = _mm_aesenclast_si128(a2, b0);\
a3 = _mm_shuffle_epi8(a3, (SUBSH_MASK[3]));\
a3 = _mm_aesenclast_si128(a3, b0);\
a4 = _mm_shuffle_epi8(a4, (SUBSH_MASK[4]));\
a4 = _mm_aesenclast_si128(a4, b0);\
a5 = _mm_shuffle_epi8(a5, (SUBSH_MASK[5]));\
a5 = _mm_aesenclast_si128(a5, b0);\
a6 = _mm_shuffle_epi8(a6, (SUBSH_MASK[6]));\
a6 = _mm_aesenclast_si128(a6, b0);\
a7 = _mm_shuffle_epi8(a7, (SUBSH_MASK[7]));\
a7 = _mm_aesenclast_si128(a7, b0);\
\
/* MixBytes */\
MixBytes(a0, a1, a2, a3, a4, a5, a6, a7, b0, b1, b2, b3, b4, b5, b6, b7);\
\
}
/* 10 rounds, P and Q in parallel */
#define ROUNDS_P_Q(){\
ROUND(0, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7);\
ROUND(1, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15);\
ROUND(2, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7);\
ROUND(3, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15);\
ROUND(4, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7);\
ROUND(5, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15);\
ROUND(6, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7);\
ROUND(7, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15);\
ROUND(8, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7);\
ROUND(9, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15);\
}
/* Matrix Transpose Step 1
* input is a 512-bit state with two columns in one xmm
* output is a 512-bit state with two rows in one xmm
* inputs: i0-i3
* outputs: i0, o1-o3
* clobbers: t0
*/
#define Matrix_Transpose_A(i0, i1, i2, i3, o1, o2, o3, t0){\
t0 = TRANSP_MASK;\
\
i0 = _mm_shuffle_epi8(i0, t0);\
i1 = _mm_shuffle_epi8(i1, t0);\
i2 = _mm_shuffle_epi8(i2, t0);\
i3 = _mm_shuffle_epi8(i3, t0);\
\
o1 = i0;\
t0 = i2;\
\
i0 = _mm_unpacklo_epi16(i0, i1);\
o1 = _mm_unpackhi_epi16(o1, i1);\
i2 = _mm_unpacklo_epi16(i2, i3);\
t0 = _mm_unpackhi_epi16(t0, i3);\
\
i0 = _mm_shuffle_epi32(i0, 216);\
o1 = _mm_shuffle_epi32(o1, 216);\
i2 = _mm_shuffle_epi32(i2, 216);\
t0 = _mm_shuffle_epi32(t0, 216);\
\
o2 = i0;\
o3 = o1;\
\
i0 = _mm_unpacklo_epi32(i0, i2);\
o1 = _mm_unpacklo_epi32(o1, t0);\
o2 = _mm_unpackhi_epi32(o2, i2);\
o3 = _mm_unpackhi_epi32(o3, t0);\
}/**/
/* Matrix Transpose Step 2
* input are two 512-bit states with two rows in one xmm
* output are two 512-bit states with one row of each state in one xmm
* inputs: i0-i3 = P, i4-i7 = Q
* outputs: (i0, o1-o7) = (P|Q)
* possible reassignments: (output reg = input reg)
* * i1 -> o3-7
* * i2 -> o5-7
* * i3 -> o7
* * i4 -> o3-7
* * i5 -> o6-7
*/
#define Matrix_Transpose_B(i0, i1, i2, i3, i4, i5, i6, i7, o1, o2, o3, o4, o5, o6, o7){\
o1 = i0;\
o2 = i1;\
i0 = _mm_unpacklo_epi64(i0, i4);\
o1 = _mm_unpackhi_epi64(o1, i4);\
o3 = i1;\
o4 = i2;\
o2 = _mm_unpacklo_epi64(o2, i5);\
o3 = _mm_unpackhi_epi64(o3, i5);\
o5 = i2;\
o6 = i3;\
o4 = _mm_unpacklo_epi64(o4, i6);\
o5 = _mm_unpackhi_epi64(o5, i6);\
o7 = i3;\
o6 = _mm_unpacklo_epi64(o6, i7);\
o7 = _mm_unpackhi_epi64(o7, i7);\
}/**/
/* Matrix Transpose Inverse Step 2
* input are two 512-bit states with one row of each state in one xmm
* output are two 512-bit states with two rows in one xmm
* inputs: i0-i7 = (P|Q)
* outputs: (i0, i2, i4, i6) = P, (o0-o3) = Q
*/
#define Matrix_Transpose_B_INV(i0, i1, i2, i3, i4, i5, i6, i7, o0, o1, o2, o3){\
o0 = i0;\
i0 = _mm_unpacklo_epi64(i0, i1);\
o0 = _mm_unpackhi_epi64(o0, i1);\
o1 = i2;\
i2 = _mm_unpacklo_epi64(i2, i3);\
o1 = _mm_unpackhi_epi64(o1, i3);\
o2 = i4;\
i4 = _mm_unpacklo_epi64(i4, i5);\
o2 = _mm_unpackhi_epi64(o2, i5);\
o3 = i6;\
i6 = _mm_unpacklo_epi64(i6, i7);\
o3 = _mm_unpackhi_epi64(o3, i7);\
}/**/
/* Matrix Transpose Output Step 2
* input is one 512-bit state with two rows in one xmm
* output is one 512-bit state with one row in the low 64-bits of one xmm
* inputs: i0,i2,i4,i6 = S
* outputs: (i0-7) = (0|S)
*/
#define Matrix_Transpose_O_B(i0, i1, i2, i3, i4, i5, i6, i7, t0){\
t0 = _mm_xor_si128(t0, t0);\
i1 = i0;\
i3 = i2;\
i5 = i4;\
i7 = i6;\
i0 = _mm_unpacklo_epi64(i0, t0);\
i1 = _mm_unpackhi_epi64(i1, t0);\
i2 = _mm_unpacklo_epi64(i2, t0);\
i3 = _mm_unpackhi_epi64(i3, t0);\
i4 = _mm_unpacklo_epi64(i4, t0);\
i5 = _mm_unpackhi_epi64(i5, t0);\
i6 = _mm_unpacklo_epi64(i6, t0);\
i7 = _mm_unpackhi_epi64(i7, t0);\
}/**/
/* Matrix Transpose Output Inverse Step 2
* input is one 512-bit state with one row in the low 64-bits of one xmm
* output is one 512-bit state with two rows in one xmm
* inputs: i0-i7 = (0|S)
* outputs: (i0, i2, i4, i6) = S
*/
#define Matrix_Transpose_O_B_INV(i0, i1, i2, i3, i4, i5, i6, i7){\
i0 = _mm_unpacklo_epi64(i0, i1);\
i2 = _mm_unpacklo_epi64(i2, i3);\
i4 = _mm_unpacklo_epi64(i4, i5);\
i6 = _mm_unpacklo_epi64(i6, i7);\
endif\
}/**/
void INIT(u64* h)
{
__m128i* const chaining = (__m128i*) h;
static __m128i xmm0, /*xmm1,*/ xmm2, /*xmm3, xmm4, xmm5,*/ xmm6, xmm7;
static __m128i /*xmm8, xmm9, xmm10, xmm11,*/ xmm12, xmm13, xmm14, xmm15;
/* load IV into registers xmm12 - xmm15 */
xmm12 = chaining[0];
xmm13 = chaining[1];
xmm14 = chaining[2];
xmm15 = chaining[3];
/* transform chaining value from column ordering into row ordering */
/* we put two rows (64 bit) of the IV into one 128-bit XMM register */
Matrix_Transpose_A(xmm12, xmm13, xmm14, xmm15, xmm2, xmm6, xmm7, xmm0);
/* store transposed IV */
chaining[0] = xmm12;
chaining[1] = xmm2;
chaining[2] = xmm6;
chaining[3] = xmm7;
}
void TF512(u64* h, u64* m)
{
__m128i* const chaining = (__m128i*) h;
__m128i* const message = (__m128i*) m;
static __m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7;
static __m128i xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15;
static __m128i TEMP0;
static __m128i TEMP1;
static __m128i TEMP2;
#ifdef IACA_TRACE
IACA_START;
#endif
/* load message into registers xmm12 - xmm15 */
xmm12 = message[0];
xmm13 = message[1];
xmm14 = message[2];
xmm15 = message[3];
/* transform message M from column ordering into row ordering */
/* we first put two rows (64 bit) of the message into one 128-bit xmm register */
Matrix_Transpose_A(xmm12, xmm13, xmm14, xmm15, xmm2, xmm6, xmm7, xmm0);
/* load previous chaining value */
/* we first put two rows (64 bit) of the CV into one 128-bit xmm register */
xmm8 = chaining[0];
xmm0 = chaining[1];
xmm4 = chaining[2];
xmm5 = chaining[3];
/* xor message to CV get input of P */
/* result: CV+M in xmm8, xmm0, xmm4, xmm5 */
xmm8 = _mm_xor_si128(xmm8, xmm12);
xmm0 = _mm_xor_si128(xmm0, xmm2);
xmm4 = _mm_xor_si128(xmm4, xmm6);
xmm5 = _mm_xor_si128(xmm5, xmm7);
/* there are now 2 rows of the Groestl state (P and Q) in each xmm register */
/* unpack to get 1 row of P (64 bit) and Q (64 bit) into one xmm register */
/* result: the 8 rows of P and Q in xmm8 - xmm12 */
Matrix_Transpose_B(xmm8, xmm0, xmm4, xmm5, xmm12, xmm2, xmm6, xmm7, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15);
/* compute the two permutations P and Q in parallel */
ROUNDS_P_Q();
/* unpack again to get two rows of P or two rows of Q in one xmm register */
Matrix_Transpose_B_INV(xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, xmm0, xmm1, xmm2, xmm3);
/* xor output of P and Q */
/* result: P(CV+M)+Q(M) in xmm0...xmm3 */
xmm0 = _mm_xor_si128(xmm0, xmm8);
xmm1 = _mm_xor_si128(xmm1, xmm10);
xmm2 = _mm_xor_si128(xmm2, xmm12);
xmm3 = _mm_xor_si128(xmm3, xmm14);
/* xor CV (feed-forward) */
/* result: P(CV+M)+Q(M)+CV in xmm0...xmm3 */
xmm0 = _mm_xor_si128(xmm0, (chaining[0]));
xmm1 = _mm_xor_si128(xmm1, (chaining[1]));
xmm2 = _mm_xor_si128(xmm2, (chaining[2]));
xmm3 = _mm_xor_si128(xmm3, (chaining[3]));
/* store CV */
chaining[0] = xmm0;
chaining[1] = xmm1;
chaining[2] = xmm2;
chaining[3] = xmm3;
#ifdef IACA_TRACE
IACA_END;
#endif
return;
}
void OF512(u64* h)
{
__m128i* const chaining = (__m128i*) h;
static __m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7;
static __m128i xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15;
static __m128i TEMP0;
static __m128i TEMP1;
static __m128i TEMP2;
/* load CV into registers xmm8, xmm10, xmm12, xmm14 */
xmm8 = chaining[0];
xmm10 = chaining[1];
xmm12 = chaining[2];
xmm14 = chaining[3];
/* there are now 2 rows of the CV in one xmm register */
/* unpack to get 1 row of P (64 bit) into one half of an xmm register */
/* result: the 8 input rows of P in xmm8 - xmm15 */
Matrix_Transpose_O_B(xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, xmm0);
/* compute the permutation P */
/* result: the output of P(CV) in xmm8 - xmm15 */
ROUNDS_P_Q();
/* unpack again to get two rows of P in one xmm register */
/* result: P(CV) in xmm8, xmm10, xmm12, xmm14 */
Matrix_Transpose_O_B_INV(xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15);
/* xor CV to P output (feed-forward) */
/* result: P(CV)+CV in xmm8, xmm10, xmm12, xmm14 */
xmm8 = _mm_xor_si128(xmm8, (chaining[0]));
xmm10 = _mm_xor_si128(xmm10, (chaining[1]));
xmm12 = _mm_xor_si128(xmm12, (chaining[2]));
xmm14 = _mm_xor_si128(xmm14, (chaining[3]));
/* transform state back from row ordering into column ordering */
/* result: final hash value in xmm9, xmm11 */
Matrix_Transpose_A(xmm8, xmm10, xmm12, xmm14, xmm4, xmm9, xmm11, xmm0);
/* we only need to return the truncated half of the state */
chaining[2] = xmm9;
chaining[3] = xmm11;
}
#endif
#if (LENGTH > 256)
#define SET_CONSTANTS(){\
ALL_FF = _mm_set_epi32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);\
@@ -768,9 +420,8 @@ void OF512(u64* h)
}/**/
void INIT(u64* h)
void INIT( __m128i* chaining )
{
__m128i* const chaining = (__m128i*) h;
static __m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7;
static __m128i xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15;
@@ -798,10 +449,8 @@ void INIT(u64* h)
chaining[7] = xmm15;
}
void TF1024(u64* h, u64* m)
void TF1024( __m128i* chaining, const __m128i* message )
{
__m128i* const chaining = (__m128i*) h;
__m128i* const message = (__m128i*) m;
static __m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7;
static __m128i xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15;
static __m128i QTEMP[8];
@@ -914,9 +563,8 @@ void TF1024(u64* h, u64* m)
return;
}
void OF1024(u64* h)
void OF1024( __m128i* chaining )
{
__m128i* const chaining = (__m128i*) h;
static __m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7;
static __m128i xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15;
static __m128i TEMP0;
@@ -961,5 +609,3 @@ void OF1024(u64* h)
return;
}
#endif

View File

@@ -15,8 +15,8 @@
__m128i ROUND_CONST_Lx;
__m128i ROUND_CONST_L0[ROUNDS512];
__m128i ROUND_CONST_L7[ROUNDS512];
__m128i ROUND_CONST_P[ROUNDS1024];
__m128i ROUND_CONST_Q[ROUNDS1024];
//__m128i ROUND_CONST_P[ROUNDS1024];
//__m128i ROUND_CONST_Q[ROUNDS1024];
__m128i TRANSP_MASK;
__m128i SUBSH_MASK[8];
__m128i ALL_1B;
@@ -351,9 +351,8 @@ __m128i ALL_FF;
}/**/
void INIT256(u64* h)
void INIT256( __m128i* chaining )
{
__m128i* const chaining = (__m128i*) h;
static __m128i xmm0, /*xmm1,*/ xmm2, /*xmm3, xmm4, xmm5,*/ xmm6, xmm7;
static __m128i /*xmm8, xmm9, xmm10, xmm11,*/ xmm12, xmm13, xmm14, xmm15;
@@ -374,10 +373,8 @@ void INIT256(u64* h)
chaining[3] = xmm7;
}
void TF512(u64* h, u64* m)
void TF512( __m128i* chaining, __m128i* message )
{
__m128i* const chaining = (__m128i*) h;
__m128i* const message = (__m128i*) m;
static __m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7;
static __m128i xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15;
static __m128i TEMP0;
@@ -449,9 +446,8 @@ void TF512(u64* h, u64* m)
return;
}
void OF512(u64* h)
void OF512( __m128i* chaining )
{
__m128i* const chaining = (__m128i*) h;
static __m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7;
static __m128i xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15;
static __m128i TEMP0;

View File

@@ -6,6 +6,9 @@
* This code is placed in the public domain
*/
// Optimized for hash and data length that are integrals of __m128i
#include <memory.h>
#include "hash-groestl.h"
#include "miner.h"
@@ -49,196 +52,191 @@
#endif
#endif
/* digest up to len bytes of input (full blocks only) */
void Transform( hashState_groestl *ctx, const u8 *in, unsigned long long len )
{
/* increment block counter */
ctx->block_counter += len/SIZE;
/* digest message, one block at a time */
for ( ; len >= SIZE; len -= SIZE, in += SIZE )
TF1024( (u64*)ctx->chaining, (u64*)in );
asm volatile ("emms");
}
/* given state h, do h <- P(h)+h */
void OutputTransformation( hashState_groestl *ctx )
{
/* determine variant */
OF1024( (u64*)ctx->chaining );
asm volatile ("emms");
}
/* initialise context */
HashReturn_gr init_groestl( hashState_groestl* ctx, int hashlen )
{
u8 i = 0;
int i;
ctx->hashlen = hashlen;
SET_CONSTANTS();
for ( i = 0; i < SIZE / 8; i++ )
ctx->chaining[i] = 0;
for ( i = 0; i < SIZE; i++ )
ctx->buffer[i] = 0;
if (ctx->chaining == NULL || ctx->buffer == NULL)
return FAIL_GR;
/* set initial value */
ctx->chaining[COLS-1] = U64BIG((u64)LENGTH);
for ( i = 0; i < SIZE512; i++ )
{
ctx->chaining[i] = _mm_setzero_si128();
ctx->buffer[i] = _mm_setzero_si128();
}
((u64*)ctx->chaining)[COLS-1] = U64BIG((u64)LENGTH);
INIT(ctx->chaining);
ctx->buf_ptr = 0;
ctx->block_counter = 0;
ctx->rem_ptr = 0;
return SUCCESS_GR;
}
/*
HashReturn_gr init_groestl( hashState_groestl* ctx )
{
return Xinit_groestl( ctx, 64 );
}
*/
HashReturn_gr reinit_groestl( hashState_groestl* ctx )
{
int i;
for ( i = 0; i < SIZE / 8; i++ )
ctx->chaining[i] = 0;
for ( i = 0; i < SIZE; i++ )
ctx->buffer[i] = 0;
if (ctx->chaining == NULL || ctx->buffer == NULL)
return FAIL_GR;
/* set initial value */
ctx->chaining[COLS-1] = U64BIG( (u64)LENGTH );
INIT( ctx->chaining );
for ( i = 0; i < SIZE512; i++ )
{
ctx->chaining[i] = _mm_setzero_si128();
ctx->buffer[i] = _mm_setzero_si128();
}
((u64*)ctx->chaining)[COLS-1] = U64BIG((u64)LENGTH);
INIT(ctx->chaining);
ctx->buf_ptr = 0;
ctx->block_counter = 0;
ctx->rem_ptr = 0;
return SUCCESS_GR;
}
//// midstate is broken
// To use midstate:
// 1. midstate must process all full blocks.
// 2. tail must be less than a full block and may not straddle a
// block boundary.
// 3. midstate and tail each must be multiples of 128 bits.
// 4. For best performance midstate length is a multiple of block size.
// 5. Midstate will work at reduced impact than full hash, if total hash
// (midstate + tail) is less than 1 block.
// This, unfortunately, is the case with all current users.
// 6. the morefull blocks the bigger the gain
/* update state with databitlen bits of input */
HashReturn_gr update_groestl( hashState_groestl* ctx,
const BitSequence_gr* input,
DataLength_gr databitlen )
// use only for midstate precalc
HashReturn_gr update_groestl( hashState_groestl* ctx, const void* input,
DataLength_gr databitlen )
{
int i;
const int msglen = (int)(databitlen/8);
__m128i* in = (__m128i*)input;
const int len = (int)databitlen / 128; // bits to __m128i
const int blocks = len / SIZE512; // __M128i to blocks
int rem = ctx->rem_ptr;
int i;
/* digest bulk of message */
Transform( ctx, input, msglen );
ctx->blk_count = blocks;
ctx->databitlen = databitlen;
/* store remaining data in buffer */
i = ( msglen / SIZE ) * SIZE;
while ( i < msglen )
ctx->buffer[(int)ctx->buf_ptr++] = input[i++];
// digest any full blocks
for ( i = 0; i < blocks; i++ )
TF1024( ctx->chaining, &in[ i * SIZE512 ] );
// adjust buf_ptr to last block
ctx->buf_ptr = blocks * SIZE512;
return SUCCESS_GR;
// copy any remaining data to buffer for final hash, it may already
// contain data from a previous update for a midstate precalc
for ( i = 0; i < len % SIZE512; i++ )
ctx->buffer[ rem + i ] = in[ ctx->buf_ptr + i ];
// adjust rem_ptr for possible new data
ctx->rem_ptr += i;
return SUCCESS_GR;
}
/* finalise: process remaining data (including padding), perform
output transformation, and write hash result to 'output' */
HashReturn_gr final_groestl( hashState_groestl* ctx,
BitSequence_gr* output )
// deprecated do not use
HashReturn_gr final_groestl( hashState_groestl* ctx, void* output )
{
int i, j;
const int len = (int)ctx->databitlen / 128; // bits to __m128i
const int blocks = ctx->blk_count + 1; // adjust for final block
ctx->buffer[(int)ctx->buf_ptr++] = 0x80;
/* pad with '0'-bits */
if ( ctx->buf_ptr > SIZE - LENGTHFIELDLEN )
{
/* padding requires two blocks */
while ( ctx->buf_ptr < SIZE )
ctx->buffer[(int)ctx->buf_ptr++] = 0;
/* digest first padding block */
Transform( ctx, ctx->buffer, SIZE );
ctx->buf_ptr = 0;
}
const int rem_ptr = ctx->rem_ptr; // end of data start of padding
const int hashlen_m128i = ctx->hashlen / 16; // bytes to __m128i
const int hash_offset = SIZE512 - hashlen_m128i; // where in buffer
int i;
// this will pad up to 120 bytes
while ( ctx->buf_ptr < SIZE - LENGTHFIELDLEN )
ctx->buffer[(int)ctx->buf_ptr++] = 0;
// first pad byte = 0x80, last pad byte = block count
// everything in between is zero
/* length padding */
ctx->block_counter++;
ctx->buf_ptr = SIZE;
while ( ctx->buf_ptr > SIZE - LENGTHFIELDLEN )
{
ctx->buffer[(int)--ctx->buf_ptr] = (u8)ctx->block_counter;
ctx->block_counter >>= 8;
}
if ( rem_ptr == len - 1 )
{
// only 128 bits left in buffer, all padding at once
ctx->buffer[rem_ptr] = _mm_set_epi8( blocks,0,0,0, 0,0,0,0,
0,0,0,0, 0,0,0,0x80 );
}
else
{
// add first padding
ctx->buffer[rem_ptr] = _mm_set_epi8( 0,0,0,0, 0,0,0,0,
0,0,0,0, 0,0,0,0x80 );
// add zero padding
for ( i = rem_ptr + 1; i < SIZE512 - 1; i++ )
ctx->buffer[i] = _mm_setzero_si128();
/* digest final padding block */
Transform( ctx, ctx->buffer, SIZE );
/* perform output transformation */
OutputTransformation( ctx );
// add length padding, second last byte is zero unless blocks > 255
ctx->buffer[i] = _mm_set_epi8( blocks, blocks>>8, 0,0, 0,0,0,0,
0, 0 ,0,0, 0,0,0,0 );
}
// store hash result in output
for ( i = ( SIZE - ctx->hashlen) / 16, j = 0; i < SIZE / 16; i++, j++ )
casti_m128i( output, j ) = casti_m128i( ctx->chaining , i );
// digest final padding block and do output transform
TF1024( ctx->chaining, ctx->buffer );
OF1024( ctx->chaining );
return SUCCESS_GR;
// store hash result in output
for ( i = 0; i < hashlen_m128i; i++ )
casti_m128i( output, i ) = ctx->chaining[ hash_offset + i];
return SUCCESS_GR;
}
HashReturn_gr update_and_final_groestl( hashState_groestl* ctx,
BitSequence_gr* output, const BitSequence_gr* input,
DataLength_gr databitlen )
HashReturn_gr update_and_final_groestl( hashState_groestl* ctx, void* output,
const void* input, DataLength_gr databitlen )
{
const int inlen = (int)(databitlen/8); // need bytes
int i, j;
const int len = (int)databitlen / 128;
const int hashlen_m128i = ctx->hashlen / 16; // bytes to __m128i
const int hash_offset = SIZE512 - hashlen_m128i;
int rem = ctx->rem_ptr;
int blocks = len / SIZE512;
__m128i* in = (__m128i*)input;
int i;
/* digest bulk of message */
Transform( ctx, input, inlen );
// --- update ---
/* store remaining data in buffer */
i = ( inlen / SIZE ) * SIZE;
while ( i < inlen )
ctx->buffer[(int)ctx->buf_ptr++] = input[i++];
// digest any full blocks, process directly from input
for ( i = 0; i < blocks; i++ )
TF1024( ctx->chaining, &in[ i * SIZE512 ] );
ctx->buf_ptr = blocks * SIZE512;
// start of final
// copy any remaining data to buffer, it may already contain data
// from a previous update for a midstate precalc
for ( i = 0; i < len % SIZE512; i++ )
ctx->buffer[ rem + i ] = in[ ctx->buf_ptr + i ];
i += rem; // use i as rem_ptr in final
ctx->buffer[(int)ctx->buf_ptr++] = 0x80;
//--- final ---
/* pad with '0'-bits */
if ( ctx->buf_ptr > SIZE - LENGTHFIELDLEN )
{
/* padding requires two blocks */
while ( ctx->buf_ptr < SIZE )
ctx->buffer[(int)ctx->buf_ptr++] = 0;
memset( ctx->buffer + ctx->buf_ptr, 0, SIZE - ctx->buf_ptr );
/* digest first padding block */
Transform( ctx, ctx->buffer, SIZE );
ctx->buf_ptr = 0;
}
blocks++; // adjust for final block
// this will pad up to 120 bytes
memset( ctx->buffer + ctx->buf_ptr, 0, SIZE - ctx->buf_ptr - LENGTHFIELDLEN );
if ( i == len -1 )
{
// only 128 bits left in buffer, all padding at once
ctx->buffer[i] = _mm_set_epi8( blocks,0,0,0, 0,0,0,0,
0,0,0,0, 0,0,0,0x80 );
}
else
{
// add first padding
ctx->buffer[i] = _mm_set_epi8( 0,0,0,0, 0,0,0,0,
0,0,0,0, 0,0,0,0x80 );
// add zero padding
for ( i += 1; i < SIZE512 - 1; i++ )
ctx->buffer[i] = _mm_setzero_si128();
/* length padding */
ctx->block_counter++;
ctx->buf_ptr = SIZE;
while (ctx->buf_ptr > SIZE - LENGTHFIELDLEN)
{
ctx->buffer[(int)--ctx->buf_ptr] = (u8)ctx->block_counter;
ctx->block_counter >>= 8;
}
// add length padding, second last byte is zero unless blocks > 255
ctx->buffer[i] = _mm_set_epi8( blocks, blocks>>8, 0,0, 0,0,0,0,
0, 0 ,0,0, 0,0,0,0 );
}
/* digest final padding block */
Transform( ctx, ctx->buffer, SIZE );
/* perform output transformation */
OutputTransformation( ctx );
// digest final padding block and do output transform
TF1024( ctx->chaining, ctx->buffer );
OF1024( ctx->chaining );
// store hash result in output
for ( i = ( SIZE - ctx->hashlen) / 16, j = 0; i < SIZE / 16; i++, j++ )
casti_m128i( output, j ) = casti_m128i( ctx->chaining , i );
// store hash result in output
for ( i = 0; i < hashlen_m128i; i++ )
casti_m128i( output, i ) = ctx->chaining[ hash_offset + i ];
return SUCCESS_GR;
return SUCCESS_GR;
}
/* hash bit sequence */

View File

@@ -9,6 +9,8 @@
#ifndef __hash_h
#define __hash_h
#include <immintrin.h>
#include <stdio.h>
#if defined(_WIN64) || defined(__WINDOWS__)
#include <windows.h>
@@ -24,22 +26,22 @@
/* some sizes (number of bytes) */
#define ROWS (8)
#define LENGTHFIELDLEN (ROWS)
#define COLS512 (8)
//#define COLS512 (8)
#define COLS1024 (16)
#define SIZE512 ((ROWS)*(COLS512))
#define SIZE1024 ((ROWS)*(COLS1024))
#define ROUNDS512 (10)
//#define SIZE512 ((ROWS)*(COLS512))
#define SIZE_1024 ((ROWS)*(COLS1024))
//#define ROUNDS512 (10)
#define ROUNDS1024 (14)
#if LENGTH<=256
#define COLS (COLS512)
#define SIZE (SIZE512)
#define ROUNDS (ROUNDS512)
#else
//#if LENGTH<=256
//#define COLS (COLS512)
//#define SIZE (SIZE512)
//#define ROUNDS (ROUNDS512)
//#else
#define COLS (COLS1024)
#define SIZE (SIZE1024)
//#define SIZE (SIZE1024)
#define ROUNDS (ROUNDS1024)
#endif
//#endif
#define ROTL64(a,n) ((((a)<<(n))|((a)>>(64-(n))))&li_64(ffffffffffffffff))
@@ -61,31 +63,29 @@ typedef unsigned char BitSequence_gr;
typedef unsigned long long DataLength_gr;
typedef enum { SUCCESS_GR = 0, FAIL_GR = 1, BAD_HASHBITLEN_GR = 2} HashReturn_gr;
// Use area128 overlay for buffer to facilitate fast copying
#define SIZE512 (SIZE_1024/16)
typedef struct {
__attribute__ ((aligned (32))) u64 chaining[SIZE/8]; // actual state
__attribute__ ((aligned (32))) BitSequence_gr buffer[SIZE]; // data buffer
u64 block_counter; /* message block counter */
int hashlen; // bytes
int buf_ptr; /* data buffer pointer */
__attribute__ ((aligned (64))) __m128i chaining[SIZE512];
__attribute__ ((aligned (64))) __m128i buffer[SIZE512];
int hashlen; // byte
int blk_count; // SIZE_m128i
int buf_ptr; // __m128i offset
int rem_ptr;
int databitlen; // bits
} hashState_groestl;
//HashReturn_gr init_groestl( hashState_groestl* );
HashReturn_gr init_groestl( hashState_groestl*, int );
HashReturn_gr reinit_groestl( hashState_groestl* );
HashReturn_gr update_groestl( hashState_groestl*, const BitSequence_gr*,
HashReturn_gr update_groestl( hashState_groestl*, const void*,
DataLength_gr );
HashReturn_gr final_groestl( hashState_groestl*, BitSequence_gr* );
HashReturn_gr final_groestl( hashState_groestl*, void* );
HashReturn_gr hash_groestl( int, const BitSequence_gr*, DataLength_gr,
BitSequence_gr* );
HashReturn_gr update_and_final_groestl( hashState_groestl*,
BitSequence_gr*, const BitSequence_gr*, DataLength_gr );
HashReturn_gr update_and_final_groestl( hashState_groestl*, void*,
const void*, DataLength_gr );
#endif /* __hash_h */

View File

@@ -49,187 +49,201 @@
#endif
#endif
/* digest up to len bytes of input (full blocks only) */
void Transform256(hashState_groestl256 *ctx,
const u8 *in,
unsigned long long len) {
/* increment block counter */
ctx->block_counter += len/SIZE;
/* digest message, one block at a time */
for (; len >= SIZE; len -= SIZE, in += SIZE)
TF512((u64*)ctx->chaining, (u64*)in);
asm volatile ("emms");
}
/* given state h, do h <- P(h)+h */
void OutputTransformation256(hashState_groestl256 *ctx) {
/* determine variant */
OF512((u64*)ctx->chaining);
asm volatile ("emms");
}
/* initialise context */
HashReturn_gr init_groestl256( hashState_groestl256* ctx, int hashlen )
{
u8 i = 0;
int i;
ctx->hashlen = hashlen;
SET_CONSTANTS();
for (i=0; i<SIZE/8; i++)
ctx->chaining[i] = 0;
for (i=0; i<SIZE; i++)
ctx->buffer[i] = 0;
if (ctx->chaining == NULL || ctx->buffer == NULL)
return FAIL_GR;
/* set initial value */
ctx->chaining[COLS-1] = U64BIG((u64)256);
INIT256(ctx->chaining);
/* set other variables */
for ( i = 0; i < SIZE256; i++ )
{
ctx->chaining[i] = _mm_setzero_si128();
ctx->buffer[i] = _mm_setzero_si128();
}
((u64*)ctx->chaining)[COLS-1] = U64BIG((u64)LENGTH);
INIT256( ctx->chaining );
ctx->buf_ptr = 0;
ctx->block_counter = 0;
ctx->rem_ptr = 0;
return SUCCESS_GR;
}
HashReturn_gr reinit_groestl256(hashState_groestl256* ctx)
{
int i;
for (i=0; i<SIZE/8; i++)
ctx->chaining[i] = 0;
for (i=0; i<SIZE; i++)
ctx->buffer[i] = 0;
if (ctx->chaining == NULL || ctx->buffer == NULL)
return FAIL_GR;
/* set initial value */
ctx->chaining[COLS-1] = 256;
for ( i = 0; i < SIZE256; i++ )
{
ctx->chaining[i] = _mm_setzero_si128();
ctx->buffer[i] = _mm_setzero_si128();
}
((u64*)ctx->chaining)[COLS-1] = U64BIG((u64)LENGTH);
INIT256(ctx->chaining);
/* set other variables */
ctx->buf_ptr = 0;
ctx->block_counter = 0;
ctx->rem_ptr = 0;
return SUCCESS_GR;
}
HashReturn_gr update_groestl256( hashState_groestl256* ctx,
const BitSequence_gr* input, DataLength_gr databitlen )
// Use this only for midstate and never for cryptonight
HashReturn_gr update_groestl256( hashState_groestl256* ctx, const void* input,
DataLength_gr databitlen )
{
const int msglen = (int)(databitlen/8); // bytes
int i;
__m128i* in = (__m128i*)input;
const int len = (int)databitlen / 128; // bits to __m128i
const int blocks = len / SIZE256; // __M128i to blocks
int rem = ctx->rem_ptr;
int i;
/* digest bulk of message */
Transform256( ctx, input, msglen );
ctx->blk_count = blocks;
ctx->databitlen = databitlen;
/* store remaining data in buffer */
i = ( msglen / SIZE ) * SIZE;
while ( i < msglen )
ctx->buffer[(int)ctx->buf_ptr++] = input[i++];
// digest any full blocks
for ( i = 0; i < blocks; i++ )
TF512( ctx->chaining, &in[ i * SIZE256 ] );
// adjust buf_ptr to last block
ctx->buf_ptr = blocks * SIZE256;
return SUCCESS_GR;
// Copy any remainder to buffer
for ( i = 0; i < len % SIZE256; i++ )
ctx->buffer[ rem + i ] = in[ ctx->buf_ptr + i ];
// adjust rem_ptr for new data
ctx->rem_ptr += i;
return SUCCESS_GR;
}
HashReturn_gr final_groestl256( hashState_groestl256* ctx,
BitSequence_gr* output )
// don't use this at all
HashReturn_gr final_groestl256( hashState_groestl256* ctx, void* output )
{
ctx->buffer[(int)ctx->buf_ptr++] = 0x80;
const int len = (int)ctx->databitlen / 128; // bits to __m128i
const int blocks = ctx->blk_count + 1; // adjust for final block
const int rem_ptr = ctx->rem_ptr; // end of data start of padding
const int hashlen_m128i = ctx->hashlen / 16; // bytes to __m128i
const int hash_offset = SIZE256 - hashlen_m128i; // where in buffer
int i;
/* pad with '0'-bits */
if ( ctx->buf_ptr > SIZE - LENGTHFIELDLEN )
{
/* padding requires two blocks */
while ( ctx->buf_ptr < SIZE )
ctx->buffer[(int)ctx->buf_ptr++] = 0;
/* digest first padding block */
Transform256( ctx, ctx->buffer, SIZE );
ctx->buf_ptr = 0;
}
while ( ctx->buf_ptr < SIZE - LENGTHFIELDLEN )
ctx->buffer[(int)ctx->buf_ptr++] = 0;
// first pad byte = 0x80, last pad byte = block count
// everything in between is zero
/* length padding */
ctx->block_counter++;
ctx->buf_ptr = SIZE;
while ( ctx->buf_ptr > SIZE - LENGTHFIELDLEN )
{
ctx->buffer[(int)--ctx->buf_ptr] = (u8)ctx->block_counter;
ctx->block_counter >>= 8;
}
if ( rem_ptr == len - 1 )
{
// all padding at once
ctx->buffer[rem_ptr] = _mm_set_epi8( blocks,0,0,0, 0,0,0,0,
0,0,0,0, 0,0,0,0x80 );
}
else
{
// add first padding
ctx->buffer[rem_ptr] = _mm_set_epi8( 0,0,0,0, 0,0,0,0,
0,0,0,0, 0,0,0,0x80 );
// add zero padding
for ( i = rem_ptr + 1; i < SIZE256 - 1; i++ )
ctx->buffer[i] = _mm_setzero_si128();
// add length padding
// cheat since we know the block count is trivial, good if block < 256
ctx->buffer[i] = _mm_set_epi8( blocks,0,0,0, 0,0,0,0,
0,0,0,0, 0,0,0,0 );
}
/* digest final padding block */
Transform256( ctx, ctx->buffer, SIZE );
/* perform output transformation */
OutputTransformation256( ctx );
// digest final padding block and do output transform
TF512( ctx->chaining, ctx->buffer );
OF512( ctx->chaining );
/* store hash result in output */
for ( int i = ( (SIZE - ctx->hashlen) / 16 ), j = 0; i < SIZE/16; i++, j++ )
casti_m128i( output, j ) = casti_m128i( ctx->chaining, i );
// store hash result in output
for ( i = 0; i < hashlen_m128i; i++ )
casti_m128i( output, i ) = ctx->chaining[ hash_offset + i];
return SUCCESS_GR;
return SUCCESS_GR;
}
HashReturn_gr update_and_final_groestl256( hashState_groestl256* ctx,
BitSequence_gr* output, const BitSequence_gr* input,
DataLength_gr databitlen )
void* output, const void* input, DataLength_gr databitlen )
{
const int msglen = (int)(databitlen/8); // bytes
int i, j;
const int len = (int)databitlen / 128;
const int hashlen_m128i = ctx->hashlen / 16; // bytes to __m128i
const int hash_offset = SIZE256 - hashlen_m128i;
int rem = ctx->rem_ptr;
int blocks = len / SIZE256;
__m128i* in = (__m128i*)input;
int i;
/* digest bulk of message */
Transform256( ctx, input, msglen );
// --- update ---
/* store remaining data in buffer */
i = ( msglen / SIZE ) * SIZE;
while ( i < msglen )
ctx->buffer[(int)ctx->buf_ptr++] = input[i++];
// digest any full blocks, process directly from input
for ( i = 0; i < blocks; i++ )
TF512( ctx->chaining, &in[ i * SIZE256 ] );
ctx->buf_ptr = blocks * SIZE256;
// start of final
ctx->buffer[(int)ctx->buf_ptr++] = 0x80;
// cryptonight has 200 byte input, an odd number of __m128i
// remainder is only 8 bytes, ie u64.
if ( databitlen % 128 !=0 )
{
// must be cryptonight, copy 64 bits of data
*(uint64_t*)(ctx->buffer) = *(uint64_t*)(&in[ ctx->buf_ptr ] );
i = -1; // signal for odd length
}
else
{
// Copy any remaining data to buffer for final transform
for ( i = 0; i < len % SIZE256; i++ )
ctx->buffer[ rem + i ] = in[ ctx->buf_ptr + i ];
i += rem; // use i as rem_ptr in final
}
/* pad with '0'-bits */
if ( ctx->buf_ptr > SIZE - LENGTHFIELDLEN )
{
/* padding requires two blocks */
while ( ctx->buf_ptr < SIZE )
ctx->buffer[(int)ctx->buf_ptr++] = 0;
/* digest first padding block */
Transform256( ctx, ctx->buffer, SIZE );
ctx->buf_ptr = 0;
}
while ( ctx->buf_ptr < SIZE - LENGTHFIELDLEN )
ctx->buffer[(int)ctx->buf_ptr++] = 0;
//--- final ---
/* length padding */
ctx->block_counter++;
ctx->buf_ptr = SIZE;
while ( ctx->buf_ptr > SIZE - LENGTHFIELDLEN )
{
ctx->buffer[(int)--ctx->buf_ptr] = (u8)ctx->block_counter;
ctx->block_counter >>= 8;
}
// adjust for final block
blocks++;
/* digest final padding block */
Transform256( ctx, ctx->buffer, SIZE );
/* perform output transformation */
OutputTransformation256( ctx );
if ( i == len - 1 )
{
// all padding at once
ctx->buffer[i] = _mm_set_epi8( blocks,blocks>>8,0,0, 0,0,0,0,
0, 0,0,0, 0,0,0,0x80 );
}
else
{
if ( i == -1 )
{
// cryptonight odd length
((uint64_t*)ctx->buffer)[ 1 ] = 0x80ull;
// finish the block with zero and length padding as normal
i = 0;
}
else
{
// add first padding
ctx->buffer[i] = _mm_set_epi8( 0,0,0,0, 0,0,0,0,
0,0,0,0, 0,0,0,0x80 );
}
// add zero padding
for ( i += 1; i < SIZE256 - 1; i++ )
ctx->buffer[i] = _mm_setzero_si128();
// add length padding
// cheat since we know the block count is trivial, good if block < 256
ctx->buffer[i] = _mm_set_epi8( blocks,blocks>>8,0,0, 0,0,0,0,
0, 0,0,0, 0,0,0,0 );
}
/* store hash result in output */
for ( i = ( (SIZE - ctx->hashlen) / 16 ), j = 0; i < SIZE/16; i++, j++ )
casti_m128i( output, j ) = casti_m128i( ctx->chaining, i );
// digest final padding block and do output transform
TF512( ctx->chaining, ctx->buffer );
OF512( ctx->chaining );
return SUCCESS_GR;
// store hash result in output
for ( i = 0; i < hashlen_m128i; i++ )
casti_m128i( output, i ) = ctx->chaining[ hash_offset + i ];
return SUCCESS_GR;
}
/* hash bit sequence */

View File

@@ -9,6 +9,7 @@
#ifndef __hash_h
#define __hash_h
#include <immintrin.h>
#include <stdio.h>
#if defined(_WIN64) || defined(__WINDOWS__)
#include <windows.h>
@@ -40,23 +41,21 @@ typedef crypto_uint64 u64;
#include IACA_MARKS
#endif
//#ifndef LENGTH
//#define LENGTH (256)
//#endif
#define LENGTH (256)
/* some sizes (number of bytes) */
#define ROWS (8)
#define LENGTHFIELDLEN (ROWS)
#define COLS512 (8)
#define COLS1024 (16)
#define SIZE512 ((ROWS)*(COLS512))
#define SIZE1024 ((ROWS)*(COLS1024))
//#define COLS1024 (16)
#define SIZE_512 ((ROWS)*(COLS512))
//#define SIZE1024 ((ROWS)*(COLS1024))
#define ROUNDS512 (10)
#define ROUNDS1024 (14)
//#define ROUNDS1024 (14)
//#if LENGTH<=256
#define COLS (COLS512)
#define SIZE (SIZE512)
//#define SIZE (SIZE512)
#define ROUNDS (ROUNDS512)
//#else
//#define COLS (COLS1024)
@@ -89,28 +88,34 @@ typedef enum
BAD_HASHBITLEN_GR = 2
} HashReturn_gr;
#define SIZE256 (SIZE_512/16)
typedef struct {
__attribute__ ((aligned (32))) u64 chaining[SIZE/8]; /* actual state */
__attribute__ ((aligned (32))) BitSequence_gr buffer[SIZE]; /* data buffer */
u64 block_counter; /* message block counter */
__attribute__ ((aligned (32))) __m128i chaining[SIZE256];
__attribute__ ((aligned (32))) __m128i buffer[SIZE256];
// __attribute__ ((aligned (32))) u64 chaining[SIZE/8]; /* actual state */
// __attribute__ ((aligned (32))) BitSequence_gr buffer[SIZE]; /* data buffer */
// u64 block_counter; /* message block counter */
int hashlen; // bytes
int blk_count;
int buf_ptr; /* data buffer pointer */
int rem_ptr;
int databitlen;
} hashState_groestl256;
HashReturn_gr init_groestl256( hashState_groestl256*, int );
HashReturn_gr reinit_groestl( hashState_groestl256* );
HashReturn_gr reinit_groestl256( hashState_groestl256* );
HashReturn_gr update_groestl( hashState_groestl256*, const BitSequence_gr*,
HashReturn_gr update_groestl256( hashState_groestl256*, const void*,
DataLength_gr );
HashReturn_gr final_groestl( hashState_groestl256*, BitSequence_gr* );
HashReturn_gr final_groestl256( hashState_groestl256*, void* );
HashReturn_gr hash_groestl( int, const BitSequence_gr*, DataLength_gr,
HashReturn_gr hash_groestli256( int, const BitSequence_gr*, DataLength_gr,
BitSequence_gr* );
HashReturn_gr update_and_final_groestl256( hashState_groestl256*,
BitSequence_gr*, const BitSequence_gr*,
DataLength_gr );
HashReturn_gr update_and_final_groestl256( hashState_groestl256*, void*,
const void*, DataLength_gr );
#endif /* __hash_h */

View File

@@ -15,7 +15,7 @@
typedef struct
{
#ifdef NO_AES_NI
sph_groestl512_context groestl;
sph_groestl512_context groestl1, groestl2;
#else
hashState_groestl groestl1, groestl2;
#endif
@@ -27,43 +27,42 @@ static groestl_ctx_holder groestl_ctx;
void init_groestl_ctx()
{
#ifdef NO_AES_NI
sph_groestl512_init( &groestl_ctx.groestl );
sph_groestl512_init( &groestl_ctx.groestl1 );
sph_groestl512_init( &groestl_ctx.groestl2 );
#else
init_groestl( &groestl_ctx.groestl1, 64 );
init_groestl( &groestl_ctx.groestl2, 64 );
#endif
}
void groestlhash(void *output, const void *input)
void groestlhash( void *output, const void *input )
{
uint32_t _ALIGN(32) hash[16];
groestl_ctx_holder ctx;
uint32_t hash[16] __attribute__ ((aligned (64)));
groestl_ctx_holder ctx __attribute__ ((aligned (64)));
memcpy( &ctx, &groestl_ctx, sizeof(groestl_ctx) );
// memset(&hash[0], 0, sizeof(hash));
#ifdef NO_AES_NI
sph_groestl512(&ctx.groestl, input, 80);
sph_groestl512_close(&ctx.groestl, hash);
sph_groestl512(&ctx.groestl1, input, 80);
sph_groestl512_close(&ctx.groestl1, hash);
sph_groestl512(&ctx.groestl, hash, 64);
sph_groestl512_close(&ctx.groestl, hash);
sph_groestl512(&ctx.groestl2, hash, 64);
sph_groestl512_close(&ctx.groestl2, hash);
#else
update_groestl( &ctx.groestl1, (char*)input, 640 );
final_groestl( &ctx.groestl1,(char*)hash);
update_and_final_groestl( &ctx.groestl1, (char*)hash,
(const char*)input, 640 );
update_groestl( &ctx.groestl2, (char*)hash, 512 );
final_groestl( &ctx.groestl2, (char*)hash);
update_and_final_groestl( &ctx.groestl2, (char*)hash,
(const char*)hash, 512 );
#endif
memcpy(output, hash, 32);
memcpy(output, hash, 32);
}
int scanhash_groestl(int thr_id, struct work *work,
uint32_t max_nonce, uint64_t *hashes_done)
int scanhash_groestl( 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];
uint32_t endiandata[20] __attribute__ ((aligned (64)));
const uint32_t first_nonce = pdata[19];
uint32_t nonce = first_nonce;
@@ -74,7 +73,7 @@ int scanhash_groestl(int thr_id, struct work *work,
do {
const uint32_t Htarg = ptarget[7];
uint32_t hash[8];
uint32_t hash[8] __attribute__ ((aligned (64)));
be32enc(&endiandata[19], nonce);
groestlhash(hash, endiandata);
@@ -106,10 +105,16 @@ bool register_groestl_algo( algo_gate_t* gate )
gate->optimizations = SSE2_OPT | AES_OPT;
gate->scanhash = (void*)&scanhash_groestl;
gate->hash = (void*)&groestlhash;
gate->hash_alt = (void*)&groestlhash;
gate->set_target = (void*)&groestl_set_target;
gate->gen_merkle_root = (void*)&SHA256_gen_merkle_root;
gate->get_max64 = (void*)&get_max64_0x3ffff;
return true;
};
bool register_dmd_gr_algo( algo_gate_t* gate )
{
register_groestl_algo( gate );
gate->gen_merkle_root = (void*)&sha256d_gen_merkle_root;
return true;
};

View File

@@ -11,7 +11,12 @@
#else
#include "aes_ni/hash-groestl.h"
#endif
#include "algo/sha3/sph_sha2.h"
#if defined __SHA__
#include <openssl/sha.h>
#else
#include "algo/sha/sph_sha2.h"
#endif
typedef struct {
#ifdef NO_AES_NI
@@ -19,7 +24,11 @@ typedef struct {
#else
hashState_groestl groestl;
#endif
sph_sha256_context sha;
#if defined __SHA__
SHA256_CTX sha;
#else
sph_sha256_context sha;
#endif
} myrgr_ctx_holder;
myrgr_ctx_holder myrgr_ctx;
@@ -31,37 +40,44 @@ void init_myrgr_ctx()
#else
init_groestl (&myrgr_ctx.groestl, 64 );
#endif
sph_sha256_init(&myrgr_ctx.sha);
#if defined __SHA__
SHA256_Init( &myrgr_ctx.sha );
#else
sph_sha256_init( &myrgr_ctx.sha );
#endif
}
void myriadhash(void *output, const void *input)
void myriadhash( void *output, const void *input )
{
myrgr_ctx_holder ctx;
memcpy( &ctx, &myrgr_ctx, sizeof(myrgr_ctx) );
uint32_t _ALIGN(32) hash[16];
myrgr_ctx_holder ctx __attribute__ ((aligned (64)));
memcpy( &ctx, &myrgr_ctx, sizeof(myrgr_ctx) );
uint32_t hash[16] __attribute__ ((aligned (64)));
#ifdef NO_AES_NI
sph_groestl512(&ctx.groestl, input, 80);
sph_groestl512_close(&ctx.groestl, hash);
sph_groestl512(&ctx.groestl, input, 80);
sph_groestl512_close(&ctx.groestl, hash);
#else
update_groestl( &ctx.groestl, (char*)input, 640 );
final_groestl( &ctx.groestl, (char*)hash);
update_and_final_groestl( &ctx.groestl, (char*)input,
(const char*)input, 640 );
#endif
sph_sha256(&ctx.sha, hash, 64);
sph_sha256_close(&ctx.sha, hash);
memcpy(output, hash, 32);
#if defined __SHA__
SHA256_Update( &ctx.sha, hash, 64 );
SHA256_Final( (unsigned char*) hash, &ctx.sha );
#else
sph_sha256(&ctx.sha, hash, 64);
sph_sha256_close(&ctx.sha, hash);
#endif
memcpy(output, hash, 32);
}
int scanhash_myriad(int thr_id, struct work *work,
uint32_t max_nonce, uint64_t *hashes_done)
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];
uint32_t endiandata[20] __attribute__ ((aligned (64)));
const uint32_t first_nonce = pdata[19];
uint32_t nonce = first_nonce;
@@ -72,7 +88,7 @@ int scanhash_myriad(int thr_id, struct work *work,
do {
const uint32_t Htarg = ptarget[7];
uint32_t hash[8];
uint32_t hash[8] __attribute__ ((aligned (64)));
be32enc(&endiandata[19], nonce);
myriadhash(hash, endiandata);
@@ -92,11 +108,10 @@ int scanhash_myriad(int thr_id, struct work *work,
bool register_myriad_algo( algo_gate_t* gate )
{
gate->optimizations = SSE2_OPT | AES_OPT;
gate->optimizations = SSE2_OPT | AES_OPT | SHA_OPT;
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;
};

View File

@@ -40,7 +40,7 @@ extern "C"{
#endif
#include <stddef.h>
#include "algo/sha3/sph_types.h"
#include "algo/sha/sph_types.h"
/**
* Output size (in bits) for Groestl-224.

View File

@@ -1,133 +0,0 @@
/*
---------------------------------------------------------------------------
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
LICENSE TERMS
The redistribution and use of this software (with or without changes)
is allowed without the payment of fees or royalties provided that:
1. source code distributions include the above copyright notice, this
list of conditions and the following disclaimer;
2. binary distributions include the above copyright notice, this list
of conditions and the following disclaimer in their documentation;
3. the name of the copyright holder is not used to endorse products
built using this software without specific written permission.
DISCLAIMER
This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue Date: 20/12/2007
*/
#ifndef _BRG_ENDIAN_H
#define _BRG_ENDIAN_H
#define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
#define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
/* Include files where endian defines and byteswap functions may reside */
#if defined( __sun )
# include <sys/isa_defs.h>
#elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ )
# include <sys/endian.h>
#elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \
defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ )
# include <machine/endian.h>
#elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ )
# if !defined( __MINGW32__ ) && !defined( _AIX )
# include <endian.h>
# if !defined( __BEOS__ )
# include <byteswap.h>
# endif
# endif
#endif
/* Now attempt to set the define for platform byte order using any */
/* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, which */
/* seem to encompass most endian symbol definitions */
#if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN )
# if defined( BYTE_ORDER ) && BYTE_ORDER == BIG_ENDIAN
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
# elif defined( BYTE_ORDER ) && BYTE_ORDER == LITTLE_ENDIAN
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
# endif
#elif defined( BIG_ENDIAN )
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
#elif defined( LITTLE_ENDIAN )
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
#endif
#if defined( _BIG_ENDIAN ) && defined( _LITTLE_ENDIAN )
# if defined( _BYTE_ORDER ) && _BYTE_ORDER == _BIG_ENDIAN
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
# elif defined( _BYTE_ORDER ) && _BYTE_ORDER == _LITTLE_ENDIAN
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
# endif
#elif defined( _BIG_ENDIAN )
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
#elif defined( _LITTLE_ENDIAN )
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
#endif
#if defined( __BIG_ENDIAN ) && defined( __LITTLE_ENDIAN )
# if defined( __BYTE_ORDER ) && __BYTE_ORDER == __BIG_ENDIAN
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
# elif defined( __BYTE_ORDER ) && __BYTE_ORDER == __LITTLE_ENDIAN
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
# endif
#elif defined( __BIG_ENDIAN )
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
#elif defined( __LITTLE_ENDIAN )
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
#endif
#if defined( __BIG_ENDIAN__ ) && defined( __LITTLE_ENDIAN__ )
# if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __BIG_ENDIAN__
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
# elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __LITTLE_ENDIAN__
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
# endif
#elif defined( __BIG_ENDIAN__ )
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
#elif defined( __LITTLE_ENDIAN__ )
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
#endif
/* if the platform byte order could not be determined, then try to */
/* set this define using common machine defines */
#if !defined(PLATFORM_BYTE_ORDER)
#if defined( __alpha__ ) || defined( __alpha ) || defined( i386 ) || \
defined( __i386__ ) || defined( _M_I86 ) || defined( _M_IX86 ) || \
defined( __OS2__ ) || defined( sun386 ) || defined( __TURBOC__ ) || \
defined( vax ) || defined( vms ) || defined( VMS ) || \
defined( __VMS ) || defined( _M_X64 )
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
#elif defined( AMIGA ) || defined( applec ) || defined( __AS400__ ) || \
defined( _CRAY ) || defined( __hppa ) || defined( __hp9000 ) || \
defined( ibm370 ) || defined( mc68000 ) || defined( m68k ) || \
defined( __MRC__ ) || defined( __MVS__ ) || defined( __MWERKS__ ) || \
defined( sparc ) || defined( __sparc) || defined( SYMANTEC_C ) || \
defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM ) || \
defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX )
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
#elif 0 /* **** EDIT HERE IF NECESSARY **** */
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
#elif 0 /* **** EDIT HERE IF NECESSARY **** */
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
#else
# error Please edit lines 126 or 128 in brg_endian.h to set the platform byte order
#endif
#endif
#endif

View File

@@ -1,231 +0,0 @@
/*
---------------------------------------------------------------------------
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
(a few lines added by Soeren S. Thomsen, October 2008)
LICENSE TERMS
The redistribution and use of this software (with or without changes)
is allowed without the payment of fees or royalties provided that:
1. source code distributions include the above copyright notice, this
list of conditions and the following disclaimer;
2. binary distributions include the above copyright notice, this list
of conditions and the following disclaimer in their documentation;
3. the name of the copyright holder is not used to endorse products
built using this software without specific written permission.
DISCLAIMER
This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue Date: 20/12/2007
The unsigned integer types defined here are of the form uint_<nn>t where
<nn> is the length of the type; for example, the unsigned 32-bit type is
'uint_32t'. These are NOT the same as the 'C99 integer types' that are
defined in the inttypes.h and stdint.h headers since attempts to use these
types have shown that support for them is still highly variable. However,
since the latter are of the form uint<nn>_t, a regular expression search
and replace (in VC++ search on 'uint_{:z}t' and replace with 'uint\1_t')
can be used to convert the types used here to the C99 standard types.
*/
#ifndef _BRG_TYPES_H
#define _BRG_TYPES_H
#if defined(__cplusplus)
extern "C" {
#endif
#include <limits.h>
#if defined( _MSC_VER ) && ( _MSC_VER >= 1300 )
# include <stddef.h>
# define ptrint_t intptr_t
#elif defined( __GNUC__ ) && ( __GNUC__ >= 3 )
# include <stdint.h>
# define ptrint_t intptr_t
#else
# define ptrint_t int
#endif
#ifndef BRG_UI8
# define BRG_UI8
# if UCHAR_MAX == 255u
typedef unsigned char uint_8t;
# else
# error Please define uint_8t as an 8-bit unsigned integer type in brg_types.h
# endif
#endif
#ifndef BRG_UI16
# define BRG_UI16
# if USHRT_MAX == 65535u
typedef unsigned short uint_16t;
# else
# error Please define uint_16t as a 16-bit unsigned short type in brg_types.h
# endif
#endif
#ifndef BRG_UI32
# define BRG_UI32
# if UINT_MAX == 4294967295u
# define li_32(h) 0x##h##u
typedef unsigned int uint_32t;
# elif ULONG_MAX == 4294967295u
# define li_32(h) 0x##h##ul
typedef unsigned long uint_32t;
# elif defined( _CRAY )
# error This code needs 32-bit data types, which Cray machines do not provide
# else
# error Please define uint_32t as a 32-bit unsigned integer type in brg_types.h
# endif
#endif
#ifndef BRG_UI64
# if defined( __BORLANDC__ ) && !defined( __MSDOS__ )
# define BRG_UI64
# define li_64(h) 0x##h##ui64
typedef unsigned __int64 uint_64t;
# elif defined( _MSC_VER ) && ( _MSC_VER < 1300 ) /* 1300 == VC++ 7.0 */
# define BRG_UI64
# define li_64(h) 0x##h##ui64
typedef unsigned __int64 uint_64t;
# elif defined( __sun ) && defined( ULONG_MAX ) && ULONG_MAX == 0xfffffffful
# define BRG_UI64
# define li_64(h) 0x##h##ull
typedef unsigned long long uint_64t;
# elif defined( __MVS__ )
# define BRG_UI64
# define li_64(h) 0x##h##ull
typedef unsigned int long long uint_64t;
# elif defined( UINT_MAX ) && UINT_MAX > 4294967295u
# if UINT_MAX == 18446744073709551615u
# define BRG_UI64
# define li_64(h) 0x##h##u
typedef unsigned int uint_64t;
# endif
# elif defined( ULONG_MAX ) && ULONG_MAX > 4294967295u
# if ULONG_MAX == 18446744073709551615ul
# define BRG_UI64
# define li_64(h) 0x##h##ul
typedef unsigned long uint_64t;
# endif
# elif defined( ULLONG_MAX ) && ULLONG_MAX > 4294967295u
# if ULLONG_MAX == 18446744073709551615ull
# define BRG_UI64
# define li_64(h) 0x##h##ull
typedef unsigned long long uint_64t;
# endif
# elif defined( ULONG_LONG_MAX ) && ULONG_LONG_MAX > 4294967295u
# if ULONG_LONG_MAX == 18446744073709551615ull
# define BRG_UI64
# define li_64(h) 0x##h##ull
typedef unsigned long long uint_64t;
# endif
# endif
#endif
#if !defined( BRG_UI64 )
# if defined( NEED_UINT_64T )
# error Please define uint_64t as an unsigned 64 bit type in brg_types.h
# endif
#endif
#ifndef RETURN_VALUES
# define RETURN_VALUES
# if defined( DLL_EXPORT )
# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )
# define VOID_RETURN __declspec( dllexport ) void __stdcall
# define INT_RETURN __declspec( dllexport ) int __stdcall
# elif defined( __GNUC__ )
# define VOID_RETURN __declspec( __dllexport__ ) void
# define INT_RETURN __declspec( __dllexport__ ) int
# else
# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers
# endif
# elif defined( DLL_IMPORT )
# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )
# define VOID_RETURN __declspec( dllimport ) void __stdcall
# define INT_RETURN __declspec( dllimport ) int __stdcall
# elif defined( __GNUC__ )
# define VOID_RETURN __declspec( __dllimport__ ) void
# define INT_RETURN __declspec( __dllimport__ ) int
# else
# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers
# endif
# elif defined( __WATCOMC__ )
# define VOID_RETURN void __cdecl
# define INT_RETURN int __cdecl
# else
# define VOID_RETURN void
# define INT_RETURN int
# endif
#endif
/* These defines are used to detect and set the memory alignment of pointers.
Note that offsets are in bytes.
ALIGN_OFFSET(x,n) return the positive or zero offset of
the memory addressed by the pointer 'x'
from an address that is aligned on an
'n' byte boundary ('n' is a power of 2)
ALIGN_FLOOR(x,n) return a pointer that points to memory
that is aligned on an 'n' byte boundary
and is not higher than the memory address
pointed to by 'x' ('n' is a power of 2)
ALIGN_CEIL(x,n) return a pointer that points to memory
that is aligned on an 'n' byte boundary
and is not lower than the memory address
pointed to by 'x' ('n' is a power of 2)
*/
#define ALIGN_OFFSET(x,n) (((ptrint_t)(x)) & ((n) - 1))
#define ALIGN_FLOOR(x,n) ((uint_8t*)(x) - ( ((ptrint_t)(x)) & ((n) - 1)))
#define ALIGN_CEIL(x,n) ((uint_8t*)(x) + (-((ptrint_t)(x)) & ((n) - 1)))
/* These defines are used to declare buffers in a way that allows
faster operations on longer variables to be used. In all these
defines 'size' must be a power of 2 and >= 8. NOTE that the
buffer size is in bytes but the type length is in bits
UNIT_TYPEDEF(x,size) declares a variable 'x' of length
'size' bits
BUFR_TYPEDEF(x,size,bsize) declares a buffer 'x' of length 'bsize'
bytes defined as an array of variables
each of 'size' bits (bsize must be a
multiple of size / 8)
UNIT_CAST(x,size) casts a variable to a type of
length 'size' bits
UPTR_CAST(x,size) casts a pointer to a pointer to a
varaiable of length 'size' bits
*/
#define UI_TYPE(size) uint_##size##t
#define UNIT_TYPEDEF(x,size) typedef UI_TYPE(size) x
#define BUFR_TYPEDEF(x,size,bsize) typedef UI_TYPE(size) x[bsize / (size >> 3)]
#define UNIT_CAST(x,size) ((UI_TYPE(size) )(x))
#define UPTR_CAST(x,size) ((UI_TYPE(size)*)(x))
/* Added by Soeren S. Thomsen (begin) */
#define u8 uint_8t
#define u32 uint_32t
#define u64 uint_64t
/* (end) */
#if defined(__cplusplus)
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +0,0 @@
#ifndef GRSOASM_H
#define GRSOASM_H
#include "grso.h"
void grsoP1024ASM (u64 *x) ;
void grsoQ1024ASM (u64 *x) ;
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +0,0 @@
#ifndef GRSOASM_H
#define GRSOASM_H
/* really same as the mmx asm.h */
/* made just in case something must be changed */
#include "grso.h"
void grsoP1024ASM (u64 *x) ;
void grsoQ1024ASM (u64 *x) ;
#endif

View File

@@ -1,110 +0,0 @@
/* hash.c January 2011
*
* Groestl-512 implementation with inline assembly containing mmx and
* sse instructions. Optimized for Opteron.
* Authors: Krystian Matusiewicz and Soeren S. Thomsen
*
* This code is placed in the public domain
*/
//#include "grso.h"
//#include "grso-asm.h"
// #include "grsotab.h"
#define DECL_GRS
/* load initial constants */
#define GRS_I \
do { \
int i; \
/* set initial value */ \
for (i = 0; i < grsoCOLS-1; i++) sts_grs.grsstate[i] = 0; \
sts_grs.grsstate[grsoCOLS-1] = grsoU64BIG((u64)(8*grsoDIGESTSIZE)); \
\
/* set other variables */ \
sts_grs.grsbuf_ptr = 0; \
sts_grs.grsblock_counter = 0; \
} while (0); \
/* load hash */
#define GRS_U \
do { \
unsigned char* in = hash; \
unsigned long long index = 0; \
\
/* if the buffer contains data that has not yet been digested, first \
add data to buffer until full */ \
if (sts_grs.grsbuf_ptr) { \
while (sts_grs.grsbuf_ptr < grsoSIZE && index < 64) { \
hashbuf[(int)sts_grs.grsbuf_ptr++] = in[index++]; \
} \
if (sts_grs.grsbuf_ptr < grsoSIZE) continue; \
\
/* digest buffer */ \
sts_grs.grsbuf_ptr = 0; \
grsoTransform(&sts_grs, hashbuf, grsoSIZE); \
} \
\
/* digest bulk of message */ \
grsoTransform(&sts_grs, in+index, 64-index); \
index += ((64-index)/grsoSIZE)*grsoSIZE; \
\
/* store remaining data in buffer */ \
while (index < 64) { \
hashbuf[(int)sts_grs.grsbuf_ptr++] = in[index++]; \
} \
\
} while (0);
/* groestl512 hash loaded */
/* hash = groestl512(loaded) */
#define GRS_C \
do { \
char *out = hash; \
int i, j = 0; \
unsigned char *s = (unsigned char*)sts_grs.grsstate; \
\
hashbuf[sts_grs.grsbuf_ptr++] = 0x80; \
\
/* pad with '0'-bits */ \
if (sts_grs.grsbuf_ptr > grsoSIZE-grsoLENGTHFIELDLEN) { \
/* padding requires two blocks */ \
while (sts_grs.grsbuf_ptr < grsoSIZE) { \
hashbuf[sts_grs.grsbuf_ptr++] = 0; \
} \
/* digest first padding block */ \
grsoTransform(&sts_grs, hashbuf, grsoSIZE); \
sts_grs.grsbuf_ptr = 0; \
} \
while (sts_grs.grsbuf_ptr < grsoSIZE-grsoLENGTHFIELDLEN) { \
hashbuf[sts_grs.grsbuf_ptr++] = 0; \
} \
\
/* length padding */ \
sts_grs.grsblock_counter++; \
sts_grs.grsbuf_ptr = grsoSIZE; \
while (sts_grs.grsbuf_ptr > grsoSIZE-grsoLENGTHFIELDLEN) { \
hashbuf[--sts_grs.grsbuf_ptr] = (unsigned char)sts_grs.grsblock_counter; \
sts_grs.grsblock_counter >>= 8; \
} \
\
/* digest final padding block */ \
grsoTransform(&sts_grs, hashbuf, grsoSIZE); \
/* perform output transformation */ \
grsoOutputTransformation(&sts_grs); \
\
/* store hash result in output */ \
for (i = grsoSIZE-grsoDIGESTSIZE; i < grsoSIZE; i++,j++) { \
out[j] = s[i]; \
} \
\
/* zeroise relevant variables and deallocate memory */ \
for (i = 0; i < grsoCOLS; i++) { \
sts_grs.grsstate[i] = 0; \
} \
for (i = 0; i < grsoSIZE; i++) { \
hashbuf[i] = 0; \
} \
} while (0);

View File

@@ -1,57 +0,0 @@
/* hash.c January 2011
*
* Groestl-512 implementation with inline assembly containing mmx and
* sse instructions. Optimized for Opteron.
* Authors: Krystian Matusiewicz and Soeren S. Thomsen
*
* This code is placed in the public domain
*/
#include "algo/groestl/sse2/grso-asm.h"
#include "algo/groestl/sse2/grso.h"
#include "algo/groestl/sse2/grsotab.h"
/* digest up to len bytes of input (full blocks only) */
void grsoTransform(grsoState *ctx,
const unsigned char *in,
unsigned long long len) {
u64 y[grsoCOLS+2] __attribute__ ((aligned (16)));
u64 z[grsoCOLS+2] __attribute__ ((aligned (16)));
u64 *m, *h = (u64*)ctx->grsstate;
int i;
/* increment block counter */
ctx->grsblock_counter += len/grsoSIZE;
/* digest message, one block at a time */
for (; len >= grsoSIZE; len -= grsoSIZE, in += grsoSIZE) {
m = (u64*)in;
for (i = 0; i < grsoCOLS; i++) {
y[i] = m[i];
z[i] = m[i] ^ h[i];
}
grsoQ1024ASM(y);
grsoP1024ASM(z);
/* h' == h + Q(m) + P(h+m) */
for (i = 0; i < grsoCOLS; i++) {
h[i] ^= z[i] ^ y[i];
}
}
}
/* given state h, do h <- P(h)+h */
void grsoOutputTransformation(grsoState *ctx) {
u64 z[grsoCOLS] __attribute__ ((aligned (16)));
int j;
for (j = 0; j < grsoCOLS; j++) {
z[j] = ctx->grsstate[j];
}
grsoP1024ASM(z);
for (j = 0; j < grsoCOLS; j++) {
ctx->grsstate[j] ^= z[j];
}
}

View File

@@ -1,62 +0,0 @@
#ifndef __hash_h
#define __hash_h
#include <stdio.h>
#include <stdlib.h>
#include "brg_endian.h"
#include "brg_types.h"
/* some sizes (number of bytes) */
#define grsoROWS 8
#define grsoLENGTHFIELDLEN grsoROWS
#define grsoCOLS 16
#define grsoSIZE (grsoROWS*grsoCOLS)
#define grsoDIGESTSIZE 64
#define grsoROUNDS 14
#define grsoROTL64(a,n) ((((a)<<(n))|((a)>>(64-(n))))&((u64)0xffffffffffffffffULL))
#if (PLATFORM_BYTE_ORDER == IS_BIG_ENDIAN)
#error
#endif /* IS_BIG_ENDIAN */
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
#define EXT_BYTE(var,n) ((u8)((u64)(var) >> (8*n)))
#define grsoU64BIG(a) \
((grsoROTL64(a, 8) & ((u64)0x000000ff000000ffULL)) | \
(grsoROTL64(a,24) & ((u64)0x0000ff000000ff00ULL)) | \
(grsoROTL64(a,40) & ((u64)0x00ff000000ff0000ULL)) | \
(grsoROTL64(a,56) & ((u64)0xff000000ff000000ULL)))
#endif /* IS_LITTLE_ENDIAN */
typedef struct {
u64 grsstate[grsoCOLS]; /* actual state */
u64 grsblock_counter; /* message block counter */
int grsbuf_ptr; /* data buffer pointer */
} grsoState;
//extern int grsoInit(grsoState* ctx);
//extern int grsoUpdate(grsoState* ctx, const unsigned char* in,
// unsigned long long len);
//extern int grsoUpdateq(grsoState* ctx, const unsigned char* in);
//extern int grsoFinal(grsoState* ctx,
// unsigned char* out);
//
//extern int grsohash(unsigned char *out,
// const unsigned char *in,
// unsigned long long len);
/* digest up to len bytes of input (full blocks only) */
void grsoTransform( grsoState *ctx, const unsigned char *in,
unsigned long long len );
/* given state h, do h <- P(h)+h */
void grsoOutputTransformation( grsoState *ctx );
int grso_init ( grsoState* sts_grs );
int grso_update ( grsoState* sts_grs, char* hashbuf, char* hash );
int grso_close ( grsoState *sts_grs, char* hashbuf, char* hash );
#endif /* __hash_h */

File diff suppressed because one or more lines are too long

View File

@@ -36,7 +36,7 @@
#define SPH_HAMSI_H__
#include <stddef.h>
#include "algo/sha3/sph_types.h"
#include "algo/sha/sph_types.h"
#ifdef __cplusplus
extern "C"{

View File

@@ -66,7 +66,7 @@ extern "C"{
#endif
#include <stddef.h>
#include "algo/sha3/sph_types.h"
#include "algo/sha/sph_types.h"
/**
* Output size (in bits) for HAVAL-128/3.

View File

@@ -25,7 +25,7 @@
void bastionhash(void *output, const void *input)
{
unsigned char _ALIGN(128) hash[64] = { 0 };
unsigned char hash[64] __attribute__ ((aligned (64)));
#ifdef NO_AES_NI
sph_echo512_context ctx_echo;
@@ -36,7 +36,6 @@ void bastionhash(void *output, const void *input)
sph_fugue512_context ctx_fugue;
sph_whirlpool_context ctx_whirlpool;
sph_shabal512_context ctx_shabal;
// sph_skein512_context ctx_skein;
sph_hamsi512_context ctx_hamsi;
unsigned char hashbuf[128] __attribute__ ((aligned (16)));
@@ -47,8 +46,10 @@ void bastionhash(void *output, const void *input)
HEFTY1(input, 80, hash);
init_luffa( &ctx_luffa, 512 );
update_luffa( &ctx_luffa, hash, 64 );
final_luffa( &ctx_luffa, hash );
update_and_final_luffa( &ctx_luffa, (BitSequence*)hash,
(const BitSequence*)hash, 64 );
// update_luffa( &ctx_luffa, hash, 64 );
// final_luffa( &ctx_luffa, hash );
if (hash[0] & 0x8)
{
@@ -60,9 +61,6 @@ void bastionhash(void *output, const void *input)
SKN_I;
SKN_U;
SKN_C;
// sph_skein512_init(&ctx_skein);
// sph_skein512(&ctx_skein, hash, 64);
// sph_skein512_close(&ctx_skein, hash);
}
sph_whirlpool_init(&ctx_whirlpool);
@@ -81,13 +79,17 @@ void bastionhash(void *output, const void *input)
sph_echo512_close(&ctx_echo, hash);
#else
init_echo( &ctx_echo, 512 );
update_echo ( &ctx_echo, hash, 512 );
final_echo( &ctx_echo, hash );
update_final_echo ( &ctx_echo,(BitSequence*)hash,
(const BitSequence*)hash, 512 );
// update_echo ( &ctx_echo, hash, 512 );
// final_echo( &ctx_echo, hash );
#endif
} else {
init_luffa( &ctx_luffa, 512 );
update_luffa( &ctx_luffa, hash, 64 );
final_luffa( &ctx_luffa, hash );
update_and_final_luffa( &ctx_luffa, (BitSequence*)hash,
(const BitSequence*)hash, 64 );
// update_luffa( &ctx_luffa, hash, 64 );
// final_luffa( &ctx_luffa, hash );
}
sph_shabal512_init(&ctx_shabal);
@@ -98,9 +100,6 @@ void bastionhash(void *output, const void *input)
SKN_I;
SKN_U;
SKN_C;
// sph_skein512_init(&ctx_skein);
// sph_skein512(&ctx_skein, hash, 64);
// sph_skein512_close(&ctx_skein, hash);
if (hash[0] & 0x8)
{
@@ -124,8 +123,10 @@ void bastionhash(void *output, const void *input)
sph_hamsi512_close(&ctx_hamsi, hash);
} else {
init_luffa( &ctx_luffa, 512 );
update_luffa( &ctx_luffa, hash, 64 );
final_luffa( &ctx_luffa, hash );
update_and_final_luffa( &ctx_luffa, (BitSequence*)hash,
(const BitSequence*)hash, 64 );
// update_luffa( &ctx_luffa, hash, 64 );
// final_luffa( &ctx_luffa, hash );
}
memcpy(output, hash, 32);
@@ -170,7 +171,6 @@ bool register_bastion_algo( algo_gate_t* gate )
gate->optimizations = SSE2_OPT | AES_OPT;
gate->scanhash = (void*)&scanhash_bastion;
gate->hash = (void*)&bastionhash;
gate->hash_alt = (void*)&bastionhash;
return true;
};

View File

@@ -20,7 +20,7 @@
#include "algo/fugue/sph_fugue.h"
#include "algo/shabal/sph_shabal.h"
#include "algo/whirlpool/sph_whirlpool.h"
#include "algo/sha2/sph-sha2.h"
#include "algo/sha/sph_sha2.h"
#include "algo/haval/sph-haval.h"
#ifndef NO_AES_NI
@@ -58,8 +58,8 @@ typedef struct {
#endif
} hmq1725_ctx_holder;
static hmq1725_ctx_holder hmq1725_ctx;
static __thread sph_bmw512_context hmq_bmw_mid;
static hmq1725_ctx_holder hmq1725_ctx __attribute__ ((aligned (64)));
static __thread sph_bmw512_context hmq_bmw_mid __attribute__ ((aligned (64)));
void init_hmq1725_ctx()
{
@@ -127,13 +127,13 @@ void hmq_bmw512_midstate( const void* input )
sph_bmw512( &hmq_bmw_mid, input, 64 );
}
__thread hmq1725_ctx_holder h_ctx;
__thread hmq1725_ctx_holder h_ctx __attribute__ ((aligned (64)));
extern void hmq1725hash(void *state, const void *input)
{
const uint32_t mask = 24;
uint32_t hashA[16] __attribute__((aligned(64)));
uint32_t hashB[16] __attribute__((aligned(64)));
uint32_t hashA[32] __attribute__((aligned(64)));
uint32_t hashB[32] __attribute__((aligned(64)));
const int midlen = 64; // bytes
const int tail = 80 - midlen; // 16
@@ -307,8 +307,8 @@ extern void hmq1725hash(void *state, const void *input)
int scanhash_hmq1725( int thr_id, struct work *work, int32_t max_nonce,
uint64_t *hashes_done )
{
uint32_t endiandata[20] __attribute__((aligned(64)));
uint32_t hash64[8] __attribute__((aligned(32)));
uint32_t endiandata[32] __attribute__((aligned(64)));
uint32_t hash64[8] __attribute__((aligned(64)));
uint32_t *pdata = work->data;
uint32_t *ptarget = work->target;
uint32_t n = pdata[19] - 1;
@@ -416,11 +416,10 @@ int scanhash_hmq1725( int thr_id, struct work *work, int32_t max_nonce,
bool register_hmq1725_algo( algo_gate_t* gate )
{
init_hmq1725_ctx();
gate->optimizations = SSE2_OPT | AES_OPT | AVX_OPT | AVX2_OPT;
gate->optimizations = SSE2_OPT | AES_OPT | AVX_OPT | AVX2_OPT | SHA_OPT;
gate->set_target = (void*)&scrypt_set_target;
gate->scanhash = (void*)&scanhash_hmq1725;
gate->hash = (void*)&hmq1725hash;
gate->hash_alt = (void*)&hmq1725hash;
return true;
};

View File

@@ -1,171 +0,0 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2013 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_PRIMITIVES_BLOCK_H
#define BITCOIN_PRIMITIVES_BLOCK_H
#include "serialize.h"
#include "hodl_uint256.h"
/** Nodes collect new transactions into a block, hash them into a hash tree,
* and scan through nonce values to make the block's hash satisfy proof-of-work
* requirements. When they solve the proof-of-work, they broadcast the block
* to everyone and the block is added to the block chain. The first transaction
* in the block is a special one that creates a new coin owned by the creator
* of the block.
*/
class CBlockHeader
{
public:
// header
static const int32_t CURRENT_VERSION=4;
int32_t nVersion;
uint256 hashPrevBlock;
uint256 hashMerkleRoot;
uint32_t nTime;
uint32_t nBits;
uint32_t nNonce;
uint32_t nStartLocation;
uint32_t nFinalCalculation;
CBlockHeader()
{
SetNull();
}
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(this->nVersion);
nVersion = this->nVersion;
READWRITE(hashPrevBlock);
READWRITE(hashMerkleRoot);
READWRITE(nTime);
READWRITE(nBits);
READWRITE(nNonce);
READWRITE(nStartLocation);
READWRITE(nFinalCalculation);
}
void SetNull()
{
nVersion = CBlockHeader::CURRENT_VERSION;
hashPrevBlock.SetNull();
hashMerkleRoot.SetNull();
nTime = 0;
nBits = 0;
nNonce = 0;
nStartLocation = 0;
nFinalCalculation = 0;
}
bool IsNull() const
{
return (nBits == 0);
}
uint256 GetHash() const;
uint256 GetMidHash() const;
uint256 FindBestPatternHash(int& collisions,char *scratchpad,int nThreads);
uint256 FindBestPatternHash(int& collisions,char *scratchpad);
int64_t GetBlockTime() const
{
return (int64_t)nTime;
}
};
class CBlock : public CBlockHeader
{
public:
// network and disk
//std::vector<CTransaction> vtx;
std::vector<int> vtx;
// memory only
mutable std::vector<uint256> vMerkleTree;
CBlock()
{
SetNull();
}
CBlock(const CBlockHeader &header)
{
SetNull();
*((CBlockHeader*)this) = header;
}
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(*(CBlockHeader*)this);
READWRITE(vtx);
}
void SetNull()
{
CBlockHeader::SetNull();
vtx.clear();
vMerkleTree.clear();
}
CBlockHeader GetBlockHeader() const
{
CBlockHeader block;
block.nVersion = nVersion;
block.hashPrevBlock = hashPrevBlock;
block.hashMerkleRoot = hashMerkleRoot;
block.nTime = nTime;
block.nBits = nBits;
block.nNonce = nNonce;
block.nStartLocation = nStartLocation;
block.nFinalCalculation = nFinalCalculation;
return block;
}
std::string ToString() const;
};
/** Describes a place in the block chain to another node such that if the
* other node doesn't have the same branch, it can find a recent common trunk.
* The further back it is, the further before the fork it may be.
*/
struct CBlockLocator
{
std::vector<uint256> vHave;
CBlockLocator() {}
CBlockLocator(const std::vector<uint256>& vHaveIn)
{
vHave = vHaveIn;
}
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
if (!(nType & SER_GETHASH))
READWRITE(nVersion);
READWRITE(vHave);
}
void SetNull()
{
vHave.clear();
}
bool IsNull() const
{
return vHave.empty();
}
};
#endif // BITCOIN_PRIMITIVES_BLOCK_H

View File

@@ -1,70 +0,0 @@
// Copyright (c) 2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_CRYPTO_COMMON_H
#define BITCOIN_CRYPTO_COMMON_H
#if defined(HAVE_CONFIG_H)
#include "bitcoin-config.h"
#endif
#if ((defined(_WIN64) || defined(__WINDOWS__)))
#include "hodl-endian.h"
#endif
#include <stdint.h>
uint16_t static inline ReadLE16(const unsigned char* ptr)
{
return le16toh(*((uint16_t*)ptr));
}
uint32_t static inline ReadLE32(const unsigned char* ptr)
{
return le32toh(*((uint32_t*)ptr));
}
uint64_t static inline ReadLE64(const unsigned char* ptr)
{
return le64toh(*((uint64_t*)ptr));
}
void static inline WriteLE16(unsigned char* ptr, uint16_t x)
{
*((uint16_t*)ptr) = htole16(x);
}
void static inline WriteLE32(unsigned char* ptr, uint32_t x)
{
*((uint32_t*)ptr) = htole32(x);
}
void static inline WriteLE64(unsigned char* ptr, uint64_t x)
{
*((uint64_t*)ptr) = htole64(x);
}
uint32_t static inline ReadBE32(const unsigned char* ptr)
{
return be32toh(*((uint32_t*)ptr));
}
uint64_t static inline ReadBE64(const unsigned char* ptr)
{
return be64toh(*((uint64_t*)ptr));
}
void static inline WriteBE32(unsigned char* ptr, uint32_t x)
{
*((uint32_t*)ptr) = htobe32(x);
}
void static inline WriteBE64(unsigned char* ptr, uint64_t x)
{
*((uint64_t*)ptr) = htobe64(x);
}
#endif // BITCOIN_CRYPTO_COMMON_H
//#endif

View File

@@ -1,83 +0,0 @@
// Copyright (c) 2013-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "hash.h"
#include "common.h"
#include "hmac_sha512.h"
inline uint32_t ROTL32(uint32_t x, int8_t r)
{
return (x << r) | (x >> (32 - r));
}
unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char>& vDataToHash)
{
// The following is MurmurHash3 (x86_32), see http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp
uint32_t h1 = nHashSeed;
if (vDataToHash.size() > 0)
{
const uint32_t c1 = 0xcc9e2d51;
const uint32_t c2 = 0x1b873593;
const int nblocks = vDataToHash.size() / 4;
//----------
// body
const uint8_t* blocks = &vDataToHash[0] + nblocks * 4;
for (int i = -nblocks; i; i++) {
uint32_t k1 = ReadLE32(blocks + i*4);
k1 *= c1;
k1 = ROTL32(k1, 15);
k1 *= c2;
h1 ^= k1;
h1 = ROTL32(h1, 13);
h1 = h1 * 5 + 0xe6546b64;
}
//----------
// tail
const uint8_t* tail = (const uint8_t*)(&vDataToHash[0] + nblocks * 4);
uint32_t k1 = 0;
switch (vDataToHash.size() & 3) {
case 3:
k1 ^= tail[2] << 16;
case 2:
k1 ^= tail[1] << 8;
case 1:
k1 ^= tail[0];
k1 *= c1;
k1 = ROTL32(k1, 15);
k1 *= c2;
h1 ^= k1;
};
}
//----------
// finalization
h1 ^= vDataToHash.size();
h1 ^= h1 >> 16;
h1 *= 0x85ebca6b;
h1 ^= h1 >> 13;
h1 *= 0xc2b2ae35;
h1 ^= h1 >> 16;
return h1;
}
void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64])
{
unsigned char num[4];
num[0] = (nChild >> 24) & 0xFF;
num[1] = (nChild >> 16) & 0xFF;
num[2] = (nChild >> 8) & 0xFF;
num[3] = (nChild >> 0) & 0xFF;
CHMAC_SHA512(chainCode.begin(), chainCode.size()).Write(&header, 1).Write(data, 32).Write(num, 4).Finalize(output);
}

View File

@@ -1,176 +0,0 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2013 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_HASH_H
#define BITCOIN_HASH_H
#include <iostream>
//#include "ripemd160.h"
#include "sha256.h"
#include "serialize.h"
#include "hodl_uint256.h"
//#include "version.h"
#include <vector>
static const int PROTOCOL_VERSION = 70002;
typedef uint256 ChainCode;
/** A hasher class for Bitcoin's 256-bit hash (double SHA-256). */
class CHash256 {
private:
CSHA256 sha;
public:
static const size_t OUTPUT_SIZE = CSHA256::OUTPUT_SIZE;
void Finalize(unsigned char hash[OUTPUT_SIZE]) {
unsigned char buf[sha.OUTPUT_SIZE];
sha.Finalize(buf);
sha.Reset().Write(buf, sha.OUTPUT_SIZE).Finalize(hash);
}
CHash256& Write(const unsigned char *data, size_t len) {
sha.Write(data, len);
return *this;
}
CHash256& Reset() {
sha.Reset();
return *this;
}
};
/** A hasher class for Bitcoin's 160-bit hash (SHA-256 + RIPEMD-160). */
/*
class CHash160 {
private:
CSHA256 sha;
public:
static const size_t OUTPUT_SIZE = CRIPEMD160::OUTPUT_SIZE;
void Finalize(unsigned char hash[OUTPUT_SIZE]) {
unsigned char buf[sha.OUTPUT_SIZE];
sha.Finalize(buf);
CRIPEMD160().Write(buf, sha.OUTPUT_SIZE).Finalize(hash);
}
CHash160& Write(const unsigned char *data, size_t len) {
sha.Write(data, len);
return *this;
}
CHash160& Reset() {
sha.Reset();
return *this;
}
};
*/
/** Compute the 256-bit hash of an object. */
template<typename T1>
inline uint256 Hash(const T1 pbegin, const T1 pend)
{
static const unsigned char pblank[1] = {};
uint256 result;
CHash256().Write(pbegin == pend ? pblank : (const unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0]))
.Finalize((unsigned char*)&result);
return result;
}
/** Compute the 256-bit hash of the concatenation of two objects. */
template<typename T1, typename T2>
inline uint256 Hash(const T1 p1begin, const T1 p1end,
const T2 p2begin, const T2 p2end) {
static const unsigned char pblank[1] = {};
uint256 result;
CHash256().Write(p1begin == p1end ? pblank : (const unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0]))
.Write(p2begin == p2end ? pblank : (const unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0]))
.Finalize((unsigned char*)&result);
return result;
}
/** Compute the 256-bit hash of the concatenation of three objects. */
template<typename T1, typename T2, typename T3>
inline uint256 Hash(const T1 p1begin, const T1 p1end,
const T2 p2begin, const T2 p2end,
const T3 p3begin, const T3 p3end) {
static const unsigned char pblank[1] = {};
uint256 result;
CHash256().Write(p1begin == p1end ? pblank : (const unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0]))
.Write(p2begin == p2end ? pblank : (const unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0]))
.Write(p3begin == p3end ? pblank : (const unsigned char*)&p3begin[0], (p3end - p3begin) * sizeof(p3begin[0]))
.Finalize((unsigned char*)&result);
return result;
}
/** Compute the 160-bit hash an object. */
/*
template<typename T1>
inline uint160 Hash160(const T1 pbegin, const T1 pend)
{
static unsigned char pblank[1] = {};
uint160 result;
CHash160().Write(pbegin == pend ? pblank : (const unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0]))
.Finalize((unsigned char*)&result);
return result;
}
*/
/** Compute the 160-bit hash of a vector. */
/*
inline uint160 Hash160(const std::vector<unsigned char>& vch)
{
return Hash160(vch.begin(), vch.end());
}
*/
/** A writer stream (for serialization) that computes a 256-bit hash. */
class CHashWriter
{
private:
CHash256 ctx;
public:
int nType;
int nVersion;
CHashWriter(int nTypeIn, int nVersionIn) : nType(nTypeIn), nVersion(nVersionIn) {}
CHashWriter& write(const char *pch, size_t size) {
ctx.Write((const unsigned char*)pch, size);
return (*this);
}
// invalidates the object
uint256 GetHash() {
uint256 result;
ctx.Finalize((unsigned char*)&result);
return result;
}
template<typename T>
CHashWriter& operator<<(const T& obj) {
// Serialize to this stream
::Serialize(*this, obj, nType, nVersion);
return (*this);
}
};
/** Compute the 256-bit hash of an object's serialization. */
template<typename T>
uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
{
CHashWriter ss(nType, nVersion);
ss << obj;
return ss.GetHash();
}
unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char>& vDataToHash);
void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64]);
#endif // BITCOIN_HASH_H

View File

@@ -1,33 +0,0 @@
// Copyright (c) 2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "hmac_sha512.h"
#include <string.h>
CHMAC_SHA512::CHMAC_SHA512(const unsigned char* key, size_t keylen)
{
unsigned char rkey[128];
if (keylen <= 128) {
memcpy(rkey, key, keylen);
memset(rkey + keylen, 0, 128 - keylen);
} else {
CSHA512().Write(key, keylen).Finalize(rkey);
memset(rkey + 64, 0, 64);
}
for (int n = 0; n < 128; n++)
rkey[n] ^= 0x5c;
outer.Write(rkey, 128);
for (int n = 0; n < 128; n++)
rkey[n] ^= 0x5c ^ 0x36;
inner.Write(rkey, 128);
}
void CHMAC_SHA512::Finalize(unsigned char hash[OUTPUT_SIZE])
{
unsigned char temp[64];
inner.Finalize(temp);
outer.Write(temp, 64).Finalize(hash);
}

View File

@@ -1,32 +0,0 @@
// Copyright (c) 2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_CRYPTO_HMAC_SHA512_H
#define BITCOIN_CRYPTO_HMAC_SHA512_H
#include "sha512.h"
#include <stdint.h>
#include <stdlib.h>
/** A hasher class for HMAC-SHA-512. */
class CHMAC_SHA512
{
private:
CSHA512 outer;
CSHA512 inner;
public:
static const size_t OUTPUT_SIZE = 64;
CHMAC_SHA512(const unsigned char* key, size_t keylen);
CHMAC_SHA512& Write(const unsigned char* data, size_t len)
{
inner.Write(data, len);
return *this;
}
void Finalize(unsigned char hash[OUTPUT_SIZE]);
};
#endif // BITCOIN_CRYPTO_HMAC_SHA512_H

View File

@@ -4,7 +4,7 @@
#include "miner.h"
//#include "algo-gate-api.h"
#include "hodl-gate.h"
#include "hodl.h"
//#include "hodl.h"
#include "hodl-wolf.h"
#define HODL_NSTARTLOC_INDEX 20
@@ -98,9 +98,11 @@ int hodl_scanhash( int thr_id, struct work* work, uint32_t max_nonce,
uint64_t *hashes_done )
{
#ifdef NO_AES_NI
GetPsuedoRandomData( hodl_scratchbuf, work->data, thr_id );
pthread_barrier_wait( &hodl_barrier );
return scanhash_hodl( thr_id, work, max_nonce, hashes_done );
applog( LOG_ERR, "Only CPUs with AES are supported, use legacy version.");
return false;
// GetPsuedoRandomData( hodl_scratchbuf, work->data, thr_id );
// pthread_barrier_wait( &hodl_barrier );
// return scanhash_hodl( thr_id, work, max_nonce, hashes_done );
#else
GenRandomGarbage( hodl_scratchbuf, work->data, thr_id );
pthread_barrier_wait( &hodl_barrier );

View File

@@ -13,35 +13,41 @@
void GenerateGarbageCore(CacheEntry *Garbage, int ThreadID, int ThreadCount, void *MidHash)
{
#ifdef __AVX__
uint64_t* TempBufs[SHA512_PARALLEL_N];
uint64_t* TempBufs[SHA512_PARALLEL_N] ;
uint64_t* desination[SHA512_PARALLEL_N];
for (int i=0; i<SHA512_PARALLEL_N; ++i) {
for ( int i=0; i<SHA512_PARALLEL_N; ++i )
{
TempBufs[i] = (uint64_t*)malloc(32);
memcpy(TempBufs[i], MidHash, 32);
}
uint32_t StartChunk = ThreadID * (TOTAL_CHUNKS / ThreadCount);
for(uint32_t i = StartChunk; i < StartChunk + (TOTAL_CHUNKS / ThreadCount); i+= SHA512_PARALLEL_N) {
for(int j=0; j<SHA512_PARALLEL_N; ++j) {
((uint32_t*)TempBufs[j])[0] = i + j;
desination[j] = (uint64_t*)((uint8_t *)Garbage + ((i+j) * GARBAGE_CHUNK_SIZE));
for ( uint32_t i = StartChunk;
i < StartChunk + (TOTAL_CHUNKS / ThreadCount); i+= SHA512_PARALLEL_N )
{
for ( int j=0; j<SHA512_PARALLEL_N; ++j )
{
( (uint32_t*)TempBufs[j] )[0] = i + j;
desination[j] = (uint64_t*)( (uint8_t *)Garbage + ( (i+j)
* GARBAGE_CHUNK_SIZE ) );
}
sha512Compute32b_parallel(TempBufs, desination);
sha512Compute32b_parallel( TempBufs, desination );
}
for (int i=0; i<SHA512_PARALLEL_N; ++i) {
free(TempBufs[i]);
}
for ( int i=0; i<SHA512_PARALLEL_N; ++i )
free( TempBufs[i] );
#else
uint32_t TempBuf[8];
memcpy(TempBuf, MidHash, 32);
memcpy( TempBuf, MidHash, 32 );
uint32_t StartChunk = ThreadID * (TOTAL_CHUNKS / ThreadCount);
for(uint32_t i = StartChunk; i < StartChunk + (TOTAL_CHUNKS / ThreadCount); ++i)
for ( uint32_t i = StartChunk;
i < StartChunk + (TOTAL_CHUNKS / ThreadCount); ++i )
{
TempBuf[0] = i;
SHA512((uint8_t *)TempBuf, 32, ((uint8_t *)Garbage) + (i * GARBAGE_CHUNK_SIZE));
SHA512( ( uint8_t *)TempBuf, 32,
( (uint8_t *)Garbage ) + ( i * GARBAGE_CHUNK_SIZE ) );
}
#endif
}

View File

@@ -1,168 +0,0 @@
#include "miner.h"
#include "hodl-gate.h"
#include "hodl_uint256.h"
#include "hodl_arith_uint256.h"
#include "block.h"
#include <sstream>
#include "tinyformat.h"
#include <unordered_map>
#include "hash.h"
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <openssl/sha.h>
#define BEGIN(a) ((char*)&(a))
#define END(a) ((char*)&((&(a))[1]))
#define PSUEDORANDOM_DATA_SIZE 30 //2^30 = 1GB
#define PSUEDORANDOM_DATA_CHUNK_SIZE 6 //2^6 = 64 bytes //must be same as SHA512_DIGEST_LENGTH 64
#define L2CACHE_TARGET 12 // 2^12 = 4096 bytes
#define AES_ITERATIONS 15
void SHA512Filler(char *mainMemoryPsuedoRandomData, int threadNumber, uint256 midHash){
//Generate psuedo random data to store in main memory
uint32_t chunks=(1<<(PSUEDORANDOM_DATA_SIZE-PSUEDORANDOM_DATA_CHUNK_SIZE)); //2^(30-6) = 16 mil
uint32_t chunkSize=(1<<(PSUEDORANDOM_DATA_CHUNK_SIZE)); //2^6 = 64 bytes
unsigned char hash_tmp[sizeof(midHash)];
memcpy((char*)&hash_tmp[0], (char*)&midHash, sizeof(midHash) );
uint32_t* index = (uint32_t*)hash_tmp;
// uint32_t chunksToProcess=chunks/totalThreads;
uint32_t chunksToProcess = chunks / opt_n_threads;
uint32_t startChunk=threadNumber*chunksToProcess;
for( uint32_t i = startChunk; i < startChunk+chunksToProcess; i++){
//This changes the first character of hash_tmp
*index = i;
SHA512((unsigned char*)hash_tmp, sizeof(hash_tmp), (unsigned char*)&(mainMemoryPsuedoRandomData[i*chunkSize]));
}
}
extern "C"
// max_nonce is not used by this function
int scanhash_hodl( int threadNumber, struct work* work, uint32_t max_nonce,
uint64_t *hashes_done )
{
unsigned char *mainMemoryPsuedoRandomData = hodl_scratchbuf;
uint32_t *pdata = work->data;
uint32_t *ptarget = work->target;
//retreive target
std::stringstream s;
for (int i = 7; i>=0; i--)
s << strprintf("%08x", ptarget[i]);
//retreive preveios hash
std::stringstream p;
for (int i = 0; i < 8; i++)
p << strprintf("%08x", swab32(pdata[8 - i]));
//retreive merkleroot
std::stringstream m;
for (int i = 0; i < 8; i++)
m << strprintf("%08x", swab32(pdata[16 - i]));
CBlock pblock;
pblock.SetNull();
pblock.nVersion=swab32(pdata[0]);
pblock.nNonce=swab32(pdata[19]);
pblock.nTime=swab32(pdata[17]);
pblock.nBits=swab32(pdata[18]);
pblock.hashPrevBlock=uint256S(p.str());
pblock.hashMerkleRoot=uint256S(m.str());
uint256 hashTarget=uint256S(s.str());
int collisions=0;
uint256 hash;
//Begin AES Search
//Allocate temporary memory
uint32_t cacheMemorySize = (1<<L2CACHE_TARGET); //2^12 = 4096 bytes
uint32_t comparisonSize=(1<<(PSUEDORANDOM_DATA_SIZE-L2CACHE_TARGET)); //2^(30-12) = 256K
unsigned char *cacheMemoryOperatingData;
unsigned char *cacheMemoryOperatingData2;
cacheMemoryOperatingData=new unsigned char[cacheMemorySize+16];
cacheMemoryOperatingData2=new unsigned char[cacheMemorySize];
//Create references to data as 32 bit arrays
uint32_t* cacheMemoryOperatingData32 = (uint32_t*)cacheMemoryOperatingData;
uint32_t* cacheMemoryOperatingData322 = (uint32_t*)cacheMemoryOperatingData2;
//Search for pattern in psuedorandom data
unsigned char key[32] = {0};
unsigned char iv[AES_BLOCK_SIZE];
int outlen1, outlen2;
//Iterate over the data
// int searchNumber=comparisonSize/totalThreads;
int searchNumber = comparisonSize / opt_n_threads;
int startLoc=threadNumber*searchNumber;
EVP_CIPHER_CTX ctx;
for(int32_t k = startLoc;k<startLoc+searchNumber && !work_restart[threadNumber].restart;k++){
//copy data to first l2 cache
memcpy((char*)&cacheMemoryOperatingData[0], (char*)&mainMemoryPsuedoRandomData[k*cacheMemorySize], cacheMemorySize);
for(int j=0;j<AES_ITERATIONS;j++){
//use last 4 bytes of first cache as next location
uint32_t nextLocation = cacheMemoryOperatingData32[(cacheMemorySize/4)-1]%comparisonSize;
//Copy data from indicated location to second l2 cache -
memcpy((char*)&cacheMemoryOperatingData2[0], (char*)&mainMemoryPsuedoRandomData[nextLocation*cacheMemorySize], cacheMemorySize);
//XOR location data into second cache
for(uint32_t i = 0; i < cacheMemorySize/4; i++)
cacheMemoryOperatingData322[i] = cacheMemoryOperatingData32[i] ^ cacheMemoryOperatingData322[i];
memcpy(key,(unsigned char*)&cacheMemoryOperatingData2[cacheMemorySize-32],32);
memcpy(iv,(unsigned char*)&cacheMemoryOperatingData2[cacheMemorySize-AES_BLOCK_SIZE],AES_BLOCK_SIZE);
EVP_EncryptInit(&ctx, EVP_aes_256_cbc(), key, iv);
EVP_EncryptUpdate(&ctx, cacheMemoryOperatingData, &outlen1, cacheMemoryOperatingData2, cacheMemorySize);
EVP_EncryptFinal(&ctx, cacheMemoryOperatingData + outlen1, &outlen2);
EVP_CIPHER_CTX_cleanup(&ctx);
}
//use last X bits as solution
uint32_t solution=cacheMemoryOperatingData32[(cacheMemorySize/4)-1]%comparisonSize;
if(solution<1000){
uint32_t proofOfCalculation=cacheMemoryOperatingData32[(cacheMemorySize/4)-2];
pblock.nStartLocation = k;
pblock.nFinalCalculation = proofOfCalculation;
hash = Hash(BEGIN(pblock.nVersion), END(pblock.nFinalCalculation));
collisions++;
if (UintToArith256(hash) <= UintToArith256(hashTarget) && !work_restart[threadNumber].restart){
pdata[21] = swab32(pblock.nFinalCalculation);
pdata[20] = swab32(pblock.nStartLocation);
*hashes_done = collisions;
//free memory
delete [] cacheMemoryOperatingData;
delete [] cacheMemoryOperatingData2;
return 1;
}
}
}
//free memory
delete [] cacheMemoryOperatingData;
delete [] cacheMemoryOperatingData2;
*hashes_done = collisions;
return 0;
}
extern "C"
void GetPsuedoRandomData( char* mainMemoryPsuedoRandomData, uint32_t *pdata,
int thr_id )
{
//retreive preveios hash
std::stringstream p;
for (int i = 0; i < 8; i++)
p << strprintf("%08x", swab32(pdata[8 - i]));
//retreive merkleroot
std::stringstream m;
for (int i = 0; i < 8; i++)
m << strprintf("%08x", swab32(pdata[16 - i]));
CBlock pblock;
pblock.SetNull();
pblock.nVersion=swab32(pdata[0]);
pblock.nTime=swab32(pdata[17]);
pblock.nBits=swab32(pdata[18]);
pblock.hashPrevBlock= uint256S(p.str());
pblock.hashMerkleRoot= uint256S(m.str());
pblock.nNonce=swab32(pdata[19]);
uint256 midHash = Hash(BEGIN(pblock.nVersion), END(pblock.nNonce));
SHA512Filler( mainMemoryPsuedoRandomData, thr_id, midHash);
}

View File

@@ -1,11 +0,0 @@
extern int scanhash_hodl( int thr_id, struct work* work, uint32_t max_nonce,
uint64_t *hashes_done );
extern void GetPsuedoRandomData( char* mainMemoryPsuedoRandomData,
uint32_t *pdata, int thr_id );
void hodl_set_target( struct work* work, double diff );
void hodl_copy_workdata( struct work* work, struct work* g_work );

View File

@@ -1,258 +0,0 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "hodl_arith_uint256.h"
#include "hodl_uint256.h"
#include "utilstrencodings.h"
#include "common.h"
#include <stdio.h>
#include <string.h>
template <unsigned int BITS>
base_uint<BITS>::base_uint(const std::string& str)
{
SetHex(str);
}
template <unsigned int BITS>
base_uint<BITS>& base_uint<BITS>::operator<<=(unsigned int shift)
{
base_uint<BITS> a(*this);
for (int i = 0; i < WIDTH; i++)
pn[i] = 0;
int k = shift / 32;
shift = shift % 32;
for (int i = 0; i < WIDTH; i++) {
if (i + k + 1 < WIDTH && shift != 0)
pn[i + k + 1] |= (a.pn[i] >> (32 - shift));
if (i + k < WIDTH)
pn[i + k] |= (a.pn[i] << shift);
}
return *this;
}
template <unsigned int BITS>
base_uint<BITS>& base_uint<BITS>::operator>>=(unsigned int shift)
{
base_uint<BITS> a(*this);
for (int i = 0; i < WIDTH; i++)
pn[i] = 0;
int k = shift / 32;
shift = shift % 32;
for (int i = 0; i < WIDTH; i++) {
if (i - k - 1 >= 0 && shift != 0)
pn[i - k - 1] |= (a.pn[i] << (32 - shift));
if (i - k >= 0)
pn[i - k] |= (a.pn[i] >> shift);
}
return *this;
}
template <unsigned int BITS>
base_uint<BITS>& base_uint<BITS>::operator*=(uint32_t b32)
{
uint64_t carry = 0;
for (int i = 0; i < WIDTH; i++) {
uint64_t n = carry + (uint64_t)b32 * pn[i];
pn[i] = n & 0xffffffff;
carry = n >> 32;
}
return *this;
}
template <unsigned int BITS>
base_uint<BITS>& base_uint<BITS>::operator*=(const base_uint& b)
{
base_uint<BITS> a = *this;
*this = 0;
for (int j = 0; j < WIDTH; j++) {
uint64_t carry = 0;
for (int i = 0; i + j < WIDTH; i++) {
uint64_t n = carry + pn[i + j] + (uint64_t)a.pn[j] * b.pn[i];
pn[i + j] = n & 0xffffffff;
carry = n >> 32;
}
}
return *this;
}
template <unsigned int BITS>
base_uint<BITS>& base_uint<BITS>::operator/=(const base_uint& b)
{
base_uint<BITS> div = b; // make a copy, so we can shift.
base_uint<BITS> num = *this; // make a copy, so we can subtract.
*this = 0; // the quotient.
int num_bits = num.bits();
int div_bits = div.bits();
if (div_bits == 0)
throw uint_error("Division by zero");
if (div_bits > num_bits) // the result is certainly 0.
return *this;
int shift = num_bits - div_bits;
div <<= shift; // shift so that div and num align.
while (shift >= 0) {
if (num >= div) {
num -= div;
pn[shift / 32] |= (1 << (shift & 31)); // set a bit of the result.
}
div >>= 1; // shift back.
shift--;
}
// num now contains the remainder of the division.
return *this;
}
template <unsigned int BITS>
int base_uint<BITS>::CompareTo(const base_uint<BITS>& b) const
{
for (int i = WIDTH - 1; i >= 0; i--) {
if (pn[i] < b.pn[i])
return -1;
if (pn[i] > b.pn[i])
return 1;
}
return 0;
}
template <unsigned int BITS>
bool base_uint<BITS>::EqualTo(uint64_t b) const
{
for (int i = WIDTH - 1; i >= 2; i--) {
if (pn[i])
return false;
}
if (pn[1] != (b >> 32))
return false;
if (pn[0] != (b & 0xfffffffful))
return false;
return true;
}
template <unsigned int BITS>
double base_uint<BITS>::getdouble() const
{
double ret = 0.0;
double fact = 1.0;
for (int i = 0; i < WIDTH; i++) {
ret += fact * pn[i];
fact *= 4294967296.0;
}
return ret;
}
template <unsigned int BITS>
std::string base_uint<BITS>::GetHex() const
{
return ArithToUint256(*this).GetHex();
}
template <unsigned int BITS>
void base_uint<BITS>::SetHex(const char* psz)
{
*this = UintToArith256(uint256S(psz));
}
template <unsigned int BITS>
void base_uint<BITS>::SetHex(const std::string& str)
{
SetHex(str.c_str());
}
template <unsigned int BITS>
std::string base_uint<BITS>::ToString() const
{
return (GetHex());
}
template <unsigned int BITS>
unsigned int base_uint<BITS>::bits() const
{
for (int pos = WIDTH - 1; pos >= 0; pos--) {
if (pn[pos]) {
for (int bits = 31; bits > 0; bits--) {
if (pn[pos] & 1 << bits)
return 32 * pos + bits + 1;
}
return 32 * pos + 1;
}
}
return 0;
}
// Explicit instantiations for base_uint<256>
template base_uint<256>::base_uint(const std::string&);
template base_uint<256>& base_uint<256>::operator<<=(unsigned int);
template base_uint<256>& base_uint<256>::operator>>=(unsigned int);
template base_uint<256>& base_uint<256>::operator*=(uint32_t b32);
template base_uint<256>& base_uint<256>::operator*=(const base_uint<256>& b);
template base_uint<256>& base_uint<256>::operator/=(const base_uint<256>& b);
template int base_uint<256>::CompareTo(const base_uint<256>&) const;
template bool base_uint<256>::EqualTo(uint64_t) const;
template double base_uint<256>::getdouble() const;
template std::string base_uint<256>::GetHex() const;
template std::string base_uint<256>::ToString() const;
template void base_uint<256>::SetHex(const char*);
template void base_uint<256>::SetHex(const std::string&);
template unsigned int base_uint<256>::bits() const;
// This implementation directly uses shifts instead of going
// through an intermediate MPI representation.
arith_uint256& arith_uint256::SetCompact(uint32_t nCompact, bool* pfNegative, bool* pfOverflow)
{
int nSize = nCompact >> 24;
uint32_t nWord = nCompact & 0x007fffff;
if (nSize <= 3) {
nWord >>= 8 * (3 - nSize);
*this = nWord;
} else {
*this = nWord;
*this <<= 8 * (nSize - 3);
}
if (pfNegative)
*pfNegative = nWord != 0 && (nCompact & 0x00800000) != 0;
if (pfOverflow)
*pfOverflow = nWord != 0 && ((nSize > 34) ||
(nWord > 0xff && nSize > 33) ||
(nWord > 0xffff && nSize > 32));
return *this;
}
uint32_t arith_uint256::GetCompact(bool fNegative) const
{
int nSize = (bits() + 7) / 8;
uint32_t nCompact = 0;
if (nSize <= 3) {
nCompact = GetLow64() << 8 * (3 - nSize);
} else {
arith_uint256 bn = *this >> 8 * (nSize - 3);
nCompact = bn.GetLow64();
}
// The 0x00800000 bit denotes the sign.
// Thus, if it is already set, divide the mantissa by 256 and increase the exponent.
if (nCompact & 0x00800000) {
nCompact >>= 8;
nSize++;
}
assert((nCompact & ~0x007fffff) == 0);
assert(nSize < 256);
nCompact |= nSize << 24;
nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0);
return nCompact;
}
uint256 ArithToUint256(const arith_uint256 &a)
{
uint256 b;
for(int x=0; x<a.WIDTH; ++x)
WriteLE32(b.begin() + x*4, a.pn[x]);
return b;
}
arith_uint256 UintToArith256(const uint256 &a)
{
arith_uint256 b;
for(int x=0; x<b.WIDTH; ++x)
b.pn[x] = ReadLE32(a.begin() + x*4);
return b;
}

View File

@@ -1,290 +0,0 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_ARITH_UINT256_H
#define BITCOIN_ARITH_UINT256_H
#include <assert.h>
#include <cstring>
#include <stdexcept>
#include <stdint.h>
#include <string>
#include <vector>
class uint256;
class uint_error : public std::runtime_error {
public:
explicit uint_error(const std::string& str) : std::runtime_error(str) {}
};
/** Template base class for unsigned big integers. */
template<unsigned int BITS>
class base_uint
{
protected:
enum { WIDTH=BITS/32 };
uint32_t pn[WIDTH];
public:
base_uint()
{
for (int i = 0; i < WIDTH; i++)
pn[i] = 0;
}
base_uint(const base_uint& b)
{
for (int i = 0; i < WIDTH; i++)
pn[i] = b.pn[i];
}
base_uint& operator=(const base_uint& b)
{
for (int i = 0; i < WIDTH; i++)
pn[i] = b.pn[i];
return *this;
}
base_uint(uint64_t b)
{
pn[0] = (unsigned int)b;
pn[1] = (unsigned int)(b >> 32);
for (int i = 2; i < WIDTH; i++)
pn[i] = 0;
}
explicit base_uint(const std::string& str);
bool operator!() const
{
for (int i = 0; i < WIDTH; i++)
if (pn[i] != 0)
return false;
return true;
}
const base_uint operator~() const
{
base_uint ret;
for (int i = 0; i < WIDTH; i++)
ret.pn[i] = ~pn[i];
return ret;
}
const base_uint operator-() const
{
base_uint ret;
for (int i = 0; i < WIDTH; i++)
ret.pn[i] = ~pn[i];
ret++;
return ret;
}
double getdouble() const;
base_uint& operator=(uint64_t b)
{
pn[0] = (unsigned int)b;
pn[1] = (unsigned int)(b >> 32);
for (int i = 2; i < WIDTH; i++)
pn[i] = 0;
return *this;
}
base_uint& operator^=(const base_uint& b)
{
for (int i = 0; i < WIDTH; i++)
pn[i] ^= b.pn[i];
return *this;
}
base_uint& operator&=(const base_uint& b)
{
for (int i = 0; i < WIDTH; i++)
pn[i] &= b.pn[i];
return *this;
}
base_uint& operator|=(const base_uint& b)
{
for (int i = 0; i < WIDTH; i++)
pn[i] |= b.pn[i];
return *this;
}
base_uint& operator^=(uint64_t b)
{
pn[0] ^= (unsigned int)b;
pn[1] ^= (unsigned int)(b >> 32);
return *this;
}
base_uint& operator|=(uint64_t b)
{
pn[0] |= (unsigned int)b;
pn[1] |= (unsigned int)(b >> 32);
return *this;
}
base_uint& operator<<=(unsigned int shift);
base_uint& operator>>=(unsigned int shift);
base_uint& operator+=(const base_uint& b)
{
uint64_t carry = 0;
for (int i = 0; i < WIDTH; i++)
{
uint64_t n = carry + pn[i] + b.pn[i];
pn[i] = n & 0xffffffff;
carry = n >> 32;
}
return *this;
}
base_uint& operator-=(const base_uint& b)
{
*this += -b;
return *this;
}
base_uint& operator+=(uint64_t b64)
{
base_uint b;
b = b64;
*this += b;
return *this;
}
base_uint& operator-=(uint64_t b64)
{
base_uint b;
b = b64;
*this += -b;
return *this;
}
base_uint& operator*=(uint32_t b32);
base_uint& operator*=(const base_uint& b);
base_uint& operator/=(const base_uint& b);
base_uint& operator++()
{
// prefix operator
int i = 0;
while (++pn[i] == 0 && i < WIDTH-1)
i++;
return *this;
}
const base_uint operator++(int)
{
// postfix operator
const base_uint ret = *this;
++(*this);
return ret;
}
base_uint& operator--()
{
// prefix operator
int i = 0;
while (--pn[i] == (uint32_t)-1 && i < WIDTH-1)
i++;
return *this;
}
const base_uint operator--(int)
{
// postfix operator
const base_uint ret = *this;
--(*this);
return ret;
}
int CompareTo(const base_uint& b) const;
bool EqualTo(uint64_t b) const;
friend inline const base_uint operator+(const base_uint& a, const base_uint& b) { return base_uint(a) += b; }
friend inline const base_uint operator-(const base_uint& a, const base_uint& b) { return base_uint(a) -= b; }
friend inline const base_uint operator*(const base_uint& a, const base_uint& b) { return base_uint(a) *= b; }
friend inline const base_uint operator/(const base_uint& a, const base_uint& b) { return base_uint(a) /= b; }
friend inline const base_uint operator|(const base_uint& a, const base_uint& b) { return base_uint(a) |= b; }
friend inline const base_uint operator&(const base_uint& a, const base_uint& b) { return base_uint(a) &= b; }
friend inline const base_uint operator^(const base_uint& a, const base_uint& b) { return base_uint(a) ^= b; }
friend inline const base_uint operator>>(const base_uint& a, int shift) { return base_uint(a) >>= shift; }
friend inline const base_uint operator<<(const base_uint& a, int shift) { return base_uint(a) <<= shift; }
friend inline const base_uint operator*(const base_uint& a, uint32_t b) { return base_uint(a) *= b; }
friend inline bool operator==(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) == 0; }
friend inline bool operator!=(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) != 0; }
friend inline bool operator>(const base_uint& a, const base_uint& b) { return a.CompareTo(b) > 0; }
friend inline bool operator<(const base_uint& a, const base_uint& b) { return a.CompareTo(b) < 0; }
friend inline bool operator>=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) >= 0; }
friend inline bool operator<=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) <= 0; }
friend inline bool operator==(const base_uint& a, uint64_t b) { return a.EqualTo(b); }
friend inline bool operator!=(const base_uint& a, uint64_t b) { return !a.EqualTo(b); }
std::string GetHex() const;
void SetHex(const char* psz);
void SetHex(const std::string& str);
std::string ToString() const;
unsigned int size() const
{
return sizeof(pn);
}
/**
* Returns the position of the highest bit set plus one, or zero if the
* value is zero.
*/
unsigned int bits() const;
uint64_t GetLow64() const
{
assert(WIDTH >= 2);
return pn[0] | (uint64_t)pn[1] << 32;
}
};
/** 256-bit unsigned big integer. */
class arith_uint256 : public base_uint<256> {
public:
arith_uint256() {}
arith_uint256(const base_uint<256>& b) : base_uint<256>(b) {}
arith_uint256(uint64_t b) : base_uint<256>(b) {}
explicit arith_uint256(const std::string& str) : base_uint<256>(str) {}
/**
* The "compact" format is a representation of a whole
* number N using an unsigned 32bit number similar to a
* floating point format.
* The most significant 8 bits are the unsigned exponent of base 256.
* This exponent can be thought of as "number of bytes of N".
* The lower 23 bits are the mantissa.
* Bit number 24 (0x800000) represents the sign of N.
* N = (-1^sign) * mantissa * 256^(exponent-3)
*
* Satoshi's original implementation used BN_bn2mpi() and BN_mpi2bn().
* MPI uses the most significant bit of the first byte as sign.
* Thus 0x1234560000 is compact (0x05123456)
* and 0xc0de000000 is compact (0x0600c0de)
*
* Bitcoin only uses this "compact" format for encoding difficulty
* targets, which are unsigned 256bit quantities. Thus, all the
* complexities of the sign bit and using base 256 are probably an
* implementation accident.
*/
arith_uint256& SetCompact(uint32_t nCompact, bool *pfNegative = NULL, bool *pfOverflow = NULL);
uint32_t GetCompact(bool fNegative = false) const;
friend uint256 ArithToUint256(const arith_uint256 &);
friend arith_uint256 UintToArith256(const uint256 &);
};
uint256 ArithToUint256(const arith_uint256 &);
arith_uint256 UintToArith256(const uint256 &);
#endif // BITCOIN_ARITH_UINT256_H

View File

@@ -1,145 +0,0 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "hodl_uint256.h"
#include "utilstrencodings.h"
#include <stdio.h>
#include <string.h>
template <unsigned int BITS>
base_blob<BITS>::base_blob(const std::vector<unsigned char>& vch)
{
assert(vch.size() == sizeof(data));
memcpy(data, &vch[0], sizeof(data));
}
template <unsigned int BITS>
std::string base_blob<BITS>::GetHex() const
{
char psz[sizeof(data) * 2 + 1];
for (unsigned int i = 0; i < sizeof(data); i++)
sprintf(psz + i * 2, "%02x", data[sizeof(data) - i - 1]);
return std::string(psz, psz + sizeof(data) * 2);
}
template <unsigned int BITS>
void base_blob<BITS>::SetHex(const char* psz)
{
memset(data, 0, sizeof(data));
// skip leading spaces
while (isspace(*psz))
psz++;
// skip 0x
if (psz[0] == '0' && tolower(psz[1]) == 'x')
psz += 2;
// hex string to uint
const char* pbegin = psz;
while (::HexDigit(*psz) != -1)
psz++;
psz--;
unsigned char* p1 = (unsigned char*)data;
unsigned char* pend = p1 + WIDTH;
while (psz >= pbegin && p1 < pend) {
*p1 = ::HexDigit(*psz--);
if (psz >= pbegin) {
*p1 |= ((unsigned char)::HexDigit(*psz--) << 4);
p1++;
}
}
}
template <unsigned int BITS>
void base_blob<BITS>::SetHex(const std::string& str)
{
SetHex(str.c_str());
}
template <unsigned int BITS>
std::string base_blob<BITS>::ToString() const
{
return (GetHex());
}
// Explicit instantiations for base_blob<160>
template base_blob<160>::base_blob(const std::vector<unsigned char>&);
template std::string base_blob<160>::GetHex() const;
template std::string base_blob<160>::ToString() const;
template void base_blob<160>::SetHex(const char*);
template void base_blob<160>::SetHex(const std::string&);
// Explicit instantiations for base_blob<256>
template base_blob<256>::base_blob(const std::vector<unsigned char>&);
template std::string base_blob<256>::GetHex() const;
template std::string base_blob<256>::ToString() const;
template void base_blob<256>::SetHex(const char*);
template void base_blob<256>::SetHex(const std::string&);
static void inline HashMix(uint32_t& a, uint32_t& b, uint32_t& c)
{
// Taken from lookup3, by Bob Jenkins.
a -= c;
a ^= ((c << 4) | (c >> 28));
c += b;
b -= a;
b ^= ((a << 6) | (a >> 26));
a += c;
c -= b;
c ^= ((b << 8) | (b >> 24));
b += a;
a -= c;
a ^= ((c << 16) | (c >> 16));
c += b;
b -= a;
b ^= ((a << 19) | (a >> 13));
a += c;
c -= b;
c ^= ((b << 4) | (b >> 28));
b += a;
}
static void inline HashFinal(uint32_t& a, uint32_t& b, uint32_t& c)
{
// Taken from lookup3, by Bob Jenkins.
c ^= b;
c -= ((b << 14) | (b >> 18));
a ^= c;
a -= ((c << 11) | (c >> 21));
b ^= a;
b -= ((a << 25) | (a >> 7));
c ^= b;
c -= ((b << 16) | (b >> 16));
a ^= c;
a -= ((c << 4) | (c >> 28));
b ^= a;
b -= ((a << 14) | (a >> 18));
c ^= b;
c -= ((b << 24) | (b >> 8));
}
uint64_t uint256::GetHash(const uint256& salt) const
{
uint32_t a, b, c;
const uint32_t *pn = (const uint32_t*)data;
const uint32_t *salt_pn = (const uint32_t*)salt.data;
a = b = c = 0xdeadbeef + WIDTH;
a += pn[0] ^ salt_pn[0];
b += pn[1] ^ salt_pn[1];
c += pn[2] ^ salt_pn[2];
HashMix(a, b, c);
a += pn[3] ^ salt_pn[3];
b += pn[4] ^ salt_pn[4];
c += pn[5] ^ salt_pn[5];
HashMix(a, b, c);
a += pn[6] ^ salt_pn[6];
b += pn[7] ^ salt_pn[7];
HashFinal(a, b, c);
return ((((uint64_t)b) << 32) | c);
}

View File

@@ -1,158 +0,0 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_UINT256_H
#define BITCOIN_UINT256_H
#include <assert.h>
#include <cstring>
#include <stdexcept>
#include <stdint.h>
#include <string>
#include <vector>
/** Template base class for fixed-sized opaque blobs. */
template<unsigned int BITS>
class base_blob
{
protected:
enum { WIDTH=BITS/8 };
uint8_t data[WIDTH];
public:
base_blob()
{
memset(data, 0, sizeof(data));
}
explicit base_blob(const std::vector<unsigned char>& vch);
bool IsNull() const
{
for (int i = 0; i < WIDTH; i++)
if (data[i] != 0)
return false;
return true;
}
void SetNull()
{
memset(data, 0, sizeof(data));
}
friend inline bool operator==(const base_blob& a, const base_blob& b) { return memcmp(a.data, b.data, sizeof(a.data)) == 0; }
friend inline bool operator!=(const base_blob& a, const base_blob& b) { return memcmp(a.data, b.data, sizeof(a.data)) != 0; }
friend inline bool operator<(const base_blob& a, const base_blob& b) { return memcmp(a.data, b.data, sizeof(a.data)) < 0; }
std::string GetHex() const;
void SetHex(const char* psz);
void SetHex(const std::string& str);
std::string ToString() const;
unsigned char* begin()
{
return &data[0];
}
unsigned char* end()
{
return &data[WIDTH];
}
const unsigned char* begin() const
{
return &data[0];
}
const unsigned char* end() const
{
return &data[WIDTH];
}
unsigned int size() const
{
return sizeof(data);
}
unsigned int GetSerializeSize(int nType, int nVersion) const
{
return sizeof(data);
}
template<typename Stream>
void Serialize(Stream& s, int nType, int nVersion) const
{
s.write((char*)data, sizeof(data));
}
template<typename Stream>
void Unserialize(Stream& s, int nType, int nVersion)
{
s.read((char*)data, sizeof(data));
}
};
/** 160-bit opaque blob.
* @note This type is called uint160 for historical reasons only. It is an opaque
* blob of 160 bits and has no integer operations.
*/
class uint160 : public base_blob<160> {
public:
uint160() {}
uint160(const base_blob<160>& b) : base_blob<160>(b) {}
explicit uint160(const std::vector<unsigned char>& vch) : base_blob<160>(vch) {}
};
/** 256-bit opaque blob.
* @note This type is called uint256 for historical reasons only. It is an
* opaque blob of 256 bits and has no integer operations. Use arith_uint256 if
* those are required.
*/
class uint256 : public base_blob<256> {
public:
uint256() {}
uint256(const base_blob<256>& b) : base_blob<256>(b) {}
explicit uint256(const std::vector<unsigned char>& vch) : base_blob<256>(vch) {}
/** A cheap hash function that just returns 64 bits from the result, it can be
* used when the contents are considered uniformly random. It is not appropriate
* when the value can easily be influenced from outside as e.g. a network adversary could
* provide values to trigger worst-case behavior.
* @note The result of this function is not stable between little and big endian.
*/
uint64_t GetCheapHash() const
{
uint64_t result;
memcpy((void*)&result, (void*)data, 8);
return result;
}
/** A more secure, salted hash function.
* @note This hash is not stable between little and big endian.
*/
uint64_t GetHash(const uint256& salt) const;
};
/* uint256 from const char *.
* This is a separate function because the constructor uint256(const char*) can result
* in dangerously catching uint256(0).
*/
inline uint256 uint256S(const char *str)
{
uint256 rv;
rv.SetHex(str);
return rv;
}
/* uint256 from std::string.
* This is a separate function because the constructor uint256(const std::string &str) can result
* in dangerously catching uint256(0) via std::string(const char*).
*/
inline uint256 uint256S(const std::string& str)
{
uint256 rv;
rv.SetHex(str);
return rv;
}
#endif // BITCOIN_UINT256_H

View File

@@ -1,155 +0,0 @@
/* Macros to swap the order of bytes in integer values.
Copyright (C) 1997-2014 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#if !defined _BYTESWAP_H && !defined _NETINET_IN_H && !defined _ENDIAN_H
# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
#endif
#ifndef _BITS_BYTESWAP_H
#define _BITS_BYTESWAP_H 1
#include <features.h>
#include <bits/types.h>
#include <bits/wordsize.h>
/* Swap bytes in 16 bit value. */
#define __bswap_constant_16(x) \
((unsigned short int) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)))
/* Get __bswap_16. */
#include <bits/byteswap-16.h>
/* Swap bytes in 32 bit value. */
#define __bswap_constant_32(x) \
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
#ifdef __GNUC__
# if __GNUC_PREREQ (4, 3)
static __inline unsigned int
__bswap_32 (unsigned int __bsx)
{
return __builtin_bswap32 (__bsx);
}
# elif __GNUC__ >= 2
# if __WORDSIZE == 64 || (defined __i486__ || defined __pentium__ \
|| defined __pentiumpro__ || defined __pentium4__ \
|| defined __k8__ || defined __athlon__ \
|| defined __k6__ || defined __nocona__ \
|| defined __core2__ || defined __geode__ \
|| defined __amdfam10__)
/* To swap the bytes in a word the i486 processors and up provide the
`bswap' opcode. On i386 we have to use three instructions. */
# define __bswap_32(x) \
(__extension__ \
({ unsigned int __v, __x = (x); \
if (__builtin_constant_p (__x)) \
__v = __bswap_constant_32 (__x); \
else \
__asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); \
__v; }))
# else
# define __bswap_32(x) \
(__extension__ \
({ unsigned int __v, __x = (x); \
if (__builtin_constant_p (__x)) \
__v = __bswap_constant_32 (__x); \
else \
__asm__ ("rorw $8, %w0;" \
"rorl $16, %0;" \
"rorw $8, %w0" \
: "=r" (__v) \
: "0" (__x) \
: "cc"); \
__v; }))
# endif
# else
# define __bswap_32(x) \
(__extension__ \
({ unsigned int __x = (x); __bswap_constant_32 (__x); }))
# endif
#else
static __inline unsigned int
__bswap_32 (unsigned int __bsx)
{
return __bswap_constant_32 (__bsx);
}
#endif
#if __GNUC_PREREQ (2, 0)
/* Swap bytes in 64 bit value. */
# define __bswap_constant_64(x) \
(__extension__ ((((x) & 0xff00000000000000ull) >> 56) \
| (((x) & 0x00ff000000000000ull) >> 40) \
| (((x) & 0x0000ff0000000000ull) >> 24) \
| (((x) & 0x000000ff00000000ull) >> 8) \
| (((x) & 0x00000000ff000000ull) << 8) \
| (((x) & 0x0000000000ff0000ull) << 24) \
| (((x) & 0x000000000000ff00ull) << 40) \
| (((x) & 0x00000000000000ffull) << 56)))
# if __GNUC_PREREQ (4, 3)
static __inline __uint64_t
__bswap_64 (__uint64_t __bsx)
{
return __builtin_bswap64 (__bsx);
}
# elif __WORDSIZE == 64
# define __bswap_64(x) \
(__extension__ \
({ __uint64_t __v, __x = (x); \
if (__builtin_constant_p (__x)) \
__v = __bswap_constant_64 (__x); \
else \
__asm__ ("bswap %q0" : "=r" (__v) : "0" (__x)); \
__v; }))
# else
# define __bswap_64(x) \
(__extension__ \
({ union { __extension__ __uint64_t __ll; \
unsigned int __l[2]; } __w, __r; \
if (__builtin_constant_p (x)) \
__r.__ll = __bswap_constant_64 (x); \
else \
{ \
__w.__ll = (x); \
__r.__l[0] = __bswap_32 (__w.__l[1]); \
__r.__l[1] = __bswap_32 (__w.__l[0]); \
} \
__r.__ll; }))
# endif
#else
# define __bswap_constant_64(x) \
((((x) & 0xff00000000000000ull) >> 56) \
| (((x) & 0x00ff000000000000ull) >> 40) \
| (((x) & 0x0000ff0000000000ull) >> 24) \
| (((x) & 0x000000ff00000000ull) >> 8) \
| (((x) & 0x00000000ff000000ull) << 8) \
| (((x) & 0x0000000000ff0000ull) << 24) \
| (((x) & 0x000000000000ff00ull) << 40) \
| (((x) & 0x00000000000000ffull) << 56))
static __inline __uint64_t
__bswap_64 (__uint64_t __bsx)
{
return __bswap_constant_64 (__bsx);
}
#endif
#endif /* _BITS_BYTESWAP_H */

View File

@@ -1,103 +0,0 @@
/* Copyright (C) 1992-2014 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
// cloned from /usr/endian.h and modified
#ifndef _ENDIAN_H
#define _ENDIAN_H 1
//#include <features.h>
/* Definitions for byte order, according to significance of bytes,
from low addresses to high addresses. The value is what you get by
putting '4' in the most significant byte, '3' in the second most
significant byte, '2' in the second least significant byte, and '1'
in the least significant byte, and then writing down one digit for
each byte, starting with the byte at the lowest address at the left,
and proceeding to the byte with the highest address at the right. */
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#define __PDP_ENDIAN 3412
/* This file defines `__BYTE_ORDER' for the particular machine. */
//#include <bits/endian.h>
#define __BYTE_ORDER __LITTLE_ENDIAN
/* Some machines may need to use a different endianness for floating point
values. */
#ifndef __FLOAT_WORD_ORDER
# define __FLOAT_WORD_ORDER __BYTE_ORDER
#endif
#ifdef __USE_BSD
# define LITTLE_ENDIAN __LITTLE_ENDIAN
# define BIG_ENDIAN __BIG_ENDIAN
# define PDP_ENDIAN __PDP_ENDIAN
# define BYTE_ORDER __BYTE_ORDER
#endif
#if __BYTE_ORDER == __LITTLE_ENDIAN
# define __LONG_LONG_PAIR(HI, LO) LO, HI
#elif __BYTE_ORDER == __BIG_ENDIAN
# define __LONG_LONG_PAIR(HI, LO) HI, LO
#endif
#if defined __USE_BSD && !defined __ASSEMBLER__
/* Conversion interfaces. */
//# include <bits/byteswap.h>
#include "my-byteswap.h"
# if __BYTE_ORDER == __LITTLE_ENDIAN
# define htobe16(x) __bswap_16 (x)
# define htole16(x) (x)
# define be16toh(x) __bswap_16 (x)
# define le16toh(x) (x)
# define htobe32(x) __bswap_32 (x)
# define htole32(x) (x)
# define be32toh(x) __bswap_32 (x)
# define le32toh(x) (x)
# define htobe64(x) __bswap_64 (x)
# define htole64(x) (x)
# define be64toh(x) __bswap_64 (x)
# define le64toh(x) (x)
# else
# define htobe16(x) (x)
# define htole16(x) __bswap_16 (x)
# define be16toh(x) (x)
# define le16toh(x) __bswap_16 (x)
# define htobe32(x) (x)
# define htole32(x) __bswap_32 (x)
# define be32toh(x) (x)
# define le32toh(x) __bswap_32 (x)
# define htobe64(x) (x)
# define htole64(x) __bswap_64 (x)
# define be64toh(x) (x)
# define le64toh(x) __bswap_64 (x)
# endif
#endif
#endif /* endian.h */

View File

@@ -1,862 +0,0 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_SERIALIZE_H
#define BITCOIN_SERIALIZE_H
#if ((defined(_WIN64) || defined(__WINDOWS__)))
#include "hodl-endian.h"
#endif
#include <algorithm>
#include <assert.h>
#include <ios>
#include <limits>
#include <map>
#include <set>
#include <stdint.h>
#include <string>
#include <string.h>
#include <utility>
#include <vector>
class CScript;
static const unsigned int MAX_SIZE = 0x02000000;
/**
* Used to bypass the rule against non-const reference to temporary
* where it makes sense with wrappers such as CFlatData or CTxDB
*/
template<typename T>
inline T& REF(const T& val)
{
return const_cast<T&>(val);
}
/**
* Used to acquire a non-const pointer "this" to generate bodies
* of const serialization operations from a template
*/
template<typename T>
inline T* NCONST_PTR(const T* val)
{
return const_cast<T*>(val);
}
/**
* Get begin pointer of vector (non-const version).
* @note These functions avoid the undefined case of indexing into an empty
* vector, as well as that of indexing after the end of the vector.
*/
template <class T, class TAl>
inline T* begin_ptr(std::vector<T,TAl>& v)
{
return v.empty() ? NULL : &v[0];
}
/** Get begin pointer of vector (const version) */
template <class T, class TAl>
inline const T* begin_ptr(const std::vector<T,TAl>& v)
{
return v.empty() ? NULL : &v[0];
}
/** Get end pointer of vector (non-const version) */
template <class T, class TAl>
inline T* end_ptr(std::vector<T,TAl>& v)
{
return v.empty() ? NULL : (&v[0] + v.size());
}
/** Get end pointer of vector (const version) */
template <class T, class TAl>
inline const T* end_ptr(const std::vector<T,TAl>& v)
{
return v.empty() ? NULL : (&v[0] + v.size());
}
/*
* Lowest-level serialization and conversion.
* @note Sizes of these types are verified in the tests
*/
template<typename Stream> inline void ser_writedata8(Stream &s, uint8_t obj)
{
s.write((char*)&obj, 1);
}
template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj)
{
obj = htole16(obj);
s.write((char*)&obj, 2);
}
template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj)
{
obj = htole32(obj);
s.write((char*)&obj, 4);
}
template<typename Stream> inline void ser_writedata64(Stream &s, uint64_t obj)
{
obj = htole64(obj);
s.write((char*)&obj, 8);
}
template<typename Stream> inline uint8_t ser_readdata8(Stream &s)
{
uint8_t obj;
s.read((char*)&obj, 1);
return obj;
}
template<typename Stream> inline uint16_t ser_readdata16(Stream &s)
{
uint16_t obj;
s.read((char*)&obj, 2);
return le16toh(obj);
}
template<typename Stream> inline uint32_t ser_readdata32(Stream &s)
{
uint32_t obj;
s.read((char*)&obj, 4);
return le32toh(obj);
}
template<typename Stream> inline uint64_t ser_readdata64(Stream &s)
{
uint64_t obj;
s.read((char*)&obj, 8);
return le64toh(obj);
}
inline uint64_t ser_double_to_uint64(double x)
{
union { double x; uint64_t y; } tmp;
tmp.x = x;
return tmp.y;
}
inline uint32_t ser_float_to_uint32(float x)
{
union { float x; uint32_t y; } tmp;
tmp.x = x;
return tmp.y;
}
inline double ser_uint64_to_double(uint64_t y)
{
union { double x; uint64_t y; } tmp;
tmp.y = y;
return tmp.x;
}
inline float ser_uint32_to_float(uint32_t y)
{
union { float x; uint32_t y; } tmp;
tmp.y = y;
return tmp.x;
}
/////////////////////////////////////////////////////////////////
//
// Templates for serializing to anything that looks like a stream,
// i.e. anything that supports .read(char*, size_t) and .write(char*, size_t)
//
enum
{
// primary actions
SER_NETWORK = (1 << 0),
SER_DISK = (1 << 1),
SER_GETHASH = (1 << 2),
};
#define READWRITE(obj) (::SerReadWrite(s, (obj), nType, nVersion, ser_action))
/**
* Implement three methods for serializable objects. These are actually wrappers over
* "SerializationOp" template, which implements the body of each class' serialization
* code. Adding "ADD_SERIALIZE_METHODS" in the body of the class causes these wrappers to be
* added as members.
*/
#define ADD_SERIALIZE_METHODS \
size_t GetSerializeSize(int nType, int nVersion) const { \
CSizeComputer s(nType, nVersion); \
NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize(), nType, nVersion);\
return s.size(); \
} \
template<typename Stream> \
void Serialize(Stream& s, int nType, int nVersion) const { \
NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize(), nType, nVersion);\
} \
template<typename Stream> \
void Unserialize(Stream& s, int nType, int nVersion) { \
SerializationOp(s, CSerActionUnserialize(), nType, nVersion); \
}
/*
* Basic Types
*/
inline unsigned int GetSerializeSize(char a, int, int=0) { return 1; }
inline unsigned int GetSerializeSize(int8_t a, int, int=0) { return 1; }
inline unsigned int GetSerializeSize(uint8_t a, int, int=0) { return 1; }
inline unsigned int GetSerializeSize(int16_t a, int, int=0) { return 2; }
inline unsigned int GetSerializeSize(uint16_t a, int, int=0) { return 2; }
inline unsigned int GetSerializeSize(int32_t a, int, int=0) { return 4; }
inline unsigned int GetSerializeSize(uint32_t a, int, int=0) { return 4; }
inline unsigned int GetSerializeSize(int64_t a, int, int=0) { return 8; }
inline unsigned int GetSerializeSize(uint64_t a, int, int=0) { return 8; }
inline unsigned int GetSerializeSize(float a, int, int=0) { return 4; }
inline unsigned int GetSerializeSize(double a, int, int=0) { return 8; }
template<typename Stream> inline void Serialize(Stream& s, char a, int, int=0) { ser_writedata8(s, a); } // TODO Get rid of bare char
template<typename Stream> inline void Serialize(Stream& s, int8_t a, int, int=0) { ser_writedata8(s, a); }
template<typename Stream> inline void Serialize(Stream& s, uint8_t a, int, int=0) { ser_writedata8(s, a); }
template<typename Stream> inline void Serialize(Stream& s, int16_t a, int, int=0) { ser_writedata16(s, a); }
template<typename Stream> inline void Serialize(Stream& s, uint16_t a, int, int=0) { ser_writedata16(s, a); }
template<typename Stream> inline void Serialize(Stream& s, int32_t a, int, int=0) { ser_writedata32(s, a); }
template<typename Stream> inline void Serialize(Stream& s, uint32_t a, int, int=0) { ser_writedata32(s, a); }
template<typename Stream> inline void Serialize(Stream& s, int64_t a, int, int=0) { ser_writedata64(s, a); }
template<typename Stream> inline void Serialize(Stream& s, uint64_t a, int, int=0) { ser_writedata64(s, a); }
template<typename Stream> inline void Serialize(Stream& s, float a, int, int=0) { ser_writedata32(s, ser_float_to_uint32(a)); }
template<typename Stream> inline void Serialize(Stream& s, double a, int, int=0) { ser_writedata64(s, ser_double_to_uint64(a)); }
template<typename Stream> inline void Unserialize(Stream& s, char& a, int, int=0) { a = ser_readdata8(s); } // TODO Get rid of bare char
template<typename Stream> inline void Unserialize(Stream& s, int8_t& a, int, int=0) { a = ser_readdata8(s); }
template<typename Stream> inline void Unserialize(Stream& s, uint8_t& a, int, int=0) { a = ser_readdata8(s); }
template<typename Stream> inline void Unserialize(Stream& s, int16_t& a, int, int=0) { a = ser_readdata16(s); }
template<typename Stream> inline void Unserialize(Stream& s, uint16_t& a, int, int=0) { a = ser_readdata16(s); }
template<typename Stream> inline void Unserialize(Stream& s, int32_t& a, int, int=0) { a = ser_readdata32(s); }
template<typename Stream> inline void Unserialize(Stream& s, uint32_t& a, int, int=0) { a = ser_readdata32(s); }
template<typename Stream> inline void Unserialize(Stream& s, int64_t& a, int, int=0) { a = ser_readdata64(s); }
template<typename Stream> inline void Unserialize(Stream& s, uint64_t& a, int, int=0) { a = ser_readdata64(s); }
template<typename Stream> inline void Unserialize(Stream& s, float& a, int, int=0) { a = ser_uint32_to_float(ser_readdata32(s)); }
template<typename Stream> inline void Unserialize(Stream& s, double& a, int, int=0) { a = ser_uint64_to_double(ser_readdata64(s)); }
inline unsigned int GetSerializeSize(bool a, int, int=0) { return sizeof(char); }
template<typename Stream> inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; ser_writedata8(s, f); }
template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0) { char f=ser_readdata8(s); a=f; }
/**
* Compact Size
* size < 253 -- 1 byte
* size <= USHRT_MAX -- 3 bytes (253 + 2 bytes)
* size <= UINT_MAX -- 5 bytes (254 + 4 bytes)
* size > UINT_MAX -- 9 bytes (255 + 8 bytes)
*/
inline unsigned int GetSizeOfCompactSize(uint64_t nSize)
{
if (nSize < 253) return sizeof(unsigned char);
else if (nSize <= std::numeric_limits<unsigned short>::max()) return sizeof(unsigned char) + sizeof(unsigned short);
else if (nSize <= std::numeric_limits<unsigned int>::max()) return sizeof(unsigned char) + sizeof(unsigned int);
else return sizeof(unsigned char) + sizeof(uint64_t);
}
template<typename Stream>
void WriteCompactSize(Stream& os, uint64_t nSize)
{
if (nSize < 253)
{
ser_writedata8(os, nSize);
}
else if (nSize <= std::numeric_limits<unsigned short>::max())
{
ser_writedata8(os, 253);
ser_writedata16(os, nSize);
}
else if (nSize <= std::numeric_limits<unsigned int>::max())
{
ser_writedata8(os, 254);
ser_writedata32(os, nSize);
}
else
{
ser_writedata8(os, 255);
ser_writedata64(os, nSize);
}
return;
}
template<typename Stream>
uint64_t ReadCompactSize(Stream& is)
{
uint8_t chSize = ser_readdata8(is);
uint64_t nSizeRet = 0;
if (chSize < 253)
{
nSizeRet = chSize;
}
else if (chSize == 253)
{
nSizeRet = ser_readdata16(is);
if (nSizeRet < 253)
throw std::ios_base::failure("non-canonical ReadCompactSize()");
}
else if (chSize == 254)
{
nSizeRet = ser_readdata32(is);
if (nSizeRet < 0x10000u)
throw std::ios_base::failure("non-canonical ReadCompactSize()");
}
else
{
nSizeRet = ser_readdata64(is);
if (nSizeRet < 0x100000000ULL)
throw std::ios_base::failure("non-canonical ReadCompactSize()");
}
if (nSizeRet > (uint64_t)MAX_SIZE)
throw std::ios_base::failure("ReadCompactSize(): size too large");
return nSizeRet;
}
/**
* Variable-length integers: bytes are a MSB base-128 encoding of the number.
* The high bit in each byte signifies whether another digit follows. To make
* sure the encoding is one-to-one, one is subtracted from all but the last digit.
* Thus, the byte sequence a[] with length len, where all but the last byte
* has bit 128 set, encodes the number:
*
* (a[len-1] & 0x7F) + sum(i=1..len-1, 128^i*((a[len-i-1] & 0x7F)+1))
*
* Properties:
* * Very small (0-127: 1 byte, 128-16511: 2 bytes, 16512-2113663: 3 bytes)
* * Every integer has exactly one encoding
* * Encoding does not depend on size of original integer type
* * No redundancy: every (infinite) byte sequence corresponds to a list
* of encoded integers.
*
* 0: [0x00] 256: [0x81 0x00]
* 1: [0x01] 16383: [0xFE 0x7F]
* 127: [0x7F] 16384: [0xFF 0x00]
* 128: [0x80 0x00] 16511: [0x80 0xFF 0x7F]
* 255: [0x80 0x7F] 65535: [0x82 0xFD 0x7F]
* 2^32: [0x8E 0xFE 0xFE 0xFF 0x00]
*/
template<typename I>
inline unsigned int GetSizeOfVarInt(I n)
{
int nRet = 0;
while(true) {
nRet++;
if (n <= 0x7F)
break;
n = (n >> 7) - 1;
}
return nRet;
}
template<typename Stream, typename I>
void WriteVarInt(Stream& os, I n)
{
unsigned char tmp[(sizeof(n)*8+6)/7];
int len=0;
while(true) {
tmp[len] = (n & 0x7F) | (len ? 0x80 : 0x00);
if (n <= 0x7F)
break;
n = (n >> 7) - 1;
len++;
}
do {
ser_writedata8(os, tmp[len]);
} while(len--);
}
template<typename Stream, typename I>
I ReadVarInt(Stream& is)
{
I n = 0;
while(true) {
unsigned char chData = ser_readdata8(is);
n = (n << 7) | (chData & 0x7F);
if (chData & 0x80)
n++;
else
return n;
}
}
#define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
#define VARINT(obj) REF(WrapVarInt(REF(obj)))
#define LIMITED_STRING(obj,n) REF(LimitedString< n >(REF(obj)))
/**
* Wrapper for serializing arrays and POD.
*/
class CFlatData
{
protected:
char* pbegin;
char* pend;
public:
CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) { }
template <class T, class TAl>
explicit CFlatData(std::vector<T,TAl> &v)
{
pbegin = (char*)begin_ptr(v);
pend = (char*)end_ptr(v);
}
char* begin() { return pbegin; }
const char* begin() const { return pbegin; }
char* end() { return pend; }
const char* end() const { return pend; }
unsigned int GetSerializeSize(int, int=0) const
{
return pend - pbegin;
}
template<typename Stream>
void Serialize(Stream& s, int, int=0) const
{
s.write(pbegin, pend - pbegin);
}
template<typename Stream>
void Unserialize(Stream& s, int, int=0)
{
s.read(pbegin, pend - pbegin);
}
};
template<typename I>
class CVarInt
{
protected:
I &n;
public:
CVarInt(I& nIn) : n(nIn) { }
unsigned int GetSerializeSize(int, int) const {
return GetSizeOfVarInt<I>(n);
}
template<typename Stream>
void Serialize(Stream &s, int, int) const {
WriteVarInt<Stream,I>(s, n);
}
template<typename Stream>
void Unserialize(Stream& s, int, int) {
n = ReadVarInt<Stream,I>(s);
}
};
template<size_t Limit>
class LimitedString
{
protected:
std::string& string;
public:
LimitedString(std::string& string) : string(string) {}
template<typename Stream>
void Unserialize(Stream& s, int, int=0)
{
size_t size = ReadCompactSize(s);
if (size > Limit) {
throw std::ios_base::failure("String length limit exceeded");
}
string.resize(size);
if (size != 0)
s.read((char*)&string[0], size);
}
template<typename Stream>
void Serialize(Stream& s, int, int=0) const
{
WriteCompactSize(s, string.size());
if (!string.empty())
s.write((char*)&string[0], string.size());
}
unsigned int GetSerializeSize(int, int=0) const
{
return GetSizeOfCompactSize(string.size()) + string.size();
}
};
template<typename I>
CVarInt<I> WrapVarInt(I& n) { return CVarInt<I>(n); }
/**
* Forward declarations
*/
/**
* string
*/
template<typename C> unsigned int GetSerializeSize(const std::basic_string<C>& str, int, int=0);
template<typename Stream, typename C> void Serialize(Stream& os, const std::basic_string<C>& str, int, int=0);
template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_string<C>& str, int, int=0);
/**
* vector
* vectors of unsigned char are a special case and are intended to be serialized as a single opaque blob.
*/
template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&);
template<typename T, typename A, typename V> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const V&);
template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion);
template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&);
template<typename Stream, typename T, typename A, typename V> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const V&);
template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion);
template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const unsigned char&);
template<typename Stream, typename T, typename A, typename V> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const V&);
template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion);
/**
* others derived from vector
*/
extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion);
template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion);
template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion);
/**
* pair
*/
template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion);
template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion);
template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion);
/**
* map
*/
template<typename K, typename T, typename Pred, typename A> unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion);
template<typename Stream, typename K, typename T, typename Pred, typename A> void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion);
template<typename Stream, typename K, typename T, typename Pred, typename A> void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion);
/**
* set
*/
template<typename K, typename Pred, typename A> unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion);
template<typename Stream, typename K, typename Pred, typename A> void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion);
template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion);
/**
* If none of the specialized versions above matched, default to calling member function.
* "int nType" is changed to "long nType" to keep from getting an ambiguous overload error.
* The compiler will only cast int to long if none of the other templates matched.
* Thanks to Boost serialization for this idea.
*/
template<typename T>
inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion)
{
return a.GetSerializeSize((int)nType, nVersion);
}
template<typename Stream, typename T>
inline void Serialize(Stream& os, const T& a, long nType, int nVersion)
{
a.Serialize(os, (int)nType, nVersion);
}
template<typename Stream, typename T>
inline void Unserialize(Stream& is, T& a, long nType, int nVersion)
{
a.Unserialize(is, (int)nType, nVersion);
}
/**
* string
*/
template<typename C>
unsigned int GetSerializeSize(const std::basic_string<C>& str, int, int)
{
return GetSizeOfCompactSize(str.size()) + str.size() * sizeof(str[0]);
}
template<typename Stream, typename C>
void Serialize(Stream& os, const std::basic_string<C>& str, int, int)
{
WriteCompactSize(os, str.size());
if (!str.empty())
os.write((char*)&str[0], str.size() * sizeof(str[0]));
}
template<typename Stream, typename C>
void Unserialize(Stream& is, std::basic_string<C>& str, int, int)
{
unsigned int nSize = ReadCompactSize(is);
str.resize(nSize);
if (nSize != 0)
is.read((char*)&str[0], nSize * sizeof(str[0]));
}
/**
* vector
*/
template<typename T, typename A>
unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&)
{
return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T));
}
template<typename T, typename A, typename V>
unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const V&)
{
unsigned int nSize = GetSizeOfCompactSize(v.size());
for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
nSize += GetSerializeSize((*vi), nType, nVersion);
return nSize;
}
template<typename T, typename A>
inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion)
{
return GetSerializeSize_impl(v, nType, nVersion, T());
}
template<typename Stream, typename T, typename A>
void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&)
{
WriteCompactSize(os, v.size());
if (!v.empty())
os.write((char*)&v[0], v.size() * sizeof(T));
}
template<typename Stream, typename T, typename A, typename V>
void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const V&)
{
WriteCompactSize(os, v.size());
for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
::Serialize(os, (*vi), nType, nVersion);
}
template<typename Stream, typename T, typename A>
inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion)
{
Serialize_impl(os, v, nType, nVersion, T());
}
template<typename Stream, typename T, typename A>
void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const unsigned char&)
{
// Limit size per read so bogus size value won't cause out of memory
v.clear();
unsigned int nSize = ReadCompactSize(is);
unsigned int i = 0;
while (i < nSize)
{
unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
v.resize(i + blk);
is.read((char*)&v[i], blk * sizeof(T));
i += blk;
}
}
template<typename Stream, typename T, typename A, typename V>
void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const V&)
{
v.clear();
unsigned int nSize = ReadCompactSize(is);
unsigned int i = 0;
unsigned int nMid = 0;
while (nMid < nSize)
{
nMid += 5000000 / sizeof(T);
if (nMid > nSize)
nMid = nSize;
v.resize(nMid);
for (; i < nMid; i++)
Unserialize(is, v[i], nType, nVersion);
}
}
template<typename Stream, typename T, typename A>
inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion)
{
Unserialize_impl(is, v, nType, nVersion, T());
}
/**
* others derived from vector
*/
inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion)
{
return GetSerializeSize((const std::vector<unsigned char>&)v, nType, nVersion);
}
template<typename Stream>
void Serialize(Stream& os, const CScript& v, int nType, int nVersion)
{
Serialize(os, (const std::vector<unsigned char>&)v, nType, nVersion);
}
template<typename Stream>
void Unserialize(Stream& is, CScript& v, int nType, int nVersion)
{
Unserialize(is, (std::vector<unsigned char>&)v, nType, nVersion);
}
/**
* pair
*/
template<typename K, typename T>
unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion)
{
return GetSerializeSize(item.first, nType, nVersion) + GetSerializeSize(item.second, nType, nVersion);
}
template<typename Stream, typename K, typename T>
void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion)
{
Serialize(os, item.first, nType, nVersion);
Serialize(os, item.second, nType, nVersion);
}
template<typename Stream, typename K, typename T>
void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion)
{
Unserialize(is, item.first, nType, nVersion);
Unserialize(is, item.second, nType, nVersion);
}
/**
* map
*/
template<typename K, typename T, typename Pred, typename A>
unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion)
{
unsigned int nSize = GetSizeOfCompactSize(m.size());
for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)
nSize += GetSerializeSize((*mi), nType, nVersion);
return nSize;
}
template<typename Stream, typename K, typename T, typename Pred, typename A>
void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion)
{
WriteCompactSize(os, m.size());
for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)
Serialize(os, (*mi), nType, nVersion);
}
template<typename Stream, typename K, typename T, typename Pred, typename A>
void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion)
{
m.clear();
unsigned int nSize = ReadCompactSize(is);
typename std::map<K, T, Pred, A>::iterator mi = m.begin();
for (unsigned int i = 0; i < nSize; i++)
{
std::pair<K, T> item;
Unserialize(is, item, nType, nVersion);
mi = m.insert(mi, item);
}
}
/**
* set
*/
template<typename K, typename Pred, typename A>
unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion)
{
unsigned int nSize = GetSizeOfCompactSize(m.size());
for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
nSize += GetSerializeSize((*it), nType, nVersion);
return nSize;
}
template<typename Stream, typename K, typename Pred, typename A>
void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion)
{
WriteCompactSize(os, m.size());
for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
Serialize(os, (*it), nType, nVersion);
}
template<typename Stream, typename K, typename Pred, typename A>
void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion)
{
m.clear();
unsigned int nSize = ReadCompactSize(is);
typename std::set<K, Pred, A>::iterator it = m.begin();
for (unsigned int i = 0; i < nSize; i++)
{
K key;
Unserialize(is, key, nType, nVersion);
it = m.insert(it, key);
}
}
/**
* Support for ADD_SERIALIZE_METHODS and READWRITE macro
*/
struct CSerActionSerialize
{
bool ForRead() const { return false; }
};
struct CSerActionUnserialize
{
bool ForRead() const { return true; }
};
template<typename Stream, typename T>
inline void SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action)
{
::Serialize(s, obj, nType, nVersion);
}
template<typename Stream, typename T>
inline void SerReadWrite(Stream& s, T& obj, int nType, int nVersion, CSerActionUnserialize ser_action)
{
::Unserialize(s, obj, nType, nVersion);
}
class CSizeComputer
{
protected:
size_t nSize;
public:
int nType;
int nVersion;
CSizeComputer(int nTypeIn, int nVersionIn) : nSize(0), nType(nTypeIn), nVersion(nVersionIn) {}
CSizeComputer& write(const char *psz, size_t nSize)
{
this->nSize += nSize;
return *this;
}
template<typename T>
CSizeComputer& operator<<(const T& obj)
{
::Serialize(*this, obj, nType, nVersion);
return (*this);
}
size_t size() const {
return nSize;
}
};
#endif // BITCOIN_SERIALIZE_H

View File

@@ -1,187 +0,0 @@
// Copyright (c) 2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "sha256.h"
#include "common.h"
#include <string.h>
// Internal implementation code.
namespace
{
/// Internal SHA-256 implementation.
namespace sha256
{
uint32_t inline Ch(uint32_t x, uint32_t y, uint32_t z) { return z ^ (x & (y ^ z)); }
uint32_t inline Maj(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (z & (x | y)); }
uint32_t inline Sigma0(uint32_t x) { return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10); }
uint32_t inline Sigma1(uint32_t x) { return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7); }
uint32_t inline sigma0(uint32_t x) { return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3); }
uint32_t inline sigma1(uint32_t x) { return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10); }
/** One round of SHA-256. */
void inline Round(uint32_t a, uint32_t b, uint32_t c, uint32_t& d, uint32_t e, uint32_t f, uint32_t g, uint32_t& h, uint32_t k, uint32_t w)
{
uint32_t t1 = h + Sigma1(e) + Ch(e, f, g) + k + w;
uint32_t t2 = Sigma0(a) + Maj(a, b, c);
d += t1;
h = t1 + t2;
}
/** Initialize SHA-256 state. */
void inline Initialize(uint32_t* s)
{
s[0] = 0x6a09e667ul;
s[1] = 0xbb67ae85ul;
s[2] = 0x3c6ef372ul;
s[3] = 0xa54ff53aul;
s[4] = 0x510e527ful;
s[5] = 0x9b05688cul;
s[6] = 0x1f83d9abul;
s[7] = 0x5be0cd19ul;
}
/** Perform one SHA-256 transformation, processing a 64-byte chunk. */
void Transform(uint32_t* s, const unsigned char* chunk)
{
uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = ReadBE32(chunk + 0));
Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = ReadBE32(chunk + 4));
Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = ReadBE32(chunk + 8));
Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = ReadBE32(chunk + 12));
Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = ReadBE32(chunk + 16));
Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = ReadBE32(chunk + 20));
Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = ReadBE32(chunk + 24));
Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = ReadBE32(chunk + 28));
Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = ReadBE32(chunk + 32));
Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = ReadBE32(chunk + 36));
Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = ReadBE32(chunk + 40));
Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = ReadBE32(chunk + 44));
Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = ReadBE32(chunk + 48));
Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = ReadBE32(chunk + 52));
Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = ReadBE32(chunk + 56));
Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = ReadBE32(chunk + 60));
Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0(w1));
Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0(w2));
Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += sigma1(w0) + w11 + sigma0(w3));
Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += sigma1(w1) + w12 + sigma0(w4));
Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += sigma1(w2) + w13 + sigma0(w5));
Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += sigma1(w3) + w14 + sigma0(w6));
Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += sigma1(w4) + w15 + sigma0(w7));
Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += sigma1(w5) + w0 + sigma0(w8));
Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += sigma1(w6) + w1 + sigma0(w9));
Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += sigma1(w7) + w2 + sigma0(w10));
Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += sigma1(w8) + w3 + sigma0(w11));
Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += sigma1(w9) + w4 + sigma0(w12));
Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13));
Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14));
Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15));
Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0(w0));
Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0(w1));
Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0(w2));
Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += sigma1(w0) + w11 + sigma0(w3));
Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += sigma1(w1) + w12 + sigma0(w4));
Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += sigma1(w2) + w13 + sigma0(w5));
Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += sigma1(w3) + w14 + sigma0(w6));
Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += sigma1(w4) + w15 + sigma0(w7));
Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += sigma1(w5) + w0 + sigma0(w8));
Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += sigma1(w6) + w1 + sigma0(w9));
Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += sigma1(w7) + w2 + sigma0(w10));
Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += sigma1(w8) + w3 + sigma0(w11));
Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += sigma1(w9) + w4 + sigma0(w12));
Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += sigma1(w10) + w5 + sigma0(w13));
Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += sigma1(w11) + w6 + sigma0(w14));
Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += sigma1(w12) + w7 + sigma0(w15));
Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0(w0));
Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0(w1));
Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0(w2));
Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += sigma1(w0) + w11 + sigma0(w3));
Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += sigma1(w1) + w12 + sigma0(w4));
Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += sigma1(w2) + w13 + sigma0(w5));
Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += sigma1(w3) + w14 + sigma0(w6));
Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += sigma1(w4) + w15 + sigma0(w7));
Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += sigma1(w5) + w0 + sigma0(w8));
Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += sigma1(w6) + w1 + sigma0(w9));
Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += sigma1(w7) + w2 + sigma0(w10));
Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += sigma1(w8) + w3 + sigma0(w11));
Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += sigma1(w9) + w4 + sigma0(w12));
Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += sigma1(w10) + w5 + sigma0(w13));
Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += sigma1(w11) + w6 + sigma0(w14));
Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15));
Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0(w0));
s[0] += a;
s[1] += b;
s[2] += c;
s[3] += d;
s[4] += e;
s[5] += f;
s[6] += g;
s[7] += h;
}
} // namespace sha256
} // namespace
////// SHA-256
CSHA256::CSHA256() : bytes(0)
{
sha256::Initialize(s);
}
CSHA256& CSHA256::Write(const unsigned char* data, size_t len)
{
const unsigned char* end = data + len;
size_t bufsize = bytes % 64;
if (bufsize && bufsize + len >= 64) {
// Fill the buffer, and process it.
memcpy(buf + bufsize, data, 64 - bufsize);
bytes += 64 - bufsize;
data += 64 - bufsize;
sha256::Transform(s, buf);
bufsize = 0;
}
while (end >= data + 64) {
// Process full chunks directly from the source.
sha256::Transform(s, data);
bytes += 64;
data += 64;
}
if (end > data) {
// Fill the buffer with what remains.
memcpy(buf + bufsize, data, end - data);
bytes += end - data;
}
return *this;
}
void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
{
static const unsigned char pad[64] = {0x80};
unsigned char sizedesc[8];
WriteBE64(sizedesc, bytes << 3);
Write(pad, 1 + ((119 - (bytes % 64)) % 64));
Write(sizedesc, 8);
WriteBE32(hash, s[0]);
WriteBE32(hash + 4, s[1]);
WriteBE32(hash + 8, s[2]);
WriteBE32(hash + 12, s[3]);
WriteBE32(hash + 16, s[4]);
WriteBE32(hash + 20, s[5]);
WriteBE32(hash + 24, s[6]);
WriteBE32(hash + 28, s[7]);
}
CSHA256& CSHA256::Reset()
{
bytes = 0;
sha256::Initialize(s);
return *this;
}

View File

@@ -1,28 +0,0 @@
// Copyright (c) 2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_CRYPTO_SHA256_H
#define BITCOIN_CRYPTO_SHA256_H
#include <stdint.h>
#include <stdlib.h>
/** A hasher class for SHA-256. */
class CSHA256
{
private:
uint32_t s[8];
unsigned char buf[64];
size_t bytes;
public:
static const size_t OUTPUT_SIZE = 32;
CSHA256();
CSHA256& Write(const unsigned char* data, size_t len);
void Finalize(unsigned char hash[OUTPUT_SIZE]);
CSHA256& Reset();
};
#endif // BITCOIN_CRYPTO_SHA256_H

View File

@@ -1,205 +0,0 @@
// Copyright (c) 2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "sha512.h"
#include "common.h"
#include <string.h>
// Internal implementation code.
namespace
{
/// Internal SHA-512 implementation.
namespace sha512
{
uint64_t inline Ch(uint64_t x, uint64_t y, uint64_t z) { return z ^ (x & (y ^ z)); }
uint64_t inline Maj(uint64_t x, uint64_t y, uint64_t z) { return (x & y) | (z & (x | y)); }
uint64_t inline Sigma0(uint64_t x) { return (x >> 28 | x << 36) ^ (x >> 34 | x << 30) ^ (x >> 39 | x << 25); }
uint64_t inline Sigma1(uint64_t x) { return (x >> 14 | x << 50) ^ (x >> 18 | x << 46) ^ (x >> 41 | x << 23); }
uint64_t inline sigma0(uint64_t x) { return (x >> 1 | x << 63) ^ (x >> 8 | x << 56) ^ (x >> 7); }
uint64_t inline sigma1(uint64_t x) { return (x >> 19 | x << 45) ^ (x >> 61 | x << 3) ^ (x >> 6); }
/** One round of SHA-512. */
void inline Round(uint64_t a, uint64_t b, uint64_t c, uint64_t& d, uint64_t e, uint64_t f, uint64_t g, uint64_t& h, uint64_t k, uint64_t w)
{
uint64_t t1 = h + Sigma1(e) + Ch(e, f, g) + k + w;
uint64_t t2 = Sigma0(a) + Maj(a, b, c);
d += t1;
h = t1 + t2;
}
/** Initialize SHA-256 state. */
void inline Initialize(uint64_t* s)
{
s[0] = 0x6a09e667f3bcc908ull;
s[1] = 0xbb67ae8584caa73bull;
s[2] = 0x3c6ef372fe94f82bull;
s[3] = 0xa54ff53a5f1d36f1ull;
s[4] = 0x510e527fade682d1ull;
s[5] = 0x9b05688c2b3e6c1full;
s[6] = 0x1f83d9abfb41bd6bull;
s[7] = 0x5be0cd19137e2179ull;
}
/** Perform one SHA-512 transformation, processing a 128-byte chunk. */
void Transform(uint64_t* s, const unsigned char* chunk)
{
uint64_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
uint64_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
Round(a, b, c, d, e, f, g, h, 0x428a2f98d728ae22ull, w0 = ReadBE64(chunk + 0));
Round(h, a, b, c, d, e, f, g, 0x7137449123ef65cdull, w1 = ReadBE64(chunk + 8));
Round(g, h, a, b, c, d, e, f, 0xb5c0fbcfec4d3b2full, w2 = ReadBE64(chunk + 16));
Round(f, g, h, a, b, c, d, e, 0xe9b5dba58189dbbcull, w3 = ReadBE64(chunk + 24));
Round(e, f, g, h, a, b, c, d, 0x3956c25bf348b538ull, w4 = ReadBE64(chunk + 32));
Round(d, e, f, g, h, a, b, c, 0x59f111f1b605d019ull, w5 = ReadBE64(chunk + 40));
Round(c, d, e, f, g, h, a, b, 0x923f82a4af194f9bull, w6 = ReadBE64(chunk + 48));
Round(b, c, d, e, f, g, h, a, 0xab1c5ed5da6d8118ull, w7 = ReadBE64(chunk + 56));
Round(a, b, c, d, e, f, g, h, 0xd807aa98a3030242ull, w8 = ReadBE64(chunk + 64));
Round(h, a, b, c, d, e, f, g, 0x12835b0145706fbeull, w9 = ReadBE64(chunk + 72));
Round(g, h, a, b, c, d, e, f, 0x243185be4ee4b28cull, w10 = ReadBE64(chunk + 80));
Round(f, g, h, a, b, c, d, e, 0x550c7dc3d5ffb4e2ull, w11 = ReadBE64(chunk + 88));
Round(e, f, g, h, a, b, c, d, 0x72be5d74f27b896full, w12 = ReadBE64(chunk + 96));
Round(d, e, f, g, h, a, b, c, 0x80deb1fe3b1696b1ull, w13 = ReadBE64(chunk + 104));
Round(c, d, e, f, g, h, a, b, 0x9bdc06a725c71235ull, w14 = ReadBE64(chunk + 112));
Round(b, c, d, e, f, g, h, a, 0xc19bf174cf692694ull, w15 = ReadBE64(chunk + 120));
Round(a, b, c, d, e, f, g, h, 0xe49b69c19ef14ad2ull, w0 += sigma1(w14) + w9 + sigma0(w1));
Round(h, a, b, c, d, e, f, g, 0xefbe4786384f25e3ull, w1 += sigma1(w15) + w10 + sigma0(w2));
Round(g, h, a, b, c, d, e, f, 0x0fc19dc68b8cd5b5ull, w2 += sigma1(w0) + w11 + sigma0(w3));
Round(f, g, h, a, b, c, d, e, 0x240ca1cc77ac9c65ull, w3 += sigma1(w1) + w12 + sigma0(w4));
Round(e, f, g, h, a, b, c, d, 0x2de92c6f592b0275ull, w4 += sigma1(w2) + w13 + sigma0(w5));
Round(d, e, f, g, h, a, b, c, 0x4a7484aa6ea6e483ull, w5 += sigma1(w3) + w14 + sigma0(w6));
Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcbd41fbd4ull, w6 += sigma1(w4) + w15 + sigma0(w7));
Round(b, c, d, e, f, g, h, a, 0x76f988da831153b5ull, w7 += sigma1(w5) + w0 + sigma0(w8));
Round(a, b, c, d, e, f, g, h, 0x983e5152ee66dfabull, w8 += sigma1(w6) + w1 + sigma0(w9));
Round(h, a, b, c, d, e, f, g, 0xa831c66d2db43210ull, w9 += sigma1(w7) + w2 + sigma0(w10));
Round(g, h, a, b, c, d, e, f, 0xb00327c898fb213full, w10 += sigma1(w8) + w3 + sigma0(w11));
Round(f, g, h, a, b, c, d, e, 0xbf597fc7beef0ee4ull, w11 += sigma1(w9) + w4 + sigma0(w12));
Round(e, f, g, h, a, b, c, d, 0xc6e00bf33da88fc2ull, w12 += sigma1(w10) + w5 + sigma0(w13));
Round(d, e, f, g, h, a, b, c, 0xd5a79147930aa725ull, w13 += sigma1(w11) + w6 + sigma0(w14));
Round(c, d, e, f, g, h, a, b, 0x06ca6351e003826full, w14 += sigma1(w12) + w7 + sigma0(w15));
Round(b, c, d, e, f, g, h, a, 0x142929670a0e6e70ull, w15 += sigma1(w13) + w8 + sigma0(w0));
Round(a, b, c, d, e, f, g, h, 0x27b70a8546d22ffcull, w0 += sigma1(w14) + w9 + sigma0(w1));
Round(h, a, b, c, d, e, f, g, 0x2e1b21385c26c926ull, w1 += sigma1(w15) + w10 + sigma0(w2));
Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc5ac42aedull, w2 += sigma1(w0) + w11 + sigma0(w3));
Round(f, g, h, a, b, c, d, e, 0x53380d139d95b3dfull, w3 += sigma1(w1) + w12 + sigma0(w4));
Round(e, f, g, h, a, b, c, d, 0x650a73548baf63deull, w4 += sigma1(w2) + w13 + sigma0(w5));
Round(d, e, f, g, h, a, b, c, 0x766a0abb3c77b2a8ull, w5 += sigma1(w3) + w14 + sigma0(w6));
Round(c, d, e, f, g, h, a, b, 0x81c2c92e47edaee6ull, w6 += sigma1(w4) + w15 + sigma0(w7));
Round(b, c, d, e, f, g, h, a, 0x92722c851482353bull, w7 += sigma1(w5) + w0 + sigma0(w8));
Round(a, b, c, d, e, f, g, h, 0xa2bfe8a14cf10364ull, w8 += sigma1(w6) + w1 + sigma0(w9));
Round(h, a, b, c, d, e, f, g, 0xa81a664bbc423001ull, w9 += sigma1(w7) + w2 + sigma0(w10));
Round(g, h, a, b, c, d, e, f, 0xc24b8b70d0f89791ull, w10 += sigma1(w8) + w3 + sigma0(w11));
Round(f, g, h, a, b, c, d, e, 0xc76c51a30654be30ull, w11 += sigma1(w9) + w4 + sigma0(w12));
Round(e, f, g, h, a, b, c, d, 0xd192e819d6ef5218ull, w12 += sigma1(w10) + w5 + sigma0(w13));
Round(d, e, f, g, h, a, b, c, 0xd69906245565a910ull, w13 += sigma1(w11) + w6 + sigma0(w14));
Round(c, d, e, f, g, h, a, b, 0xf40e35855771202aull, w14 += sigma1(w12) + w7 + sigma0(w15));
Round(b, c, d, e, f, g, h, a, 0x106aa07032bbd1b8ull, w15 += sigma1(w13) + w8 + sigma0(w0));
Round(a, b, c, d, e, f, g, h, 0x19a4c116b8d2d0c8ull, w0 += sigma1(w14) + w9 + sigma0(w1));
Round(h, a, b, c, d, e, f, g, 0x1e376c085141ab53ull, w1 += sigma1(w15) + w10 + sigma0(w2));
Round(g, h, a, b, c, d, e, f, 0x2748774cdf8eeb99ull, w2 += sigma1(w0) + w11 + sigma0(w3));
Round(f, g, h, a, b, c, d, e, 0x34b0bcb5e19b48a8ull, w3 += sigma1(w1) + w12 + sigma0(w4));
Round(e, f, g, h, a, b, c, d, 0x391c0cb3c5c95a63ull, w4 += sigma1(w2) + w13 + sigma0(w5));
Round(d, e, f, g, h, a, b, c, 0x4ed8aa4ae3418acbull, w5 += sigma1(w3) + w14 + sigma0(w6));
Round(c, d, e, f, g, h, a, b, 0x5b9cca4f7763e373ull, w6 += sigma1(w4) + w15 + sigma0(w7));
Round(b, c, d, e, f, g, h, a, 0x682e6ff3d6b2b8a3ull, w7 += sigma1(w5) + w0 + sigma0(w8));
Round(a, b, c, d, e, f, g, h, 0x748f82ee5defb2fcull, w8 += sigma1(w6) + w1 + sigma0(w9));
Round(h, a, b, c, d, e, f, g, 0x78a5636f43172f60ull, w9 += sigma1(w7) + w2 + sigma0(w10));
Round(g, h, a, b, c, d, e, f, 0x84c87814a1f0ab72ull, w10 += sigma1(w8) + w3 + sigma0(w11));
Round(f, g, h, a, b, c, d, e, 0x8cc702081a6439ecull, w11 += sigma1(w9) + w4 + sigma0(w12));
Round(e, f, g, h, a, b, c, d, 0x90befffa23631e28ull, w12 += sigma1(w10) + w5 + sigma0(w13));
Round(d, e, f, g, h, a, b, c, 0xa4506cebde82bde9ull, w13 += sigma1(w11) + w6 + sigma0(w14));
Round(c, d, e, f, g, h, a, b, 0xbef9a3f7b2c67915ull, w14 += sigma1(w12) + w7 + sigma0(w15));
Round(b, c, d, e, f, g, h, a, 0xc67178f2e372532bull, w15 += sigma1(w13) + w8 + sigma0(w0));
Round(a, b, c, d, e, f, g, h, 0xca273eceea26619cull, w0 += sigma1(w14) + w9 + sigma0(w1));
Round(h, a, b, c, d, e, f, g, 0xd186b8c721c0c207ull, w1 += sigma1(w15) + w10 + sigma0(w2));
Round(g, h, a, b, c, d, e, f, 0xeada7dd6cde0eb1eull, w2 += sigma1(w0) + w11 + sigma0(w3));
Round(f, g, h, a, b, c, d, e, 0xf57d4f7fee6ed178ull, w3 += sigma1(w1) + w12 + sigma0(w4));
Round(e, f, g, h, a, b, c, d, 0x06f067aa72176fbaull, w4 += sigma1(w2) + w13 + sigma0(w5));
Round(d, e, f, g, h, a, b, c, 0x0a637dc5a2c898a6ull, w5 += sigma1(w3) + w14 + sigma0(w6));
Round(c, d, e, f, g, h, a, b, 0x113f9804bef90daeull, w6 += sigma1(w4) + w15 + sigma0(w7));
Round(b, c, d, e, f, g, h, a, 0x1b710b35131c471bull, w7 += sigma1(w5) + w0 + sigma0(w8));
Round(a, b, c, d, e, f, g, h, 0x28db77f523047d84ull, w8 += sigma1(w6) + w1 + sigma0(w9));
Round(h, a, b, c, d, e, f, g, 0x32caab7b40c72493ull, w9 += sigma1(w7) + w2 + sigma0(w10));
Round(g, h, a, b, c, d, e, f, 0x3c9ebe0a15c9bebcull, w10 += sigma1(w8) + w3 + sigma0(w11));
Round(f, g, h, a, b, c, d, e, 0x431d67c49c100d4cull, w11 += sigma1(w9) + w4 + sigma0(w12));
Round(e, f, g, h, a, b, c, d, 0x4cc5d4becb3e42b6ull, w12 += sigma1(w10) + w5 + sigma0(w13));
Round(d, e, f, g, h, a, b, c, 0x597f299cfc657e2aull, w13 += sigma1(w11) + w6 + sigma0(w14));
Round(c, d, e, f, g, h, a, b, 0x5fcb6fab3ad6faecull, w14 + sigma1(w12) + w7 + sigma0(w15));
Round(b, c, d, e, f, g, h, a, 0x6c44198c4a475817ull, w15 + sigma1(w13) + w8 + sigma0(w0));
s[0] += a;
s[1] += b;
s[2] += c;
s[3] += d;
s[4] += e;
s[5] += f;
s[6] += g;
s[7] += h;
}
} // namespace sha512
} // namespace
////// SHA-512
CSHA512::CSHA512() : bytes(0)
{
sha512::Initialize(s);
}
CSHA512& CSHA512::Write(const unsigned char* data, size_t len)
{
const unsigned char* end = data + len;
size_t bufsize = bytes % 128;
if (bufsize && bufsize + len >= 128) {
// Fill the buffer, and process it.
memcpy(buf + bufsize, data, 128 - bufsize);
bytes += 128 - bufsize;
data += 128 - bufsize;
sha512::Transform(s, buf);
bufsize = 0;
}
while (end >= data + 128) {
// Process full chunks directly from the source.
sha512::Transform(s, data);
data += 128;
bytes += 128;
}
if (end > data) {
// Fill the buffer with what remains.
memcpy(buf + bufsize, data, end - data);
bytes += end - data;
}
return *this;
}
void CSHA512::Finalize(unsigned char hash[OUTPUT_SIZE])
{
static const unsigned char pad[128] = {0x80};
unsigned char sizedesc[16] = {0x00};
WriteBE64(sizedesc + 8, bytes << 3);
Write(pad, 1 + ((239 - (bytes % 128)) % 128));
Write(sizedesc, 16);
WriteBE64(hash, s[0]);
WriteBE64(hash + 8, s[1]);
WriteBE64(hash + 16, s[2]);
WriteBE64(hash + 24, s[3]);
WriteBE64(hash + 32, s[4]);
WriteBE64(hash + 40, s[5]);
WriteBE64(hash + 48, s[6]);
WriteBE64(hash + 56, s[7]);
}
CSHA512& CSHA512::Reset()
{
bytes = 0;
sha512::Initialize(s);
return *this;
}

View File

@@ -1,28 +0,0 @@
// Copyright (c) 2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_CRYPTO_SHA512_H
#define BITCOIN_CRYPTO_SHA512_H
#include <stdint.h>
#include <stdlib.h>
/** A hasher class for SHA-512. */
class CSHA512
{
private:
uint64_t s[8];
unsigned char buf[128];
size_t bytes;
public:
static const size_t OUTPUT_SIZE = 64;
CSHA512();
CSHA512& Write(const unsigned char* data, size_t len);
void Finalize(unsigned char hash[OUTPUT_SIZE]);
CSHA512& Reset();
};
#endif // BITCOIN_CRYPTO_SHA512_H

File diff suppressed because it is too large Load Diff

View File

@@ -1,497 +0,0 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "utilstrencodings.h"
#include "tinyformat.h"
#include <cstdlib>
#include <cstring>
#include <errno.h>
#include <limits>
using namespace std;
string SanitizeString(const string& str)
{
/**
* safeChars chosen to allow simple messages/URLs/email addresses, but avoid anything
* even possibly remotely dangerous like & or >
*/
static string safeChars("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890 .,;_/:?@()");
string strResult;
for (std::string::size_type i = 0; i < str.size(); i++)
{
if (safeChars.find(str[i]) != std::string::npos)
strResult.push_back(str[i]);
}
return strResult;
}
const signed char p_util_hexdigit[256] =
{ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,
-1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, };
signed char HexDigit(char c)
{
return p_util_hexdigit[(unsigned char)c];
}
bool IsHex(const string& str)
{
for(std::string::const_iterator it(str.begin()); it != str.end(); ++it)
{
if (HexDigit(*it) < 0)
return false;
}
return (str.size() > 0) && (str.size()%2 == 0);
}
vector<unsigned char> ParseHex(const char* psz)
{
// convert hex dump to vector
vector<unsigned char> vch;
while (true)
{
while (isspace(*psz))
psz++;
signed char c = HexDigit(*psz++);
if (c == (signed char)-1)
break;
unsigned char n = (c << 4);
c = HexDigit(*psz++);
if (c == (signed char)-1)
break;
n |= c;
vch.push_back(n);
}
return vch;
}
vector<unsigned char> ParseHex(const string& str)
{
return ParseHex(str.c_str());
}
string EncodeBase64(const unsigned char* pch, size_t len)
{
static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
string strRet="";
strRet.reserve((len+2)/3*4);
int mode=0, left=0;
const unsigned char *pchEnd = pch+len;
while (pch<pchEnd)
{
int enc = *(pch++);
switch (mode)
{
case 0: // we have no bits
strRet += pbase64[enc >> 2];
left = (enc & 3) << 4;
mode = 1;
break;
case 1: // we have two bits
strRet += pbase64[left | (enc >> 4)];
left = (enc & 15) << 2;
mode = 2;
break;
case 2: // we have four bits
strRet += pbase64[left | (enc >> 6)];
strRet += pbase64[enc & 63];
mode = 0;
break;
}
}
if (mode)
{
strRet += pbase64[left];
strRet += '=';
if (mode == 1)
strRet += '=';
}
return strRet;
}
string EncodeBase64(const string& str)
{
return EncodeBase64((const unsigned char*)str.c_str(), str.size());
}
vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid)
{
static const int decode64_table[256] =
{
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
-1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
if (pfInvalid)
*pfInvalid = false;
vector<unsigned char> vchRet;
vchRet.reserve(strlen(p)*3/4);
int mode = 0;
int left = 0;
while (1)
{
int dec = decode64_table[(unsigned char)*p];
if (dec == -1) break;
p++;
switch (mode)
{
case 0: // we have no bits and get 6
left = dec;
mode = 1;
break;
case 1: // we have 6 bits and keep 4
vchRet.push_back((left<<2) | (dec>>4));
left = dec & 15;
mode = 2;
break;
case 2: // we have 4 bits and get 6, we keep 2
vchRet.push_back((left<<4) | (dec>>2));
left = dec & 3;
mode = 3;
break;
case 3: // we have 2 bits and get 6
vchRet.push_back((left<<6) | dec);
mode = 0;
break;
}
}
if (pfInvalid)
switch (mode)
{
case 0: // 4n base64 characters processed: ok
break;
case 1: // 4n+1 base64 character processed: impossible
*pfInvalid = true;
break;
case 2: // 4n+2 base64 characters processed: require '=='
if (left || p[0] != '=' || p[1] != '=' || decode64_table[(unsigned char)p[2]] != -1)
*pfInvalid = true;
break;
case 3: // 4n+3 base64 characters processed: require '='
if (left || p[0] != '=' || decode64_table[(unsigned char)p[1]] != -1)
*pfInvalid = true;
break;
}
return vchRet;
}
string DecodeBase64(const string& str)
{
vector<unsigned char> vchRet = DecodeBase64(str.c_str());
return (vchRet.size() == 0) ? string() : string((const char*)&vchRet[0], vchRet.size());
}
string EncodeBase32(const unsigned char* pch, size_t len)
{
static const char *pbase32 = "abcdefghijklmnopqrstuvwxyz234567";
string strRet="";
strRet.reserve((len+4)/5*8);
int mode=0, left=0;
const unsigned char *pchEnd = pch+len;
while (pch<pchEnd)
{
int enc = *(pch++);
switch (mode)
{
case 0: // we have no bits
strRet += pbase32[enc >> 3];
left = (enc & 7) << 2;
mode = 1;
break;
case 1: // we have three bits
strRet += pbase32[left | (enc >> 6)];
strRet += pbase32[(enc >> 1) & 31];
left = (enc & 1) << 4;
mode = 2;
break;
case 2: // we have one bit
strRet += pbase32[left | (enc >> 4)];
left = (enc & 15) << 1;
mode = 3;
break;
case 3: // we have four bits
strRet += pbase32[left | (enc >> 7)];
strRet += pbase32[(enc >> 2) & 31];
left = (enc & 3) << 3;
mode = 4;
break;
case 4: // we have two bits
strRet += pbase32[left | (enc >> 5)];
strRet += pbase32[enc & 31];
mode = 0;
}
}
static const int nPadding[5] = {0, 6, 4, 3, 1};
if (mode)
{
strRet += pbase32[left];
for (int n=0; n<nPadding[mode]; n++)
strRet += '=';
}
return strRet;
}
string EncodeBase32(const string& str)
{
return EncodeBase32((const unsigned char*)str.c_str(), str.size());
}
vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid)
{
static const int decode32_table[256] =
{
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1,
-1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 0, 1, 2,
3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
23, 24, 25, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
if (pfInvalid)
*pfInvalid = false;
vector<unsigned char> vchRet;
vchRet.reserve((strlen(p))*5/8);
int mode = 0;
int left = 0;
while (1)
{
int dec = decode32_table[(unsigned char)*p];
if (dec == -1) break;
p++;
switch (mode)
{
case 0: // we have no bits and get 5
left = dec;
mode = 1;
break;
case 1: // we have 5 bits and keep 2
vchRet.push_back((left<<3) | (dec>>2));
left = dec & 3;
mode = 2;
break;
case 2: // we have 2 bits and keep 7
left = left << 5 | dec;
mode = 3;
break;
case 3: // we have 7 bits and keep 4
vchRet.push_back((left<<1) | (dec>>4));
left = dec & 15;
mode = 4;
break;
case 4: // we have 4 bits, and keep 1
vchRet.push_back((left<<4) | (dec>>1));
left = dec & 1;
mode = 5;
break;
case 5: // we have 1 bit, and keep 6
left = left << 5 | dec;
mode = 6;
break;
case 6: // we have 6 bits, and keep 3
vchRet.push_back((left<<2) | (dec>>3));
left = dec & 7;
mode = 7;
break;
case 7: // we have 3 bits, and keep 0
vchRet.push_back((left<<5) | dec);
mode = 0;
break;
}
}
if (pfInvalid)
switch (mode)
{
case 0: // 8n base32 characters processed: ok
break;
case 1: // 8n+1 base32 characters processed: impossible
case 3: // +3
case 6: // +6
*pfInvalid = true;
break;
case 2: // 8n+2 base32 characters processed: require '======'
if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || p[4] != '=' || p[5] != '=' || decode32_table[(unsigned char)p[6]] != -1)
*pfInvalid = true;
break;
case 4: // 8n+4 base32 characters processed: require '===='
if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || decode32_table[(unsigned char)p[4]] != -1)
*pfInvalid = true;
break;
case 5: // 8n+5 base32 characters processed: require '==='
if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || decode32_table[(unsigned char)p[3]] != -1)
*pfInvalid = true;
break;
case 7: // 8n+7 base32 characters processed: require '='
if (left || p[0] != '=' || decode32_table[(unsigned char)p[1]] != -1)
*pfInvalid = true;
break;
}
return vchRet;
}
string DecodeBase32(const string& str)
{
vector<unsigned char> vchRet = DecodeBase32(str.c_str());
return (vchRet.size() == 0) ? string() : string((const char*)&vchRet[0], vchRet.size());
}
bool ParseInt32(const std::string& str, int32_t *out)
{
char *endp = NULL;
errno = 0; // strtol will not set errno if valid
long int n = strtol(str.c_str(), &endp, 10);
if(out) *out = (int)n;
// Note that strtol returns a *long int*, so even if strtol doesn't report a over/underflow
// we still have to check that the returned value is within the range of an *int32_t*. On 64-bit
// platforms the size of these types may be different.
return endp && *endp == 0 && !errno &&
n >= std::numeric_limits<int32_t>::min() &&
n <= std::numeric_limits<int32_t>::max();
}
std::string FormatParagraph(const std::string in, size_t width, size_t indent)
{
std::stringstream out;
size_t col = 0;
size_t ptr = 0;
while(ptr < in.size())
{
// Find beginning of next word
ptr = in.find_first_not_of(' ', ptr);
if (ptr == std::string::npos)
break;
// Find end of next word
size_t endword = in.find_first_of(' ', ptr);
if (endword == std::string::npos)
endword = in.size();
// Add newline and indentation if this wraps over the allowed width
if (col > 0)
{
if ((col + endword - ptr) > width)
{
out << '\n';
for(size_t i=0; i<indent; ++i)
out << ' ';
col = 0;
} else
out << ' ';
}
// Append word
out << in.substr(ptr, endword - ptr);
col += endword - ptr + 1;
ptr = endword;
}
return out.str();
}
std::string i64tostr(int64_t n)
{
return strprintf("%d", n);
}
std::string itostr(int n)
{
return strprintf("%d", n);
}
int64_t atoi64(const char* psz)
{
#ifdef _MSC_VER
return _atoi64(psz);
#else
return strtoll(psz, NULL, 10);
#endif
}
int64_t atoi64(const std::string& str)
{
#ifdef _MSC_VER
return _atoi64(str.c_str());
#else
return strtoll(str.c_str(), NULL, 10);
#endif
}
int atoi(const std::string& str)
{
return atoi(str.c_str());
}

View File

@@ -1,98 +0,0 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
/**
* Utilities for converting data from/to strings.
*/
#ifndef BITCOIN_UTILSTRENCODINGS_H
#define BITCOIN_UTILSTRENCODINGS_H
#include <stdint.h>
#include <string>
#include <vector>
#define BEGIN(a) ((char*)&(a))
#define END(a) ((char*)&((&(a))[1]))
#define UBEGIN(a) ((unsigned char*)&(a))
#define UEND(a) ((unsigned char*)&((&(a))[1]))
#define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0]))
/** This is needed because the foreach macro can't get over the comma in pair<t1, t2> */
#define PAIRTYPE(t1, t2) std::pair<t1, t2>
std::string SanitizeString(const std::string& str);
std::vector<unsigned char> ParseHex(const char* psz);
std::vector<unsigned char> ParseHex(const std::string& str);
signed char HexDigit(char c);
bool IsHex(const std::string& str);
std::vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid = NULL);
std::string DecodeBase64(const std::string& str);
std::string EncodeBase64(const unsigned char* pch, size_t len);
std::string EncodeBase64(const std::string& str);
std::vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid = NULL);
std::string DecodeBase32(const std::string& str);
std::string EncodeBase32(const unsigned char* pch, size_t len);
std::string EncodeBase32(const std::string& str);
std::string i64tostr(int64_t n);
std::string itostr(int n);
int64_t atoi64(const char* psz);
int64_t atoi64(const std::string& str);
int atoi(const std::string& str);
/**
* Convert string to signed 32-bit integer with strict parse error feedback.
* @returns true if the entire string could be parsed as valid integer,
* false if not the entire string could be parsed or when overflow or underflow occurred.
*/
bool ParseInt32(const std::string& str, int32_t *out);
template<typename T>
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
{
std::string rv;
static const char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
rv.reserve((itend-itbegin)*3);
for(T it = itbegin; it < itend; ++it)
{
unsigned char val = (unsigned char)(*it);
if(fSpaces && it != itbegin)
rv.push_back(' ');
rv.push_back(hexmap[val>>4]);
rv.push_back(hexmap[val&15]);
}
return rv;
}
template<typename T>
inline std::string HexStr(const T& vch, bool fSpaces=false)
{
return HexStr(vch.begin(), vch.end(), fSpaces);
}
/**
* Format a paragraph of text to a fixed width, adding spaces for
* indentation to any added line.
*/
std::string FormatParagraph(const std::string in, size_t width=79, size_t indent=0);
/**
* Timing-attack-resistant comparison.
* Takes time proportional to length
* of first argument.
*/
template <typename T>
bool TimingResistantEqual(const T& a, const T& b)
{
if (b.size() == 0) return a.size() == 0;
size_t accumulator = a.size() ^ b.size();
for (size_t i = 0; i < a.size(); i++)
accumulator |= a[i] ^ b[i%b.size()];
return accumulator == 0;
}
#endif // BITCOIN_UTILSTRENCODINGS_H

166
algo/jh/jha.c Normal file
View File

@@ -0,0 +1,166 @@
#include "miner.h"
#include "algo-gate-api.h"
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include "algo/blake/sph_blake.h"
#include "algo/jh/sph_jh.h"
#include "algo/keccak/sph_keccak.h"
#include "algo/skein/sph_skein.h"
#ifdef NO_AES_NI
#include "algo/groestl/sph_groestl.h"
#else
#include "algo/groestl/aes_ni/hash-groestl.h"
#endif
static __thread sph_keccak512_context jha_kec_mid __attribute__ ((aligned (64)));
void jha_kec_midstate( const void* input )
{
sph_keccak512_init( &jha_kec_mid );
sph_keccak512( &jha_kec_mid, input, 64 );
}
void jha_hash(void *output, const void *input)
{
uint8_t _ALIGN(128) hash[64];
#ifdef NO_AES_NI
sph_groestl512_context ctx_groestl;
#else
hashState_groestl ctx_groestl;
#endif
sph_blake512_context ctx_blake;
sph_jh512_context ctx_jh;
sph_keccak512_context ctx_keccak;
sph_skein512_context ctx_skein;
sph_keccak512_init(&ctx_keccak);
memcpy( &ctx_keccak, &jha_kec_mid, sizeof jha_kec_mid );
sph_keccak512(&ctx_keccak, input+64, 16 );
sph_keccak512_close(&ctx_keccak, hash );
// Heavy & Light Pair Loop
for (int round = 0; round < 3; round++)
{
if (hash[0] & 0x01)
{
#ifdef NO_AES_NI
sph_groestl512_init(&ctx_groestl);
sph_groestl512(&ctx_groestl, hash, 64 );
sph_groestl512_close(&ctx_groestl, hash );
#else
init_groestl( &ctx_groestl, 64 );
update_and_final_groestl( &ctx_groestl, (char*)hash,
(char*)hash, 512 );
#endif
}
else
{
sph_skein512_init(&ctx_skein);
sph_skein512(&ctx_skein, hash, 64);
sph_skein512_close(&ctx_skein, hash );
}
if (hash[0] & 0x01)
{
sph_blake512_init(&ctx_blake);
sph_blake512(&ctx_blake, hash, 64);
sph_blake512_close(&ctx_blake, hash );
}
else
{
sph_jh512_init(&ctx_jh);
sph_jh512(&ctx_jh, hash, 64 );
sph_jh512_close(&ctx_jh, hash );
}
}
memcpy(output, hash, 32);
}
int scanhash_jha(int thr_id, struct work *work, uint32_t max_nonce, uint64_t *hashes_done)
{
uint32_t _ALIGN(128) hash32[8];
uint32_t _ALIGN(128) endiandata[20];
uint32_t *pdata = work->data;
uint32_t *ptarget = work->target;
const uint32_t first_nonce = pdata[19];
const uint32_t Htarg = ptarget[7];
uint32_t n = pdata[19] - 1;
uint64_t htmax[] = {
0,
0xF,
0xFF,
0xFFF,
0xFFFF,
0x10000000
};
uint32_t masks[] = {
0xFFFFFFFF,
0xFFFFFFF0,
0xFFFFFF00,
0xFFFFF000,
0xFFFF0000,
0
};
// we need bigendian data...
for (int i=0; i < 19; i++) {
be32enc(&endiandata[i], pdata[i]);
}
jha_kec_midstate( endiandata );
#ifdef DEBUG_ALGO
printf("[%d] Htarg=%X\n", thr_id, Htarg);
#endif
for (int m=0; m < 6; m++) {
if (Htarg <= htmax[m]) {
uint32_t mask = masks[m];
do {
pdata[19] = ++n;
be32enc(&endiandata[19], n);
jha_hash(hash32, endiandata);
#ifndef DEBUG_ALGO
if ((!(hash32[7] & mask)) && fulltest(hash32, ptarget)) {
work_set_target_ratio(work, hash32);
*hashes_done = n - first_nonce + 1;
return 1;
}
#else
if (!(n % 0x1000) && !thr_id) printf(".");
if (!(hash32[7] & mask)) {
printf("[%d]",thr_id);
if (fulltest(hash32, ptarget)) {
work_set_target_ratio(work, hash32);
*hashes_done = n - first_nonce + 1;
return 1;
}
}
#endif
} while (n < max_nonce && !work_restart[thr_id].restart);
// see blake.c if else to understand the loop on htmax => mask
break;
}
}
*hashes_done = n - first_nonce + 1;
pdata[19] = n;
return 0;
}
bool register_jha_algo( algo_gate_t* gate )
{
gate->optimizations = SSE2_OPT | AES_OPT;
gate->scanhash = (void*)&scanhash_jha;
gate->hash = (void*)&jha_hash;
gate->set_target = (void*)&scrypt_set_target;
return true;
};

View File

@@ -41,7 +41,7 @@ extern "C"{
#endif
#include <stddef.h>
#include "algo/sha3/sph_types.h"
#include "algo/sha/sph_types.h"
/**
* Output size (in bits) for JH-224.

View File

@@ -41,7 +41,7 @@ extern "C"{
#endif
#include <stddef.h>
#include "algo/sha3/sph_types.h"
#include "algo/sha/sph_types.h"
/**
* Output size (in bits) for Keccak-224.

View File

@@ -41,7 +41,7 @@ extern "C"{
#endif
#include <stddef.h>
#include "algo/sha3/sph_types.h"
#include "algo/sha/sph_types.h"
#define QSTATIC static

View File

@@ -4,11 +4,11 @@
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include "sha3/sph_sha2.h"
#include "ripemd/sph_ripemd.h"
//#define DEBUG_ALGO
#include "sha/sph_sha2.h"
#if defined __SHA__
#include <openssl/sha.h>
#endif
#define LBRY_NTIME_INDEX 25
#define LBRY_NBITS_INDEX 26
@@ -16,62 +16,70 @@
#define LBRY_WORK_DATA_SIZE 192
#define LBRY_WORK_CMP_SIZE 76 // same as default
/* Move init out of loop, so init once externally, and then use one single memcpy with that bigger memory block */
typedef struct {
sph_sha256_context sha256;
sph_sha512_context sha512;
sph_ripemd160_context ripemd;
} lbryhash_context_holder;
/* no need to copy, because close reinit the context */
static lbryhash_context_holder ctx;
void init_lbry_contexts(void *dummy)
{
sph_sha256_init(&ctx.sha256);
sph_sha512_init(&ctx.sha512);
sph_ripemd160_init(&ctx.ripemd);
}
void lbry_hash(void* output, const void* input)
{
sph_sha256_context ctx_sha256;
sph_sha512_context ctx_sha512;
sph_ripemd160_context ctx_ripemd;
uint32_t _ALIGN(64) hashA[16];
uint32_t _ALIGN(64) hashB[16];
uint32_t _ALIGN(64) hashC[16];
#if defined __SHA__
SHA256_CTX ctx_sha256 __attribute__ ((aligned (64)));
#else
sph_sha256_context ctx_sha256 __attribute__ ((aligned (64)));
#endif
sph_sha512_context ctx_sha512 __attribute__ ((aligned (64)));
sph_ripemd160_context ctx_ripemd __attribute__ ((aligned (64)));
uint32_t _ALIGN(64) hashA[16];
uint32_t _ALIGN(64) hashB[16];
uint32_t _ALIGN(64) hashC[16];
sph_sha256_init(&ctx_sha256);
sph_sha256 (&ctx_sha256, input, 112);
sph_sha256_close(&ctx_sha256, hashA);
#if defined __SHA__
SHA256_Init( &ctx_sha256 );
SHA256_Update( &ctx_sha256, input, 112 );
SHA256_Final( (unsigned char*) hashA, &ctx_sha256 );
sph_sha256_init(&ctx_sha256);
sph_sha256 (&ctx_sha256, hashA, 32);
sph_sha256_close(&ctx_sha256, hashA);
SHA256_Init( &ctx_sha256 );
SHA256_Update( &ctx_sha256, hashA, 32 );
SHA256_Final( (unsigned char*) hashA, &ctx_sha256 );
#else
sph_sha256_init( &ctx_sha256 );
sph_sha256 ( &ctx_sha256, input, 112 );
sph_sha256_close( &ctx_sha256, hashA );
sph_sha512_init(&ctx_sha512);
sph_sha512 (&ctx_sha512, hashA, 32);
sph_sha512_close(&ctx_sha512, hashA);
sph_sha256_init( &ctx_sha256 );
sph_sha256 ( &ctx_sha256, hashA, 32 );
sph_sha256_close( &ctx_sha256, hashA );
#endif
sph_ripemd160_init(&ctx_ripemd);
sph_ripemd160 (&ctx_ripemd, hashA, 32);
sph_ripemd160_close(&ctx_ripemd, hashB);
sph_sha512_init( &ctx_sha512 );
sph_sha512 ( &ctx_sha512, hashA, 32 );
sph_sha512_close( &ctx_sha512, hashA );
sph_ripemd160_init(&ctx_ripemd);
sph_ripemd160 (&ctx_ripemd, hashA+8, 32);
sph_ripemd160_close(&ctx_ripemd, hashC);
sph_ripemd160_init( &ctx_ripemd );
sph_ripemd160 ( &ctx_ripemd, hashA, 32 );
sph_ripemd160_close( &ctx_ripemd, hashB );
sph_sha256_init(&ctx_sha256);
sph_sha256 (&ctx_sha256, hashB, 20);
sph_sha256 (&ctx_sha256, hashC, 20);
sph_sha256_close(&ctx_sha256, hashA);
sph_ripemd160_init( &ctx_ripemd );
sph_ripemd160 ( &ctx_ripemd, hashA+8, 32 );
sph_ripemd160_close( &ctx_ripemd, hashC );
sph_sha256_init(&ctx_sha256);
sph_sha256 (&ctx_sha256, hashA, 32);
sph_sha256_close(&ctx_sha256, hashA);
#if defined __SHA__
SHA256_Init( &ctx_sha256 );
SHA256_Update( &ctx_sha256, hashB, 20 );
SHA256_Update( &ctx_sha256, hashC, 20 );
SHA256_Final( (unsigned char*) hashA, &ctx_sha256 );
memcpy(output, hashA, 32);
SHA256_Init( &ctx_sha256 );
SHA256_Update( &ctx_sha256, hashA, 32 );
SHA256_Final( (unsigned char*) hashA, &ctx_sha256 );
#else
sph_sha256_init( &ctx_sha256 );
sph_sha256 ( &ctx_sha256, hashB, 20 );
sph_sha256 ( &ctx_sha256, hashC, 20 );
sph_sha256_close( &ctx_sha256, hashA );
sph_sha256_init( &ctx_sha256 );
sph_sha256 ( &ctx_sha256, hashA, 32 );
sph_sha256_close( &ctx_sha256, hashA );
#endif
memcpy( output, hashA, 32 );
}
int scanhash_lbry( int thr_id, struct work *work, uint32_t max_nonce,
@@ -83,8 +91,8 @@ int scanhash_lbry( int thr_id, struct work *work, uint32_t max_nonce,
const uint32_t first_nonce = pdata[27];
const uint32_t Htarg = ptarget[7];
uint32_t hash64[8] __attribute__((aligned(32)));
uint32_t endiandata[32];
uint32_t hash64[8] __attribute__((aligned(64)));
uint32_t endiandata[32] __attribute__ ((aligned (64)));
uint64_t htmax[] = {
0,
@@ -211,9 +219,9 @@ int64_t lbry_get_max64() { return 0x1ffffLL; }
bool register_lbry_algo( algo_gate_t* gate )
{
gate->optimizations = SSE2_OPT | SHA_OPT;
gate->scanhash = (void*)&scanhash_lbry;
gate->hash = (void*)&lbry_hash;
gate->hash_alt = (void*)&lbry_hash;
gate->calc_network_diff = (void*)&lbry_calc_network_diff;
gate->get_max64 = (void*)&lbry_get_max64;
gate->build_stratum_request = (void*)&lbry_le_build_stratum_request;

View File

@@ -41,7 +41,7 @@ extern "C"{
#endif
#include <stddef.h>
#include "algo/sha3/sph_types.h"
#include "algo/sha/sph_types.h"
/**
* Output size (in bits) for Luffa-224.

View File

@@ -25,10 +25,8 @@
#define MULT2(a0,a1) do \
{ \
__m128i b; \
a0 = _mm_xor_si128( a0, _mm_shuffle_epi32( _mm_and_si128(a1,MASK), 16 ) ); \
b = a0; \
a0 = _mm_or_si128( _mm_srli_si128(a0,4), _mm_slli_si128(a1,12) ); \
__m128i b = _mm_xor_si128( a0, _mm_shuffle_epi32( _mm_and_si128(a1,MASK), 16 ) ); \
a0 = _mm_or_si128( _mm_srli_si128(b,4), _mm_slli_si128(a1,12) ); \
a1 = _mm_or_si128( _mm_srli_si128(a1,4), _mm_slli_si128(b,12) ); \
} while(0)
@@ -188,13 +186,10 @@
#define MIXTON1024(r0,r1,r2,r3,s0,s1,s2,s3,p0,p1,p2,p3,q0,q1,q2,q3)\
NMLTOM1024(r0,r1,r2,r3,s0,s1,s2,s3,p0,p1,p2,p3,q0,q1,q2,q3);
static void rnd512( hashState_luffa *state, __m128i msg1, __m128i msg0 );
//static void rnd512( hashState_luffa *state );
static void finalization512( hashState_luffa *state, uint32 *b );
/* initial values of chaining variables */
static const uint32 IV[40] __attribute((aligned(16))) = {
0xdbf78465,0x4eaa6fb4,0x44b051e0,0x6d251e69,
@@ -300,13 +295,17 @@ HashReturn final_luffa(hashState_luffa *state, BitSequence *hashval)
{
// transform pad block
if ( state->rembytes )
{
// not empty, data is in buffer
rnd512( state, casti_m128i( state->buffer, 1 ),
casti_m128i( state->buffer, 0 ) );
}
else
{
// empty pad block, constant data
rnd512( state, _mm_setzero_si128(),
_mm_set_epi8( 0,0,0,0, 0,0,0,0, 0,0,0,0, 0x80,0,0,0 ) );
rnd512( state, _mm_setzero_si128(),
_mm_set_epi8( 0,0,0,0, 0,0,0,0, 0,0,0,0, 0x80,0,0,0 ) );
}
finalization512(state, (uint32*) hashval);
if ( state->hashbitlen > 512 )
@@ -332,13 +331,17 @@ HashReturn update_and_final_luffa( hashState_luffa *state, BitSequence* output,
// 16 byte partial block exists for 80 byte len
if ( state->rembytes )
// remaining 16 data bytes + 16 bytes padding
rnd512( state, _mm_set_epi8( 0,0,0,0, 0,0,0,0, 0,0,0,0, 0x80,0,0,0 ),
{
// padding of partial block
rnd512( state, _mm_set_epi8( 0,0,0,0, 0,0,0,0, 0,0,0,0, 0x80,0,0,0 ),
mm_byteswap_epi32( cast_m128i( data ) ) );
}
else
{
// empty pad block
rnd512( state, _mm_setzero_si128(),
_mm_set_epi8( 0,0,0,0, 0,0,0,0, 0,0,0,0, 0x80,0,0,0 ) );
rnd512( state, _mm_setzero_si128(),
_mm_set_epi8( 0,0,0,0, 0,0,0,0, 0,0,0,0, 0x80,0,0,0 ) );
}
finalization512( state, (uint32*) output );
if ( state->hashbitlen > 512 )
@@ -358,9 +361,6 @@ static void rnd512( hashState_luffa *state, __m128i msg1, __m128i msg0 )
__m128i tmp[2];
__m128i x[8];
// _mm_prefetch( chainv, _MM_HINT_T0 );
// _mm_prefetch( chainv + 4, _MM_HINT_T0 );
t[0] = chainv[0];
t[1] = chainv[1];
@@ -513,25 +513,62 @@ static void rnd512( hashState_luffa *state, __m128i msg1, __m128i msg0 )
tmp[0], tmp[1] );
STEP_PART2( chainv[8], chainv[9], t[0], t[1], CNS128[30], CNS128[31],
tmp[0], tmp[1] );
return;
}
/***************************************************/
/* Finalization function */
/* state: hash context */
/* b[8]: hash values */
#if defined (__AVX2__)
static void finalization512( hashState_luffa *state, uint32 *b )
{
uint32 hash[8] __attribute((aligned(64)));
__m256i* chainv = (__m256i*)state->chainv;
__m256i t;
const __m128i zero = _mm_setzero_si128();
rnd512( state, zero, zero );
t = chainv[0];
t = _mm256_xor_si256( t, chainv[1] );
t = _mm256_xor_si256( t, chainv[2] );
t = _mm256_xor_si256( t, chainv[3] );
t = _mm256_xor_si256( t, chainv[4] );
t = _mm256_shuffle_epi32( t, 27 );
_mm256_store_si256( (__m256i*)hash, t );
casti_m256i( b, 0 ) = mm256_byteswap_epi32( casti_m256i( hash, 0 ) );
rnd512( state, zero, zero );
t = chainv[0];
t = _mm256_xor_si256( t, chainv[1] );
t = _mm256_xor_si256( t, chainv[2] );
t = _mm256_xor_si256( t, chainv[3] );
t = _mm256_xor_si256( t, chainv[4] );
t = _mm256_shuffle_epi32( t, 27 );
_mm256_store_si256( (__m256i*)hash, t );
casti_m256i( b, 1 ) = mm256_byteswap_epi32( casti_m256i( hash, 0 ) );
}
#else
static void finalization512( hashState_luffa *state, uint32 *b )
{
uint32 hash[8] __attribute((aligned(64)));
__m128i* chainv = state->chainv;
__m128i t[2];
const __m128i zero = _mm_setzero_si128();
/*---- blank round with m=0 ----*/
rnd512( state, _mm_setzero_si128(), _mm_setzero_si128() );
// _mm_prefetch( b, _MM_HINT_T0 );
rnd512( state, zero, zero );
t[0] = chainv[0];
t[1] = chainv[1];
@@ -553,7 +590,7 @@ static void finalization512( hashState_luffa *state, uint32 *b )
casti_m128i( b, 0 ) = mm_byteswap_epi32( casti_m128i( hash, 0 ) );
casti_m128i( b, 1 ) = mm_byteswap_epi32( casti_m128i( hash, 1 ) );
rnd512( state, _mm_setzero_si128(), _mm_setzero_si128() );
rnd512( state, zero, zero );
t[0] = chainv[0];
t[1] = chainv[1];
@@ -574,8 +611,7 @@ static void finalization512( hashState_luffa *state, uint32 *b )
casti_m128i( b, 2 ) = mm_byteswap_epi32( casti_m128i( hash, 0 ) );
casti_m128i( b, 3 ) = mm_byteswap_epi32( casti_m128i( hash, 1 ) );
return;
}
#endif
/***************************************************/

View File

@@ -19,7 +19,7 @@
*/
#include <emmintrin.h>
#include "algo/sha3/sha3-defs.h"
#include "algo/sha/sha3-defs.h"
/* The length of digests*/
#define DIGEST_BIT_LEN_224 224
#define DIGEST_BIT_LEN_256 256
@@ -46,8 +46,8 @@
/*********************************/
typedef struct {
uint32 buffer[8] __attribute((aligned(16)));
__m128i chainv[10]; /* Chaining values */
uint32 buffer[8] __attribute((aligned(32)));
__m128i chainv[10] __attribute((aligned(32))); /* Chaining values */
// uint64 bitlen[2]; /* Message length in bits */
// uint32 rembitlen; /* Length of buffer data to be hashed */
int hashbitlen;

View File

@@ -49,11 +49,10 @@ void lyra2_blake256_midstate( const void* input )
void lyra2re_hash(void *state, const void *input)
{
lyra2re_ctx_holder ctx;
lyra2re_ctx_holder ctx __attribute__ ((aligned (64))) ;
memcpy(&ctx, &lyra2re_ctx, sizeof(lyra2re_ctx));
// uint32_t _ALIGN(128) hashA[8], hashB[8];
uint8_t _ALIGN(128) hash[32*8];
uint8_t _ALIGN(64) hash[32*8];
#define hashA hash
#define hashB hash+16
@@ -63,7 +62,6 @@ void lyra2re_hash(void *state, const void *input)
memcpy( &ctx.blake, &lyra2_blake_mid, sizeof lyra2_blake_mid );
sph_blake256( &ctx.blake, input + midlen, tail );
// sph_blake256(&ctx.blake, input, 80);
sph_blake256_close(&ctx.blake, hashA);
sph_keccak256(&ctx.keccak, hashA, 32);
@@ -91,7 +89,7 @@ int scanhash_lyra2re(int thr_id, struct work *work,
uint32_t *pdata = work->data;
uint32_t *ptarget = work->target;
uint32_t _ALIGN(64) endiandata[20];
uint32_t hash[8] __attribute__((aligned(32)));
uint32_t hash[8] __attribute__((aligned(64)));
const uint32_t first_nonce = pdata[19];
uint32_t nonce = first_nonce;
const uint32_t Htarg = ptarget[7];
@@ -161,7 +159,6 @@ bool register_lyra2re_algo( algo_gate_t* gate )
// gate->miner_thread_init = (void*)&lyra2re_thread_init;
gate->scanhash = (void*)&scanhash_lyra2re;
gate->hash = (void*)&lyra2re_hash;
gate->hash_alt = (void*)&lyra2re_hash;
gate->get_max64 = (void*)&lyra2re_get_max64;
gate->set_target = (void*)&lyra2re_set_target;
return true;

View File

@@ -48,10 +48,11 @@ void l2v2_blake256_midstate( const void* input )
void lyra2rev2_hash( void *state, const void *input )
{
lyra2v2_ctx_holder ctx;
lyra2v2_ctx_holder ctx __attribute__ ((aligned (64)));
memcpy( &ctx, &lyra2v2_ctx, sizeof(lyra2v2_ctx) );
uint32_t _ALIGN(128) hashA[8], hashB[8];
uint8_t hash[128] __attribute__ ((aligned (64)));
#define hashA hash
#define hashB hash+64
const int midlen = 64; // bytes
const int tail = 80 - midlen; // 16
@@ -84,8 +85,8 @@ int scanhash_lyra2rev2(int thr_id, struct work *work,
{
uint32_t *pdata = work->data;
uint32_t *ptarget = work->target;
uint32_t _ALIGN(64) endiandata[20];
uint32_t hash[8] __attribute__((aligned(32)));
uint32_t endiandata[20] __attribute__ ((aligned (64)));
uint32_t hash[8] __attribute__((aligned(64)));
const uint32_t first_nonce = pdata[19];
uint32_t nonce = first_nonce;
const uint32_t Htarg = ptarget[7];
@@ -124,7 +125,6 @@ void lyra2rev2_set_target( struct work* work, double job_diff )
work_set_target( work, job_diff / (256.0 * opt_diff_factor) );
}
bool lyra2rev2_thread_init()
{
const int64_t ROW_LEN_INT64 = BLOCK_LEN_INT64 * 4; // nCols
@@ -138,7 +138,7 @@ bool lyra2rev2_thread_init()
#if defined (__AVX2__)
memset_zero_m256i( (__m256i*)l2v2_wholeMatrix, i/32 );
#elif defined(__AVX__)
#elif defined (__AVX__)
memset_zero_m128i( (__m128i*)l2v2_wholeMatrix, i/16 );
#else
memset( l2v2_wholeMatrix, 0, i );
@@ -151,10 +151,9 @@ bool register_lyra2rev2_algo( algo_gate_t* gate )
init_lyra2rev2_ctx();
gate->optimizations = SSE2_OPT | AES_OPT | AVX_OPT | AVX2_OPT;
gate->miner_thread_init = (void*)&lyra2rev2_thread_init;
gate->scanhash = (void*)&scanhash_lyra2rev2;
gate->hash = (void*)&lyra2rev2_hash;
gate->hash_alt = (void*)&lyra2rev2_hash;
gate->set_target = (void*)&lyra2rev2_set_target;
gate->scanhash = (void*)&scanhash_lyra2rev2;
gate->hash = (void*)&lyra2rev2_hash;
gate->set_target = (void*)&lyra2rev2_set_target;
return true;
};

View File

@@ -4,22 +4,23 @@
#include "lyra2.h"
#include "avxdefs.h"
__thread uint64_t* zoin_wholeMatrix;
__thread uint64_t* lyra2z330_wholeMatrix;
void zoin_hash(void *state, const void *input, uint32_t height)
void lyra2z330_hash(void *state, const void *input, uint32_t height)
{
uint32_t _ALIGN(256) hash[16];
LYRA2Z( zoin_wholeMatrix, hash, 32, input, 80, input, 80, 2, 330, 256);
LYRA2Z( lyra2z330_wholeMatrix, hash, 32, input, 80, input, 80,
2, 330, 256 );
memcpy(state, hash, 32);
}
int scanhash_zoin( int thr_id, struct work *work, uint32_t max_nonce,
uint64_t *hashes_done )
int scanhash_lyra2z330( int thr_id, struct work *work, uint32_t max_nonce,
uint64_t *hashes_done )
{
uint32_t _ALIGN(128) hash[8];
uint32_t _ALIGN(128) endiandata[20];
uint32_t hash[8] __attribute__ ((aligned (64)));
uint32_t endiandata[20] __attribute__ ((aligned (64)));
uint32_t *pdata = work->data;
uint32_t *ptarget = work->target;
const uint32_t Htarg = ptarget[7];
@@ -34,7 +35,7 @@ int scanhash_zoin( int thr_id, struct work *work, uint32_t max_nonce,
do {
be32enc(&endiandata[19], nonce);
zoin_hash( hash, endiandata, work->height );
lyra2z330_hash( hash, endiandata, work->height );
if (hash[7] <= Htarg && fulltest(hash, ptarget)) {
work_set_target_ratio(work, hash);
@@ -51,35 +52,28 @@ int scanhash_zoin( int thr_id, struct work *work, uint32_t max_nonce,
return 0;
}
void zoin_set_target( struct work* work, double job_diff )
void lyra2z330_set_target( struct work* work, double job_diff )
{
work_set_target( work, job_diff / (256.0 * opt_diff_factor) );
}
/*
bool zoin_get_work_height( struct work* work, struct stratum_ctx* sctx )
{
work->height = sctx->bloc_height;
return false;
}
*/
bool zoin_thread_init()
bool lyra2z330_thread_init()
{
const int64_t ROW_LEN_INT64 = BLOCK_LEN_INT64 * 256; // nCols
const int64_t ROW_LEN_BYTES = ROW_LEN_INT64 * 8;
int i = (int64_t)ROW_LEN_BYTES * 330; // nRows;
zoin_wholeMatrix = _mm_malloc( i, 64 );
lyra2z330_wholeMatrix = _mm_malloc( i, 64 );
if ( zoin_wholeMatrix == NULL )
if ( lyra2z330_wholeMatrix == NULL )
return false;
#if defined (__AVX2__)
memset_zero_m256i( (__m256i*)zoin_wholeMatrix, i/32 );
memset_zero_m256i( (__m256i*)lyra2z330_wholeMatrix, i/32 );
#elif defined(__AVX__)
memset_zero_m128i( (__m128i*)zoin_wholeMatrix, i/16 );
memset_zero_m128i( (__m128i*)lyra2z330_wholeMatrix, i/16 );
#else
memset( zoin_wholeMatrix, 0, i );
memset( lyra2z330_wholeMatrix, 0, i );
#endif
return true;
}
@@ -87,13 +81,11 @@ bool zoin_thread_init()
bool register_lyra2z330_algo( algo_gate_t* gate )
{
gate->optimizations = SSE2_OPT | AES_OPT | AVX_OPT | AVX2_OPT;
gate->miner_thread_init = (void*)&zoin_thread_init;
gate->scanhash = (void*)&scanhash_zoin;
gate->hash = (void*)&zoin_hash;
gate->hash_alt = (void*)&zoin_hash;
gate->miner_thread_init = (void*)&lyra2z330_thread_init;
gate->scanhash = (void*)&scanhash_lyra2z330;
gate->hash = (void*)&lyra2z330_hash;
gate->get_max64 = (void*)&get_max64_0xffffLL;
gate->set_target = (void*)&zoin_set_target;
// gate->prevent_dupes = (void*)&zoin_get_work_height;
gate->set_target = (void*)&lyra2z330_set_target;
return true;
};

View File

@@ -22,9 +22,9 @@ void zcoin_midstate( const void* input )
//void zcoin_hash(void *state, const void *input, uint32_t height)
void zcoin_hash(void *state, const void *input )
{
uint32_t _ALIGN(256) hash[16];
uint32_t _ALIGN(64) hash[16];
sph_blake256_context ctx_blake;
sph_blake256_context ctx_blake __attribute__ ((aligned (64)));
memcpy( &ctx_blake, &zcoin_blake_mid, sizeof zcoin_blake_mid );
sph_blake256( &ctx_blake, input + 64, 16 );
@@ -38,8 +38,8 @@ void zcoin_hash(void *state, const void *input )
int scanhash_zcoin( int thr_id, struct work *work, uint32_t max_nonce,
uint64_t *hashes_done )
{
uint32_t _ALIGN(128) hash[8];
uint32_t _ALIGN(128) endiandata[20];
uint32_t _ALIGN(64) hash[8];
uint32_t _ALIGN(64) endiandata[20];
uint32_t *pdata = work->data;
uint32_t *ptarget = work->target;
const uint32_t Htarg = ptarget[7];
@@ -115,7 +115,6 @@ bool register_zcoin_algo( algo_gate_t* gate )
gate->miner_thread_init = (void*)&zcoin_thread_init;
gate->scanhash = (void*)&scanhash_zcoin;
gate->hash = (void*)&zcoin_hash;
gate->hash_alt = (void*)&zcoin_hash;
gate->get_max64 = (void*)&get_max64_0xffffLL;
gate->set_target = (void*)&zcoin_set_target;
// gate->prevent_dupes = (void*)&zcoin_get_work_height;

View File

@@ -8,12 +8,16 @@
#include <string.h>
#include <float.h>
#include <math.h>
#include "algo/sha2/sph-sha2.h"
#include "algo/sha/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"
#if defined __SHA__
#include <openssl/sha.h>
#endif
#define EPSa DBL_EPSILON
#define EPS1 DBL_EPSILON
@@ -64,9 +68,7 @@ double GaussianQuad_N2(const double x1, const double x2)
double x[6], w[6];
//gauleg(a2, b2, x, w);
// int m;
double z1, z, xm, xl, pp, p3, p2, p1;
// m=3;
xm=0.5*(x2+x1);
xl=0.5*(x2-x1);
for(int i=1;i<=3;i++)
@@ -117,9 +119,12 @@ uint32_t sw2_(int nnounce)
return ((uint32_t)(GaussianQuad_N2(0., wmax)*(1.+EPSa)*1.e6));
}
typedef struct {
#if defined __SHA__
SHA256_CTX sha256;
#else
sph_sha256_context sha256;
#endif
sph_sha512_context sha512;
sph_keccak512_context keccak;
sph_whirlpool_context whirlpool;
@@ -128,13 +133,15 @@ typedef struct {
sph_ripemd160_context ripemd;
} m7m_ctx_holder;
sph_sha256_context m7m_ctx_final_sha256;
m7m_ctx_holder m7m_ctx;
void init_m7m_ctx()
{
sph_sha256_init( &m7m_ctx_final_sha256 );
#if defined __SHA__
SHA256_Init( &m7m_ctx.sha256 );
#else
sph_sha256_init( &m7m_ctx.sha256 );
#endif
sph_sha512_init( &m7m_ctx.sha512 );
sph_keccak512_init( &m7m_ctx.keccak );
sph_whirlpool_init( &m7m_ctx.whirlpool );
@@ -154,34 +161,41 @@ int scanhash_m7m_hash( int thr_id, struct work* work,
{
uint32_t *pdata = work->data;
uint32_t *ptarget = work->target;
uint32_t data[32] __attribute__((aligned(128)));
uint32_t data[32] __attribute__((aligned(64)));
uint32_t *data_p64 = data + (M7_MIDSTATE_LEN / sizeof(data[0]));
uint32_t hash[8] __attribute__((aligned(32)));
uint8_t bhash[7][64] __attribute__((aligned(32)));
uint32_t hash[8] __attribute__((aligned(64)));
uint8_t bhash[7][64] __attribute__((aligned(64)));
uint32_t n = pdata[19] - 1;
uint32_t usw_, mpzscale;
const uint32_t first_nonce = pdata[19];
char data_str[161], hash_str[65], target_str[65];
//uint8_t *bdata = 0;
uint8_t bdata[8192];
uint8_t bdata[8192] __attribute__ ((aligned (64)));
int rc = 0, i, digits;
int bytes;
size_t p = sizeof(unsigned long), a = 64/p, b = 32/p;
m7m_ctx_holder ctx1, ctx2;
m7m_ctx_holder ctx1, ctx2 __attribute__ ((aligned (64)));
memcpy( &ctx1, &m7m_ctx, sizeof(m7m_ctx) );
#if defined __SHA__
SHA256_CTX ctxf_sha256;
#else
sph_sha256_context ctxf_sha256;
memcpy( &ctxf_sha256, &m7m_ctx_final_sha256, sizeof(ctxf_sha256) );
#endif
memcpy(data, pdata, 80);
sph_sha256( &ctx1.sha256, data, M7_MIDSTATE_LEN );
sph_sha512( &ctx1.sha512, data, M7_MIDSTATE_LEN );
sph_keccak512( &ctx1.keccak, data, M7_MIDSTATE_LEN );
sph_whirlpool( &ctx1.whirlpool, data, M7_MIDSTATE_LEN );
sph_haval256_5( &ctx1.haval, data, M7_MIDSTATE_LEN );
sph_tiger( &ctx1.tiger, data, M7_MIDSTATE_LEN );
sph_ripemd160( &ctx1.ripemd, data, M7_MIDSTATE_LEN );
#if defined __SHA__
SHA256_Update( &ctx1.sha256, data, M7_MIDSTATE_LEN );
#else
sph_sha256( &ctx1.sha256, data, M7_MIDSTATE_LEN );
#endif
sph_sha512( &ctx1.sha512, data, M7_MIDSTATE_LEN );
sph_keccak512( &ctx1.keccak, data, M7_MIDSTATE_LEN );
sph_whirlpool( &ctx1.whirlpool, data, M7_MIDSTATE_LEN );
sph_haval256_5( &ctx1.haval, data, M7_MIDSTATE_LEN );
sph_tiger( &ctx1.tiger, data, M7_MIDSTATE_LEN );
sph_ripemd160( &ctx1.ripemd, data, M7_MIDSTATE_LEN );
mpz_t magipi, magisw, product, bns0, bns1;
mpf_t magifpi, magifpi0, mpt1, mpt2, mptmp, mpten;
@@ -207,9 +221,13 @@ int scanhash_m7m_hash( int thr_id, struct work* work,
memcpy( &ctx2, &ctx1, sizeof(m7m_ctx) );
#if defined __SHA__
SHA256_Update( &ctx2.sha256, data_p64, 80 - M7_MIDSTATE_LEN );
SHA256_Final( (unsigned char*) (bhash[0]), &ctx2.sha256 );
#else
sph_sha256( &ctx2.sha256, data_p64, 80 - M7_MIDSTATE_LEN );
sph_sha256_close( &ctx2.sha256, (void*)(bhash[0]) );
#endif
sph_sha512( &ctx2.sha512, data_p64, 80 - M7_MIDSTATE_LEN );
sph_sha512_close( &ctx2.sha512, (void*)(bhash[1]) );
@@ -243,8 +261,15 @@ int scanhash_m7m_hash( int thr_id, struct work* work,
bytes = mpz_sizeinbase(product, 256);
mpz_export((void *)bdata, NULL, -1, 1, 0, 0, product);
#if defined __SHA__
SHA256_Init( &ctxf_sha256 );
SHA256_Update( &ctxf_sha256, bdata, bytes );
SHA256_Final( (unsigned char*) hash, &ctxf_sha256 );
#else
sph_sha256_init( &ctxf_sha256 );
sph_sha256( &ctxf_sha256, bdata, bytes );
sph_sha256_close( &ctxf_sha256, (void*)(hash) );
#endif
digits=(int)((sqrt((double)(n/2))*(1.+EPS))/9000+75);
mp_bitcnt_t prec = (long int)(digits*BITS_PER_DIGIT+16);
@@ -278,8 +303,15 @@ int scanhash_m7m_hash( int thr_id, struct work* work,
mpzscale=bytes;
mpz_export(bdata, NULL, -1, 1, 0, 0, product);
#if defined __SHA__
SHA256_Init( &ctxf_sha256 );
SHA256_Update( &ctxf_sha256, bdata, bytes );
SHA256_Final( (unsigned char*) hash, &ctxf_sha256 );
#else
sph_sha256_init( &ctxf_sha256 );
sph_sha256( &ctxf_sha256, bdata, bytes );
sph_sha256_close( &ctxf_sha256, (void*)(hash) );
#endif
}
const unsigned char *hash_ = (const unsigned char *)hash;
@@ -329,210 +361,6 @@ out:
return rc;
}
int scanhash_m7m_hash_t(int thr_id, uint32_t *pdata, const uint32_t *ptarget,
uint64_t max_nonce, unsigned long *hashes_done, struct timespec cpu_dec_time)
{
uint32_t data[32] __attribute__((aligned(128)));
uint32_t *data_p64 = data + (M7_MIDSTATE_LEN / sizeof(data[0]));
uint32_t hash[8] __attribute__((aligned(32)));
uint8_t bhash[7][64] __attribute__((aligned(32)));
uint32_t n = pdata[19] - 1;
uint32_t usw_, mpzscale;
const uint32_t first_nonce = pdata[19];
char data_str[161], hash_str[65], target_str[65];
//uint8_t *bdata = 0;
uint8_t bdata[8192];
int rc = 0, i, digits;
int bytes;
size_t p = sizeof(unsigned long), a = 64/p, b = 32/p;
memcpy(data, pdata, 80);
sph_sha256_context ctx_final_sha256;
sph_sha256_context ctx_sha256;
sph_sha512_context ctx_sha512;
sph_keccak512_context ctx_keccak;
sph_whirlpool_context ctx_whirlpool;
sph_haval256_5_context ctx_haval;
sph_tiger_context ctx_tiger;
sph_ripemd160_context ctx_ripemd;
sph_sha256_init(&ctx_final_sha256);
sph_sha256_init(&ctx_sha256);
sph_sha256 (&ctx_sha256, data, M7_MIDSTATE_LEN);
sph_sha512_init(&ctx_sha512);
sph_sha512 (&ctx_sha512, data, M7_MIDSTATE_LEN);
sph_keccak512_init(&ctx_keccak);
sph_keccak512 (&ctx_keccak, data, M7_MIDSTATE_LEN);
sph_whirlpool_init(&ctx_whirlpool);
sph_whirlpool (&ctx_whirlpool, data, M7_MIDSTATE_LEN);
sph_haval256_5_init(&ctx_haval);
sph_haval256_5 (&ctx_haval, data, M7_MIDSTATE_LEN);
sph_tiger_init(&ctx_tiger);
sph_tiger (&ctx_tiger, data, M7_MIDSTATE_LEN);
sph_ripemd160_init(&ctx_ripemd);
sph_ripemd160 (&ctx_ripemd, data, M7_MIDSTATE_LEN);
sph_sha256_context ctx2_sha256;
sph_sha512_context ctx2_sha512;
sph_keccak512_context ctx2_keccak;
sph_whirlpool_context ctx2_whirlpool;
sph_haval256_5_context ctx2_haval;
sph_tiger_context ctx2_tiger;
sph_ripemd160_context ctx2_ripemd;
mpz_t magipi, magisw, product, bns0, bns1;
mpf_t magifpi, magifpi0, mpt1, mpt2, mptmp, mpten;
mpz_inits(magipi, magisw, bns0, bns1, NULL);
mpz_init2(product, 512);
mp_bitcnt_t prec0 = (long int)((int)((sqrt((double)(INT_MAX))*(1.+EPS))/9000+75)*BITS_PER_DIGIT+16);
mpf_set_default_prec(prec0);
mpf_init(magifpi);
mpf_init(magifpi0);
mpf_init(mpt1);
mpf_init(mpt2);
mpf_init(mptmp);
mpf_init_set_ui(mpten, 10);
mpf_set_str(mpt2, "0.8e3b1a9b359805c2e54c6415037f2e336893b6457f7754f6b4ae045eb6c5f2bedb26a114030846be7", 16);
mpf_set_str(magifpi0, "0.b7bfc6837e20bdb22653f1fc419f6bc33ca80eb65b7b0246f7f3b65689560aea1a2f2fd95f254d68c", 16);
do {
data[19] = ++n;
memset(bhash, 0, 7 * 64);
ctx2_sha256 = ctx_sha256;
sph_sha256 (&ctx2_sha256, data_p64, 80 - M7_MIDSTATE_LEN);
sph_sha256_close(&ctx2_sha256, (void*)(bhash[0]));
ctx2_sha512 = ctx_sha512;
sph_sha512 (&ctx2_sha512, data_p64, 80 - M7_MIDSTATE_LEN);
sph_sha512_close(&ctx2_sha512, (void*)(bhash[1]));
ctx2_keccak = ctx_keccak;
sph_keccak512 (&ctx2_keccak, data_p64, 80 - M7_MIDSTATE_LEN);
sph_keccak512_close(&ctx2_keccak, (void*)(bhash[2]));
ctx2_whirlpool = ctx_whirlpool;
sph_whirlpool (&ctx2_whirlpool, data_p64, 80 - M7_MIDSTATE_LEN);
sph_whirlpool_close(&ctx2_whirlpool, (void*)(bhash[3]));
ctx2_haval = ctx_haval;
sph_haval256_5 (&ctx2_haval, data_p64, 80 - M7_MIDSTATE_LEN);
sph_haval256_5_close(&ctx2_haval, (void*)(bhash[4]));
ctx2_tiger = ctx_tiger;
sph_tiger (&ctx2_tiger, data_p64, 80 - M7_MIDSTATE_LEN);
sph_tiger_close(&ctx2_tiger, (void*)(bhash[5]));
ctx2_ripemd = ctx_ripemd;
sph_ripemd160 (&ctx2_ripemd, data_p64, 80 - M7_MIDSTATE_LEN);
sph_ripemd160_close(&ctx2_ripemd, (void*)(bhash[6]));
mpz_import(bns0, a, -1, p, -1, 0, bhash[0]);
mpz_set(bns1, bns0);
mpz_set(product, bns0);
for(int i=1; i < 7; i++){
mpz_import(bns0, a, -1, p, -1, 0, bhash[i]);
mpz_add(bns1, bns1, bns0);
mpz_mul(product, product, bns0);
}
mpz_mul(product, product, bns1);
mpz_mul(product, product, product);
bytes = mpz_sizeinbase(product, 256);
mpz_export((void *)bdata, NULL, -1, 1, 0, 0, product);
sph_sha256 (&ctx_final_sha256, bdata, bytes);
sph_sha256_close(&ctx_final_sha256, (void*)(hash));
digits=(int)((sqrt((double)(n/2))*(1.+EPS))/9000+75);
mp_bitcnt_t prec = (long int)(digits*BITS_PER_DIGIT+16);
mpf_set_prec_raw(magifpi, prec);
mpf_set_prec_raw(mptmp, prec);
mpf_set_prec_raw(mpt1, prec);
mpf_set_prec_raw(mpt2, prec);
usw_ = sw2_(n/2);
mpzscale = 1;
mpz_set_ui(magisw, usw_);
for(i = 0; i < 5; i++)
{
mpf_set_d(mpt1, 0.25*mpzscale);
mpf_sub(mpt1, mpt1, mpt2);
mpf_abs(mpt1, mpt1);
mpf_div(magifpi, magifpi0, mpt1);
mpf_pow_ui(mptmp, mpten, digits >> 1);
mpf_mul(magifpi, magifpi, mptmp);
mpz_set_f(magipi, magifpi);
mpz_add(magipi,magipi,magisw);
mpz_add(product,product,magipi);
mpz_import(bns0, b, -1, p, -1, 0, (void*)(hash));
mpz_add(bns1, bns1, bns0);
mpz_mul(product,product,bns1);
mpz_cdiv_q (product, product, bns0);
bytes = mpz_sizeinbase(product, 256);
mpzscale=bytes;
mpz_export(bdata, NULL, -1, 1, 0, 0, product);
sph_sha256 (&ctx_final_sha256, bdata, bytes);
sph_sha256_close(&ctx_final_sha256, (void*)(hash));
}
if (n%10 == 0) nanosleep(&cpu_dec_time, NULL);
const unsigned char *hash_ = (const unsigned char *)hash;
const unsigned char *target_ = (const unsigned char *)ptarget;
for (i = 31; i >= 0; i--) {
if (hash_[i] != target_[i]) {
rc = hash_[i] < target_[i];
break;
}
}
if (unlikely(rc)) {
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:
mpf_set_prec_raw(magifpi, prec0);
mpf_set_prec_raw(magifpi0, prec0);
mpf_set_prec_raw(mptmp, prec0);
mpf_set_prec_raw(mpt1, prec0);
mpf_set_prec_raw(mpt2, prec0);
mpf_clear(magifpi);
mpf_clear(magifpi0);
mpf_clear(mpten);
mpf_clear(mptmp);
mpf_clear(mpt1);
mpf_clear(mpt2);
mpz_clears(magipi, magisw, product, bns0, bns1, NULL);
*hashes_done = n - first_nonce + 1;
return rc;
}
void m7m_reverse_endian( struct work *work )
{
swab32_array( work->data, work->data, 20 );
@@ -540,7 +368,7 @@ void m7m_reverse_endian( struct work *work )
bool register_m7m_algo( algo_gate_t *gate )
{
gate->optimizations = SSE2_OPT | AES_OPT | AVX_OPT;
gate->optimizations = SSE2_OPT | AES_OPT | AVX_OPT | SHA_OPT;
init_m7m_ctx();
gate->scanhash = (void*)scanhash_m7m_hash;
gate->build_stratum_request = (void*)&std_be_build_stratum_request;

View File

@@ -1085,7 +1085,6 @@ bool register_neoscrypt_algo( algo_gate_t* gate )
{
gate->scanhash = (void*)&scanhash_neoscrypt;
gate->hash = (void*)&neoscrypt;
gate->hash_alt = (void*)&neoscrypt;
gate->get_max64 = (void*)&get_neoscrypt_max64;
gate->set_target = (void*)&scrypt_set_target;
gate->wait_for_diff = (void*)&neoscrypt_wait_for_diff;

View File

@@ -17,10 +17,7 @@
#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
#ifndef NO_AES_NI
#include "algo/groestl/aes_ni/hash-groestl.h"
#endif
@@ -46,14 +43,14 @@ void init_nist5_ctx()
void nist5hash(void *output, const void *input)
{
size_t hashptr;
unsigned char hashbuf[128] __attribute__ ((aligned (32)));
unsigned char hashbuf[128];
sph_u64 hashctA;
sph_u64 hashctB;
unsigned char hash[128];
unsigned char hash[128] __attribute__ ((aligned (64))) ;
#define hashA hash
#define hashB hash+64
nist5_ctx_holder ctx;
nist5_ctx_holder ctx __attribute__ ((aligned (64)));
memcpy( &ctx, &nist5_ctx, sizeof(nist5_ctx) );
DECL_BLK;
@@ -62,15 +59,11 @@ void nist5hash(void *output, const void *input)
BLK_C;
#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);
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);
update_and_final_groestl( &ctx.groestl, (char*)hash,
(const char*)hash, 512 );
#endif
DECL_JH;
@@ -162,7 +155,6 @@ bool register_nist5_algo( algo_gate_t* gate )
init_nist5_ctx();
gate->scanhash = (void*)&scanhash_nist5;
gate->hash = (void*)&nist5hash;
gate->hash_alt = (void*)&nist5hash;
return true;
};

View File

@@ -19,10 +19,7 @@
#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
#ifndef NO_AES_NI
#include "algo/groestl/aes_ni/hash-groestl.h"
#endif
@@ -116,17 +113,14 @@ inline static void quarkhash(void *state, const void *input)
{
#ifdef NO_AES_NI
grsoState sts_grs;
GRS_I;
GRS_U;
GRS_C;
// sph_groestl512_init( &ctx );
// sph_groestl512 ( &ctx, hash, 64 );
// sph_groestl512_close( &ctx, hash );
sph_groestl512_init( &ctx );
sph_groestl512 ( &ctx, hash, 64 );
sph_groestl512_close( &ctx, hash );
#else
reinit_groestl( &ctx );
update_groestl( &ctx, (char*)hash, 512 );
final_groestl( &ctx, (char*)hash );
update_and_final_groestl( &ctx, (char*)hash, (char*)hash, 512 );
// update_groestl( &ctx, (char*)hash, 512 );
// final_groestl( &ctx, (char*)hash );
#endif
} while(0); continue;
@@ -179,83 +173,6 @@ inline static void quarkhash(void *state, const void *input)
memcpy(state, hash, 32);
}
void quarkhash_alt(void *state, const void *input)
{
sph_blake512_context ctx_blake1,
ctx_blake2;
sph_bmw512_context ctx_bmw1,
ctx_bmw2;
sph_groestl512_context ctx_groestl1,
ctx_groestl2;
sph_skein512_context ctx_skein1,
ctx_skein2;
sph_jh512_context ctx_jh1,
ctx_jh2;
sph_keccak512_context ctx_keccak1,
ctx_keccak2;
sph_blake512_init(&ctx_blake1);
sph_bmw512_init(&ctx_bmw1);
sph_groestl512_init(&ctx_groestl1);
sph_skein512_init(&ctx_skein1);
sph_groestl512_init(&ctx_groestl2);
sph_jh512_init(&ctx_jh1);
sph_blake512_init(&ctx_blake2);
sph_bmw512_init(&ctx_bmw2);
sph_keccak512_init(&ctx_keccak1);
sph_skein512_init(&ctx_skein2);
sph_keccak512_init(&ctx_keccak2);
sph_jh512_init(&ctx_jh2);
uint32_t _ALIGN(128) hash[16];
uint32_t mask = 8;
sph_blake512 (&ctx_blake1, input, 80);
sph_blake512_close (&ctx_blake1, hash); //0
sph_bmw512 (&ctx_bmw1, hash, 64);
sph_bmw512_close(&ctx_bmw1, hash); //1
if (hash[0] & mask) {
sph_groestl512 (&ctx_groestl1, hash, 64);
sph_groestl512_close(&ctx_groestl1, hash); //2
} else {
sph_skein512 (&ctx_skein1, hash, 64);
sph_skein512_close(&ctx_skein1, hash); //2
}
sph_groestl512 (&ctx_groestl2, hash, 64);
sph_groestl512_close(&ctx_groestl2, hash); //3
sph_jh512 (&ctx_jh1, hash, 64);
sph_jh512_close(&ctx_jh1, hash); //4
if (hash[0] & mask) {
sph_blake512 (&ctx_blake2, hash, 64);
sph_blake512_close(&ctx_blake2, hash); //5
} else {
sph_bmw512 (&ctx_bmw2, hash, 64);
sph_bmw512_close(&ctx_bmw2, hash); //5
}
sph_keccak512 (&ctx_keccak1, hash, 64);
sph_keccak512_close(&ctx_keccak1, hash); //6
sph_skein512 (&ctx_skein2, hash, 64);
sph_skein512_close(&ctx_skein2, hash); //7
if (hash[0] & mask) {
sph_keccak512 (&ctx_keccak2, hash, 64);
sph_keccak512_close(&ctx_keccak2, hash); //8
} else {
sph_jh512 (&ctx_jh2, hash, 64);
sph_jh512_close(&ctx_jh2, hash); //8
}
memcpy(state, hash, 32);
}
int scanhash_quark( int thr_id, struct work *work, uint32_t max_nonce,
uint64_t *hashes_done)
{
@@ -293,7 +210,6 @@ bool register_quark_algo( algo_gate_t* gate )
gate->optimizations = SSE2_OPT | AES_OPT;
gate->scanhash = (void*)&scanhash_quark;
gate->hash = (void*)&quarkhash;
gate->hash_alt = (void*)&quarkhash_alt;
return true;
};

View File

@@ -34,7 +34,7 @@ typedef struct
#endif
} deep_ctx_holder;
deep_ctx_holder deep_ctx;
deep_ctx_holder deep_ctx __attribute((aligned(64)));
static __thread hashState_luffa deep_luffa_mid;
void init_deep_ctx()
@@ -59,7 +59,7 @@ void deep_hash(void *output, const void *input)
unsigned char hash[128] __attribute((aligned(64)));
#define hashB hash+64
deep_ctx_holder ctx;
deep_ctx_holder ctx __attribute((aligned(64)));
memcpy( &ctx, &deep_ctx, sizeof(deep_ctx) );
const int midlen = 64; // bytes
@@ -156,7 +156,6 @@ bool register_deep_algo( algo_gate_t* gate )
init_deep_ctx();
gate->scanhash = (void*)&scanhash_deep;
gate->hash = (void*)&deep_hash;
// gate->hash_alt = (void*)&qubithash_alt;
return true;
};

View File

@@ -70,65 +70,32 @@ void qubithash(void *output, const void *input)
update_and_final_luffa( &ctx.luffa, (BitSequence*)hash,
(const BitSequence*)input + midlen, tail );
cubehashUpdate( &ctx.cubehash, (const byte*) hash,64);
cubehashDigest( &ctx.cubehash, (byte*)hash);
cubehashUpdateDigest( &ctx.cubehash, (byte*)hash,
(const byte*) hash, 64 );
sph_shavite512( &ctx.shavite, hash, 64);
sph_shavite512_close( &ctx.shavite, hash);
update_sd( &ctx.simd, (const BitSequence *)hash,512);
final_sd( &ctx.simd, (BitSequence *)hash);
update_final_sd( &ctx.simd, (BitSequence *)hash,
(const BitSequence*)hash, 512 );
#ifdef NO_AES_NI
sph_echo512 (&ctx.echo, (const void*) hash, 64);
sph_echo512_close(&ctx.echo, (void*) hash);
#else
update_echo ( &ctx.echo, (const BitSequence *) hash, 512);
final_echo( &ctx.echo, (BitSequence *) hash);
update_final_echo( &ctx.echo, (BitSequence *) hash,
(const BitSequence *) hash, 512 );
#endif
asm volatile ("emms");
memcpy(output, hash, 32);
}
void qubithash_alt(void *output, const void *input)
{
sph_luffa512_context ctx_luffa;
sph_cubehash512_context ctx_cubehash;
sph_shavite512_context ctx_shavite;
sph_simd512_context ctx_simd;
sph_echo512_context ctx_echo;
uint8_t hash[64];
sph_luffa512_init(&ctx_luffa);
sph_luffa512 (&ctx_luffa, input, 80);
sph_luffa512_close(&ctx_luffa, (void*) hash);
sph_cubehash512_init(&ctx_cubehash);
sph_cubehash512 (&ctx_cubehash, (const void*) hash, 64);
sph_cubehash512_close(&ctx_cubehash, (void*) hash);
sph_shavite512_init(&ctx_shavite);
sph_shavite512 (&ctx_shavite, (const void*) hash, 64);
sph_shavite512_close(&ctx_shavite, (void*) hash);
sph_simd512_init(&ctx_simd);
sph_simd512 (&ctx_simd, (const void*) hash, 64);
sph_simd512_close(&ctx_simd, (void*) hash);
sph_echo512_init(&ctx_echo);
sph_echo512 (&ctx_echo, (const void*) hash, 64);
sph_echo512_close(&ctx_echo, (void*) hash);
memcpy(output, hash, 32);
}
int scanhash_qubit(int thr_id, struct work *work,
uint32_t max_nonce, uint64_t *hashes_done)
{
uint32_t endiandata[20] __attribute__((aligned(64)));
uint32_t hash64[8] __attribute__((aligned(32)));
uint32_t hash64[8] __attribute__((aligned(64)));
uint32_t *pdata = work->data;
uint32_t *ptarget = work->target;
uint32_t n = pdata[19] - 1;
@@ -197,7 +164,6 @@ bool register_qubit_algo( algo_gate_t* gate )
init_qubit_ctx();
gate->scanhash = (void*)&scanhash_qubit;
gate->hash = (void*)&qubithash;
gate->hash_alt = (void*)&qubithash_alt;
return true;
};

View File

@@ -263,7 +263,7 @@ sph_ripemd_init(void *cc)
#define RFUN ripemd_round
#define HASH ripemd
#define LE32 1
#include "algo/sha3/md_helper.c"
#include "algo/sha/md_helper.c"
#undef RFUN
#undef HASH
#undef LE32
@@ -517,7 +517,7 @@ sph_ripemd128_init(void *cc)
#define RFUN ripemd128_round
#define HASH ripemd128
#define LE32 1
#include "algo/sha3/md_helper.c"
#include "algo/sha/md_helper.c"
#undef RFUN
#undef HASH
#undef LE32
@@ -810,7 +810,7 @@ sph_ripemd160_init(void *cc)
#define RFUN ripemd160_round
#define HASH ripemd160
#define LE32 1
#include "algo/sha3/md_helper.c"
#include "algo/sha/md_helper.c"
#undef RFUN
#undef HASH
#undef LE32

View File

@@ -57,7 +57,7 @@
#define SPH_RIPEMD_H__
#include <stddef.h>
#include "algo/sha3/sph_types.h"
#include "algo/sha/sph_types.h"
/**
* Output size (in bits) for RIPEMD.

View File

@@ -110,7 +110,6 @@ bool register_s3_algo( algo_gate_t* gate )
algo_not_tested();
gate->scanhash = (void*)&scanhash_s3;
gate->hash = (void*)&s3hash;
gate->hash_alt = (void*)&s3hash;
// gate->get_max64 = &s3_get_max64;
return true;
};

View File

@@ -781,7 +781,6 @@ bool register_scrypt_algo( algo_gate_t* gate )
gate->miner_thread_init =(void*)&scrypt_miner_thread_init;
gate->scanhash = (void*)&scanhash_scrypt;
gate->hash = (void*)&scrypt_1024_1_1_256_24way;
gate->hash_alt = (void*)&scrypt_1024_1_1_256_24way;
gate->set_target = (void*)&scrypt_set_target;
gate->get_max64 = (void*)&scrypt_get_max64;
@@ -789,5 +788,6 @@ bool register_scrypt_algo( algo_gate_t* gate )
scratchbuf_size = 1024;
else
scratchbuf_size = opt_scrypt_n;
return true;
};

View File

@@ -241,7 +241,6 @@ 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*)&scrypt_set_target;
gate->get_max64 = (void*)&get_max64_0x40LL;

Some files were not shown because too many files have changed in this diff Show More