diff --git a/.gitignore b/.gitignore index ca18306c6..1e46f13e7 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,7 @@ web/assets/ .idea/* web/yaamp/.idea/ *.0 +web/keys.sample.php +web/yaamp/modules/site/coin_form.php +web/yaamp/modules/site/index.php +web/yaamp/modules/site/results/current_results.php diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index f9546188c..000000000 --- a/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: cpp -script: - - (cd blocknotify && make) - - (cd stratum/iniparser && make) - - (cd stratum && make) diff --git a/README.md b/README.md index f710ee0d2..dcab8da7f 100644 --- a/README.md +++ b/README.md @@ -1,137 +1,32 @@ -[![Build Status](https://travis-ci.org/tpruvot/yiimp.svg?branch=next)](https://travis-ci.org/tpruvot/yiimp) +### Welcome to the cryptopool.builders github! +### This fork of YiiMP is designed to work with our Ultimate Crypto-Server Installer program. +Trying to install this on a server not built by our installer will cause headaches, frustrations, and screaming loudly at your monitor. -#yiimp - yaamp fork +#### Please go to https://github.com/cryptopool-builders/Multi-Pool-Installer for our installer. -WARNINGS -- Use at your own risks. -- Usage of this software requires abilities with sysadmin, database admin, coin daemons, and sometimes a bit of programming. Running a production pool can literally be more work than a full-time job. +## Changes to this fork include but not limited to: -Required: +``` +- File structure - +$STORAGE_ROOT/yiimp/site/web +$STORAGE_ROOT/yiimp/site/stratum (Only on single server installs) +$STORAGE_ROOT/yiimp/site/configuration +$STORAGE_ROOT/yiimp/site/crons +$STORAGE_ROOT/yiimp/site/log +$STORAGE_ROOT/yiimp/starts - linux, mysql, php, memcached, a webserver (lighttpd or nginx recommended) +- Site Files- +Updated various files to work with new file structure +``` -Config for nginx: +## Donations for continued support of this script are welcomed at: +* BTC 3DvcaPT3Kio8Hgyw4ZA9y1feNnKZjH7Y21 +* BCH qrf2fhk2pfka5k649826z4683tuqehaq2sc65nfz3e +* ETH 0x6A047e5410f433FDBF32D7fb118B6246E3b7C136 +* LTC MLS5pfgb7QMqBm3pmBvuJ7eRCRgwLV25Nz - location / { - try_files $uri @rewrite; - } - - location @rewrite { - rewrite ^/(.*)$ /index.php?r=$1; - } - - location ~ \.php$ { - fastcgi_pass unix:/var/run/php5-fpm.sock; - fastcgi_index index.php; - include fastcgi_params; - } - - -If you use apache, it should be something like that (already set in web/.htaccess): - - RewriteEngine on - - RewriteCond %{REQUEST_FILENAME} !-f - RewriteRule ^(.*) index.php?r=$1 [QSA] - - -If you use lighttpd, use the following config: - - $HTTP["host"] =~ "yiimp.ccminer.org" { - server.document-root = "/var/yaamp/web" - url.rewrite-if-not-file = ( - "^(.*)/([0-9]+)$" => "index.php?r=$1&id=$2", - "^(.*)\?(.*)" => "index.php?r=$1&$2", - "^(.*)" => "index.php?r=$1", - "." => "index.php" - ) - - url.access-deny = ( "~", ".dat", ".log" ) - } - - -For the database, import the initial dump present in the sql/ folder - -Then, apply the migration scripts to be in sync with the current git, they are sorted by date of change. - -Your database need at least 2 users, one for the web site (php) and one for the stratum connections (password set in config/algo.conf). - - - -The recommended install folder for the stratum engine is /var/stratum. Copy all the .conf files, run.sh, the stratum binary and the blocknotify binary to this folder. - -Some scripts are expecting the web folder to be /var/web. You can use directory symlinks... - - -Add your exchange API public and secret keys in these two separated files: - - /etc/yiimp/keys.php - fixed path in code - web/serverconfig.php - use sample as base... - -You can find sample config files in web/serverconfig.sample.php and web/keys.sample.php - -This web application includes some command line tools, add bin/ folder to your path and type "yiimp" to list them, "yiimp checkup" can help to test your initial setup. -Future scripts and maybe the "cron" jobs will then use this yiic console interface. - -You need at least three backend shells (in screen) running these scripts: - - web/main.sh - web/loop2.sh - web/block.sh - -Start one stratum per algo using the run.sh script with the algo as parameter. For example, for x11: - - run.sh x11 - -Edit each .conf file with proper values. - -Look at rc.local, it starts all three backend shells and all stratum processes. Copy it to the /etc folder so that all screen shells are started at boot up. - -All your coin's config files need to blocknotify their corresponding stratum using something like: - - blocknotify=blocknotify yaamp.com:port coinid %s - -On the website, go to http://server.com/site/adminRights to login as admin. You have to change it to something different in the code (web/yaamp/modules/site/SiteController.php). A real admin login may be added later, but you can setup a password authentification with your web server, sample for lighttpd: - - htpasswd -c /etc/yiimp/admin.htpasswd - -and in the lighttpd config file: - - # Admin access - $HTTP["url"] =~ "^/site/adminRights" { - auth.backend = "htpasswd" - auth.backend.htpasswd.userfile = "/etc/yiimp/admin.htpasswd" - auth.require = ( - "/" => ( - "method" => "basic", - "realm" => "Yiimp Administration", - "require" => "valid-user" - ) - ) - } - -And finally remove the IP filter check in SiteController.php - - - -There are logs generated in the /var/stratum folder and /var/log/stratum/debug.log for the php log. - -More instructions coming as needed. - - -There a lot of unused code in the php branch. Lot come from other projects I worked on and I've been lazy to clean it up before to integrate it to yaamp. It's mostly based on the Yii framework which implements a lightweight MVC. - - http://www.yiiframework.com/ - - -Credits: - -Thanks to globalzon to have released the initial Yaamp source code. - --- - -You can support this project donating to tpruvot : - -BTC : 1Auhps1mHZQpoX4mCcVL8odU81VakZQ6dR +## Credits: +* Thanks to tpruvot for the yiimp release +* Thanks to mailinabox for the installer idea diff --git a/README.md.old b/README.md.old new file mode 100644 index 000000000..58687f6c4 --- /dev/null +++ b/README.md.old @@ -0,0 +1,136 @@ +[![Build Status](https://travis-ci.org/tpruvot/yiimp.svg?branch=next)](https://travis-ci.org/tpruvot/yiimp) + +#yiimp - yaamp fork + +WARNINGS +- Use at your own risks. +- Usage of this software requires abilities with sysadmin, database admin, coin daemons, and sometimes a bit of programming. Running a production pool can literally be more work than a full-time job. + +Required: + + linux, mysql, php, memcached, a webserver (lighttpd or nginx recommended) + + +Config for nginx: + + location / { + try_files $uri @rewrite; + } + + location @rewrite { + rewrite ^/(.*)$ /index.php?r=$1; + } + + location ~ \.php$ { + fastcgi_pass unix:/var/run/php5-fpm.sock; + fastcgi_index index.php; + include fastcgi_params; + } + + +If you use apache, it should be something like that (already set in web/.htaccess): + + RewriteEngine on + + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^(.*) index.php?r=$1 [QSA] + + +If you use lighttpd, use the following config: + + $HTTP["host"] =~ "yiimp.ccminer.org" { + server.document-root = "/var/yaamp/web" + url.rewrite-if-not-file = ( + "^(.*)/([0-9]+)$" => "index.php?r=$1&id=$2", + "^(.*)\?(.*)" => "index.php?r=$1&$2", + "^(.*)" => "index.php?r=$1", + "." => "index.php" + ) + + url.access-deny = ( "~", ".dat", ".log" ) + } + + +For the database, import the initial dump present in the sql/ folder + +Then, apply the migration scripts to be in sync with the current git, they are sorted by date of change. + +Your database need at least 2 users, one for the web site (php) and one for the stratum connections (password set in config/algo.conf). + + + +The recommended install folder for the stratum engine is /var/stratum. Copy all the .conf files, run.sh, the stratum binary and the blocknotify binary to this folder. + +Some scripts are expecting the web folder to be /var/web. You can use directory symlinks... + + +Add your exchange API public and secret keys in these two separated files: + + /etc/yiimp/keys.php - fixed path in code + web/serverconfig.php - use sample as base... + +You can find sample config files in web/serverconfig.sample.php and web/keys.sample.php + +This web application includes some command line tools, add bin/ folder to your path and type "yiimp" to list them, "yiimp checkup" can help to test your initial setup. +Future scripts and maybe the "cron" jobs will then use this yiic console interface. + +You need at least three backend shells (in screen) running these scripts: + + web/main.sh + web/loop2.sh + web/block.sh + +Start one stratum per algo using the run.sh script with the algo as parameter. For example, for x11: + + run.sh x11 + +Edit each .conf file with proper values. + +Look at rc.local, it starts all three backend shells and all stratum processes. Copy it to the /etc folder so that all screen shells are started at boot up. + +All your coin's config files need to blocknotify their corresponding stratum using something like: + + blocknotify=blocknotify yaamp.com:port coinid %s + +On the website, go to http://server.com/site/adminRights to login as admin. You have to change it to something different in the code (web/yaamp/modules/site/SiteController.php). A real admin login may be added later, but you can setup a password authentification with your web server, sample for lighttpd: + + htpasswd -c /etc/yiimp/admin.htpasswd + +and in the lighttpd config file: + + # Admin access + $HTTP["url"] =~ "^/site/adminRights" { + auth.backend = "htpasswd" + auth.backend.htpasswd.userfile = "/etc/yiimp/admin.htpasswd" + auth.require = ( + "/" => ( + "method" => "basic", + "realm" => "Yiimp Administration", + "require" => "valid-user" + ) + ) + } + +And finally remove the IP filter check in SiteController.php + + + +There are logs generated in the /var/stratum folder and /var/log/stratum/debug.log for the php log. + +More instructions coming as needed. + + +There a lot of unused code in the php branch. Lot come from other projects I worked on and I've been lazy to clean it up before to integrate it to yaamp. It's mostly based on the Yii framework which implements a lightweight MVC. + + http://www.yiiframework.com/ + + +Credits: + +Thanks to globalzon to have released the initial Yaamp source code. + +-- + +You can support this project donating to tpruvot : + +BTC : 1Auhps1mHZQpoX4mCcVL8odU81VakZQ6dR diff --git a/_config.yml b/_config.yml new file mode 100644 index 000000000..bad826676 --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-midnight diff --git a/bin/blocknotify.sh b/bin/blocknotify.sh deleted file mode 100755 index 8b8357aae..000000000 --- a/bin/blocknotify.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -# -# callback script... replaced by blocknotify binary -# -# blocknotify="blocknotify.sh --host yaamp --port $stratum_port --id $coin->id --block %s --password tu8tu5" - diff --git a/bin/kill_stratum b/bin/kill_stratum deleted file mode 100755 index 4d8d06e22..000000000 --- a/bin/kill_stratum +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -PLINE=$(ps -ef | grep "stratum config/$1" | grep -v grep) -if [ $? ]; then - PS=$(echo $PLINE | cut -d ' ' -f 2) - if [ $PS ]; then - kill $PS - echo "killed stratum process $PS" - else - echo "Process not found" - exit 1 - fi -fi diff --git a/bin/yiimp b/bin/yiimp index 269115bfe..86076d19f 100755 --- a/bin/yiimp +++ b/bin/yiimp @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash ROOTDIR=/data/yiimp DIR=`pwd` diff --git a/bin/yiimp_restart_loop.sh b/bin/yiimp_restart_loop.sh deleted file mode 100755 index 2fb52f324..000000000 --- a/bin/yiimp_restart_loop.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -# Restart the pseudo cron screens... - -LOG_DIR=/work/yiimp/log -WEB_DIR=/var/web - -screen -X -S main quit -screen -X -S loop2 quit -screen -X -S blocks quit -screen -X -S debug quit - -screen -dmS main $WEB_DIR/main.sh -screen -dmS loop2 $WEB_DIR/loop2.sh -screen -dmS blocks $WEB_DIR/blocks.sh - -screen -dmS debug tail -f $LOG_DIR/debug.log - diff --git a/rc.local b/rc.local index 68f8200db..9ecef084c 100644 --- a/rc.local +++ b/rc.local @@ -53,6 +53,7 @@ screen -dmS allium $STRATUM_DIR/run.sh allium #screen -dmS lyra2 $STRATUM_DIR/run.sh lyra2 screen -dmS lyra2v2 $STRATUM_DIR/run.sh lyra2v2 screen -dmS lyra2z $STRATUM_DIR/run.sh lyra2z +screen -dmS lyra2zz $STRATUM_DIR/run.sh lyra2zz screen -dmS rainforest $STRATUM_DIR/run.sh rainforest screen -dmS blakecoin $STRATUM_DIR/run.sh blakecoin # blake 8 diff --git a/sql/2018-09-22-workers.sql b/sql/2018-09-22-workers.sql new file mode 100644 index 000000000..892b6e546 --- /dev/null +++ b/sql/2018-09-22-workers.sql @@ -0,0 +1,6 @@ +-- Recent additions to add after db init (.gz) +-- mysql yaamp -p < file.sql + +-- filled by the stratum instance, to allow to handle/watch multiple instances + +ALTER TABLE `workers` MODIFY COLUMN name VARCHAR(98); diff --git a/sql/2019-03-coins_thepool_life.sql b/sql/2019-03-coins_thepool_life.sql new file mode 100644 index 000000000..e5fa67c77 --- /dev/null +++ b/sql/2019-03-coins_thepool_life.sql @@ -0,0 +1,11 @@ +-- Recent additions to add after db init (.gz) +-- mysql yaamp -p < file.sql + +-- Additional fields for additions by cryptopool.builders + +ALTER TABLE `coins` ADD `link_twitter` varchar(1024) DEFAULT NULL AFTER `link_explorer`; +ALTER TABLE `coins` ADD `link_facebook` varchar(1024) DEFAULT NULL AFTER `link_twitter`; +ALTER TABLE `coins` ADD `donation_address` varchar(1024) DEFAULT NULL AFTER `link_facebook`; +ALTER TABLE `coins` ADD `link_discord` varchar(1024) DEFAULT NULL AFTER `link_twitter`; +ALTER TABLE `coins` ADD `usefaucet` tinyint(1) UNSIGNED NOT NULL DEFAULT '0' AFTER `donation_address`; +ALTER TABLE `coins` ADD `dedicatedport` int(11) DEFAULT NULL AFTER `rpcport`; diff --git a/sql/2019-11-10-yiimp.sql.gz b/sql/2019-11-10-yiimp.sql.gz new file mode 100644 index 000000000..f3a41f248 Binary files /dev/null and b/sql/2019-11-10-yiimp.sql.gz differ diff --git a/sql/labels.json b/sql/labels.json index 4d9190876..bf0ae2e44 100644 --- a/sql/labels.json +++ b/sql/labels.json @@ -530,6 +530,7 @@ "MUN":"Muniti", "MWC":"MultiWalletCoin", "MXT":"MarteXcoin", +"MXBIT":"Matrixbit", "MYC":"MyCoin", "MYR":"Myriadcoin", "MYST":"MystCoin", diff --git a/stratum/Makefile b/stratum/Makefile index 3bf978bf3..e833354c0 100755 --- a/stratum/Makefile +++ b/stratum/Makefile @@ -1,4 +1,11 @@ - +##################### +# Special credits to the following devs that make this YiiMP stratum possible +# tpruvot https://github.com/tpruvot/yiimp +# barrystyle https://github.com/barrystyle +# Alexg Discord +# Kudaraidee https://github.com/Kudaraidee/yiimp +# And all the other devs that have helped with this project +##################### CC=gcc CFLAGS= -g -march=native @@ -63,4 +70,3 @@ install: clean all strip -s stratum cp stratum /usr/local/bin/ cp stratum ../bin/ - diff --git a/stratum/algos/KeccakP-800-SnP.h b/stratum/algos/KeccakP-800-SnP.h new file mode 100644 index 000000000..4b2556c06 --- /dev/null +++ b/stratum/algos/KeccakP-800-SnP.h @@ -0,0 +1,41 @@ +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _KeccakP_800_SnP_h_ +#define _KeccakP_800_SnP_h_ + +/** For the documentation, see SnP-documentation.h. + */ + +#define KeccakP800_implementation "32-bit reference implementation" +#define KeccakP800_stateSizeInBytes 100 +#define KeccakP800_stateAlignment 4 + +#ifdef KeccakReference +void KeccakP800_StaticInitialize( void ); +#else +#define KeccakP800_StaticInitialize() +#endif +void KeccakP800_Initialize(void *state); +void KeccakP800_AddByte(void *state, unsigned char data, unsigned int offset); +void KeccakP800_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP800_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP800_OverwriteWithZeroes(void *state, unsigned int byteCount); +void KeccakP800_Permute_12rounds(void *state); +void KeccakP800_Permute_22rounds(void *state); +void KeccakP800_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP800_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length); + +#endif diff --git a/stratum/algos/KeccakP-800-reference.c b/stratum/algos/KeccakP-800-reference.c new file mode 100644 index 000000000..b71a4889d --- /dev/null +++ b/stratum/algos/KeccakP-800-reference.c @@ -0,0 +1,421 @@ +/* +Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, +Michaël Peeters, Gilles Van Assche and Ronny Van Keer, +hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ + +--- + +This file implements Keccak-p[800] in a SnP-compatible way. +Please refer to SnP-documentation.h for more details. + +This implementation comes with KeccakP-800-SnP.h in the same folder. +Please refer to LowLevel.build for the exact list of other files it must be combined with. +*/ + +#include +#include +#include +#include +#include "brg_endian.h" +#ifdef KeccakReference +#include "displayIntermediateValues.h" +#endif + +typedef unsigned char UINT8; +typedef unsigned int UINT32; +typedef UINT32 tKeccakLane; + +#define maxNrRounds 22 +#define nrLanes 25 +#define index(x, y) (((x)%5)+5*((y)%5)) + +#ifdef KeccakReference + +static tKeccakLane KeccakRoundConstants[maxNrRounds]; +static unsigned int KeccakRhoOffsets[nrLanes]; + +/* ---------------------------------------------------------------- */ + +void KeccakP800_InitializeRoundConstants(void); +void KeccakP800_InitializeRhoOffsets(void); +static int LFSR86540(UINT8 *LFSR); + +void KeccakP800_StaticInitialize(void) +{ + if (sizeof(tKeccakLane) != 4) { + printf("tKeccakLane should be 32-bit wide\n"); + abort(); + } + KeccakP800_InitializeRoundConstants(); + KeccakP800_InitializeRhoOffsets(); +} + +void KeccakP800_InitializeRoundConstants(void) +{ + UINT8 LFSRstate = 0x01; + unsigned int i, j, bitPosition; + + for(i=0; i> (8*j)) & 0xFF; +} + +void KeccakP800OnWords(tKeccakLane *state, unsigned int nrRounds) +{ + unsigned int i; + +#ifdef KeccakReference + displayStateAsLanes(3, "Same, with lanes as 32-bit words", state, 800); +#endif + + for(i=(maxNrRounds-nrRounds); i> (sizeof(tKeccakLane)*8-offset))) : a) + +static void theta(tKeccakLane *A) +{ + unsigned int x, y; + tKeccakLane C[5], D[5]; + + for(x=0; x<5; x++) { + C[x] = 0; + for(y=0; y<5; y++) + C[x] ^= A[index(x, y)]; + } + for(x=0; x<5; x++) + D[x] = ROL32(C[(x+1)%5], 1) ^ C[(x+4)%5]; + for(x=0; x<5; x++) + for(y=0; y<5; y++) + A[index(x, y)] ^= D[x]; +} + +static void rho(tKeccakLane *A) +{ + unsigned int x, y; + + for(x=0; x<5; x++) for(y=0; y<5; y++) + A[index(x, y)] = ROL32(A[index(x, y)], KeccakRhoOffsets[index(x, y)]); +} + +static void pi(tKeccakLane *A) +{ + unsigned int x, y; + tKeccakLane tempA[25]; + + for(x=0; x<5; x++) for(y=0; y<5; y++) + tempA[index(x, y)] = A[index(x, y)]; + for(x=0; x<5; x++) for(y=0; y<5; y++) + A[index(0*x+1*y, 2*x+3*y)] = tempA[index(x, y)]; +} + +static void chi(tKeccakLane *A) +{ + unsigned int x, y; + tKeccakLane C[5]; + + for(y=0; y<5; y++) { + for(x=0; x<5; x++) + C[x] = A[index(x, y)] ^ ((~A[index(x+1, y)]) & A[index(x+2, y)]); + for(x=0; x<5; x++) + A[index(x, y)] = C[x]; + } +} + +static void iota(tKeccakLane *A, unsigned int indexRound) +{ + A[index(0, 0)] ^= KeccakRoundConstants[indexRound]; +} + +/* ---------------------------------------------------------------- */ + +void KeccakP800_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length) +{ + assert(offset < 100); + assert(offset+length <= 100); + memcpy(data, (unsigned char*)state+offset, length); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP800_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) +{ + unsigned int i; + + assert(offset < 100); + assert(offset+length <= 100); + for(i=0; i +#include +#include +#include + +#include "Lyra2-zz.h" +#include "Sponge.h" + +/** + * Executes Lyra2 based on the G function from Blake2b. This version supports salts and passwords + * whose combined length is smaller than the size of the memory matrix, (i.e., (nRows x nCols x b) bits, + * where "b" is the underlying sponge's bitrate). In this implementation, the "basil" is composed by all + * integer parameters (treated as type "unsigned int") in the order they are provided, plus the value + * of nCols, (i.e., basil = kLen || pwdlen || saltlen || timeCost || nRows || nCols). + * + * @param K The derived key to be output by the algorithm + * @param kLen Desired key length + * @param pwd User password + * @param pwdlen Password length + * @param salt Salt + * @param saltlen Salt length + * @param timeCost Parameter to determine the processing time (T) + * @param nRows Number or rows of the memory matrix (R) + * @param nCols Number of columns of the memory matrix (C) + * + * @return 0 if the key is generated correctly; -1 if there is an error (usually due to lack of memory for allocation) + */ +int LYRA2ZZ(void *K, uint64_t kLen, const void *pwd, uint64_t pwdlen, const void *salt, uint64_t saltlen, uint64_t timeCost, uint64_t nRows, uint64_t nCols) +{ + //============================= Basic variables ============================// + int64_t row = 2; //index of row to be processed + int64_t prev = 1; //index of prev (last row ever computed/modified) + int64_t rowa = 0; //index of row* (a previous row, deterministically picked during Setup and randomly picked while Wandering) + int64_t tau; //Time Loop iterator + int64_t step = 1; //Visitation step (used during Setup and Wandering phases) + int64_t window = 2; //Visitation window (used to define which rows can be revisited during Setup) + int64_t gap = 1; //Modifier to the step, assuming the values 1 or -1 + int64_t i; //auxiliary iteration counter + //==========================================================================/ + + //========== Initializing the Memory Matrix and pointers to it =============// + //Tries to allocate enough space for the whole memory matrix + const int64_t ROW_LEN_INT64 = BLOCK_LEN_INT64 * nCols; + const int64_t ROW_LEN_BYTES = ROW_LEN_INT64 * 8; + + i = (int64_t) ((int64_t) nRows * (int64_t) ROW_LEN_BYTES); + uint64_t *wholeMatrix = malloc(i); + if (wholeMatrix == NULL) { + return -1; + } + memset(wholeMatrix, 0, i); + + //Allocates pointers to each row of the matrix + uint64_t **memMatrix = malloc(nRows * sizeof (uint64_t*)); + if (memMatrix == NULL) { + return -1; + } + //Places the pointers in the correct positions + uint64_t *ptrWord = wholeMatrix; + for (i = 0; i < nRows; i++) { + memMatrix[i] = ptrWord; + ptrWord += ROW_LEN_INT64; + } + //==========================================================================/ + + //============= Getting the password + salt + basil padded with 10*1 ===============// + //OBS.:The memory matrix will temporarily hold the password: not for saving memory, + //but this ensures that the password copied locally will be overwritten as soon as possible + + //First, we clean enough blocks for the password, salt, basil and padding + uint64_t nBlocksInput = ((saltlen + pwdlen + 6 * sizeof (uint64_t)) / BLOCK_LEN_BLAKE2_SAFE_BYTES) + 1; + byte *ptrByte = (byte*) wholeMatrix; + memset(ptrByte, 0, nBlocksInput * BLOCK_LEN_BLAKE2_SAFE_BYTES); + + //Prepends the password + memcpy(ptrByte, pwd, pwdlen); + ptrByte += pwdlen; + + //Concatenates the salt + memcpy(ptrByte, salt, saltlen); + ptrByte += saltlen; + + //Concatenates the basil: every integer passed as parameter, in the order they are provided by the interface + memcpy(ptrByte, &kLen, sizeof (uint64_t)); + ptrByte += sizeof (uint64_t); + memcpy(ptrByte, &pwdlen, sizeof (uint64_t)); + ptrByte += sizeof (uint64_t); + memcpy(ptrByte, &saltlen, sizeof (uint64_t)); + ptrByte += sizeof (uint64_t); + memcpy(ptrByte, &timeCost, sizeof (uint64_t)); + ptrByte += sizeof (uint64_t); + memcpy(ptrByte, &nRows, sizeof (uint64_t)); + ptrByte += sizeof (uint64_t); + memcpy(ptrByte, &nCols, sizeof (uint64_t)); + ptrByte += sizeof (uint64_t); + + //Now comes the padding + *ptrByte = 0x80; //first byte of padding: right after the password + ptrByte = (byte*) wholeMatrix; //resets the pointer to the start of the memory matrix + ptrByte += nBlocksInput * BLOCK_LEN_BLAKE2_SAFE_BYTES - 1; //sets the pointer to the correct position: end of incomplete block + *ptrByte ^= 0x01; //last byte of padding: at the end of the last incomplete block + //==========================================================================/ + + //======================= Initializing the Sponge State ====================// + //Sponge state: 16 uint64_t, BLOCK_LEN_INT64 words of them for the bitrate (b) and the remainder for the capacity (c) + uint64_t *state = malloc(16 * sizeof (uint64_t)); + if (state == NULL) { + return -1; + } + initState(state); + //==========================================================================/ + + //================================ Setup Phase =============================// + //Absorbing salt, password and basil: this is the only place in which the block length is hard-coded to 512 bits + ptrWord = wholeMatrix; + for (i = 0; i < nBlocksInput; i++) { + absorbBlockBlake2Safe(state, ptrWord); //absorbs each block of pad(pwd || salt || basil) + ptrWord += BLOCK_LEN_BLAKE2_SAFE_INT64; //goes to next block of pad(pwd || salt || basil) + } + + //Initializes M[0] and M[1] + reducedSqueezeRow0(state, memMatrix[0], nCols); //The locally copied password is most likely overwritten here + reducedDuplexRow1(state, memMatrix[0], memMatrix[1], nCols); + + do { + //M[row] = rand; //M[row*] = M[row*] XOR rotW(rand) + reducedDuplexRowSetup(state, memMatrix[prev], memMatrix[rowa], memMatrix[row], nCols); + + //updates the value of row* (deterministically picked during Setup)) + rowa = (rowa + step) & (window - 1); + //update prev: it now points to the last row ever computed + prev = row; + //updates row: goes to the next row to be computed + row++; + + //Checks if all rows in the window where visited. + if (rowa == 0) { + step = window + gap; //changes the step: approximately doubles its value + window *= 2; //doubles the size of the re-visitation window + gap = -gap; //inverts the modifier to the step + } + + } while (row < nRows); + //==========================================================================/ + + //============================ Wandering Phase =============================// + row = 0; //Resets the visitation to the first row of the memory matrix + for (tau = 1; tau <= timeCost; tau++) { + //Step is approximately half the number of all rows of the memory matrix for an odd tau; otherwise, it is -1 + step = (tau % 2 == 0) ? -1 : nRows / 2 - 1; + do { + //Selects a pseudorandom index row* + //------------------------------------------------------------------------------------------ + //rowa = ((unsigned int)state[0]) & (nRows-1); //(USE THIS IF nRows IS A POWER OF 2) + rowa = ((uint64_t) (state[0])) % nRows; //(USE THIS FOR THE "GENERIC" CASE) + //------------------------------------------------------------------------------------------ + + //Performs a reduced-round duplexing operation over M[row*] XOR M[prev], updating both M[row*] and M[row] + reducedDuplexRow(state, memMatrix[prev], memMatrix[rowa], memMatrix[row], nCols); + + //update prev: it now points to the last row ever computed + prev = row; + + //updates row: goes to the next row to be computed + //------------------------------------------------------------------------------------------ + //row = (row + step) & (nRows-1); //(USE THIS IF nRows IS A POWER OF 2) + row = (row + step) % nRows; //(USE THIS FOR THE "GENERIC" CASE) + //------------------------------------------------------------------------------------------ + } while (row != 0); + } + //==========================================================================/ + + //============================ Wrap-up Phase ===============================// + //Absorbs the last block of the memory matrix + absorbBlock(state, memMatrix[rowa]); + + //Squeezes the key + squeeze(state, K, kLen); + //==========================================================================/ + + //========================= Freeing the memory =============================// + free(memMatrix); + free(wholeMatrix); + + //Wiping out the sponge's internal state before freeing it + memset(state, 0, 16 * sizeof (uint64_t)); + free(state); + //==========================================================================/ + + return 0; +} diff --git a/stratum/algos/Lyra2-zz.h b/stratum/algos/Lyra2-zz.h new file mode 100644 index 000000000..e56a5a7b3 --- /dev/null +++ b/stratum/algos/Lyra2-zz.h @@ -0,0 +1,55 @@ +/** + * Header file for the Lyra2 Password Hashing Scheme (PHS). + * + * Author: The Lyra PHC team (http://www.lyra-kdf.net/) -- 2014. + * + * This software is hereby placed in the public domain. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef LYRA2ZZ_H_ +#define LYRA2ZZ_H_ + +#include + +typedef unsigned char byte; + +//Block length required so Blake2's Initialization Vector (IV) is not overwritten (THIS SHOULD NOT BE MODIFIED) +#define BLOCK_LEN_BLAKE2_SAFE_INT64 12 //768 bits (=96 bytes, =12 uint64_t) +#define BLOCK_LEN_BLAKE2_SAFE_BYTES (BLOCK_LEN_BLAKE2_SAFE_INT64 * 8) //same as above, in bytes + +#define LYRA2ZZ_BLOCK_HEADER_LEN_BYTES 112 +#define LYRA2ZZ_BLOCK_HEADER_NONCE_OFFSET 19 /* 19 * 4 bytes */ + +#define LYRA2ZZ_BLOCK_HEADER_UINT32_LEN 32 + +#ifdef BLOCK_LEN_BITS + #define BLOCK_LEN_INT64 (BLOCK_LEN_BITS/64) //Block length: 1024 bits (=128 bytes, =16 uint64_t) + #define BLOCK_LEN_BYTES (BLOCK_LEN_BITS/8) //Block length, in bytes +#else //default block length: 1024 bits + #define BLOCK_LEN_INT64 16 //Block length: 1024 bits (=128 bytes, =16 uint64_t) + #define BLOCK_LEN_BYTES (BLOCK_LEN_INT64 * 8) //Block length, in bytes +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +int LYRA2ZZ(void *K, uint64_t kLen, const void *pwd, uint64_t pwdlen, const void *salt, uint64_t saltlen, uint64_t timeCost, uint64_t nRows, uint64_t nCols); + +#ifdef __cplusplus +} + +#endif + +#endif /* LYRA2ZZ_H_ */ diff --git a/stratum/algos/Lyra2.c b/stratum/algos/Lyra2.c index dbcc3fa6b..1d68fd1a0 100644 --- a/stratum/algos/Lyra2.c +++ b/stratum/algos/Lyra2.c @@ -212,3 +212,176 @@ int LYRA2(void *K, int64_t kLen, const void *pwd, int32_t pwdlen, const void *sa return 0; } + +int LYRA2_3(void *K, int64_t kLen, const void *pwd, int32_t pwdlen, const void *salt, int32_t saltlen, int64_t timeCost, const int16_t nRows, const int16_t nCols) +{ + //============================= Basic variables ============================// + int64_t row = 2; //index of row to be processed + int64_t prev = 1; //index of prev (last row ever computed/modified) + int64_t rowa = 0; //index of row* (a previous row, deterministically picked during Setup and randomly picked while Wandering) + int64_t tau; //Time Loop iterator + int64_t step = 1; //Visitation step (used during Setup and Wandering phases) + int64_t window = 2; //Visitation window (used to define which rows can be revisited during Setup) + int64_t gap = 1; //Modifier to the step, assuming the values 1 or -1 + int64_t i; //auxiliary iteration counter + int64_t v64; // 64bit var for memcpy + uint64_t instance = 0; + //==========================================================================/ + + //========== Initializing the Memory Matrix and pointers to it =============// + //Tries to allocate enough space for the whole memory matrix + + const int64_t ROW_LEN_INT64 = BLOCK_LEN_INT64 * nCols; + const int64_t ROW_LEN_BYTES = ROW_LEN_INT64 * 8; + // for Lyra2REv2, nCols = 4, v1 was using 8 + const int64_t BLOCK_LEN = (nCols == 4) ? BLOCK_LEN_BLAKE2_SAFE_INT64 : BLOCK_LEN_BLAKE2_SAFE_BYTES; + + size_t sz = (size_t)ROW_LEN_BYTES * nRows; + uint64_t *wholeMatrix = malloc(sz); + if (wholeMatrix == NULL) { + return -1; + } + memset(wholeMatrix, 0, sz); + + //Allocates pointers to each row of the matrix + uint64_t **memMatrix = malloc(sizeof(uint64_t*) * nRows); + if (memMatrix == NULL) { + return -1; + } + //Places the pointers in the correct positions + uint64_t *ptrWord = wholeMatrix; + for (i = 0; i < nRows; i++) { + memMatrix[i] = ptrWord; + ptrWord += ROW_LEN_INT64; + } + //==========================================================================/ + + //============= Getting the password + salt + basil padded with 10*1 ===============// + //OBS.:The memory matrix will temporarily hold the password: not for saving memory, + //but this ensures that the password copied locally will be overwritten as soon as possible + + //First, we clean enough blocks for the password, salt, basil and padding + int64_t nBlocksInput = ((saltlen + pwdlen + 6 * sizeof(uint64_t)) / BLOCK_LEN_BLAKE2_SAFE_BYTES) + 1; + + byte *ptrByte = (byte*) wholeMatrix; + + //Prepends the password + memcpy(ptrByte, pwd, pwdlen); + ptrByte += pwdlen; + + //Concatenates the salt + memcpy(ptrByte, salt, saltlen); + ptrByte += saltlen; + + memset(ptrByte, 0, (size_t) (nBlocksInput * BLOCK_LEN_BLAKE2_SAFE_BYTES - (saltlen + pwdlen))); + + //Concatenates the basil: every integer passed as parameter, in the order they are provided by the interface + memcpy(ptrByte, &kLen, sizeof(int64_t)); + ptrByte += sizeof(uint64_t); + v64 = pwdlen; + memcpy(ptrByte, &v64, sizeof(int64_t)); + ptrByte += sizeof(uint64_t); + v64 = saltlen; + memcpy(ptrByte, &v64, sizeof(int64_t)); + ptrByte += sizeof(uint64_t); + v64 = timeCost; + memcpy(ptrByte, &v64, sizeof(int64_t)); + ptrByte += sizeof(uint64_t); + v64 = nRows; + memcpy(ptrByte, &v64, sizeof(int64_t)); + ptrByte += sizeof(uint64_t); + v64 = nCols; + memcpy(ptrByte, &v64, sizeof(int64_t)); + ptrByte += sizeof(uint64_t); + + //Now comes the padding + *ptrByte = 0x80; //first byte of padding: right after the password + ptrByte = (byte*) wholeMatrix; //resets the pointer to the start of the memory matrix + ptrByte += nBlocksInput * BLOCK_LEN_BLAKE2_SAFE_BYTES - 1; //sets the pointer to the correct position: end of incomplete block + *ptrByte ^= 0x01; //last byte of padding: at the end of the last incomplete block + //==========================================================================/ + + //======================= Initializing the Sponge State ====================// + //Sponge state: 16 uint64_t, BLOCK_LEN_INT64 words of them for the bitrate (b) and the remainder for the capacity (c) + uint64_t state[16]; + initState(state); + //==========================================================================/ + + //================================ Setup Phase =============================// + //Absorbing salt, password and basil: this is the only place in which the block length is hard-coded to 512 bits + ptrWord = wholeMatrix; + for (i = 0; i < nBlocksInput; i++) { + absorbBlockBlake2Safe(state, ptrWord); //absorbs each block of pad(pwd || salt || basil) + ptrWord += BLOCK_LEN; //goes to next block of pad(pwd || salt || basil) + } + + //Initializes M[0] and M[1] + reducedSqueezeRow0(state, memMatrix[0], nCols); //The locally copied password is most likely overwritten here + + reducedDuplexRow1(state, memMatrix[0], memMatrix[1], nCols); + + do { + //M[row] = rand; //M[row*] = M[row*] XOR rotW(rand) + + reducedDuplexRowSetup(state, memMatrix[prev], memMatrix[rowa], memMatrix[row], nCols); + + //updates the value of row* (deterministically picked during Setup)) + rowa = (rowa + step) & (window - 1); + //update prev: it now points to the last row ever computed + prev = row; + //updates row: goes to the next row to be computed + row++; + + //Checks if all rows in the window where visited. + if (rowa == 0) { + step = window + gap; //changes the step: approximately doubles its value + window *= 2; //doubles the size of the re-visitation window + gap = -gap; //inverts the modifier to the step + } + + } while (row < nRows); + //==========================================================================/ + + //============================ Wandering Phase =============================// + row = 0; //Resets the visitation to the first row of the memory matrix + for (tau = 1; tau <= timeCost; tau++) { + //Step is approximately half the number of all rows of the memory matrix for an odd tau; otherwise, it is -1 + step = (tau % 2 == 0) ? -1 : nRows / 2 - 1; + do { + //Selects a pseudorandom index row* + //------------------------------------------------------------------------------------------ + instance = state[instance % 16]; + rowa = state[instance % 16] & (unsigned int)(nRows-1); + + //rowa = state[0] & (unsigned int)(nRows-1); //(USE THIS IF nRows IS A POWER OF 2) + //rowa = state[0] % nRows; //(USE THIS FOR THE "GENERIC" CASE) + //------------------------------------------------------------------------------------------ + + //Performs a reduced-round duplexing operation over M[row*] XOR M[prev], updating both M[row*] and M[row] + reducedDuplexRow(state, memMatrix[prev], memMatrix[rowa], memMatrix[row], nCols); + + //update prev: it now points to the last row ever computed + prev = row; + + //updates row: goes to the next row to be computed + //------------------------------------------------------------------------------------------ + row = (row + step) & (unsigned int)(nRows-1); //(USE THIS IF nRows IS A POWER OF 2) + //row = (row + step) % nRows; //(USE THIS FOR THE "GENERIC" CASE) + //------------------------------------------------------------------------------------------ + + } while (row != 0); + } + + //============================ Wrap-up Phase ===============================// + //Absorbs the last block of the memory matrix + absorbBlock(state, memMatrix[rowa]); + + //Squeezes the key + squeeze(state, K, (unsigned int) kLen); + + //========================= Freeing the memory =============================// + free(memMatrix); + free(wholeMatrix); + + return 0; +} diff --git a/stratum/algos/Lyra2.h b/stratum/algos/Lyra2.h index e25432a1a..2b8773d6d 100644 --- a/stratum/algos/Lyra2.h +++ b/stratum/algos/Lyra2.h @@ -38,5 +38,6 @@ typedef unsigned char byte; #endif int LYRA2(void *K, int64_t kLen, const void *pwd, int32_t pwdlen, const void *salt, int32_t saltlen, int64_t timeCost, const int64_t nRows, const int16_t nCols); +int LYRA2_3(void *K, int64_t kLen, const void *pwd, int32_t pwdlen, const void *salt, int32_t saltlen, int64_t timeCost, const int16_t nRows, const int16_t nCols); #endif /* LYRA2_H_ */ diff --git a/stratum/algos/argon2d.c b/stratum/algos/argon2d.c new file mode 100644 index 000000000..0510ecadc --- /dev/null +++ b/stratum/algos/argon2d.c @@ -0,0 +1,102 @@ +#include +#include +#include +#include + +#include "sysendian.h" + +#include "ar2/argon2.h" +#include "ar2/core.h" + +static const size_t INPUT_BYTES = 80; // Lenth of a block header in bytes. Input Length = Salt Length (salt = input) +static const size_t OUTPUT_BYTES = 32; // Length of output needed for a 256-bit hash +static const unsigned int DEFAULT_ARGON2_FLAG = 2; //Same as ARGON2_DEFAULT_FLAGS + +void argon2d_call(const void *input, void *output) +{ + argon2_context context; + context.out = (uint8_t *)output; + context.outlen = (uint32_t)OUTPUT_BYTES; + context.pwd = (uint8_t *)input; + context.pwdlen = (uint32_t)INPUT_BYTES; + context.salt = (uint8_t *)input; //salt = input + context.saltlen = (uint32_t)INPUT_BYTES; + context.secret = NULL; + context.secretlen = 0; + context.ad = NULL; + context.adlen = 0; + context.allocate_cbk = NULL; + context.free_cbk = NULL; + context.flags = DEFAULT_ARGON2_FLAG; // = ARGON2_DEFAULT_FLAGS + // main configurable Argon2 hash parameters + context.m_cost = 250; // Memory in KiB (250KB) + context.lanes = 4; // Degree of Parallelism + context.threads = 1; // Threads + context.t_cost = 1; // Iterations + + argon2_ctx(&context, Argon2_d); +} +void argon2d_dyn_call(const void *input, void *output) +{ + argon2_context context; + context.out = (uint8_t *)output; + context.outlen = (uint32_t)OUTPUT_BYTES; + context.pwd = (uint8_t *)input; + context.pwdlen = (uint32_t)INPUT_BYTES; + context.salt = (uint8_t *)input; //salt = input + context.saltlen = (uint32_t)INPUT_BYTES; + context.secret = NULL; + context.secretlen = 0; + context.ad = NULL; + context.adlen = 0; + context.allocate_cbk = NULL; + context.free_cbk = NULL; + context.flags = DEFAULT_ARGON2_FLAG; // = ARGON2_DEFAULT_FLAGS + // main configurable Argon2 hash parameters + context.m_cost = 500; // Memory in KiB (512KB) + context.lanes = 8; // Degree of Parallelism + context.threads = 1; // Threads + context.t_cost = 2; // Iterations + + argon2_ctx(&context, Argon2_d); +} + +void argon2d_uis_call(const void *input, void *output) +{ + argon2_context context; + context.out = (uint8_t *)output; + context.outlen = (uint32_t)OUTPUT_BYTES; + context.pwd = (uint8_t *)input; + context.pwdlen = (uint32_t)INPUT_BYTES; + context.salt = (uint8_t *)input; //salt = input + context.saltlen = (uint32_t)INPUT_BYTES; + context.secret = NULL; + context.secretlen = 0; + context.ad = NULL; + context.adlen = 0; + context.allocate_cbk = NULL; + context.free_cbk = NULL; + context.flags = DEFAULT_ARGON2_FLAG; // = ARGON2_DEFAULT_FLAGS + // main configurable Argon2 hash parameters + context.m_cost = 4096; // Memory in KiB (4MB) + context.lanes = 4; // Degree of Parallelism + context.threads = 1; // Threads + context.t_cost = 1; // Iterations + + argon2_ctx(&context, Argon2_d); +} + +void argon2d_crds_hash(const unsigned char* input, unsigned char* output, unsigned int len) +{ + argon2d_call(input, output); +} + +void argon2d_dyn_hash(const unsigned char* input, unsigned char* output, unsigned int len) +{ + argon2d_dyn_call(input, output); +} + +void argon2d_uis_hash(const unsigned char* input, unsigned char* output, unsigned int len) +{ + argon2d_uis_call(input, output); +} diff --git a/stratum/algos/argon2d.h b/stratum/algos/argon2d.h new file mode 100644 index 000000000..8e20bd08e --- /dev/null +++ b/stratum/algos/argon2d.h @@ -0,0 +1,18 @@ +#ifndef ARGON2D_H +#define ARGON2D_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void argon2d_crds_hash(const char* input, char* output, unsigned int len); +void argon2d_dyn_hash(const char* input, char* output, unsigned int len); +void argon2d_uis_hash(const char* input, char* output, unsigned int len); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/stratum/algos/argon2d/argon2.c b/stratum/algos/argon2d/argon2.c new file mode 100644 index 000000000..5eabe35dc --- /dev/null +++ b/stratum/algos/argon2d/argon2.c @@ -0,0 +1,458 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#include +#include +#include + +#include "argon2.h" +#include "encoding.h" +#include "core.h" + +const char *argon2_type2string(argon2_type type, int uppercase) { + switch (type) { + case Argon2_d: + return uppercase ? "Argon2d" : "argon2d"; + case Argon2_i: + return uppercase ? "Argon2i" : "argon2i"; + case Argon2_id: + return uppercase ? "Argon2id" : "argon2id"; + } + + return NULL; +} + +int argon2_ctx(argon2_context *context, argon2_type type) { + /* 1. Validate all inputs */ + int result = validate_inputs(context); + uint32_t memory_blocks, segment_length; + argon2_instance_t instance; + + if (ARGON2_OK != result) { + return result; + } + + if (Argon2_d != type && Argon2_i != type && Argon2_id != type) { + return ARGON2_INCORRECT_TYPE; + } + + /* 2. Align memory size */ + /* Minimum memory_blocks = 8L blocks, where L is the number of lanes */ + memory_blocks = context->m_cost; + + if (memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes) { + memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes; + } + + segment_length = memory_blocks / (context->lanes * ARGON2_SYNC_POINTS); + /* Ensure that all segments have equal length */ + memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS); + + instance.version = context->version; + instance.memory = NULL; + instance.passes = context->t_cost; + instance.memory_blocks = memory_blocks; + instance.segment_length = segment_length; + instance.lane_length = segment_length * ARGON2_SYNC_POINTS; + instance.lanes = context->lanes; + instance.threads = context->threads; + instance.type = type; + + if (instance.threads > instance.lanes) { + instance.threads = instance.lanes; + } + + /* 3. Initialization: Hashing inputs, allocating memory, filling first + * blocks + */ + result = initialize(&instance, context); + + if (ARGON2_OK != result) { + return result; + } + + /* 4. Filling memory */ + result = fill_memory_blocks(&instance); + + if (ARGON2_OK != result) { + return result; + } + /* 5. Finalization */ + finalize(context, &instance); + + return ARGON2_OK; +} + +int argon2_hash(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, const size_t saltlen, + void *hash, const size_t hashlen, char *encoded, + const size_t encodedlen, argon2_type type, + const uint32_t version){ + + argon2_context context; + int result; + uint8_t *out; + + if (pwdlen > ARGON2_MAX_PWD_LENGTH) { + return ARGON2_PWD_TOO_LONG; + } + + if (saltlen > ARGON2_MAX_SALT_LENGTH) { + return ARGON2_SALT_TOO_LONG; + } + + if (hashlen > ARGON2_MAX_OUTLEN) { + return ARGON2_OUTPUT_TOO_LONG; + } + + if (hashlen < ARGON2_MIN_OUTLEN) { + return ARGON2_OUTPUT_TOO_SHORT; + } + + out = malloc(hashlen); + if (!out) { + return ARGON2_MEMORY_ALLOCATION_ERROR; + } + + context.out = (uint8_t *)out; + context.outlen = (uint32_t)hashlen; + context.pwd = CONST_CAST(uint8_t *)pwd; + context.pwdlen = (uint32_t)pwdlen; + context.salt = CONST_CAST(uint8_t *)salt; + context.saltlen = (uint32_t)saltlen; + context.secret = NULL; + context.secretlen = 0; + context.ad = NULL; + context.adlen = 0; + context.t_cost = t_cost; + context.m_cost = m_cost; + context.lanes = parallelism; + context.threads = parallelism; + context.allocate_cbk = NULL; + context.free_cbk = NULL; + context.flags = ARGON2_DEFAULT_FLAGS; + context.version = version; + + result = argon2_ctx(&context, type); + + if (result != ARGON2_OK) { + clear_internal_memory(out, hashlen); + free(out); + return result; + } + + /* if raw hash requested, write it */ + if (hash) { + memcpy(hash, out, hashlen); + } + + /* if encoding requested, write it */ + if (encoded && encodedlen) { + if (encode_string(encoded, encodedlen, &context, type) != ARGON2_OK) { + clear_internal_memory(out, hashlen); /* wipe buffers if error */ + clear_internal_memory(encoded, encodedlen); + free(out); + return ARGON2_ENCODING_FAIL; + } + } + clear_internal_memory(out, hashlen); + free(out); + + return ARGON2_OK; +} + +int argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, const size_t hashlen, + char *encoded, const size_t encodedlen, + const uint32_t version) { + + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + NULL, hashlen, encoded, encodedlen, Argon2_i, + version ); +} + +int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, const size_t hashlen, + const uint32_t version ) { + + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + hash, hashlen, NULL, 0, Argon2_i, version ); +} + +int argon2d_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, const size_t hashlen, + char *encoded, const size_t encodedlen, + const uint32_t version ) { + + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + NULL, hashlen, encoded, encodedlen, Argon2_d, + version ); +} + +int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, const size_t hashlen, + const uint32_t version ) { + + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + hash, hashlen, NULL, 0, Argon2_d, version ); +} + +int argon2id_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, const size_t hashlen, + char *encoded, const size_t encodedlen, + const uint32_t version ) { + + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + NULL, hashlen, encoded, encodedlen, Argon2_id, + version); +} + +int argon2id_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, const size_t hashlen, + const uint32_t version ) { + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + hash, hashlen, NULL, 0, Argon2_id, version ); +} + +static int argon2_compare(const uint8_t *b1, const uint8_t *b2, size_t len) { + size_t i; + uint8_t d = 0U; + + for (i = 0U; i < len; i++) { + d |= b1[i] ^ b2[i]; + } + return (int)((1 & ((d - 1) >> 8)) - 1); +} + +int argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen, + argon2_type type) { + + argon2_context ctx; + uint8_t *desired_result = NULL; + + int ret = ARGON2_OK; + + size_t encoded_len; + uint32_t max_field_len; + + if (pwdlen > ARGON2_MAX_PWD_LENGTH) { + return ARGON2_PWD_TOO_LONG; + } + + if (encoded == NULL) { + return ARGON2_DECODING_FAIL; + } + + encoded_len = strlen(encoded); + if (encoded_len > UINT32_MAX) { + return ARGON2_DECODING_FAIL; + } + + /* No field can be longer than the encoded length */ + max_field_len = (uint32_t)encoded_len; + + ctx.saltlen = max_field_len; + ctx.outlen = max_field_len; + + ctx.salt = malloc(ctx.saltlen); + ctx.out = malloc(ctx.outlen); + if (!ctx.salt || !ctx.out) { + ret = ARGON2_MEMORY_ALLOCATION_ERROR; + goto fail; + } + + ctx.pwd = (uint8_t *)pwd; + ctx.pwdlen = (uint32_t)pwdlen; + + ret = decode_string(&ctx, encoded, type); + if (ret != ARGON2_OK) { + goto fail; + } + + /* Set aside the desired result, and get a new buffer. */ + desired_result = ctx.out; + ctx.out = malloc(ctx.outlen); + if (!ctx.out) { + ret = ARGON2_MEMORY_ALLOCATION_ERROR; + goto fail; + } + + ret = argon2_verify_ctx(&ctx, (char *)desired_result, type); + if (ret != ARGON2_OK) { + goto fail; + } + +fail: + free(ctx.salt); + free(ctx.out); + free(desired_result); + + return ret; +} + +int argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen) { + + return argon2_verify(encoded, pwd, pwdlen, Argon2_i); +} + +int argon2d_verify(const char *encoded, const void *pwd, const size_t pwdlen) { + + return argon2_verify(encoded, pwd, pwdlen, Argon2_d); +} + +int argon2id_verify(const char *encoded, const void *pwd, const size_t pwdlen) { + + return argon2_verify(encoded, pwd, pwdlen, Argon2_id); +} + +int argon2d_ctx(argon2_context *context) { + return argon2_ctx(context, Argon2_d); +} + +int argon2i_ctx(argon2_context *context) { + return argon2_ctx(context, Argon2_i); +} + +int argon2id_ctx(argon2_context *context) { + return argon2_ctx(context, Argon2_id); +} + +int argon2_verify_ctx(argon2_context *context, const char *hash, + argon2_type type) { + int ret = argon2_ctx(context, type); + if (ret != ARGON2_OK) { + return ret; + } + + if (argon2_compare((uint8_t *)hash, context->out, context->outlen)) { + return ARGON2_VERIFY_MISMATCH; + } + + return ARGON2_OK; +} + +int argon2d_verify_ctx(argon2_context *context, const char *hash) { + return argon2_verify_ctx(context, hash, Argon2_d); +} + +int argon2i_verify_ctx(argon2_context *context, const char *hash) { + return argon2_verify_ctx(context, hash, Argon2_i); +} + +int argon2id_verify_ctx(argon2_context *context, const char *hash) { + return argon2_verify_ctx(context, hash, Argon2_id); +} + +const char *argon2_error_message(int error_code) { + switch (error_code) { + case ARGON2_OK: + return "OK"; + case ARGON2_OUTPUT_PTR_NULL: + return "Output pointer is NULL"; + case ARGON2_OUTPUT_TOO_SHORT: + return "Output is too short"; + case ARGON2_OUTPUT_TOO_LONG: + return "Output is too long"; + case ARGON2_PWD_TOO_SHORT: + return "Password is too short"; + case ARGON2_PWD_TOO_LONG: + return "Password is too long"; + case ARGON2_SALT_TOO_SHORT: + return "Salt is too short"; + case ARGON2_SALT_TOO_LONG: + return "Salt is too long"; + case ARGON2_AD_TOO_SHORT: + return "Associated data is too short"; + case ARGON2_AD_TOO_LONG: + return "Associated data is too long"; + case ARGON2_SECRET_TOO_SHORT: + return "Secret is too short"; + case ARGON2_SECRET_TOO_LONG: + return "Secret is too long"; + case ARGON2_TIME_TOO_SMALL: + return "Time cost is too small"; + case ARGON2_TIME_TOO_LARGE: + return "Time cost is too large"; + case ARGON2_MEMORY_TOO_LITTLE: + return "Memory cost is too small"; + case ARGON2_MEMORY_TOO_MUCH: + return "Memory cost is too large"; + case ARGON2_LANES_TOO_FEW: + return "Too few lanes"; + case ARGON2_LANES_TOO_MANY: + return "Too many lanes"; + case ARGON2_PWD_PTR_MISMATCH: + return "Password pointer is NULL, but password length is not 0"; + case ARGON2_SALT_PTR_MISMATCH: + return "Salt pointer is NULL, but salt length is not 0"; + case ARGON2_SECRET_PTR_MISMATCH: + return "Secret pointer is NULL, but secret length is not 0"; + case ARGON2_AD_PTR_MISMATCH: + return "Associated data pointer is NULL, but ad length is not 0"; + case ARGON2_MEMORY_ALLOCATION_ERROR: + return "Memory allocation error"; + case ARGON2_FREE_MEMORY_CBK_NULL: + return "The free memory callback is NULL"; + case ARGON2_ALLOCATE_MEMORY_CBK_NULL: + return "The allocate memory callback is NULL"; + case ARGON2_INCORRECT_PARAMETER: + return "Argon2_Context context is NULL"; + case ARGON2_INCORRECT_TYPE: + return "There is no such version of Argon2"; + case ARGON2_OUT_PTR_MISMATCH: + return "Output pointer mismatch"; + case ARGON2_THREADS_TOO_FEW: + return "Not enough threads"; + case ARGON2_THREADS_TOO_MANY: + return "Too many threads"; + case ARGON2_MISSING_ARGS: + return "Missing arguments"; + case ARGON2_ENCODING_FAIL: + return "Encoding failed"; + case ARGON2_DECODING_FAIL: + return "Decoding failed"; + case ARGON2_THREAD_FAIL: + return "Threading failure"; + case ARGON2_DECODING_LENGTH_FAIL: + return "Some of encoded parameters are too long or too short"; + case ARGON2_VERIFY_MISMATCH: + return "The password does not match the supplied hash"; + default: + return "Unknown error code"; + } +} +/* +size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost, uint32_t parallelism, + uint32_t saltlen, uint32_t hashlen, argon2_type type) { + return strlen("$$v=$m=,t=,p=$$") + strlen(argon2_type2string(type, 0)) + + numlen(t_cost) + numlen(m_cost) + numlen(parallelism) + + b64len(saltlen) + b64len(hashlen) + numlen(ARGON2_VERSION_NUMBER) + 1; +} +*/ diff --git a/stratum/algos/argon2d/argon2.h b/stratum/algos/argon2d/argon2.h new file mode 100644 index 000000000..6e7e98b19 --- /dev/null +++ b/stratum/algos/argon2d/argon2.h @@ -0,0 +1,442 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#ifndef ARGON2_H +#define ARGON2_H + +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Symbols visibility control */ +#ifdef A2_VISCTL +#define ARGON2_PUBLIC __attribute__((visibility("default"))) +#define ARGON2_LOCAL __attribute__ ((visibility ("hidden"))) +#elif _MSC_VER +#define ARGON2_PUBLIC __declspec(dllexport) +#define ARGON2_LOCAL +#else +#define ARGON2_PUBLIC +#define ARGON2_LOCAL +#endif + +/* + * Argon2 input parameter restrictions + */ + +/* Minimum and maximum number of lanes (degree of parallelism) */ +#define ARGON2_MIN_LANES UINT32_C(1) +#define ARGON2_MAX_LANES UINT32_C(0xFFFFFF) + +/* Minimum and maximum number of threads */ +#define ARGON2_MIN_THREADS UINT32_C(1) +#define ARGON2_MAX_THREADS UINT32_C(0xFFFFFF) + +/* Number of synchronization points between lanes per pass */ +#define ARGON2_SYNC_POINTS UINT32_C(4) + +/* Minimum and maximum digest size in bytes */ +#define ARGON2_MIN_OUTLEN UINT32_C(4) +#define ARGON2_MAX_OUTLEN UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum number of memory blocks (each of BLOCK_SIZE bytes) */ +#define ARGON2_MIN_MEMORY UINT32_C(1) +/* #define ARGON2_MIN_MEMORY (2 * ARGON2_SYNC_POINTS) */ /* 2 blocks per slice */ + + +#define ARGON2_MIN(a, b) ((a) < (b) ? (a) : (b)) +/* Max memory size is addressing-space/2, topping at 2^32 blocks (4 TB) */ +#define ARGON2_MAX_MEMORY_BITS \ + ARGON2_MIN(UINT32_C(32), (sizeof(void *) * CHAR_BIT - 10 - 1)) +#define ARGON2_MAX_MEMORY \ + ARGON2_MIN(UINT32_C(0xFFFFFFFF), UINT64_C(1) << ARGON2_MAX_MEMORY_BITS) + +/* Minimum and maximum number of passes */ +#define ARGON2_MIN_TIME UINT32_C(1) +#define ARGON2_MAX_TIME UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum password length in bytes */ +#define ARGON2_MIN_PWD_LENGTH UINT32_C(0) +#define ARGON2_MAX_PWD_LENGTH UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum associated data length in bytes */ +#define ARGON2_MIN_AD_LENGTH UINT32_C(0) +#define ARGON2_MAX_AD_LENGTH UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum salt length in bytes */ +#define ARGON2_MIN_SALT_LENGTH UINT32_C(0) +#define ARGON2_MAX_SALT_LENGTH UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum key length in bytes */ +#define ARGON2_MIN_SECRET UINT32_C(0) +#define ARGON2_MAX_SECRET UINT32_C(0xFFFFFFFF) + +/* Flags to determine which fields are securely wiped (default = no wipe). */ +#define ARGON2_DEFAULT_FLAGS UINT32_C(0) +#define ARGON2_FLAG_CLEAR_PASSWORD (UINT32_C(1) << 0) +#define ARGON2_FLAG_CLEAR_SECRET (UINT32_C(1) << 1) + +/* Global flag to determine if we are wiping internal memory buffers. This flag + * is defined in core.c and deafults to 1 (wipe internal memory). */ +extern int FLAG_clear_internal_memory; + +/* Error codes */ +typedef enum Argon2_ErrorCodes { + ARGON2_OK = 0, + + ARGON2_OUTPUT_PTR_NULL = -1, + + ARGON2_OUTPUT_TOO_SHORT = -2, + ARGON2_OUTPUT_TOO_LONG = -3, + + ARGON2_PWD_TOO_SHORT = -4, + ARGON2_PWD_TOO_LONG = -5, + + ARGON2_SALT_TOO_SHORT = -6, + ARGON2_SALT_TOO_LONG = -7, + + ARGON2_AD_TOO_SHORT = -8, + ARGON2_AD_TOO_LONG = -9, + + ARGON2_SECRET_TOO_SHORT = -10, + ARGON2_SECRET_TOO_LONG = -11, + + ARGON2_TIME_TOO_SMALL = -12, + ARGON2_TIME_TOO_LARGE = -13, + + ARGON2_MEMORY_TOO_LITTLE = -14, + ARGON2_MEMORY_TOO_MUCH = -15, + + ARGON2_LANES_TOO_FEW = -16, + ARGON2_LANES_TOO_MANY = -17, + + ARGON2_PWD_PTR_MISMATCH = -18, /* NULL ptr with non-zero length */ + ARGON2_SALT_PTR_MISMATCH = -19, /* NULL ptr with non-zero length */ + ARGON2_SECRET_PTR_MISMATCH = -20, /* NULL ptr with non-zero length */ + ARGON2_AD_PTR_MISMATCH = -21, /* NULL ptr with non-zero length */ + + ARGON2_MEMORY_ALLOCATION_ERROR = -22, + + ARGON2_FREE_MEMORY_CBK_NULL = -23, + ARGON2_ALLOCATE_MEMORY_CBK_NULL = -24, + + ARGON2_INCORRECT_PARAMETER = -25, + ARGON2_INCORRECT_TYPE = -26, + + ARGON2_OUT_PTR_MISMATCH = -27, + + ARGON2_THREADS_TOO_FEW = -28, + ARGON2_THREADS_TOO_MANY = -29, + + ARGON2_MISSING_ARGS = -30, + + ARGON2_ENCODING_FAIL = -31, + + ARGON2_DECODING_FAIL = -32, + + ARGON2_THREAD_FAIL = -33, + + ARGON2_DECODING_LENGTH_FAIL = -34, + + ARGON2_VERIFY_MISMATCH = -35 +} argon2_error_codes; + +/* Memory allocator types --- for external allocation */ +typedef int (*allocate_fptr)(uint8_t **memory, size_t bytes_to_allocate); +typedef void (*deallocate_fptr)(uint8_t *memory, size_t bytes_to_allocate); + +/* Argon2 external data structures */ + +/* + ***** + * Context: structure to hold Argon2 inputs: + * output array and its length, + * password and its length, + * salt and its length, + * secret and its length, + * associated data and its length, + * number of passes, amount of used memory (in KBytes, can be rounded up a bit) + * number of parallel threads that will be run. + * All the parameters above affect the output hash value. + * Additionally, two function pointers can be provided to allocate and + * deallocate the memory (if NULL, memory will be allocated internally). + * Also, three flags indicate whether to erase password, secret as soon as they + * are pre-hashed (and thus not needed anymore), and the entire memory + ***** + * Simplest situation: you have output array out[8], password is stored in + * pwd[32], salt is stored in salt[16], you do not have keys nor associated + * data. You need to spend 1 GB of RAM and you run 5 passes of Argon2d with + * 4 parallel lanes. + * You want to erase the password, but you're OK with last pass not being + * erased. You want to use the default memory allocator. + * Then you initialize: + Argon2_Context(out,8,pwd,32,salt,16,NULL,0,NULL,0,5,1<<20,4,4,NULL,NULL,true,false,false,false) + */ +typedef struct Argon2_Context { + uint8_t *out; /* output array */ + uint32_t outlen; /* digest length */ + + uint8_t *pwd; /* password array */ + uint32_t pwdlen; /* password length */ + + uint8_t *salt; /* salt array */ + uint32_t saltlen; /* salt length */ + + uint8_t *secret; /* key array */ + uint32_t secretlen; /* key length */ + + uint8_t *ad; /* associated data array */ + uint32_t adlen; /* associated data length */ + + uint32_t t_cost; /* number of passes */ + uint32_t m_cost; /* amount of memory requested (KB) */ + uint32_t lanes; /* number of lanes */ + uint32_t threads; /* maximum number of threads */ + + uint32_t version; /* version number */ + + allocate_fptr allocate_cbk; /* pointer to memory allocator */ + deallocate_fptr free_cbk; /* pointer to memory deallocator */ + + uint32_t flags; /* array of bool options */ +} argon2_context; + +/* Argon2 primitive type */ +typedef enum Argon2_type { + Argon2_d = 0, + Argon2_i = 1, + Argon2_id = 2 +} argon2_type; + +/* Version of the algorithm */ +#define ARGON2_VERSION_10 0x10 +#define ARGON2_VERSION_13 0x13 + +/* + * Function that gives the string representation of an argon2_type. + * @param type The argon2_type that we want the string for + * @param uppercase Whether the string should have the first letter uppercase + * @return NULL if invalid type, otherwise the string representation. + */ +ARGON2_PUBLIC const char *argon2_type2string(argon2_type type, int uppercase); + +/* + * Function that performs memory-hard hashing with certain degree of parallelism + * @param context Pointer to the Argon2 internal structure + * @return Error code if smth is wrong, ARGON2_OK otherwise + */ +ARGON2_PUBLIC int argon2_ctx(argon2_context *context, argon2_type type); + +/** + * Hashes a password with Argon2i, producing an encoded hash + * @param t_cost Number of iterations + * @param m_cost Sets memory usage to m_cost kibibytes + * @param parallelism Number of threads and compute lanes + * @param pwd Pointer to password + * @param pwdlen Password size in bytes + * @param salt Pointer to salt + * @param saltlen Salt size in bytes + * @param hashlen Desired length of the hash in bytes + * @param encoded Buffer where to write the encoded hash + * @param encodedlen Size of the buffer (thus max size of the encoded hash) + * @pre Different parallelism levels will give different results + * @pre Returns ARGON2_OK if successful + */ +ARGON2_PUBLIC int argon2i_hash_encoded(const uint32_t t_cost, + const uint32_t m_cost, + const uint32_t parallelism, + const void *pwd, const size_t pwdlen, + const void *salt, const size_t saltlen, + const size_t hashlen, char *encoded, + const size_t encodedlen, + const uint32_t version ); + +/** + * Hashes a password with Argon2i, producing a raw hash at @hash + * @param t_cost Number of iterations + * @param m_cost Sets memory usage to m_cost kibibytes + * @param parallelism Number of threads and compute lanes + * @param pwd Pointer to password + * @param pwdlen Password size in bytes + * @param salt Pointer to salt + * @param saltlen Salt size in bytes + * @param hash Buffer where to write the raw hash - updated by the function + * @param hashlen Desired length of the hash in bytes + * @pre Different parallelism levels will give different results + * @pre Returns ARGON2_OK if successful + */ +ARGON2_PUBLIC int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, + const size_t hashlen, + const uint32_t version ); + +ARGON2_PUBLIC int argon2d_hash_encoded(const uint32_t t_cost, + const uint32_t m_cost, + const uint32_t parallelism, + const void *pwd, const size_t pwdlen, + const void *salt, const size_t saltlen, + const size_t hashlen, char *encoded, + const size_t encodedlen, + const uint32_t version ); + +ARGON2_PUBLIC int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, + const size_t hashlen, + const uint32_t version ); + +ARGON2_PUBLIC int argon2id_hash_encoded(const uint32_t t_cost, + const uint32_t m_cost, + const uint32_t parallelism, + const void *pwd, const size_t pwdlen, + const void *salt, const size_t saltlen, + const size_t hashlen, char *encoded, + const size_t encodedlen, + const uint32_t version ); + +ARGON2_PUBLIC int argon2id_hash_raw(const uint32_t t_cost, + const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, + const size_t hashlen, + const uint32_t version ); + +/* generic function underlying the above ones */ +ARGON2_PUBLIC int argon2_hash(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, + const size_t hashlen, char *encoded, + const size_t encodedlen, argon2_type type, + const uint32_t version ); + +/** + * Verifies a password against an encoded string + * Encoded string is restricted as in validate_inputs() + * @param encoded String encoding parameters, salt, hash + * @param pwd Pointer to password + * @pre Returns ARGON2_OK if successful + */ +ARGON2_PUBLIC int argon2i_verify(const char *encoded, const void *pwd, + const size_t pwdlen); + +ARGON2_PUBLIC int argon2d_verify(const char *encoded, const void *pwd, + const size_t pwdlen); + +ARGON2_PUBLIC int argon2id_verify(const char *encoded, const void *pwd, + const size_t pwdlen); + +/* generic function underlying the above ones */ +ARGON2_PUBLIC int argon2_verify(const char *encoded, const void *pwd, + const size_t pwdlen, argon2_type type); + +/** + * Argon2d: Version of Argon2 that picks memory blocks depending + * on the password and salt. Only for side-channel-free + * environment!! + ***** + * @param context Pointer to current Argon2 context + * @return Zero if successful, a non zero error code otherwise + */ +ARGON2_PUBLIC int argon2d_ctx(argon2_context *context); + +/** + * Argon2i: Version of Argon2 that picks memory blocks + * independent on the password and salt. Good for side-channels, + * but worse w.r.t. tradeoff attacks if only one pass is used. + ***** + * @param context Pointer to current Argon2 context + * @return Zero if successful, a non zero error code otherwise + */ +ARGON2_PUBLIC int argon2i_ctx(argon2_context *context); + +/** + * Argon2id: Version of Argon2 where the first half-pass over memory is + * password-independent, the rest are password-dependent (on the password and + * salt). OK against side channels (they reduce to 1/2-pass Argon2i), and + * better with w.r.t. tradeoff attacks (similar to Argon2d). + ***** + * @param context Pointer to current Argon2 context + * @return Zero if successful, a non zero error code otherwise + */ +ARGON2_PUBLIC int argon2id_ctx(argon2_context *context); + +/** + * Verify if a given password is correct for Argon2d hashing + * @param context Pointer to current Argon2 context + * @param hash The password hash to verify. The length of the hash is + * specified by the context outlen member + * @return Zero if successful, a non zero error code otherwise + */ +ARGON2_PUBLIC int argon2d_verify_ctx(argon2_context *context, const char *hash); + +/** + * Verify if a given password is correct for Argon2i hashing + * @param context Pointer to current Argon2 context + * @param hash The password hash to verify. The length of the hash is + * specified by the context outlen member + * @return Zero if successful, a non zero error code otherwise + */ +ARGON2_PUBLIC int argon2i_verify_ctx(argon2_context *context, const char *hash); + +/** + * Verify if a given password is correct for Argon2id hashing + * @param context Pointer to current Argon2 context + * @param hash The password hash to verify. The length of the hash is + * specified by the context outlen member + * @return Zero if successful, a non zero error code otherwise + */ +ARGON2_PUBLIC int argon2id_verify_ctx(argon2_context *context, + const char *hash); + +/* generic function underlying the above ones */ +ARGON2_PUBLIC int argon2_verify_ctx(argon2_context *context, const char *hash, + argon2_type type); + +/** + * Get the associated error message for given error code + * @return The error message associated with the given error code + */ +ARGON2_PUBLIC const char *argon2_error_message(int error_code); + +/** + * Returns the encoded hash length for the given input parameters + * @param t_cost Number of iterations + * @param m_cost Memory usage in kibibytes + * @param parallelism Number of threads; used to compute lanes + * @param saltlen Salt size in bytes + * @param hashlen Hash size in bytes + * @param type The argon2_type that we want the encoded length for + * @return The encoded hash length in bytes + */ +ARGON2_PUBLIC size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost, + uint32_t parallelism, uint32_t saltlen, + uint32_t hashlen, argon2_type type); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/stratum/algos/argon2d/core.c b/stratum/algos/argon2d/core.c new file mode 100644 index 000000000..ed4d84121 --- /dev/null +++ b/stratum/algos/argon2d/core.c @@ -0,0 +1,635 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +/*For memory wiping*/ +#ifdef _MSC_VER +#include +#include /* For SecureZeroMemory */ +#endif +#if defined __STDC_LIB_EXT1__ +#define __STDC_WANT_LIB_EXT1__ 1 +#endif +#define VC_GE_2005(version) (version >= 1400) + +#include +#include +#include + +#include "core.h" +#include "thread.h" +#include "../blake2/blake2.h" +#include "../blake2/blake2-impl.h" + +#ifdef GENKAT +#include "genkat.h" +#endif + +#if defined(__clang__) +#if __has_attribute(optnone) +#define NOT_OPTIMIZED __attribute__((optnone)) +#endif +#elif defined(__GNUC__) +#define GCC_VERSION \ + (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#if GCC_VERSION >= 40400 +#define NOT_OPTIMIZED __attribute__((optimize("O0"))) +#endif +#endif +#ifndef NOT_OPTIMIZED +#define NOT_OPTIMIZED +#endif + +/***************Instance and Position constructors**********/ +void init_block_value(block *b, uint8_t in) { memset(b->v, in, sizeof(b->v)); } + +void copy_block(block *dst, const block *src) { + memcpy(dst->v, src->v, sizeof(uint64_t) * ARGON2_QWORDS_IN_BLOCK); +} + +void xor_block(block *dst, const block *src) { + int i; + for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { + dst->v[i] ^= src->v[i]; + } +} + +static void load_block(block *dst, const void *input) { + unsigned i; + for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { + dst->v[i] = load64((const uint8_t *)input + i * sizeof(dst->v[i])); + } +} + +static void store_block(void *output, const block *src) { + unsigned i; + for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { + store64((uint8_t *)output + i * sizeof(src->v[i]), src->v[i]); + } +} + +/***************Memory functions*****************/ + +int allocate_memory(const argon2_context *context, uint8_t **memory, + size_t num, size_t size) { + size_t memory_size = num*size; + if (memory == NULL) { + return ARGON2_MEMORY_ALLOCATION_ERROR; + } + + /* 1. Check for multiplication overflow */ + if (size != 0 && memory_size / size != num) { + return ARGON2_MEMORY_ALLOCATION_ERROR; + } + + /* 2. Try to allocate with appropriate allocator */ + if (context->allocate_cbk) { + (context->allocate_cbk)(memory, memory_size); + } else { + *memory = malloc(memory_size); + } + + if (*memory == NULL) { + return ARGON2_MEMORY_ALLOCATION_ERROR; + } + + return ARGON2_OK; +} + +void free_memory(const argon2_context *context, uint8_t *memory, + size_t num, size_t size) { + size_t memory_size = num*size; + clear_internal_memory(memory, memory_size); + if (context->free_cbk) { + (context->free_cbk)(memory, memory_size); + } else { + free(memory); + } +} + +void NOT_OPTIMIZED secure_wipe_memory(void *v, size_t n) { +#if defined(_MSC_VER) && VC_GE_2005(_MSC_VER) + SecureZeroMemory(v, n); +#elif defined memset_s + memset_s(v, n, 0, n); +#elif defined(__OpenBSD__) + explicit_bzero(v, n); +#else + static void *(*const volatile memset_sec)(void *, int, size_t) = &memset; + memset_sec(v, 0, n); +#endif +} + +/* Memory clear flag defaults to true. */ +int FLAG_clear_internal_memory = 0; +void clear_internal_memory(void *v, size_t n) { + if (FLAG_clear_internal_memory && v) { + secure_wipe_memory(v, n); + } +} + +void finalize(const argon2_context *context, argon2_instance_t *instance) { + if (context != NULL && instance != NULL) { + block blockhash; + uint32_t l; + + copy_block(&blockhash, instance->memory + instance->lane_length - 1); + + /* XOR the last blocks */ + for (l = 1; l < instance->lanes; ++l) { + uint32_t last_block_in_lane = + l * instance->lane_length + (instance->lane_length - 1); + xor_block(&blockhash, instance->memory + last_block_in_lane); + } + + /* Hash the result */ + { + uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE]; + store_block(blockhash_bytes, &blockhash); + blake2b_long(context->out, context->outlen, blockhash_bytes, + ARGON2_BLOCK_SIZE); + /* clear blockhash and blockhash_bytes */ + clear_internal_memory(blockhash.v, ARGON2_BLOCK_SIZE); + clear_internal_memory(blockhash_bytes, ARGON2_BLOCK_SIZE); + } + +#ifdef GENKAT + print_tag(context->out, context->outlen); +#endif + + free_memory(context, (uint8_t *)instance->memory, + instance->memory_blocks, sizeof(block)); + } +} + +uint32_t index_alpha(const argon2_instance_t *instance, + const argon2_position_t *position, uint32_t pseudo_rand, + int same_lane) { + /* + * Pass 0: + * This lane : all already finished segments plus already constructed + * blocks in this segment + * Other lanes : all already finished segments + * Pass 1+: + * This lane : (SYNC_POINTS - 1) last segments plus already constructed + * blocks in this segment + * Other lanes : (SYNC_POINTS - 1) last segments + */ + uint32_t reference_area_size; + uint64_t relative_position; + uint32_t start_position, absolute_position; + + if (0 == position->pass) { + /* First pass */ + if (0 == position->slice) { + /* First slice */ + reference_area_size = + position->index - 1; /* all but the previous */ + } else { + if (same_lane) { + /* The same lane => add current segment */ + reference_area_size = + position->slice * instance->segment_length + + position->index - 1; + } else { + reference_area_size = + position->slice * instance->segment_length + + ((position->index == 0) ? (-1) : 0); + } + } + } else { + /* Second pass */ + if (same_lane) { + reference_area_size = instance->lane_length - + instance->segment_length + position->index - + 1; + } else { + reference_area_size = instance->lane_length - + instance->segment_length + + ((position->index == 0) ? (-1) : 0); + } + } + + /* 1.2.4. Mapping pseudo_rand to 0.. and produce + * relative position */ + relative_position = pseudo_rand; + relative_position = relative_position * relative_position >> 32; + relative_position = reference_area_size - 1 - + (reference_area_size * relative_position >> 32); + + /* 1.2.5 Computing starting position */ + start_position = 0; + + if (0 != position->pass) { + start_position = (position->slice == ARGON2_SYNC_POINTS - 1) + ? 0 + : (position->slice + 1) * instance->segment_length; + } + + /* 1.2.6. Computing absolute position */ + absolute_position = (start_position + relative_position) % + instance->lane_length; /* absolute position */ + return absolute_position; +} + +/* Single-threaded version for p=1 case */ +static int fill_memory_blocks_st(argon2_instance_t *instance) { + uint32_t r, s, l; + + for (r = 0; r < instance->passes; ++r) { + for (s = 0; s < ARGON2_SYNC_POINTS; ++s) { + for (l = 0; l < instance->lanes; ++l) { + argon2_position_t position = {r, l, (uint8_t)s, 0}; + fill_segment(instance, position); + } + } +#ifdef GENKAT + internal_kat(instance, r); /* Print all memory blocks */ +#endif + } + return ARGON2_OK; +} + +#if !defined(ARGON2_NO_THREADS) + +#ifdef _WIN32 +static unsigned __stdcall fill_segment_thr(void *thread_data) +#else +static void *fill_segment_thr(void *thread_data) +#endif +{ + argon2_thread_data *my_data = thread_data; + fill_segment(my_data->instance_ptr, my_data->pos); + argon2_thread_exit(); + return 0; +} + +/* Multi-threaded version for p > 1 case */ +static int fill_memory_blocks_mt(argon2_instance_t *instance) { + uint32_t r, s; + argon2_thread_handle_t *thread = NULL; + argon2_thread_data *thr_data = NULL; + int rc = ARGON2_OK; + + /* 1. Allocating space for threads */ + thread = calloc(instance->lanes, sizeof(argon2_thread_handle_t)); + if (thread == NULL) { + rc = ARGON2_MEMORY_ALLOCATION_ERROR; + goto fail; + } + + thr_data = calloc(instance->lanes, sizeof(argon2_thread_data)); + if (thr_data == NULL) { + rc = ARGON2_MEMORY_ALLOCATION_ERROR; + goto fail; + } + + for (r = 0; r < instance->passes; ++r) { + for (s = 0; s < ARGON2_SYNC_POINTS; ++s) { + uint32_t l; + + /* 2. Calling threads */ + for (l = 0; l < instance->lanes; ++l) { + argon2_position_t position; + + /* 2.1 Join a thread if limit is exceeded */ + if (l >= instance->threads) { + if (argon2_thread_join(thread[l - instance->threads])) { + rc = ARGON2_THREAD_FAIL; + goto fail; + } + } + + /* 2.2 Create thread */ + position.pass = r; + position.lane = l; + position.slice = (uint8_t)s; + position.index = 0; + thr_data[l].instance_ptr = + instance; /* preparing the thread input */ + memcpy(&(thr_data[l].pos), &position, + sizeof(argon2_position_t)); + if (argon2_thread_create(&thread[l], &fill_segment_thr, + (void *)&thr_data[l])) { + rc = ARGON2_THREAD_FAIL; + goto fail; + } + + /* fill_segment(instance, position); */ + /*Non-thread equivalent of the lines above */ + } + + /* 3. Joining remaining threads */ + for (l = instance->lanes - instance->threads; l < instance->lanes; + ++l) { + if (argon2_thread_join(thread[l])) { + rc = ARGON2_THREAD_FAIL; + goto fail; + } + } + } + +#ifdef GENKAT + internal_kat(instance, r); /* Print all memory blocks */ +#endif + } + +fail: + if (thread != NULL) { + free(thread); + } + if (thr_data != NULL) { + free(thr_data); + } + return rc; +} + +#endif /* ARGON2_NO_THREADS */ + +int fill_memory_blocks(argon2_instance_t *instance) { + if (instance == NULL || instance->lanes == 0) { + return ARGON2_INCORRECT_PARAMETER; + } +#if defined(ARGON2_NO_THREADS) + return fill_memory_blocks_st(instance); +#else + return instance->threads == 1 ? + fill_memory_blocks_st(instance) : fill_memory_blocks_mt(instance); +#endif +} + +int validate_inputs(const argon2_context *context) { + if (NULL == context) { + return ARGON2_INCORRECT_PARAMETER; + } + + if (NULL == context->out) { + return ARGON2_OUTPUT_PTR_NULL; + } + + /* Validate output length */ + if (ARGON2_MIN_OUTLEN > context->outlen) { + return ARGON2_OUTPUT_TOO_SHORT; + } + + if (ARGON2_MAX_OUTLEN < context->outlen) { + return ARGON2_OUTPUT_TOO_LONG; + } + + /* Validate password (required param) */ + if (NULL == context->pwd) { + if (0 != context->pwdlen) { + return ARGON2_PWD_PTR_MISMATCH; + } + } + + if (ARGON2_MIN_PWD_LENGTH > context->pwdlen) { + return ARGON2_PWD_TOO_SHORT; + } + + if (ARGON2_MAX_PWD_LENGTH < context->pwdlen) { + return ARGON2_PWD_TOO_LONG; + } + + /* Validate salt (required param) */ + if (NULL == context->salt) { + if (0 != context->saltlen) { + return ARGON2_SALT_PTR_MISMATCH; + } + } + + if (ARGON2_MIN_SALT_LENGTH > context->saltlen) { + return ARGON2_SALT_TOO_SHORT; + } + + if (ARGON2_MAX_SALT_LENGTH < context->saltlen) { + return ARGON2_SALT_TOO_LONG; + } + + /* Validate secret (optional param) */ + if (NULL == context->secret) { + if (0 != context->secretlen) { + return ARGON2_SECRET_PTR_MISMATCH; + } + } else { + if (ARGON2_MIN_SECRET > context->secretlen) { + return ARGON2_SECRET_TOO_SHORT; + } + if (ARGON2_MAX_SECRET < context->secretlen) { + return ARGON2_SECRET_TOO_LONG; + } + } + + /* Validate associated data (optional param) */ + if (NULL == context->ad) { + if (0 != context->adlen) { + return ARGON2_AD_PTR_MISMATCH; + } + } else { + if (ARGON2_MIN_AD_LENGTH > context->adlen) { + return ARGON2_AD_TOO_SHORT; + } + if (ARGON2_MAX_AD_LENGTH < context->adlen) { + return ARGON2_AD_TOO_LONG; + } + } + + /* Validate memory cost */ + if (ARGON2_MIN_MEMORY > context->m_cost) { + return ARGON2_MEMORY_TOO_LITTLE; + } + + if (ARGON2_MAX_MEMORY < context->m_cost) { + return ARGON2_MEMORY_TOO_MUCH; + } + + /* if (context->m_cost < 8 * context->lanes) { + return ARGON2_MEMORY_TOO_LITTLE; + } */ + + /* Validate time cost */ + if (ARGON2_MIN_TIME > context->t_cost) { + return ARGON2_TIME_TOO_SMALL; + } + + if (ARGON2_MAX_TIME < context->t_cost) { + return ARGON2_TIME_TOO_LARGE; + } + + /* Validate lanes */ + if (ARGON2_MIN_LANES > context->lanes) { + return ARGON2_LANES_TOO_FEW; + } + + if (ARGON2_MAX_LANES < context->lanes) { + return ARGON2_LANES_TOO_MANY; + } + + /* Validate threads */ + if (ARGON2_MIN_THREADS > context->threads) { + return ARGON2_THREADS_TOO_FEW; + } + + if (ARGON2_MAX_THREADS < context->threads) { + return ARGON2_THREADS_TOO_MANY; + } + + if (NULL != context->allocate_cbk && NULL == context->free_cbk) { + return ARGON2_FREE_MEMORY_CBK_NULL; + } + + if (NULL == context->allocate_cbk && NULL != context->free_cbk) { + return ARGON2_ALLOCATE_MEMORY_CBK_NULL; + } + + return ARGON2_OK; +} + +void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance) { + uint32_t l; + /* Make the first and second block in each lane as G(H0||0||i) or + G(H0||1||i) */ + uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE]; + for (l = 0; l < instance->lanes; ++l) { + + store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0); + store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4, l); + blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash, + ARGON2_PREHASH_SEED_LENGTH); + load_block(&instance->memory[l * instance->lane_length + 0], + blockhash_bytes); + + store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 1); + blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash, + ARGON2_PREHASH_SEED_LENGTH); + load_block(&instance->memory[l * instance->lane_length + 1], + blockhash_bytes); + } + clear_internal_memory(blockhash_bytes, ARGON2_BLOCK_SIZE); +} + +void initial_hash(uint8_t *blockhash, argon2_context *context, + argon2_type type) { + blake2b_state BlakeHash; + uint8_t value[sizeof(uint32_t)]; + + if (NULL == context || NULL == blockhash) { + return; + } + + blake2b_init(&BlakeHash, ARGON2_PREHASH_DIGEST_LENGTH); + + store32(&value, context->lanes); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + store32(&value, context->outlen); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + store32(&value, context->m_cost); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + store32(&value, context->t_cost); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + +// store32(&value, ARGON2_VERSION_NUMBER); + store32(&value, context->version); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + store32(&value, (uint32_t)type); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + store32(&value, context->pwdlen); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + if (context->pwd != NULL) { + blake2b_update(&BlakeHash, (const uint8_t *)context->pwd, + context->pwdlen); + + if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) { + secure_wipe_memory(context->pwd, context->pwdlen); + context->pwdlen = 0; + } + } + + store32(&value, context->saltlen); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + if (context->salt != NULL) { + blake2b_update(&BlakeHash, (const uint8_t *)context->salt, + context->saltlen); + } + + store32(&value, context->secretlen); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + if (context->secret != NULL) { + blake2b_update(&BlakeHash, (const uint8_t *)context->secret, + context->secretlen); + + if (context->flags & ARGON2_FLAG_CLEAR_SECRET) { + secure_wipe_memory(context->secret, context->secretlen); + context->secretlen = 0; + } + } + + store32(&value, context->adlen); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + if (context->ad != NULL) { + blake2b_update(&BlakeHash, (const uint8_t *)context->ad, + context->adlen); + } + + blake2b_final(&BlakeHash, blockhash, ARGON2_PREHASH_DIGEST_LENGTH); +} + +int initialize(argon2_instance_t *instance, argon2_context *context) { + uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; + int result = ARGON2_OK; + + if (instance == NULL || context == NULL) + return ARGON2_INCORRECT_PARAMETER; + instance->context_ptr = context; + + /* 1. Memory allocation */ + result = allocate_memory(context, (uint8_t **)&(instance->memory), + instance->memory_blocks, sizeof(block)); + if (result != ARGON2_OK) { + return result; + } + + /* 2. Initial hashing */ + /* H_0 + 8 extra bytes to produce the first blocks */ + /* uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; */ + /* Hashing all inputs */ + initial_hash(blockhash, context, instance->type); + /* Zeroing 8 extra bytes */ + clear_internal_memory(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, + ARGON2_PREHASH_SEED_LENGTH - + ARGON2_PREHASH_DIGEST_LENGTH); + +#ifdef GENKAT + initial_kat(blockhash, context, instance->type); +#endif + + /* 3. Creating first blocks, we always have at least two blocks in a slice + */ + fill_first_blocks(blockhash, instance); + /* Clearing the hash */ + clear_internal_memory(blockhash, ARGON2_PREHASH_SEED_LENGTH); + + return ARGON2_OK; +} diff --git a/stratum/algos/argon2d/core.h b/stratum/algos/argon2d/core.h new file mode 100644 index 000000000..78000ba9e --- /dev/null +++ b/stratum/algos/argon2d/core.h @@ -0,0 +1,228 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#ifndef ARGON2_CORE_H +#define ARGON2_CORE_H + +#include "argon2.h" + +#define CONST_CAST(x) (x)(uintptr_t) + +/**********************Argon2 internal constants*******************************/ + +enum argon2_core_constants { + /* Memory block size in bytes */ + ARGON2_BLOCK_SIZE = 1024, + ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8, + ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16, + ARGON2_HWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 32, + ARGON2_512BIT_WORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 64, + + /* Number of pseudo-random values generated by one call to Blake in Argon2i + to + generate reference block positions */ + ARGON2_ADDRESSES_IN_BLOCK = 128, + + /* Pre-hashing digest length and its extension*/ + ARGON2_PREHASH_DIGEST_LENGTH = 64, + ARGON2_PREHASH_SEED_LENGTH = 72 +}; + +/*************************Argon2 internal data types***********************/ + +/* + * Structure for the (1KB) memory block implemented as 128 64-bit words. + * Memory blocks can be copied, XORed. Internal words can be accessed by [] (no + * bounds checking). + */ +typedef struct block_ { uint64_t v[ARGON2_QWORDS_IN_BLOCK]; } block; + +/*****************Functions that work with the block******************/ + +/* Initialize each byte of the block with @in */ +void init_block_value(block *b, uint8_t in); + +/* Copy block @src to block @dst */ +void copy_block(block *dst, const block *src); + +/* XOR @src onto @dst bytewise */ +void xor_block(block *dst, const block *src); + +/* + * Argon2 instance: memory pointer, number of passes, amount of memory, type, + * and derived values. + * Used to evaluate the number and location of blocks to construct in each + * thread + */ +typedef struct Argon2_instance_t { + block *memory; /* Memory pointer */ + uint32_t version; + uint32_t passes; /* Number of passes */ + uint32_t memory_blocks; /* Number of blocks in memory */ + uint32_t segment_length; + uint32_t lane_length; + uint32_t lanes; + uint32_t threads; + argon2_type type; + int print_internals; /* whether to print the memory blocks */ + argon2_context *context_ptr; /* points back to original context */ +} argon2_instance_t; + +/* + * Argon2 position: where we construct the block right now. Used to distribute + * work between threads. + */ +typedef struct Argon2_position_t { + uint32_t pass; + uint32_t lane; + uint8_t slice; + uint32_t index; +} argon2_position_t; + +/*Struct that holds the inputs for thread handling FillSegment*/ +typedef struct Argon2_thread_data { + argon2_instance_t *instance_ptr; + argon2_position_t pos; +} argon2_thread_data; + +/*************************Argon2 core functions********************************/ + +/* Allocates memory to the given pointer, uses the appropriate allocator as + * specified in the context. Total allocated memory is num*size. + * @param context argon2_context which specifies the allocator + * @param memory pointer to the pointer to the memory + * @param size the size in bytes for each element to be allocated + * @param num the number of elements to be allocated + * @return ARGON2_OK if @memory is a valid pointer and memory is allocated + */ +int allocate_memory(const argon2_context *context, uint8_t **memory, + size_t num, size_t size); + +/* + * Frees memory at the given pointer, uses the appropriate deallocator as + * specified in the context. Also cleans the memory using clear_internal_memory. + * @param context argon2_context which specifies the deallocator + * @param memory pointer to buffer to be freed + * @param size the size in bytes for each element to be deallocated + * @param num the number of elements to be deallocated + */ +void free_memory(const argon2_context *context, uint8_t *memory, + size_t num, size_t size); + +/* Function that securely cleans the memory. This ignores any flags set + * regarding clearing memory. Usually one just calls clear_internal_memory. + * @param mem Pointer to the memory + * @param s Memory size in bytes + */ +void secure_wipe_memory(void *v, size_t n); + +/* Function that securely clears the memory if FLAG_clear_internal_memory is + * set. If the flag isn't set, this function does nothing. + * @param mem Pointer to the memory + * @param s Memory size in bytes + */ +void clear_internal_memory(void *v, size_t n); + +/* + * Computes absolute position of reference block in the lane following a skewed + * distribution and using a pseudo-random value as input + * @param instance Pointer to the current instance + * @param position Pointer to the current position + * @param pseudo_rand 32-bit pseudo-random value used to determine the position + * @param same_lane Indicates if the block will be taken from the current lane. + * If so we can reference the current segment + * @pre All pointers must be valid + */ +uint32_t index_alpha(const argon2_instance_t *instance, + const argon2_position_t *position, uint32_t pseudo_rand, + int same_lane); + +/* + * Function that validates all inputs against predefined restrictions and return + * an error code + * @param context Pointer to current Argon2 context + * @return ARGON2_OK if everything is all right, otherwise one of error codes + * (all defined in + */ +int validate_inputs(const argon2_context *context); + +/* + * Hashes all the inputs into @a blockhash[PREHASH_DIGEST_LENGTH], clears + * password and secret if needed + * @param context Pointer to the Argon2 internal structure containing memory + * pointer, and parameters for time and space requirements. + * @param blockhash Buffer for pre-hashing digest + * @param type Argon2 type + * @pre @a blockhash must have at least @a PREHASH_DIGEST_LENGTH bytes + * allocated + */ +void initial_hash(uint8_t *blockhash, argon2_context *context, + argon2_type type); + +/* + * Function creates first 2 blocks per lane + * @param instance Pointer to the current instance + * @param blockhash Pointer to the pre-hashing digest + * @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values + */ +void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance); + +/* + * Function allocates memory, hashes the inputs with Blake, and creates first + * two blocks. Returns the pointer to the main memory with 2 blocks per lane + * initialized + * @param context Pointer to the Argon2 internal structure containing memory + * pointer, and parameters for time and space requirements. + * @param instance Current Argon2 instance + * @return Zero if successful, -1 if memory failed to allocate. @context->state + * will be modified if successful. + */ +int initialize(argon2_instance_t *instance, argon2_context *context); + +/* + * XORing the last block of each lane, hashing it, making the tag. Deallocates + * the memory. + * @param context Pointer to current Argon2 context (use only the out parameters + * from it) + * @param instance Pointer to current instance of Argon2 + * @pre instance->state must point to necessary amount of memory + * @pre context->out must point to outlen bytes of memory + * @pre if context->free_cbk is not NULL, it should point to a function that + * deallocates memory + */ +void finalize(const argon2_context *context, argon2_instance_t *instance); + +/* + * Function that fills the segment using previous segments also from other + * threads + * @param context current context + * @param instance Pointer to the current instance + * @param position Current position + * @pre all block pointers must be valid + */ +void fill_segment(const argon2_instance_t *instance, + argon2_position_t position); + +/* + * Function that fills the entire memory t_cost times based on the first two + * blocks in each lane + * @param instance Pointer to the current instance + * @return ARGON2_OK if successful, @context->state + */ +int fill_memory_blocks(argon2_instance_t *instance); + +#endif diff --git a/stratum/algos/argon2d/encoding.c b/stratum/algos/argon2d/encoding.c new file mode 100644 index 000000000..12cfda4d0 --- /dev/null +++ b/stratum/algos/argon2d/encoding.c @@ -0,0 +1,463 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#include +#include +#include +#include +#include "encoding.h" +#include "core.h" + +/* + * Example code for a decoder and encoder of "hash strings", with Argon2 + * parameters. + * + * This code comprises three sections: + * + * -- The first section contains generic Base64 encoding and decoding + * functions. It is conceptually applicable to any hash function + * implementation that uses Base64 to encode and decode parameters, + * salts and outputs. It could be made into a library, provided that + * the relevant functions are made public (non-static) and be given + * reasonable names to avoid collisions with other functions. + * + * -- The second section is specific to Argon2. It encodes and decodes + * the parameters, salts and outputs. It does not compute the hash + * itself. + * + * The code was originally written by Thomas Pornin , + * to whom comments and remarks may be sent. It is released under what + * should amount to Public Domain or its closest equivalent; the + * following mantra is supposed to incarnate that fact with all the + * proper legal rituals: + * + * --------------------------------------------------------------------- + * This file is provided under the terms of Creative Commons CC0 1.0 + * Public Domain Dedication. To the extent possible under law, the + * author (Thomas Pornin) has waived all copyright and related or + * neighboring rights to this file. This work is published from: Canada. + * --------------------------------------------------------------------- + * + * Copyright (c) 2015 Thomas Pornin + */ + +/* ==================================================================== */ +/* + * Common code; could be shared between different hash functions. + * + * Note: the Base64 functions below assume that uppercase letters (resp. + * lowercase letters) have consecutive numerical codes, that fit on 8 + * bits. All modern systems use ASCII-compatible charsets, where these + * properties are true. If you are stuck with a dinosaur of a system + * that still defaults to EBCDIC then you already have much bigger + * interoperability issues to deal with. + */ + +/* + * Some macros for constant-time comparisons. These work over values in + * the 0..255 range. Returned value is 0x00 on "false", 0xFF on "true". + */ +#define EQ(x, y) ((((0U - ((unsigned)(x) ^ (unsigned)(y))) >> 8) & 0xFF) ^ 0xFF) +#define GT(x, y) ((((unsigned)(y) - (unsigned)(x)) >> 8) & 0xFF) +#define GE(x, y) (GT(y, x) ^ 0xFF) +#define LT(x, y) GT(y, x) +#define LE(x, y) GE(y, x) + +/* + * Convert value x (0..63) to corresponding Base64 character. + */ +static int b64_byte_to_char(unsigned x) { + return (LT(x, 26) & (x + 'A')) | + (GE(x, 26) & LT(x, 52) & (x + ('a' - 26))) | + (GE(x, 52) & LT(x, 62) & (x + ('0' - 52))) | (EQ(x, 62) & '+') | + (EQ(x, 63) & '/'); +} + +/* + * Convert character c to the corresponding 6-bit value. If character c + * is not a Base64 character, then 0xFF (255) is returned. + */ +static unsigned b64_char_to_byte(int c) { + unsigned x; + + x = (GE(c, 'A') & LE(c, 'Z') & (c - 'A')) | + (GE(c, 'a') & LE(c, 'z') & (c - ('a' - 26))) | + (GE(c, '0') & LE(c, '9') & (c - ('0' - 52))) | (EQ(c, '+') & 62) | + (EQ(c, '/') & 63); + return x | (EQ(x, 0) & (EQ(c, 'A') ^ 0xFF)); +} + +/* + * Convert some bytes to Base64. 'dst_len' is the length (in characters) + * of the output buffer 'dst'; if that buffer is not large enough to + * receive the result (including the terminating 0), then (size_t)-1 + * is returned. Otherwise, the zero-terminated Base64 string is written + * in the buffer, and the output length (counted WITHOUT the terminating + * zero) is returned. + */ +static size_t to_base64(char *dst, size_t dst_len, const void *src, + size_t src_len) { + size_t olen; + const unsigned char *buf; + unsigned acc, acc_len; + + olen = (src_len / 3) << 2; + switch (src_len % 3) { + case 2: + olen++; + /* fall through */ + case 1: + olen += 2; + break; + } + if (dst_len <= olen) { + return (size_t)-1; + } + acc = 0; + acc_len = 0; + buf = (const unsigned char *)src; + while (src_len-- > 0) { + acc = (acc << 8) + (*buf++); + acc_len += 8; + while (acc_len >= 6) { + acc_len -= 6; + *dst++ = (char)b64_byte_to_char((acc >> acc_len) & 0x3F); + } + } + if (acc_len > 0) { + *dst++ = (char)b64_byte_to_char((acc << (6 - acc_len)) & 0x3F); + } + *dst++ = 0; + return olen; +} + +/* + * Decode Base64 chars into bytes. The '*dst_len' value must initially + * contain the length of the output buffer '*dst'; when the decoding + * ends, the actual number of decoded bytes is written back in + * '*dst_len'. + * + * Decoding stops when a non-Base64 character is encountered, or when + * the output buffer capacity is exceeded. If an error occurred (output + * buffer is too small, invalid last characters leading to unprocessed + * buffered bits), then NULL is returned; otherwise, the returned value + * points to the first non-Base64 character in the source stream, which + * may be the terminating zero. + */ +static const char *from_base64(void *dst, size_t *dst_len, const char *src) { + size_t len; + unsigned char *buf; + unsigned acc, acc_len; + + buf = (unsigned char *)dst; + len = 0; + acc = 0; + acc_len = 0; + for (;;) { + unsigned d; + + d = b64_char_to_byte(*src); + if (d == 0xFF) { + break; + } + src++; + acc = (acc << 6) + d; + acc_len += 6; + if (acc_len >= 8) { + acc_len -= 8; + if ((len++) >= *dst_len) { + return NULL; + } + *buf++ = (acc >> acc_len) & 0xFF; + } + } + + /* + * If the input length is equal to 1 modulo 4 (which is + * invalid), then there will remain 6 unprocessed bits; + * otherwise, only 0, 2 or 4 bits are buffered. The buffered + * bits must also all be zero. + */ + if (acc_len > 4 || (acc & (((unsigned)1 << acc_len) - 1)) != 0) { + return NULL; + } + *dst_len = len; + return src; +} + +/* + * Decode decimal integer from 'str'; the value is written in '*v'. + * Returned value is a pointer to the next non-decimal character in the + * string. If there is no digit at all, or the value encoding is not + * minimal (extra leading zeros), or the value does not fit in an + * 'unsigned long', then NULL is returned. + */ +static const char *decode_decimal(const char *str, unsigned long *v) { + const char *orig; + unsigned long acc; + + acc = 0; + for (orig = str;; str++) { + int c; + + c = *str; + if (c < '0' || c > '9') { + break; + } + c -= '0'; + if (acc > (ULONG_MAX / 10)) { + return NULL; + } + acc *= 10; + if ((unsigned long)c > (ULONG_MAX - acc)) { + return NULL; + } + acc += (unsigned long)c; + } + if (str == orig || (*orig == '0' && str != (orig + 1))) { + return NULL; + } + *v = acc; + return str; +} + +/* ==================================================================== */ +/* + * Code specific to Argon2. + * + * The code below applies the following format: + * + * $argon2[$v=]$m=,t=,p=$$ + * + * where is either 'd', 'id', or 'i', is a decimal integer (positive, + * fits in an 'unsigned long'), and is Base64-encoded data (no '=' padding + * characters, no newline or whitespace). + * + * The last two binary chunks (encoded in Base64) are, in that order, + * the salt and the output. Both are required. The binary salt length and the + * output length must be in the allowed ranges defined in argon2.h. + * + * The ctx struct must contain buffers large enough to hold the salt and pwd + * when it is fed into decode_string. + */ + +int decode_string(argon2_context *ctx, const char *str, argon2_type type) { + +/* check for prefix */ +#define CC(prefix) \ + do { \ + size_t cc_len = strlen(prefix); \ + if (strncmp(str, prefix, cc_len) != 0) { \ + return ARGON2_DECODING_FAIL; \ + } \ + str += cc_len; \ + } while ((void)0, 0) + +/* optional prefix checking with supplied code */ +#define CC_opt(prefix, code) \ + do { \ + size_t cc_len = strlen(prefix); \ + if (strncmp(str, prefix, cc_len) == 0) { \ + str += cc_len; \ + { code; } \ + } \ + } while ((void)0, 0) + +/* Decoding prefix into decimal */ +#define DECIMAL(x) \ + do { \ + unsigned long dec_x; \ + str = decode_decimal(str, &dec_x); \ + if (str == NULL) { \ + return ARGON2_DECODING_FAIL; \ + } \ + (x) = dec_x; \ + } while ((void)0, 0) + + +/* Decoding prefix into uint32_t decimal */ +#define DECIMAL_U32(x) \ + do { \ + unsigned long dec_x; \ + str = decode_decimal(str, &dec_x); \ + if (str == NULL || dec_x > UINT32_MAX) { \ + return ARGON2_DECODING_FAIL; \ + } \ + (x) = (uint32_t)dec_x; \ + } while ((void)0, 0) + + +/* Decoding base64 into a binary buffer */ +#define BIN(buf, max_len, len) \ + do { \ + size_t bin_len = (max_len); \ + str = from_base64(buf, &bin_len, str); \ + if (str == NULL || bin_len > UINT32_MAX) { \ + return ARGON2_DECODING_FAIL; \ + } \ + (len) = (uint32_t)bin_len; \ + } while ((void)0, 0) + + size_t maxsaltlen = ctx->saltlen; + size_t maxoutlen = ctx->outlen; + int validation_result; + const char* type_string; + + /* We should start with the argon2_type we are using */ + type_string = argon2_type2string(type, 0); + if (!type_string) { + return ARGON2_INCORRECT_TYPE; + } + + CC("$"); + CC(type_string); + + /* Reading the version number if the default is suppressed */ + ctx->version = ARGON2_VERSION_10; + CC_opt("$v=", DECIMAL_U32(ctx->version)); + + CC("$m="); + DECIMAL_U32(ctx->m_cost); + CC(",t="); + DECIMAL_U32(ctx->t_cost); + CC(",p="); + DECIMAL_U32(ctx->lanes); + ctx->threads = ctx->lanes; + + CC("$"); + BIN(ctx->salt, maxsaltlen, ctx->saltlen); + CC("$"); + BIN(ctx->out, maxoutlen, ctx->outlen); + + /* The rest of the fields get the default values */ + ctx->secret = NULL; + ctx->secretlen = 0; + ctx->ad = NULL; + ctx->adlen = 0; + ctx->allocate_cbk = NULL; + ctx->free_cbk = NULL; + ctx->flags = ARGON2_DEFAULT_FLAGS; + + /* On return, must have valid context */ + validation_result = validate_inputs(ctx); + if (validation_result != ARGON2_OK) { + return validation_result; + } + + /* Can't have any additional characters */ + if (*str == 0) { + return ARGON2_OK; + } else { + return ARGON2_DECODING_FAIL; + } +#undef CC +#undef CC_opt +#undef DECIMAL +#undef BIN +} + +int encode_string(char *dst, size_t dst_len, argon2_context *ctx, + argon2_type type) { +#define SS(str) \ + do { \ + size_t pp_len = strlen(str); \ + if (pp_len >= dst_len) { \ + return ARGON2_ENCODING_FAIL; \ + } \ + memcpy(dst, str, pp_len + 1); \ + dst += pp_len; \ + dst_len -= pp_len; \ + } while ((void)0, 0) + +#define SX(x) \ + do { \ + char tmp[30]; \ + sprintf(tmp, "%lu", (unsigned long)(x)); \ + SS(tmp); \ + } while ((void)0, 0) + +#define SB(buf, len) \ + do { \ + size_t sb_len = to_base64(dst, dst_len, buf, len); \ + if (sb_len == (size_t)-1) { \ + return ARGON2_ENCODING_FAIL; \ + } \ + dst += sb_len; \ + dst_len -= sb_len; \ + } while ((void)0, 0) + + const char* type_string = argon2_type2string(type, 0); + int validation_result = validate_inputs(ctx); + + if (!type_string) { + return ARGON2_ENCODING_FAIL; + } + + if (validation_result != ARGON2_OK) { + return validation_result; + } + + + SS("$"); + SS(type_string); + + SS("$v="); + SX(ctx->version); + + SS("$m="); + SX(ctx->m_cost); + SS(",t="); + SX(ctx->t_cost); + SS(",p="); + SX(ctx->lanes); + + SS("$"); + SB(ctx->salt, ctx->saltlen); + + SS("$"); + SB(ctx->out, ctx->outlen); + return ARGON2_OK; + +#undef SS +#undef SX +#undef SB +} + +size_t b64len(uint32_t len) { + size_t olen = ((size_t)len / 3) << 2; + + switch (len % 3) { + case 2: + olen++; + /* fall through */ + case 1: + olen += 2; + break; + } + + return olen; +} + +size_t numlen(uint32_t num) { + size_t len = 1; + while (num >= 10) { + ++len; + num = num / 10; + } + return len; +} + diff --git a/stratum/algos/argon2d/encoding.h b/stratum/algos/argon2d/encoding.h new file mode 100644 index 000000000..7e83ec928 --- /dev/null +++ b/stratum/algos/argon2d/encoding.h @@ -0,0 +1,57 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#ifndef ENCODING_H +#define ENCODING_H +#include "argon2.h" + +#define ARGON2_MAX_DECODED_LANES UINT32_C(255) +#define ARGON2_MIN_DECODED_SALT_LEN UINT32_C(8) +#define ARGON2_MIN_DECODED_OUT_LEN UINT32_C(12) + +/* +* encode an Argon2 hash string into the provided buffer. 'dst_len' +* contains the size, in characters, of the 'dst' buffer; if 'dst_len' +* is less than the number of required characters (including the +* terminating 0), then this function returns ARGON2_ENCODING_ERROR. +* +* on success, ARGON2_OK is returned. +*/ +int encode_string(char *dst, size_t dst_len, argon2_context *ctx, + argon2_type type); + +/* +* Decodes an Argon2 hash string into the provided structure 'ctx'. +* The only fields that must be set prior to this call are ctx.saltlen and +* ctx.outlen (which must be the maximal salt and out length values that are +* allowed), ctx.salt and ctx.out (which must be buffers of the specified +* length), and ctx.pwd and ctx.pwdlen which must hold a valid password. +* +* Invalid input string causes an error. On success, the ctx is valid and all +* fields have been initialized. +* +* Returned value is ARGON2_OK on success, other ARGON2_ codes on error. +*/ +int decode_string(argon2_context *ctx, const char *str, argon2_type type); + +/* Returns the length of the encoded byte stream with length len */ +size_t b64len(uint32_t len); + +/* Returns the length of the encoded number num */ +size_t numlen(uint32_t num); + +#endif diff --git a/stratum/algos/argon2d/opt.c b/stratum/algos/argon2d/opt.c new file mode 100644 index 000000000..87ff4cc95 --- /dev/null +++ b/stratum/algos/argon2d/opt.c @@ -0,0 +1,359 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#include +#include +#include + +#include "argon2.h" +#include "core.h" + +#include "../blake2/blake2.h" +#include "../blake2/blamka-round-opt.h" + +/* + * Function fills a new memory block and optionally XORs the old block over the new one. + * Memory must be initialized. + * @param state Pointer to the just produced block. Content will be updated(!) + * @param ref_block Pointer to the reference block + * @param next_block Pointer to the block to be XORed over. May coincide with @ref_block + * @param with_xor Whether to XOR into the new block (1) or just overwrite (0) + * @pre all block pointers must be valid + */ + +#if defined(__AVX512F__) + +static void fill_block(__m512i *state, const block *ref_block, + block *next_block, int with_xor) { + __m512i block_XY[ARGON2_512BIT_WORDS_IN_BLOCK]; + unsigned int i; + + if (with_xor) { + for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) { + state[i] = _mm512_xor_si512( + state[i], _mm512_loadu_si512((const __m512i *)ref_block->v + i)); + block_XY[i] = _mm512_xor_si512( + state[i], _mm512_loadu_si512((const __m512i *)next_block->v + i)); + } + } else { + for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) { + block_XY[i] = state[i] = _mm512_xor_si512( + state[i], _mm512_loadu_si512((const __m512i *)ref_block->v + i)); + } + } + + BLAKE2_ROUND_1( state[ 0], state[ 1], state[ 2], state[ 3], + state[ 4], state[ 5], state[ 6], state[ 7] ); + BLAKE2_ROUND_1( state[ 8], state[ 9], state[10], state[11], + state[12], state[13], state[14], state[15] ); + + BLAKE2_ROUND_2( state[ 0], state[ 2], state[ 4], state[ 6], + state[ 8], state[10], state[12], state[14] ); + BLAKE2_ROUND_2( state[ 1], state[ 3], state[ 5], state[ 7], + state[ 9], state[11], state[13], state[15] ); + +/* + for (i = 0; i < 2; ++i) { + BLAKE2_ROUND_1( + state[8 * i + 0], state[8 * i + 1], state[8 * i + 2], state[8 * i + 3], + state[8 * i + 4], state[8 * i + 5], state[8 * i + 6], state[8 * i + 7]); + } + + for (i = 0; i < 2; ++i) { + BLAKE2_ROUND_2( + state[2 * 0 + i], state[2 * 1 + i], state[2 * 2 + i], state[2 * 3 + i], + state[2 * 4 + i], state[2 * 5 + i], state[2 * 6 + i], state[2 * 7 + i]); + } +*/ + + for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) { + state[i] = _mm512_xor_si512(state[i], block_XY[i]); + _mm512_storeu_si512((__m512i *)next_block->v + i, state[i]); + } +} + +#elif defined(__AVX2__) + +static void fill_block(__m256i *state, const block *ref_block, + block *next_block, int with_xor) { + __m256i block_XY[ARGON2_HWORDS_IN_BLOCK]; + unsigned int i; + + if (with_xor) { + for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) { + state[i] = _mm256_xor_si256( + state[i], _mm256_loadu_si256((const __m256i *)ref_block->v + i)); + block_XY[i] = _mm256_xor_si256( + state[i], _mm256_loadu_si256((const __m256i *)next_block->v + i)); + } + } else { + for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) { + block_XY[i] = state[i] = _mm256_xor_si256( + state[i], _mm256_loadu_si256((const __m256i *)ref_block->v + i)); + } + } + + BLAKE2_ROUND_1( state[ 0], state[ 4], state[ 1], state[ 5], + state[ 2], state[ 6], state[ 3], state[ 7] ); + BLAKE2_ROUND_1( state[ 8], state[12], state[ 9], state[13], + state[10], state[14], state[11], state[15] ); + BLAKE2_ROUND_1( state[16], state[20], state[17], state[21], + state[18], state[22], state[19], state[23] ); + BLAKE2_ROUND_1( state[24], state[28], state[25], state[29], + state[26], state[30], state[27], state[31] ); + + BLAKE2_ROUND_2( state[ 0], state[ 4], state[ 8], state[12], + state[16], state[20], state[24], state[28] ); + BLAKE2_ROUND_2( state[ 1], state[ 5], state[ 9], state[13], + state[17], state[21], state[25], state[29] ); + BLAKE2_ROUND_2( state[ 2], state[ 6], state[10], state[14], + state[18], state[22], state[26], state[30] ); + BLAKE2_ROUND_2( state[ 3], state[ 7], state[11], state[15], + state[19], state[23], state[27], state[31] ); + +/* + for (i = 0; i < 4; ++i) { + BLAKE2_ROUND_1(state[8 * i + 0], state[8 * i + 4], state[8 * i + 1], state[8 * i + 5], + state[8 * i + 2], state[8 * i + 6], state[8 * i + 3], state[8 * i + 7]); + } + + for (i = 0; i < 4; ++i) { + BLAKE2_ROUND_2(state[ 0 + i], state[ 4 + i], state[ 8 + i], state[12 + i], + state[16 + i], state[20 + i], state[24 + i], state[28 + i]); + } +*/ + + for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) { + state[i] = _mm256_xor_si256(state[i], block_XY[i]); + _mm256_storeu_si256((__m256i *)next_block->v + i, state[i]); + } +} + +#else // SSE2 + +static void fill_block(__m128i *state, const block *ref_block, + block *next_block, int with_xor) { + __m128i block_XY[ARGON2_OWORDS_IN_BLOCK]; + unsigned int i; + + if (with_xor) { + for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) { + state[i] = _mm_xor_si128( + state[i], _mm_loadu_si128((const __m128i *)ref_block->v + i)); + block_XY[i] = _mm_xor_si128( + state[i], _mm_loadu_si128((const __m128i *)next_block->v + i)); + } + } else { + for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) { + block_XY[i] = state[i] = _mm_xor_si128( + state[i], _mm_loadu_si128((const __m128i *)ref_block->v + i)); + } + } + + BLAKE2_ROUND( state[ 0], state[ 1], state[ 2], state[ 3], + state[ 4], state[ 5], state[ 6], state[ 7] ); + BLAKE2_ROUND( state[ 8], state[ 9], state[10], state[11], + state[12], state[13], state[14], state[15] ); + BLAKE2_ROUND( state[16], state[17], state[18], state[19], + state[20], state[21], state[22], state[23] ); + BLAKE2_ROUND( state[24], state[25], state[26], state[27], + state[28], state[29], state[30], state[31] ); + BLAKE2_ROUND( state[32], state[33], state[34], state[35], + state[36], state[37], state[38], state[39] ); + BLAKE2_ROUND( state[40], state[41], state[42], state[43], + state[44], state[45], state[46], state[47] ); + BLAKE2_ROUND( state[48], state[49], state[50], state[51], + state[52], state[53], state[54], state[55] ); + BLAKE2_ROUND( state[56], state[57], state[58], state[59], + state[60], state[61], state[62], state[63] ); + + BLAKE2_ROUND( state[ 0], state[ 8], state[16], state[24], + state[32], state[40], state[48], state[56] ); + BLAKE2_ROUND( state[ 1], state[ 9], state[17], state[25], + state[33], state[41], state[49], state[57] ); + BLAKE2_ROUND( state[ 2], state[10], state[18], state[26], + state[34], state[42], state[50], state[58] ); + BLAKE2_ROUND( state[ 3], state[11], state[19], state[27], + state[35], state[43], state[51], state[59] ); + BLAKE2_ROUND( state[ 4], state[12], state[20], state[28], + state[36], state[44], state[52], state[60] ); + BLAKE2_ROUND( state[ 5], state[13], state[21], state[29], + state[37], state[45], state[53], state[61] ); + BLAKE2_ROUND( state[ 6], state[14], state[22], state[30], + state[38], state[46], state[54], state[62] ); + BLAKE2_ROUND( state[ 7], state[15], state[23], state[31], + state[39], state[47], state[55], state[63] ); + +/* + for (i = 0; i < 8; ++i) { + BLAKE2_ROUND(state[8 * i + 0], state[8 * i + 1], state[8 * i + 2], + state[8 * i + 3], state[8 * i + 4], state[8 * i + 5], + state[8 * i + 6], state[8 * i + 7]); + } + + for (i = 0; i < 8; ++i) { + BLAKE2_ROUND(state[8 * 0 + i], state[8 * 1 + i], state[8 * 2 + i], + state[8 * 3 + i], state[8 * 4 + i], state[8 * 5 + i], + state[8 * 6 + i], state[8 * 7 + i]); + } +*/ + for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) { + state[i] = _mm_xor_si128(state[i], block_XY[i]); + _mm_storeu_si128((__m128i *)next_block->v + i, state[i]); + } +} + +#endif + +#if 0 +static void next_addresses(block *address_block, block *input_block) { + /*Temporary zero-initialized blocks*/ +#if defined(__AVX512F__) + __m512i zero_block[ARGON2_512BIT_WORDS_IN_BLOCK]; + __m512i zero2_block[ARGON2_512BIT_WORDS_IN_BLOCK]; +#elif defined(__AVX2__) + __m256i zero_block[ARGON2_HWORDS_IN_BLOCK]; + __m256i zero2_block[ARGON2_HWORDS_IN_BLOCK]; +#else + __m128i zero_block[ARGON2_OWORDS_IN_BLOCK]; + __m128i zero2_block[ARGON2_OWORDS_IN_BLOCK]; +#endif + + memset(zero_block, 0, sizeof(zero_block)); + memset(zero2_block, 0, sizeof(zero2_block)); + + /*Increasing index counter*/ + input_block->v[6]++; + + /*First iteration of G*/ + fill_block(zero_block, input_block, address_block, 0); + + /*Second iteration of G*/ + fill_block(zero2_block, address_block, address_block, 0); +} +#endif + +void fill_segment(const argon2_instance_t *instance, + argon2_position_t position) { + block *ref_block = NULL, *curr_block = NULL; +// block address_block, input_block; + uint64_t pseudo_rand, ref_index, ref_lane; + uint32_t prev_offset, curr_offset; + uint32_t starting_index, i; +#if defined(__AVX512F__) + __m512i state[ARGON2_512BIT_WORDS_IN_BLOCK]; +#elif defined(__AVX2__) + __m256i state[ARGON2_HWORDS_IN_BLOCK]; +#else + __m128i state[ARGON2_OWORDS_IN_BLOCK]; +#endif +// int data_independent_addressing; + + if (instance == NULL) { + return; + } + + // data_independent_addressing = + // (instance->type == Argon2_i) || + // (instance->type == Argon2_id && (position.pass == 0) && + // (position.slice < ARGON2_SYNC_POINTS / 2)); + + // if (data_independent_addressing) { + // init_block_value(&input_block, 0); + + // input_block.v[0] = position.pass; + // input_block.v[1] = position.lane; + // input_block.v[2] = position.slice; + // input_block.v[3] = instance->memory_blocks; + // input_block.v[4] = instance->passes; + // input_block.v[5] = instance->type; + // } + + starting_index = 0; + + if ((0 == position.pass) && (0 == position.slice)) { + starting_index = 2; /* we have already generated the first two blocks */ + + /* Don't forget to generate the first block of addresses: */ +// if (data_independent_addressing) { +// next_addresses(&address_block, &input_block); +// } + } + + /* Offset of the current block */ + curr_offset = position.lane * instance->lane_length + + position.slice * instance->segment_length + starting_index; + + if (0 == curr_offset % instance->lane_length) { + /* Last block in this lane */ + prev_offset = curr_offset + instance->lane_length - 1; + } else { + /* Previous block */ + prev_offset = curr_offset - 1; + } + + memcpy(state, ((instance->memory + prev_offset)->v), ARGON2_BLOCK_SIZE); + + for (i = starting_index; i < instance->segment_length; + ++i, ++curr_offset, ++prev_offset) { + /*1.1 Rotating prev_offset if needed */ + if (curr_offset % instance->lane_length == 1) { + prev_offset = curr_offset - 1; + } + + /* 1.2 Computing the index of the reference block */ + /* 1.2.1 Taking pseudo-random value from the previous block */ +// if (data_independent_addressing) { +// if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) { +// next_addresses(&address_block, &input_block); +// } +// pseudo_rand = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK]; +// } else { + pseudo_rand = instance->memory[prev_offset].v[0]; +// } + + /* 1.2.2 Computing the lane of the reference block */ + ref_lane = ((pseudo_rand >> 32)) % instance->lanes; + + if ((position.pass == 0) && (position.slice == 0)) { + /* Can not reference other lanes yet */ + ref_lane = position.lane; + } + + /* 1.2.3 Computing the number of possible reference block within the + * lane. + */ + position.index = i; + ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF, + ref_lane == position.lane); + + /* 2 Creating a new block */ + ref_block = + instance->memory + instance->lane_length * ref_lane + ref_index; + curr_block = instance->memory + curr_offset; + if (ARGON2_VERSION_10 == instance->version) { + /* version 1.2.1 and earlier: overwrite, not XOR */ + fill_block(state, ref_block, curr_block, 0); + } else { + if(0 == position.pass) { + fill_block(state, ref_block, curr_block, 0); + } else { + fill_block(state, ref_block, curr_block, 1); + } + } + } +} diff --git a/stratum/algos/argon2d/thread.c b/stratum/algos/argon2d/thread.c new file mode 100644 index 000000000..e099a00d2 --- /dev/null +++ b/stratum/algos/argon2d/thread.c @@ -0,0 +1,57 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#if !defined(ARGON2_NO_THREADS) + +#include "thread.h" +#if defined(_WIN32) +#include +#endif + +int argon2_thread_create(argon2_thread_handle_t *handle, + argon2_thread_func_t func, void *args) { + if (NULL == handle || func == NULL) { + return -1; + } +#if defined(_WIN32) + *handle = _beginthreadex(NULL, 0, func, args, 0, NULL); + return *handle != 0 ? 0 : -1; +#else + return pthread_create(handle, NULL, func, args); +#endif +} + +int argon2_thread_join(argon2_thread_handle_t handle) { +#if defined(_WIN32) + if (WaitForSingleObject((HANDLE)handle, INFINITE) == WAIT_OBJECT_0) { + return CloseHandle((HANDLE)handle) != 0 ? 0 : -1; + } + return -1; +#else + return pthread_join(handle, NULL); +#endif +} + +void argon2_thread_exit(void) { +#if defined(_WIN32) + _endthreadex(0); +#else + pthread_exit(NULL); +#endif +} + +#endif /* ARGON2_NO_THREADS */ diff --git a/stratum/algos/argon2d/thread.h b/stratum/algos/argon2d/thread.h new file mode 100644 index 000000000..49d88367b --- /dev/null +++ b/stratum/algos/argon2d/thread.h @@ -0,0 +1,67 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#ifndef ARGON2_THREAD_H +#define ARGON2_THREAD_H + +#if !defined(ARGON2_NO_THREADS) + +/* + Here we implement an abstraction layer for the simpĺe requirements + of the Argon2 code. We only require 3 primitives---thread creation, + joining, and termination---so full emulation of the pthreads API + is unwarranted. Currently we wrap pthreads and Win32 threads. + + The API defines 2 types: the function pointer type, + argon2_thread_func_t, + and the type of the thread handle---argon2_thread_handle_t. +*/ +#if defined(_WIN32) +#include +typedef unsigned(__stdcall *argon2_thread_func_t)(void *); +typedef uintptr_t argon2_thread_handle_t; +#else +#include +typedef void *(*argon2_thread_func_t)(void *); +typedef pthread_t argon2_thread_handle_t; +#endif + +/* Creates a thread + * @param handle pointer to a thread handle, which is the output of this + * function. Must not be NULL. + * @param func A function pointer for the thread's entry point. Must not be + * NULL. + * @param args Pointer that is passed as an argument to @func. May be NULL. + * @return 0 if @handle and @func are valid pointers and a thread is successfully + * created. + */ +int argon2_thread_create(argon2_thread_handle_t *handle, + argon2_thread_func_t func, void *args); + +/* Waits for a thread to terminate + * @param handle Handle to a thread created with argon2_thread_create. + * @return 0 if @handle is a valid handle, and joining completed successfully. +*/ +int argon2_thread_join(argon2_thread_handle_t handle); + +/* Terminate the current thread. Must be run inside a thread created by + * argon2_thread_create. +*/ +void argon2_thread_exit(void); + +#endif /* ARGON2_NO_THREADS */ +#endif diff --git a/stratum/algos/argon2m.c b/stratum/algos/argon2m.c new file mode 100644 index 000000000..db72b66fd --- /dev/null +++ b/stratum/algos/argon2m.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include "sysendian.h" +#include "argon2d/argon2.h" +#include "argon2d/core.h" + +static const size_t INPUT_BYTES = 80; +static const size_t OUTPUT_BYTES = 32; +static const unsigned int DEFAULT_ARGON2_FLAG = 2; + +void argon2m_hash(const char* input, char* output, uint32_t len) +{ + argon2_context context; + context.out = (uint8_t *)output; + context.outlen = (uint32_t)OUTPUT_BYTES; + context.pwd = (uint8_t *)input; + context.pwdlen = (uint32_t)INPUT_BYTES; + context.salt = (uint8_t *)input; + context.saltlen = (uint32_t)INPUT_BYTES; + context.secret = NULL; + context.secretlen = 0; + context.ad = NULL; + context.adlen = 0; + context.allocate_cbk = NULL; + context.free_cbk = NULL; + context.flags = DEFAULT_ARGON2_FLAG; + context.m_cost = 2; + context.lanes = 1; + context.threads = 1; + context.t_cost = 1; + context.version = ARGON2_VERSION_13; + + argon2_ctx( &context, Argon2_id ); +} diff --git a/stratum/algos/argon2m.h b/stratum/algos/argon2m.h new file mode 100644 index 000000000..d34fea37f --- /dev/null +++ b/stratum/algos/argon2m.h @@ -0,0 +1,11 @@ +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void argon2m_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif diff --git a/stratum/algos/balloon.c b/stratum/algos/balloon.c new file mode 100644 index 000000000..913a9c2a1 --- /dev/null +++ b/stratum/algos/balloon.c @@ -0,0 +1,213 @@ +#include +#include +#include +#include +#include +#include +#include "sha256.h" +#include "balloon.h" + +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +#ifdef __cplusplus +extern "C"{ +#endif + +static void balloon_init (struct balloon_options *opts, int64_t s_cost, int32_t t_cost) { + opts->s_cost = s_cost; + opts->t_cost = t_cost; +} + +void balloon_hash (const char* input, char* output, uint32_t len) { + balloon ((unsigned char *)input, (unsigned char *)output, len, 128, 4); +} + +void balloon (unsigned char *input, unsigned char *output, int32_t len, int64_t s_cost, int32_t t_cost) { + struct balloon_options opts; + struct hash_state s; + balloon_init (&opts, s_cost, t_cost); + hash_state_init (&s, &opts, input); + hash_state_fill (&s, input, input, len); + hash_state_mix (&s, t_cost); + hash_state_extract (&s, output); + hash_state_free (&s); +} + +int bitstream_init (struct bitstream *b) { + SHA256_Init(&b->c); + b->initialized = false; +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + b->ctx = EVP_CIPHER_CTX_new(); + EVP_CIPHER_CTX_init(b->ctx); +#else + EVP_CIPHER_CTX_init (&b->ctx); +#endif + b->zeros = malloc (BITSTREAM_BUF_SIZE * sizeof (uint8_t)); + memset (b->zeros, 0, BITSTREAM_BUF_SIZE); +} + +int bitstream_free (struct bitstream *b) { + uint8_t out[AES_BLOCK_SIZE]; + int outl; +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + EVP_EncryptFinal (b->ctx, out, &outl); + EVP_CIPHER_CTX_cleanup (b->ctx); + EVP_CIPHER_CTX_free(b->ctx); +#else + EVP_EncryptFinal (&b->ctx, out, &outl); + EVP_CIPHER_CTX_cleanup (&b->ctx); +#endif + free (b->zeros); +} + +int bitstream_seed_add (struct bitstream *b, const void *seed, size_t seedlen) { + SHA256_Update(&b->c, seed, seedlen); +} + +int bitstream_seed_finalize (struct bitstream *b) { + uint8_t key_bytes[32]; + SHA256_Final (key_bytes, &b->c); + uint8_t iv[AES_BLOCK_SIZE]; + memset (iv, 0, AES_BLOCK_SIZE); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + EVP_CIPHER_CTX_set_padding (b->ctx, 1); + EVP_EncryptInit (b->ctx, EVP_aes_128_ctr (), key_bytes, iv); +#else + EVP_CIPHER_CTX_set_padding (&b->ctx, 1); + EVP_EncryptInit (&b->ctx, EVP_aes_128_ctr (), key_bytes, iv); +#endif + b->initialized = true; +} + +static int encrypt_partial (struct bitstream *b, void *outp, int to_encrypt) { + int encl; +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + EVP_EncryptUpdate (b->ctx, outp, &encl, b->zeros, to_encrypt); +#else + EVP_EncryptUpdate (&b->ctx, outp, &encl, b->zeros, to_encrypt); +#endif +} + +int bitstream_fill_buffer (struct bitstream *b, void *out, size_t outlen) { + size_t total = 0; + while (total < outlen) { + const int to_encrypt = MIN(outlen - total, BITSTREAM_BUF_SIZE); + encrypt_partial (b, out + total, to_encrypt); + total += to_encrypt; + } +} + +int compressb (uint64_t *counter, uint8_t *out, const uint8_t *blocks[], size_t blocks_to_comp) { + unsigned int i; + SHA256_CTX ctx; + SHA256_Init (&ctx); + SHA256_Update (&ctx, counter, 8); + for (i = 0; i < blocks_to_comp; i++) + SHA256_Update (&ctx, blocks[i], BLOCK_SIZE); + SHA256_Final (out, &ctx); + *counter += 1; +} + +int expand (uint64_t *counter, uint8_t *buf, size_t blocks_in_buf) { + size_t i; + const uint8_t *blocks[1] = { buf }; + uint8_t *cur = buf + BLOCK_SIZE; + for (i = 1; i < blocks_in_buf; i++) { + compressb (counter, cur, blocks, 1); + blocks[0] += BLOCK_SIZE; + cur += BLOCK_SIZE; + } +} + +uint64_t bytes_to_littleend_uint64 (const uint8_t *bytes, size_t n_bytes) { + int i; + if (n_bytes > 8) + n_bytes = 8; + uint64_t out = 0; + for (i = n_bytes-1; i >= 0; i--) { + out <<= 8; + out |= bytes[i]; + } + return out; +} + +void * block_index (const struct hash_state *s, size_t i) { + return s->buffer + (BLOCK_SIZE * i); +} + +static uint64_t options_n_blocks (const struct balloon_options *opts) { + const uint32_t bsize = BLOCK_SIZE; + uint64_t ret = (opts->s_cost * 1024) / bsize; + return (ret < BLOCKS_MIN) ? BLOCKS_MIN : ret; +} + +void * block_last (const struct hash_state *s) { + return block_index (s, s->n_blocks - 1); +} + +int hash_state_init (struct hash_state *s, const struct balloon_options *opts, const uint8_t salt[SALT_LEN]) { + s->counter = 0; + s->n_blocks = options_n_blocks (opts); + if (s->n_blocks % 2 != 0) s->n_blocks++; + s->has_mixed = false; + s->opts = opts; + s->buffer = malloc (s->n_blocks * BLOCK_SIZE); + int a = salt[0]; + a++; + bitstream_init (&s->bstream); + bitstream_seed_add (&s->bstream, salt, SALT_LEN); + bitstream_seed_add (&s->bstream, &opts->s_cost, 8); + bitstream_seed_add (&s->bstream, &opts->t_cost, 4); + bitstream_seed_finalize (&s->bstream); +} + +int hash_state_free (struct hash_state *s) { + bitstream_free (&s->bstream); + free (s->buffer); +} + +int hash_state_fill (struct hash_state *s, const uint8_t salt[SALT_LEN], const uint8_t *in, size_t inlen) { + SHA256_CTX c; + SHA256_Init (&c); + SHA256_Update (&c, &s->counter, 8); + SHA256_Update (&c, salt, SALT_LEN); + SHA256_Update (&c, in, inlen); + SHA256_Update (&c, &s->opts->s_cost, 8); + SHA256_Update (&c, &s->opts->t_cost, 4); + SHA256_Final (s->buffer, &c); + s->counter++; + expand (&s->counter, s->buffer, s->n_blocks); +} + +int hash_state_mix (struct hash_state *s, int32_t mixrounds) { + size_t i, n; + int32_t rounds; + uint8_t buf[8]; + uint64_t neighbor; + for (rounds=0; rounds < mixrounds; rounds++) { + for (i = 0; i < s->n_blocks; i++) { + uint8_t *cur_block = block_index (s, i); + const size_t n_blocks_to_hash = 3; + const uint8_t *blocks[2+n_blocks_to_hash]; + const uint8_t *prev_block = i ? cur_block - BLOCK_SIZE : block_last (s); + blocks[0] = prev_block; + blocks[1] = cur_block; + for (n = 2; n < 2+n_blocks_to_hash; n++) { + bitstream_fill_buffer (&s->bstream, buf, 8); + neighbor = bytes_to_littleend_uint64 (buf, 8); + blocks[n] = block_index (s, neighbor % s->n_blocks); + } + compressb (&s->counter, cur_block, blocks, 2+n_blocks_to_hash); + } + s->has_mixed = true; + } +} + +int hash_state_extract (const struct hash_state *s, uint8_t out[BLOCK_SIZE]) { + uint8_t *b = block_last (s); + memcpy ((char *)out, (const char *)b, BLOCK_SIZE); +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/stratum/algos/balloon.h b/stratum/algos/balloon.h new file mode 100644 index 000000000..6a2cf3d92 --- /dev/null +++ b/stratum/algos/balloon.h @@ -0,0 +1,72 @@ +#include +#include +#include +#include +#include "sha256.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define BITSTREAM_BUF_SIZE ((32) * (AES_BLOCK_SIZE)) +#define N_NEIGHBORS (3) +#define SALT_LEN (32) +#define INLEN_MAX (1ull<<20) +#define TCOST_MIN 1ull +#define SCOST_MIN (1) +#define SCOST_MAX (UINT32_MAX) +#define BLOCKS_MIN (1ull) +#define THREADS_MAX 4096 +#define BLOCK_SIZE (32) +#define UNUSED __attribute__ ((unused)) + +struct bitstream { + bool initialized; + uint8_t *zeros; + SHA256_CTX c; +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + EVP_CIPHER_CTX* ctx; +#else + EVP_CIPHER_CTX ctx; +#endif +}; + +struct hash_state; + +struct hash_state { + uint64_t counter; + uint64_t n_blocks; + bool has_mixed; + uint8_t *buffer; + struct bitstream bstream; + const struct balloon_options *opts; +}; + +struct balloon_options { + int64_t s_cost; + int32_t t_cost; +}; + +void balloon_hash (const char* input, char* output, uint32_t len); +void balloon (unsigned char *input, unsigned char *output, int32_t len, int64_t s_cost, int32_t t_cost); + +int bitstream_init (struct bitstream *b); +int bitstream_free (struct bitstream *b); +int bitstream_seed_add (struct bitstream *b, const void *seed, size_t seedlen); +int bitstream_seed_finalize (struct bitstream *b); +int bitstream_fill_buffer (struct bitstream *b, void *out, size_t outlen); +int bitstream_rand_byte (struct bitstream *b, uint8_t *out); +int compressb (uint64_t *counter, uint8_t *out, const uint8_t *blocks[], size_t blocks_to_comp); +int expand (uint64_t *counter, uint8_t *buf, size_t blocks_in_buf); +uint64_t bytes_to_littleend_uint64 (const uint8_t *bytes, size_t n_bytes); +int hash_state_init (struct hash_state *s, const struct balloon_options *opts, const uint8_t salt[SALT_LEN]); +int hash_state_free (struct hash_state *s); +int hash_state_fill (struct hash_state *s, const uint8_t salt[SALT_LEN], const uint8_t *in, size_t inlen); +int hash_state_mix (struct hash_state *s, int32_t mixrounds); +int hash_state_extract (const struct hash_state *s, uint8_t out[BLOCK_SIZE]); +void * block_index (const struct hash_state *s, size_t i); +void * block_last (const struct hash_state *s); + +#ifdef __cplusplus +} +#endif diff --git a/stratum/algos/bcd.c b/stratum/algos/bcd.c new file mode 100644 index 000000000..447ff1046 --- /dev/null +++ b/stratum/algos/bcd.c @@ -0,0 +1,99 @@ +#include "bcd.h" +#include +#include +#include +#include + +#include "../sha3/sph_blake.h" +#include "../sha3/sph_bmw.h" +#include "../sha3/sph_groestl.h" +#include "../sha3/sph_jh.h" +#include "../sha3/sph_keccak.h" +#include "../sha3/sph_skein.h" +#include "../sha3/sph_luffa.h" +#include "../sha3/sph_cubehash.h" +#include "../sha3/sph_shavite.h" +#include "../sha3/sph_simd.h" +#include "../sha3/sph_echo.h" +#include "../sha3/sph_hamsi.h" +#include "../sha3/sph_fugue.h" +#include "../sha3/sph_sm3.h" + +#include "common.h" + +void bcd_hash(const char* input, char* output, uint32_t len) +{ + sph_blake512_context ctx_blake; + sph_bmw512_context ctx_bmw; + sph_groestl512_context ctx_groestl; + sph_skein512_context ctx_skein; + sph_jh512_context ctx_jh; + sph_keccak512_context ctx_keccak; + sm3_ctx_t ctx_sm3; + sph_cubehash512_context ctx_cubehash1; + sph_shavite512_context ctx_shavite1; + sph_simd512_context ctx_simd1; + sph_echo512_context ctx_echo1; + sph_hamsi512_context ctx_hamsi1; + sph_fugue512_context ctx_fugue1; + + uint32_t hashA[16], hashB[16]; + + sph_blake512_init(&ctx_blake); + sph_blake512 (&ctx_blake, input, len); + sph_blake512_close (&ctx_blake, hashA); + + sph_bmw512_init(&ctx_bmw); + sph_bmw512 (&ctx_bmw, hashA, 64); + sph_bmw512_close(&ctx_bmw, hashB); + + sph_groestl512_init(&ctx_groestl); + sph_groestl512 (&ctx_groestl, hashB, 64); + sph_groestl512_close(&ctx_groestl, hashA); + + sph_skein512_init(&ctx_skein); + sph_skein512 (&ctx_skein, hashA, 64); + sph_skein512_close (&ctx_skein, hashB); + + sph_jh512_init(&ctx_jh); + sph_jh512 (&ctx_jh, hashB, 64); + sph_jh512_close(&ctx_jh, hashA); + + sph_keccak512_init(&ctx_keccak); + sph_keccak512 (&ctx_keccak, hashA, 64); + sph_keccak512_close(&ctx_keccak, hashB); + + memset(hashA, 0, sizeof(hashA)); + sm3_init(&ctx_sm3); + sph_sm3(&ctx_sm3, hashB, 64); + sph_sm3_close(&ctx_sm3, hashA); + + sph_cubehash512_init (&ctx_cubehash1); + sph_cubehash512 (&ctx_cubehash1, hashA, 64); + sph_cubehash512_close(&ctx_cubehash1, hashB); + + sph_shavite512_init (&ctx_shavite1); + sph_shavite512 (&ctx_shavite1, hashB, 64); + sph_shavite512_close(&ctx_shavite1, hashA); + + sph_simd512_init (&ctx_simd1); + sph_simd512 (&ctx_simd1, hashA, 64); + sph_simd512_close(&ctx_simd1, hashB); + + sph_echo512_init (&ctx_echo1); + sph_echo512 (&ctx_echo1, hashB, 64); + sph_echo512_close(&ctx_echo1, hashA); + + sph_hamsi512_init (&ctx_hamsi1); + sph_hamsi512 (&ctx_hamsi1, hashA, 64); + sph_hamsi512_close(&ctx_hamsi1, hashB); + + sph_fugue512_init (&ctx_fugue1); + sph_fugue512 (&ctx_fugue1, hashB, 64); + sph_fugue512_close(&ctx_fugue1, hashA); + + + + memcpy(output, hashA, 32); + +} diff --git a/stratum/algos/bcd.h b/stratum/algos/bcd.h new file mode 100644 index 000000000..30b2c028f --- /dev/null +++ b/stratum/algos/bcd.h @@ -0,0 +1,16 @@ +#ifndef BCD_H +#define BCD_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void bcd_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/stratum/algos/blake2-ref/blake2-impl.h b/stratum/algos/blake2-ref/blake2-impl.h new file mode 100644 index 000000000..ace753107 --- /dev/null +++ b/stratum/algos/blake2-ref/blake2-impl.h @@ -0,0 +1,187 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#ifndef PORTABLE_BLAKE2_IMPL_H +#define PORTABLE_BLAKE2_IMPL_H + +#include +#include + +#if defined(_MSC_VER) +#define BLAKE2_INLINE __inline +#elif defined(__GNUC__) || defined(__clang__) +#define BLAKE2_INLINE __inline__ +#else +#define BLAKE2_INLINE +#endif + +/* Argon2 Team - Begin Code */ +/* + Not an exhaustive list, but should cover the majority of modern platforms + Additionally, the code will always be correct---this is only a performance + tweak. +*/ +#if (defined(__BYTE_ORDER__) && \ + (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) || \ + defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || defined(__MIPSEL__) || \ + defined(__AARCH64EL__) || defined(__amd64__) || defined(__i386__) || \ + defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || \ + defined(_M_ARM) +#define NATIVE_LITTLE_ENDIAN +#endif +/* Argon2 Team - End Code */ + +static BLAKE2_INLINE uint32_t load32(const void *src) { +#if defined(NATIVE_LITTLE_ENDIAN) + uint32_t w; + memcpy(&w, src, sizeof w); + return w; +#else + const uint8_t *p = (const uint8_t *)src; + uint32_t w = *p++; + w |= (uint32_t)(*p++) << 8; + w |= (uint32_t)(*p++) << 16; + w |= (uint32_t)(*p++) << 24; + return w; +#endif +} + +static BLAKE2_INLINE uint64_t load64(const void *src) { +#if defined(NATIVE_LITTLE_ENDIAN) + uint64_t w; + memcpy(&w, src, sizeof w); + return w; +#else + const uint8_t *p = (const uint8_t *)src; + uint64_t w = *p++; + w |= (uint64_t)(*p++) << 8; + w |= (uint64_t)(*p++) << 16; + w |= (uint64_t)(*p++) << 24; + w |= (uint64_t)(*p++) << 32; + w |= (uint64_t)(*p++) << 40; + w |= (uint64_t)(*p++) << 48; + w |= (uint64_t)(*p++) << 56; + return w; +#endif +} + +static BLAKE2_INLINE uint16_t load16( const void *src ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + uint16_t w; + memcpy(&w, src, sizeof w); + return w; +#else + const uint8_t *p = ( const uint8_t * )src; + return (( uint16_t )( p[0] ) << 0) | + (( uint16_t )( p[1] ) << 8) ; +#endif +} + +static BLAKE2_INLINE void store16( void *dst, uint16_t w ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + memcpy(dst, &w, sizeof w); +#else + uint8_t *p = ( uint8_t * )dst; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; +#endif +} + +static BLAKE2_INLINE void store32(void *dst, uint32_t w) { +#if defined(NATIVE_LITTLE_ENDIAN) + memcpy(dst, &w, sizeof w); +#else + uint8_t *p = (uint8_t *)dst; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; +#endif +} + +static BLAKE2_INLINE void store64(void *dst, uint64_t w) { +#if defined(NATIVE_LITTLE_ENDIAN) + memcpy(dst, &w, sizeof w); +#else + uint8_t *p = (uint8_t *)dst; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; +#endif +} + +static BLAKE2_INLINE uint64_t load48(const void *src) { + const uint8_t *p = (const uint8_t *)src; + uint64_t w = *p++; + w |= (uint64_t)(*p++) << 8; + w |= (uint64_t)(*p++) << 16; + w |= (uint64_t)(*p++) << 24; + w |= (uint64_t)(*p++) << 32; + w |= (uint64_t)(*p++) << 40; + return w; +} + +static BLAKE2_INLINE void store48(void *dst, uint64_t w) { + uint8_t *p = (uint8_t *)dst; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; +} + +static BLAKE2_INLINE uint32_t rotr32(const uint32_t w, const unsigned c) { + return (w >> c) | (w << (32 - c)); +} + +static BLAKE2_INLINE uint64_t rotr64(const uint64_t w, const unsigned c) { + return (w >> c) | (w << (64 - c)); +} + +/* prevents compiler optimizing out memset() */ +static BLAKE2_INLINE void secure_zero_memory(void *v, size_t n) +{ + static void *(*const volatile memset_v)(void *, int, size_t) = &memset; + memset_v(v, 0, n); +} + +void clear_internal_memory(void *v, size_t n); + +#endif \ No newline at end of file diff --git a/stratum/algos/blake2-ref/blake2.h b/stratum/algos/blake2-ref/blake2.h new file mode 100644 index 000000000..685257af9 --- /dev/null +++ b/stratum/algos/blake2-ref/blake2.h @@ -0,0 +1,192 @@ +/* + BLAKE2 reference source code package - reference C implementations + Copyright 2012, Samuel Neves . You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ +#ifndef BLAKE2_H +#define BLAKE2_H + +#include +#include + +#if defined(_MSC_VER) +#define BLAKE2_PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop)) +#else +#define BLAKE2_PACKED(x) x __attribute__((packed)) +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + + enum blake2s_constant + { + BLAKE2S_BLOCKBYTES = 64, + BLAKE2S_OUTBYTES = 32, + BLAKE2S_KEYBYTES = 32, + BLAKE2S_SALTBYTES = 8, + BLAKE2S_PERSONALBYTES = 8 + }; + + enum blake2b_constant + { + BLAKE2B_BLOCKBYTES = 128, + BLAKE2B_OUTBYTES = 64, + BLAKE2B_KEYBYTES = 64, + BLAKE2B_SALTBYTES = 16, + BLAKE2B_PERSONALBYTES = 16 + }; + + typedef struct blake2s_state__ + { + uint32_t h[8]; + uint32_t t[2]; + uint32_t f[2]; + uint8_t buf[BLAKE2S_BLOCKBYTES]; + size_t buflen; + size_t outlen; + uint8_t last_node; + } blake2s_state; + + typedef struct blake2b_state__ + { + uint64_t h[8]; + uint64_t t[2]; + uint64_t f[2]; + uint8_t buf[BLAKE2B_BLOCKBYTES]; + size_t buflen; + size_t outlen; + uint8_t last_node; + } blake2b_state; + + typedef struct blake2sp_state__ + { + blake2s_state S[8][1]; + blake2s_state R[1]; + uint8_t buf[8 * BLAKE2S_BLOCKBYTES]; + size_t buflen; + size_t outlen; + } blake2sp_state; + + typedef struct blake2bp_state__ + { + blake2b_state S[4][1]; + blake2b_state R[1]; + uint8_t buf[4 * BLAKE2B_BLOCKBYTES]; + size_t buflen; + size_t outlen; + } blake2bp_state; + + + BLAKE2_PACKED(struct blake2s_param__ + { + uint8_t digest_length; /* 1 */ + uint8_t key_length; /* 2 */ + uint8_t fanout; /* 3 */ + uint8_t depth; /* 4 */ + uint32_t leaf_length; /* 8 */ + uint32_t node_offset; /* 12 */ + uint16_t xof_length; /* 14 */ + uint8_t node_depth; /* 15 */ + uint8_t inner_length; /* 16 */ + /* uint8_t reserved[0]; */ + uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */ + uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */ + }); + + typedef struct blake2s_param__ blake2s_param; + + BLAKE2_PACKED(struct blake2b_param__ + { + uint8_t digest_length; /* 1 */ + uint8_t key_length; /* 2 */ + uint8_t fanout; /* 3 */ + uint8_t depth; /* 4 */ + uint32_t leaf_length; /* 8 */ + uint32_t node_offset; /* 12 */ + uint32_t xof_length; /* 16 */ + uint8_t node_depth; /* 17 */ + uint8_t inner_length; /* 18 */ + uint8_t reserved[14]; /* 32 */ + uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ + uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ + }); + + typedef struct blake2b_param__ blake2b_param; + + typedef struct blake2xs_state__ + { + blake2s_state S[1]; + blake2s_param P[1]; + } blake2xs_state; + + typedef struct blake2xb_state__ + { + blake2b_state S[1]; + blake2b_param P[1]; + } blake2xb_state; + + /* Padded structs result in a compile-time error */ + enum { + BLAKE2_DUMMY_1 = 1/(sizeof(blake2s_param) == BLAKE2S_OUTBYTES), + BLAKE2_DUMMY_2 = 1/(sizeof(blake2b_param) == BLAKE2B_OUTBYTES) + }; + + /* Streaming API */ + int blake2s_init( blake2s_state *S, size_t outlen ); + int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2s_init_param( blake2s_state *S, const blake2s_param *P ); + int blake2s_update( blake2s_state *S, const void *in, size_t inlen ); + int blake2s_final( blake2s_state *S, void *out, size_t outlen ); + + int blake2b_init( blake2b_state *S, size_t outlen ); + int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2b_init_param( blake2b_state *S, const blake2b_param *P ); + int blake2b_update( blake2b_state *S, const void *in, size_t inlen ); + int blake2b_final( blake2b_state *S, void *out, size_t outlen ); + + int blake2sp_init( blake2sp_state *S, size_t outlen ); + int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2sp_update( blake2sp_state *S, const void *in, size_t inlen ); + int blake2sp_final( blake2sp_state *S, void *out, size_t outlen ); + + int blake2bp_init( blake2bp_state *S, size_t outlen ); + int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2bp_update( blake2bp_state *S, const void *in, size_t inlen ); + int blake2bp_final( blake2bp_state *S, void *out, size_t outlen ); + + /* Variable output length API */ + int blake2xs_init( blake2xs_state *S, const size_t outlen ); + int blake2xs_init_key( blake2xs_state *S, const size_t outlen, const void *key, size_t keylen ); + int blake2xs_update( blake2xs_state *S, const void *in, size_t inlen ); + int blake2xs_final(blake2xs_state *S, void *out, size_t outlen); + + int blake2xb_init( blake2xb_state *S, const size_t outlen ); + int blake2xb_init_key( blake2xb_state *S, const size_t outlen, const void *key, size_t keylen ); + int blake2xb_update( blake2xb_state *S, const void *in, size_t inlen ); + int blake2xb_final(blake2xb_state *S, void *out, size_t outlen); + + /* Simple API */ + int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); + int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); + + int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); + int blake2bp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); + + int blake2xs( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); + int blake2xb( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); + + /* This is simply an alias for blake2b */ + int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); + +#if defined(__cplusplus) +} +#endif + +#endif \ No newline at end of file diff --git a/stratum/algos/blake2-ref/blake2b.c b/stratum/algos/blake2-ref/blake2b.c new file mode 100644 index 000000000..ca05df598 --- /dev/null +++ b/stratum/algos/blake2-ref/blake2b.c @@ -0,0 +1,390 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#include +#include +#include + +#include "blake2.h" +#include "blake2-impl.h" + +static const uint64_t blake2b_IV[8] = { + UINT64_C(0x6a09e667f3bcc908), UINT64_C(0xbb67ae8584caa73b), + UINT64_C(0x3c6ef372fe94f82b), UINT64_C(0xa54ff53a5f1d36f1), + UINT64_C(0x510e527fade682d1), UINT64_C(0x9b05688c2b3e6c1f), + UINT64_C(0x1f83d9abfb41bd6b), UINT64_C(0x5be0cd19137e2179)}; + +static const unsigned int blake2b_sigma[12][16] = { + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}, + {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4}, + {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8}, + {9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13}, + {2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9}, + {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11}, + {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10}, + {6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5}, + {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}, +}; + +static BLAKE2_INLINE void blake2b_set_lastnode(blake2b_state *S) { + S->f[1] = (uint64_t)-1; +} + +static BLAKE2_INLINE void blake2b_set_lastblock(blake2b_state *S) { + if (S->last_node) { + blake2b_set_lastnode(S); + } + S->f[0] = (uint64_t)-1; +} + +static BLAKE2_INLINE void blake2b_increment_counter(blake2b_state *S, + uint64_t inc) { + S->t[0] += inc; + S->t[1] += (S->t[0] < inc); +} + +static BLAKE2_INLINE void blake2b_invalidate_state(blake2b_state *S) { + clear_internal_memory(S, sizeof(*S)); /* wipe */ + blake2b_set_lastblock(S); /* invalidate for further use */ +} + +static BLAKE2_INLINE void blake2b_init0(blake2b_state *S) { + memset(S, 0, sizeof(*S)); + memcpy(S->h, blake2b_IV, sizeof(S->h)); +} + +int blake2b_init_param(blake2b_state *S, const blake2b_param *P) { + const unsigned char *p = (const unsigned char *)P; + unsigned int i; + + if (NULL == P || NULL == S) { + return -1; + } + + blake2b_init0(S); + /* IV XOR Parameter Block */ + for (i = 0; i < 8; ++i) { + S->h[i] ^= load64(&p[i * sizeof(S->h[i])]); + } + S->outlen = P->digest_length; + return 0; +} + +/* Sequential blake2b initialization */ +int blake2b_init(blake2b_state *S, size_t outlen) { + blake2b_param P; + + if (S == NULL) { + return -1; + } + + if ((outlen == 0) || (outlen > BLAKE2B_OUTBYTES)) { + blake2b_invalidate_state(S); + return -1; + } + + /* Setup Parameter Block for unkeyed BLAKE2 */ + P.digest_length = (uint8_t)outlen; + P.key_length = 0; + P.fanout = 1; + P.depth = 1; + P.leaf_length = 0; + P.node_offset = 0; + P.node_depth = 0; + P.inner_length = 0; + memset(P.reserved, 0, sizeof(P.reserved)); + memset(P.salt, 0, sizeof(P.salt)); + memset(P.personal, 0, sizeof(P.personal)); + + return blake2b_init_param(S, &P); +} + +int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key, + size_t keylen) { + blake2b_param P; + + if (S == NULL) { + return -1; + } + + if ((outlen == 0) || (outlen > BLAKE2B_OUTBYTES)) { + blake2b_invalidate_state(S); + return -1; + } + + if ((key == 0) || (keylen == 0) || (keylen > BLAKE2B_KEYBYTES)) { + blake2b_invalidate_state(S); + return -1; + } + + /* Setup Parameter Block for keyed BLAKE2 */ + P.digest_length = (uint8_t)outlen; + P.key_length = (uint8_t)keylen; + P.fanout = 1; + P.depth = 1; + P.leaf_length = 0; + P.node_offset = 0; + P.node_depth = 0; + P.inner_length = 0; + memset(P.reserved, 0, sizeof(P.reserved)); + memset(P.salt, 0, sizeof(P.salt)); + memset(P.personal, 0, sizeof(P.personal)); + + if (blake2b_init_param(S, &P) < 0) { + blake2b_invalidate_state(S); + return -1; + } + + { + uint8_t block[BLAKE2B_BLOCKBYTES]; + memset(block, 0, BLAKE2B_BLOCKBYTES); + memcpy(block, key, keylen); + blake2b_update(S, block, BLAKE2B_BLOCKBYTES); + /* Burn the key from stack */ + clear_internal_memory(block, BLAKE2B_BLOCKBYTES); + } + return 0; +} + +static void blake2b_compress(blake2b_state *S, const uint8_t *block) { + uint64_t m[16]; + uint64_t v[16]; + unsigned int i, r; + + for (i = 0; i < 16; ++i) { + m[i] = load64(block + i * sizeof(m[i])); + } + + for (i = 0; i < 8; ++i) { + v[i] = S->h[i]; + } + + v[8] = blake2b_IV[0]; + v[9] = blake2b_IV[1]; + v[10] = blake2b_IV[2]; + v[11] = blake2b_IV[3]; + v[12] = blake2b_IV[4] ^ S->t[0]; + v[13] = blake2b_IV[5] ^ S->t[1]; + v[14] = blake2b_IV[6] ^ S->f[0]; + v[15] = blake2b_IV[7] ^ S->f[1]; + +#define G(r, i, a, b, c, d) \ + do { \ + a = a + b + m[blake2b_sigma[r][2 * i + 0]]; \ + d = rotr64(d ^ a, 32); \ + c = c + d; \ + b = rotr64(b ^ c, 24); \ + a = a + b + m[blake2b_sigma[r][2 * i + 1]]; \ + d = rotr64(d ^ a, 16); \ + c = c + d; \ + b = rotr64(b ^ c, 63); \ + } while ((void)0, 0) + +#define ROUND(r) \ + do { \ + G(r, 0, v[0], v[4], v[8], v[12]); \ + G(r, 1, v[1], v[5], v[9], v[13]); \ + G(r, 2, v[2], v[6], v[10], v[14]); \ + G(r, 3, v[3], v[7], v[11], v[15]); \ + G(r, 4, v[0], v[5], v[10], v[15]); \ + G(r, 5, v[1], v[6], v[11], v[12]); \ + G(r, 6, v[2], v[7], v[8], v[13]); \ + G(r, 7, v[3], v[4], v[9], v[14]); \ + } while ((void)0, 0) + + for (r = 0; r < 12; ++r) { + ROUND(r); + } + + for (i = 0; i < 8; ++i) { + S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; + } + +#undef G +#undef ROUND +} + +int blake2b_update(blake2b_state *S, const void *in, size_t inlen) { + const uint8_t *pin = (const uint8_t *)in; + + if (inlen == 0) { + return 0; + } + + /* Sanity check */ + if (S == NULL || in == NULL) { + return -1; + } + + /* Is this a reused state? */ + if (S->f[0] != 0) { + return -1; + } + + if (S->buflen + inlen > BLAKE2B_BLOCKBYTES) { + /* Complete current block */ + size_t left = S->buflen; + size_t fill = BLAKE2B_BLOCKBYTES - left; + memcpy(&S->buf[left], pin, fill); + blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); + blake2b_compress(S, S->buf); + S->buflen = 0; + inlen -= fill; + pin += fill; + /* Avoid buffer copies when possible */ + while (inlen > BLAKE2B_BLOCKBYTES) { + blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); + blake2b_compress(S, pin); + inlen -= BLAKE2B_BLOCKBYTES; + pin += BLAKE2B_BLOCKBYTES; + } + } + memcpy(&S->buf[S->buflen], pin, inlen); + S->buflen += (unsigned int)inlen; + return 0; +} + +int blake2b_final(blake2b_state *S, void *out, size_t outlen) { + uint8_t buffer[BLAKE2B_OUTBYTES] = {0}; + unsigned int i; + + /* Sanity checks */ + if (S == NULL || out == NULL || outlen < S->outlen) { + return -1; + } + + /* Is this a reused state? */ + if (S->f[0] != 0) { + return -1; + } + + blake2b_increment_counter(S, S->buflen); + blake2b_set_lastblock(S); + memset(&S->buf[S->buflen], 0, BLAKE2B_BLOCKBYTES - S->buflen); /* Padding */ + blake2b_compress(S, S->buf); + + for (i = 0; i < 8; ++i) { /* Output full hash to temp buffer */ + store64(buffer + sizeof(S->h[i]) * i, S->h[i]); + } + + memcpy(out, buffer, S->outlen); + clear_internal_memory(buffer, sizeof(buffer)); + clear_internal_memory(S->buf, sizeof(S->buf)); + clear_internal_memory(S->h, sizeof(S->h)); + return 0; +} + +int blake2b(void *out, size_t outlen, const void *in, size_t inlen, + const void *key, size_t keylen) { + blake2b_state S; + int ret = -1; + + /* Verify parameters */ + if (NULL == in && inlen > 0) { + goto fail; + } + + if (NULL == out || outlen == 0 || outlen > BLAKE2B_OUTBYTES) { + goto fail; + } + + if ((NULL == key && keylen > 0) || keylen > BLAKE2B_KEYBYTES) { + goto fail; + } + + if (keylen > 0) { + if (blake2b_init_key(&S, outlen, key, keylen) < 0) { + goto fail; + } + } else { + if (blake2b_init(&S, outlen) < 0) { + goto fail; + } + } + + if (blake2b_update(&S, in, inlen) < 0) { + goto fail; + } + ret = blake2b_final(&S, out, outlen); + +fail: + clear_internal_memory(&S, sizeof(S)); + return ret; +} + +/* Argon2 Team - Begin Code */ +int blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen) { + uint8_t *out = (uint8_t *)pout; + blake2b_state blake_state; + uint8_t outlen_bytes[sizeof(uint32_t)] = {0}; + int ret = -1; + + if (outlen > UINT32_MAX) { + goto fail; + } + + /* Ensure little-endian byte order! */ + store32(outlen_bytes, (uint32_t)outlen); + +#define TRY(statement) \ + do { \ + ret = statement; \ + if (ret < 0) { \ + goto fail; \ + } \ + } while ((void)0, 0) + + if (outlen <= BLAKE2B_OUTBYTES) { + TRY(blake2b_init(&blake_state, outlen)); + TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes))); + TRY(blake2b_update(&blake_state, in, inlen)); + TRY(blake2b_final(&blake_state, out, outlen)); + } else { + uint32_t toproduce; + uint8_t out_buffer[BLAKE2B_OUTBYTES]; + uint8_t in_buffer[BLAKE2B_OUTBYTES]; + TRY(blake2b_init(&blake_state, BLAKE2B_OUTBYTES)); + TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes))); + TRY(blake2b_update(&blake_state, in, inlen)); + TRY(blake2b_final(&blake_state, out_buffer, BLAKE2B_OUTBYTES)); + memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2); + out += BLAKE2B_OUTBYTES / 2; + toproduce = (uint32_t)outlen - BLAKE2B_OUTBYTES / 2; + + while (toproduce > BLAKE2B_OUTBYTES) { + memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES); + TRY(blake2b(out_buffer, BLAKE2B_OUTBYTES, in_buffer, + BLAKE2B_OUTBYTES, NULL, 0)); + memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2); + out += BLAKE2B_OUTBYTES / 2; + toproduce -= BLAKE2B_OUTBYTES / 2; + } + + memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES); + TRY(blake2b(out_buffer, toproduce, in_buffer, BLAKE2B_OUTBYTES, NULL, + 0)); + memcpy(out, out_buffer, toproduce); + } +fail: + clear_internal_memory(&blake_state, sizeof(blake_state)); + return ret; +#undef TRY +} +/* Argon2 Team - End Code */ diff --git a/stratum/algos/blake2-ref/blake2s.c b/stratum/algos/blake2-ref/blake2s.c new file mode 100644 index 000000000..482310881 --- /dev/null +++ b/stratum/algos/blake2-ref/blake2s.c @@ -0,0 +1,364 @@ +/* + BLAKE2 reference source code package - reference C implementations + Copyright 2012, Samuel Neves . You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ + +#include +#include +#include + +#include "blake2.h" +#include "blake2-impl.h" + +static const uint32_t blake2s_IV[8] = +{ + 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, + 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL +}; + +static const uint8_t blake2s_sigma[10][16] = +{ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , +}; + +static void blake2s_set_lastnode( blake2s_state *S ) +{ + S->f[1] = (uint32_t)-1; +} + +/* Some helper functions, not necessarily useful */ +static int blake2s_is_lastblock( const blake2s_state *S ) +{ + return S->f[0] != 0; +} + +static void blake2s_set_lastblock( blake2s_state *S ) +{ + if( S->last_node ) blake2s_set_lastnode( S ); + + S->f[0] = (uint32_t)-1; +} + +static void blake2s_increment_counter( blake2s_state *S, const uint32_t inc ) +{ + S->t[0] += inc; + S->t[1] += ( S->t[0] < inc ); +} + +static void blake2s_init0( blake2s_state *S ) +{ + size_t i; + memset( S, 0, sizeof( blake2s_state ) ); + + for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i]; +} + +/* init2 xors IV with input parameter block */ +int blake2s_init_param( blake2s_state *S, const blake2s_param *P ) +{ + const unsigned char *p = ( const unsigned char * )( P ); + size_t i; + + blake2s_init0( S ); + + /* IV XOR ParamBlock */ + for( i = 0; i < 8; ++i ) + S->h[i] ^= load32( &p[i * 4] ); + + S->outlen = P->digest_length; + return 0; +} + + +/* Sequential blake2s initialization */ +int blake2s_init( blake2s_state *S, size_t outlen ) +{ + blake2s_param P[1]; + + /* Move interval verification here? */ + if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; + + P->digest_length = (uint8_t)outlen; + P->key_length = 0; + P->fanout = 1; + P->depth = 1; + store32( &P->leaf_length, 0 ); + store32( &P->node_offset, 0 ); + store16( &P->xof_length, 0 ); + P->node_depth = 0; + P->inner_length = 0; + /* memset(P->reserved, 0, sizeof(P->reserved) ); */ + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + return blake2s_init_param( S, P ); +} + +int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ) +{ + blake2s_param P[1]; + + if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; + + if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1; + + P->digest_length = (uint8_t)outlen; + P->key_length = (uint8_t)keylen; + P->fanout = 1; + P->depth = 1; + store32( &P->leaf_length, 0 ); + store32( &P->node_offset, 0 ); + store16( &P->xof_length, 0 ); + P->node_depth = 0; + P->inner_length = 0; + /* memset(P->reserved, 0, sizeof(P->reserved) ); */ + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + + if( blake2s_init_param( S, P ) < 0 ) return -1; + + { + uint8_t block[BLAKE2S_BLOCKBYTES]; + memset( block, 0, BLAKE2S_BLOCKBYTES ); + memcpy( block, key, keylen ); + blake2s_update( S, block, BLAKE2S_BLOCKBYTES ); + secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ + } + return 0; +} + +#define G(r,i,a,b,c,d) \ + do { \ + a = a + b + m[blake2s_sigma[r][2*i+0]]; \ + d = rotr32(d ^ a, 16); \ + c = c + d; \ + b = rotr32(b ^ c, 12); \ + a = a + b + m[blake2s_sigma[r][2*i+1]]; \ + d = rotr32(d ^ a, 8); \ + c = c + d; \ + b = rotr32(b ^ c, 7); \ + } while(0) + +#define ROUND(r) \ + do { \ + G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ + G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ + G(r,2,v[ 2],v[ 6],v[10],v[14]); \ + G(r,3,v[ 3],v[ 7],v[11],v[15]); \ + G(r,4,v[ 0],v[ 5],v[10],v[15]); \ + G(r,5,v[ 1],v[ 6],v[11],v[12]); \ + G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ + G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ + } while(0) + +static void blake2s_compress( blake2s_state *S, const uint8_t in[BLAKE2S_BLOCKBYTES] ) +{ + uint32_t m[16]; + uint32_t v[16]; + size_t i; + + for( i = 0; i < 16; ++i ) { + m[i] = load32( in + i * sizeof( m[i] ) ); + } + + for( i = 0; i < 8; ++i ) { + v[i] = S->h[i]; + } + + v[ 8] = blake2s_IV[0]; + v[ 9] = blake2s_IV[1]; + v[10] = blake2s_IV[2]; + v[11] = blake2s_IV[3]; + v[12] = S->t[0] ^ blake2s_IV[4]; + v[13] = S->t[1] ^ blake2s_IV[5]; + v[14] = S->f[0] ^ blake2s_IV[6]; + v[15] = S->f[1] ^ blake2s_IV[7]; + + ROUND( 0 ); + ROUND( 1 ); + ROUND( 2 ); + ROUND( 3 ); + ROUND( 4 ); + ROUND( 5 ); + ROUND( 6 ); + ROUND( 7 ); + ROUND( 8 ); + ROUND( 9 ); + + for( i = 0; i < 8; ++i ) { + S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; + } +} + +#undef G +#undef ROUND + +int blake2s_update( blake2s_state *S, const void *pin, size_t inlen ) +{ + const unsigned char * in = (const unsigned char *)pin; + if( inlen > 0 ) + { + size_t left = S->buflen; + size_t fill = BLAKE2S_BLOCKBYTES - left; + if( inlen > fill ) + { + S->buflen = 0; + memcpy( S->buf + left, in, fill ); /* Fill buffer */ + blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); + blake2s_compress( S, S->buf ); /* Compress */ + in += fill; inlen -= fill; + while(inlen > BLAKE2S_BLOCKBYTES) { + blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES); + blake2s_compress( S, in ); + in += BLAKE2S_BLOCKBYTES; + inlen -= BLAKE2S_BLOCKBYTES; + } + } + memcpy( S->buf + S->buflen, in, inlen ); + S->buflen += inlen; + } + return 0; +} + +int blake2s_final( blake2s_state *S, void *out, size_t outlen ) +{ + uint8_t buffer[BLAKE2S_OUTBYTES] = {0}; + size_t i; + + if( out == NULL || outlen < S->outlen ) + return -1; + + if( blake2s_is_lastblock( S ) ) + return -1; + + blake2s_increment_counter( S, ( uint32_t )S->buflen ); + blake2s_set_lastblock( S ); + memset( S->buf + S->buflen, 0, BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */ + blake2s_compress( S, S->buf ); + + for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ + store32( buffer + sizeof( S->h[i] ) * i, S->h[i] ); + + memcpy( out, buffer, outlen ); + secure_zero_memory(buffer, sizeof(buffer)); + return 0; +} + +int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) +{ + blake2s_state S[1]; + + /* Verify parameters */ + if ( NULL == in && inlen > 0 ) return -1; + + if ( NULL == out ) return -1; + + if ( NULL == key && keylen > 0) return -1; + + if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; + + if( keylen > BLAKE2S_KEYBYTES ) return -1; + + if( keylen > 0 ) + { + if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1; + } + else + { + if( blake2s_init( S, outlen ) < 0 ) return -1; + } + + blake2s_update( S, ( const uint8_t * )in, inlen ); + blake2s_final( S, out, outlen ); + return 0; +} + +#if defined(SUPERCOP) +int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) +{ + return blake2s( out, BLAKE2S_OUTBYTES, in, inlen, NULL, 0 ); +} +#endif + +#if defined(BLAKE2S_SELFTEST) +#include +#include "blake2-kat.h" +int main( void ) +{ + uint8_t key[BLAKE2S_KEYBYTES]; + uint8_t buf[BLAKE2_KAT_LENGTH]; + size_t i, step; + + for( i = 0; i < BLAKE2S_KEYBYTES; ++i ) + key[i] = ( uint8_t )i; + + for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) + buf[i] = ( uint8_t )i; + + /* Test simple API */ + for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) + { + uint8_t hash[BLAKE2S_OUTBYTES]; + blake2s( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES ); + + if( 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) ) + { + goto fail; + } + } + + /* Test streaming API */ + for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) { + for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { + uint8_t hash[BLAKE2S_OUTBYTES]; + blake2s_state S; + uint8_t * p = buf; + size_t mlen = i; + int err = 0; + + if( (err = blake2s_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) { + goto fail; + } + + while (mlen >= step) { + if ( (err = blake2s_update(&S, p, step)) < 0 ) { + goto fail; + } + mlen -= step; + p += step; + } + if ( (err = blake2s_update(&S, p, mlen)) < 0) { + goto fail; + } + if ( (err = blake2s_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) { + goto fail; + } + + if (0 != memcmp(hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES)) { + goto fail; + } + } + } + + puts( "ok" ); + return 0; +fail: + puts("error"); + return -1; +} +#endif \ No newline at end of file diff --git a/stratum/algos/blake2-ref/blamka-round-opt.h b/stratum/algos/blake2-ref/blamka-round-opt.h new file mode 100644 index 000000000..faf96662e --- /dev/null +++ b/stratum/algos/blake2-ref/blamka-round-opt.h @@ -0,0 +1,476 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#ifndef BLAKE_ROUND_MKA_OPT_H +#define BLAKE_ROUND_MKA_OPT_H + +#if defined(HAVE_CONFIG_H) +#include "config/dynamic-config.h" +#endif + +#include "blake2-impl.h" + +#include +#if defined(__SSSE3__) +#include /* for _mm_shuffle_epi8 and _mm_alignr_epi8 */ +#endif + +#if defined(__XOP__) && (defined(__GNUC__) || defined(__clang__)) +#include +#endif + +#if !defined(__AVX512F__) +#if !defined(__AVX2__) +#if !defined(__XOP__) +#if defined(__SSSE3__) +#define r16 \ + (_mm_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9)) +#define r24 \ + (_mm_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10)) +#define _mm_roti_epi64(x, c) \ + (-(c) == 32) \ + ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \ + : (-(c) == 24) \ + ? _mm_shuffle_epi8((x), r24) \ + : (-(c) == 16) \ + ? _mm_shuffle_epi8((x), r16) \ + : (-(c) == 63) \ + ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), \ + _mm_add_epi64((x), (x))) \ + : _mm_xor_si128(_mm_srli_epi64((x), -(c)), \ + _mm_slli_epi64((x), 64 - (-(c)))) +#else /* defined(__SSE2__) */ +#define _mm_roti_epi64(r, c) \ + _mm_xor_si128(_mm_srli_epi64((r), -(c)), _mm_slli_epi64((r), 64 - (-(c)))) +#endif +#else +#endif + +static BLAKE2_INLINE __m128i fBlaMka(__m128i x, __m128i y) { + const __m128i z = _mm_mul_epu32(x, y); + return _mm_add_epi64(_mm_add_epi64(x, y), _mm_add_epi64(z, z)); +} + +#define G1(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + A0 = fBlaMka(A0, B0); \ + A1 = fBlaMka(A1, B1); \ + \ + D0 = _mm_xor_si128(D0, A0); \ + D1 = _mm_xor_si128(D1, A1); \ + \ + D0 = _mm_roti_epi64(D0, -32); \ + D1 = _mm_roti_epi64(D1, -32); \ + \ + C0 = fBlaMka(C0, D0); \ + C1 = fBlaMka(C1, D1); \ + \ + B0 = _mm_xor_si128(B0, C0); \ + B1 = _mm_xor_si128(B1, C1); \ + \ + B0 = _mm_roti_epi64(B0, -24); \ + B1 = _mm_roti_epi64(B1, -24); \ + } while ((void)0, 0) + +#define G2(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + A0 = fBlaMka(A0, B0); \ + A1 = fBlaMka(A1, B1); \ + \ + D0 = _mm_xor_si128(D0, A0); \ + D1 = _mm_xor_si128(D1, A1); \ + \ + D0 = _mm_roti_epi64(D0, -16); \ + D1 = _mm_roti_epi64(D1, -16); \ + \ + C0 = fBlaMka(C0, D0); \ + C1 = fBlaMka(C1, D1); \ + \ + B0 = _mm_xor_si128(B0, C0); \ + B1 = _mm_xor_si128(B1, C1); \ + \ + B0 = _mm_roti_epi64(B0, -63); \ + B1 = _mm_roti_epi64(B1, -63); \ + } while ((void)0, 0) + +#if defined(__SSSE3__) +#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + __m128i t0 = _mm_alignr_epi8(B1, B0, 8); \ + __m128i t1 = _mm_alignr_epi8(B0, B1, 8); \ + B0 = t0; \ + B1 = t1; \ + \ + t0 = C0; \ + C0 = C1; \ + C1 = t0; \ + \ + t0 = _mm_alignr_epi8(D1, D0, 8); \ + t1 = _mm_alignr_epi8(D0, D1, 8); \ + D0 = t1; \ + D1 = t0; \ + } while ((void)0, 0) + +#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + __m128i t0 = _mm_alignr_epi8(B0, B1, 8); \ + __m128i t1 = _mm_alignr_epi8(B1, B0, 8); \ + B0 = t0; \ + B1 = t1; \ + \ + t0 = C0; \ + C0 = C1; \ + C1 = t0; \ + \ + t0 = _mm_alignr_epi8(D0, D1, 8); \ + t1 = _mm_alignr_epi8(D1, D0, 8); \ + D0 = t1; \ + D1 = t0; \ + } while ((void)0, 0) +#else /* SSE2 */ +#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + __m128i t0 = D0; \ + __m128i t1 = B0; \ + D0 = C0; \ + C0 = C1; \ + C1 = D0; \ + D0 = _mm_unpackhi_epi64(D1, _mm_unpacklo_epi64(t0, t0)); \ + D1 = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(D1, D1)); \ + B0 = _mm_unpackhi_epi64(B0, _mm_unpacklo_epi64(B1, B1)); \ + B1 = _mm_unpackhi_epi64(B1, _mm_unpacklo_epi64(t1, t1)); \ + } while ((void)0, 0) + +#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + __m128i t0, t1; \ + t0 = C0; \ + C0 = C1; \ + C1 = t0; \ + t0 = B0; \ + t1 = D0; \ + B0 = _mm_unpackhi_epi64(B1, _mm_unpacklo_epi64(B0, B0)); \ + B1 = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(B1, B1)); \ + D0 = _mm_unpackhi_epi64(D0, _mm_unpacklo_epi64(D1, D1)); \ + D1 = _mm_unpackhi_epi64(D1, _mm_unpacklo_epi64(t1, t1)); \ + } while ((void)0, 0) +#endif + +#define BLAKE2_ROUND(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + G1(A0, B0, C0, D0, A1, B1, C1, D1); \ + G2(A0, B0, C0, D0, A1, B1, C1, D1); \ + \ + DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ + \ + G1(A0, B0, C0, D0, A1, B1, C1, D1); \ + G2(A0, B0, C0, D0, A1, B1, C1, D1); \ + \ + UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ + } while ((void)0, 0) + +#else /* __AVX2__ */ + +#include + +#define rotr32(x) _mm256_shuffle_epi32(x, _MM_SHUFFLE(2, 3, 0, 1)) +#define rotr24(x) _mm256_shuffle_epi8(x, _mm256_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10, 3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10)) +#define rotr16(x) _mm256_shuffle_epi8(x, _mm256_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9, 2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9)) +#define rotr63(x) _mm256_xor_si256(_mm256_srli_epi64((x), 63), _mm256_add_epi64((x), (x))) + +#define G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + __m256i ml = _mm256_mul_epu32(A0, B0); \ + ml = _mm256_add_epi64(ml, ml); \ + A0 = _mm256_add_epi64(A0, _mm256_add_epi64(B0, ml)); \ + D0 = _mm256_xor_si256(D0, A0); \ + D0 = rotr32(D0); \ + \ + ml = _mm256_mul_epu32(C0, D0); \ + ml = _mm256_add_epi64(ml, ml); \ + C0 = _mm256_add_epi64(C0, _mm256_add_epi64(D0, ml)); \ + \ + B0 = _mm256_xor_si256(B0, C0); \ + B0 = rotr24(B0); \ + \ + ml = _mm256_mul_epu32(A1, B1); \ + ml = _mm256_add_epi64(ml, ml); \ + A1 = _mm256_add_epi64(A1, _mm256_add_epi64(B1, ml)); \ + D1 = _mm256_xor_si256(D1, A1); \ + D1 = rotr32(D1); \ + \ + ml = _mm256_mul_epu32(C1, D1); \ + ml = _mm256_add_epi64(ml, ml); \ + C1 = _mm256_add_epi64(C1, _mm256_add_epi64(D1, ml)); \ + \ + B1 = _mm256_xor_si256(B1, C1); \ + B1 = rotr24(B1); \ + } while((void)0, 0); + +#define G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + __m256i ml = _mm256_mul_epu32(A0, B0); \ + ml = _mm256_add_epi64(ml, ml); \ + A0 = _mm256_add_epi64(A0, _mm256_add_epi64(B0, ml)); \ + D0 = _mm256_xor_si256(D0, A0); \ + D0 = rotr16(D0); \ + \ + ml = _mm256_mul_epu32(C0, D0); \ + ml = _mm256_add_epi64(ml, ml); \ + C0 = _mm256_add_epi64(C0, _mm256_add_epi64(D0, ml)); \ + B0 = _mm256_xor_si256(B0, C0); \ + B0 = rotr63(B0); \ + \ + ml = _mm256_mul_epu32(A1, B1); \ + ml = _mm256_add_epi64(ml, ml); \ + A1 = _mm256_add_epi64(A1, _mm256_add_epi64(B1, ml)); \ + D1 = _mm256_xor_si256(D1, A1); \ + D1 = rotr16(D1); \ + \ + ml = _mm256_mul_epu32(C1, D1); \ + ml = _mm256_add_epi64(ml, ml); \ + C1 = _mm256_add_epi64(C1, _mm256_add_epi64(D1, ml)); \ + B1 = _mm256_xor_si256(B1, C1); \ + B1 = rotr63(B1); \ + } while((void)0, 0); + +#define DIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + B0 = _mm256_permute4x64_epi64(B0, _MM_SHUFFLE(0, 3, 2, 1)); \ + C0 = _mm256_permute4x64_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \ + D0 = _mm256_permute4x64_epi64(D0, _MM_SHUFFLE(2, 1, 0, 3)); \ + \ + B1 = _mm256_permute4x64_epi64(B1, _MM_SHUFFLE(0, 3, 2, 1)); \ + C1 = _mm256_permute4x64_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \ + D1 = _mm256_permute4x64_epi64(D1, _MM_SHUFFLE(2, 1, 0, 3)); \ + } while((void)0, 0); + +#define DIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + __m256i tmp1 = _mm256_blend_epi32(B0, B1, 0xCC); \ + __m256i tmp2 = _mm256_blend_epi32(B0, B1, 0x33); \ + B1 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \ + B0 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \ + \ + tmp1 = C0; \ + C0 = C1; \ + C1 = tmp1; \ + \ + tmp1 = _mm256_blend_epi32(D0, D1, 0xCC); \ + tmp2 = _mm256_blend_epi32(D0, D1, 0x33); \ + D0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \ + D1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \ + } while(0); + +#define UNDIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + B0 = _mm256_permute4x64_epi64(B0, _MM_SHUFFLE(2, 1, 0, 3)); \ + C0 = _mm256_permute4x64_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \ + D0 = _mm256_permute4x64_epi64(D0, _MM_SHUFFLE(0, 3, 2, 1)); \ + \ + B1 = _mm256_permute4x64_epi64(B1, _MM_SHUFFLE(2, 1, 0, 3)); \ + C1 = _mm256_permute4x64_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \ + D1 = _mm256_permute4x64_epi64(D1, _MM_SHUFFLE(0, 3, 2, 1)); \ + } while((void)0, 0); + +#define UNDIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + __m256i tmp1 = _mm256_blend_epi32(B0, B1, 0xCC); \ + __m256i tmp2 = _mm256_blend_epi32(B0, B1, 0x33); \ + B0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \ + B1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \ + \ + tmp1 = C0; \ + C0 = C1; \ + C1 = tmp1; \ + \ + tmp1 = _mm256_blend_epi32(D0, D1, 0x33); \ + tmp2 = _mm256_blend_epi32(D0, D1, 0xCC); \ + D0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \ + D1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \ + } while((void)0, 0); + +#define BLAKE2_ROUND_1(A0, A1, B0, B1, C0, C1, D0, D1) \ + do{ \ + G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + \ + DIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \ + \ + G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + \ + UNDIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \ + } while((void)0, 0); + +#define BLAKE2_ROUND_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do{ \ + G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + \ + DIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + \ + G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + \ + UNDIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + } while((void)0, 0); + +#endif /* __AVX2__ */ + +#else /* __AVX512F__ */ + +#include + +#define ror64(x, n) _mm512_ror_epi64((x), (n)) + +static __m512i muladd(__m512i x, __m512i y) +{ + __m512i z = _mm512_mul_epu32(x, y); + return _mm512_add_epi64(_mm512_add_epi64(x, y), _mm512_add_epi64(z, z)); +} + +#define G1(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + A0 = muladd(A0, B0); \ + A1 = muladd(A1, B1); \ +\ + D0 = _mm512_xor_si512(D0, A0); \ + D1 = _mm512_xor_si512(D1, A1); \ +\ + D0 = ror64(D0, 32); \ + D1 = ror64(D1, 32); \ +\ + C0 = muladd(C0, D0); \ + C1 = muladd(C1, D1); \ +\ + B0 = _mm512_xor_si512(B0, C0); \ + B1 = _mm512_xor_si512(B1, C1); \ +\ + B0 = ror64(B0, 24); \ + B1 = ror64(B1, 24); \ + } while ((void)0, 0) + +#define G2(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + A0 = muladd(A0, B0); \ + A1 = muladd(A1, B1); \ +\ + D0 = _mm512_xor_si512(D0, A0); \ + D1 = _mm512_xor_si512(D1, A1); \ +\ + D0 = ror64(D0, 16); \ + D1 = ror64(D1, 16); \ +\ + C0 = muladd(C0, D0); \ + C1 = muladd(C1, D1); \ +\ + B0 = _mm512_xor_si512(B0, C0); \ + B1 = _mm512_xor_si512(B1, C1); \ +\ + B0 = ror64(B0, 63); \ + B1 = ror64(B1, 63); \ + } while ((void)0, 0) + +#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + B0 = _mm512_permutex_epi64(B0, _MM_SHUFFLE(0, 3, 2, 1)); \ + B1 = _mm512_permutex_epi64(B1, _MM_SHUFFLE(0, 3, 2, 1)); \ +\ + C0 = _mm512_permutex_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \ + C1 = _mm512_permutex_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \ +\ + D0 = _mm512_permutex_epi64(D0, _MM_SHUFFLE(2, 1, 0, 3)); \ + D1 = _mm512_permutex_epi64(D1, _MM_SHUFFLE(2, 1, 0, 3)); \ + } while ((void)0, 0) + +#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + B0 = _mm512_permutex_epi64(B0, _MM_SHUFFLE(2, 1, 0, 3)); \ + B1 = _mm512_permutex_epi64(B1, _MM_SHUFFLE(2, 1, 0, 3)); \ +\ + C0 = _mm512_permutex_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \ + C1 = _mm512_permutex_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \ +\ + D0 = _mm512_permutex_epi64(D0, _MM_SHUFFLE(0, 3, 2, 1)); \ + D1 = _mm512_permutex_epi64(D1, _MM_SHUFFLE(0, 3, 2, 1)); \ + } while ((void)0, 0) + +#define BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + G1(A0, B0, C0, D0, A1, B1, C1, D1); \ + G2(A0, B0, C0, D0, A1, B1, C1, D1); \ +\ + DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ +\ + G1(A0, B0, C0, D0, A1, B1, C1, D1); \ + G2(A0, B0, C0, D0, A1, B1, C1, D1); \ +\ + UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ + } while ((void)0, 0) + +#define SWAP_HALVES(A0, A1) \ + do { \ + __m512i t0, t1; \ + t0 = _mm512_shuffle_i64x2(A0, A1, _MM_SHUFFLE(1, 0, 1, 0)); \ + t1 = _mm512_shuffle_i64x2(A0, A1, _MM_SHUFFLE(3, 2, 3, 2)); \ + A0 = t0; \ + A1 = t1; \ + } while((void)0, 0) + +#define SWAP_QUARTERS(A0, A1) \ + do { \ + SWAP_HALVES(A0, A1); \ + A0 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A0); \ + A1 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A1); \ + } while((void)0, 0) + +#define UNSWAP_QUARTERS(A0, A1) \ + do { \ + A0 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A0); \ + A1 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A1); \ + SWAP_HALVES(A0, A1); \ + } while((void)0, 0) + +#define BLAKE2_ROUND_1(A0, C0, B0, D0, A1, C1, B1, D1) \ + do { \ + SWAP_HALVES(A0, B0); \ + SWAP_HALVES(C0, D0); \ + SWAP_HALVES(A1, B1); \ + SWAP_HALVES(C1, D1); \ + BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1); \ + SWAP_HALVES(A0, B0); \ + SWAP_HALVES(C0, D0); \ + SWAP_HALVES(A1, B1); \ + SWAP_HALVES(C1, D1); \ + } while ((void)0, 0) + +#define BLAKE2_ROUND_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + SWAP_QUARTERS(A0, A1); \ + SWAP_QUARTERS(B0, B1); \ + SWAP_QUARTERS(C0, C1); \ + SWAP_QUARTERS(D0, D1); \ + BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1); \ + UNSWAP_QUARTERS(A0, A1); \ + UNSWAP_QUARTERS(B0, B1); \ + UNSWAP_QUARTERS(C0, C1); \ + UNSWAP_QUARTERS(D0, D1); \ + } while ((void)0, 0) + +#endif /* __AVX512F__ */ +#endif /* BLAKE_ROUND_MKA_OPT_H */ \ No newline at end of file diff --git a/stratum/algos/blake2-ref/blamka-round-ref.h b/stratum/algos/blake2-ref/blamka-round-ref.h new file mode 100644 index 000000000..2238959e1 --- /dev/null +++ b/stratum/algos/blake2-ref/blamka-round-ref.h @@ -0,0 +1,56 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#ifndef BLAKE_ROUND_MKA_H +#define BLAKE_ROUND_MKA_H + +#include "blake2.h" +#include "blake2-impl.h" + +/*designed by the Lyra PHC team */ +static BLAKE2_INLINE uint64_t fBlaMka(uint64_t x, uint64_t y) { + const uint64_t m = UINT64_C(0xFFFFFFFF); + const uint64_t xy = (x & m) * (y & m); + return x + y + 2 * xy; +} + +#define G(a, b, c, d) \ + do { \ + a = fBlaMka(a, b); \ + d = rotr64(d ^ a, 32); \ + c = fBlaMka(c, d); \ + b = rotr64(b ^ c, 24); \ + a = fBlaMka(a, b); \ + d = rotr64(d ^ a, 16); \ + c = fBlaMka(c, d); \ + b = rotr64(b ^ c, 63); \ + } while ((void)0, 0) + +#define BLAKE2_ROUND_NOMSG(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, \ + v12, v13, v14, v15) \ + do { \ + G(v0, v4, v8, v12); \ + G(v1, v5, v9, v13); \ + G(v2, v6, v10, v14); \ + G(v3, v7, v11, v15); \ + G(v0, v5, v10, v15); \ + G(v1, v6, v11, v12); \ + G(v2, v7, v8, v13); \ + G(v3, v4, v9, v14); \ + } while ((void)0, 0) + +#endif \ No newline at end of file diff --git a/stratum/algos/blake2/blake2s.c b/stratum/algos/blake2/blake2s.c new file mode 100644 index 000000000..21f860026 --- /dev/null +++ b/stratum/algos/blake2/blake2s.c @@ -0,0 +1,364 @@ +/* + BLAKE2 reference source code package - reference C implementations + Copyright 2012, Samuel Neves . You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ + +#include +#include +#include + +#include "blake2.h" +#include "blake2-impl.h" + +static const uint32_t blake2s_IV[8] = +{ + 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, + 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL +}; + +static const uint8_t blake2s_sigma[10][16] = +{ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , +}; + +static void blake2s_set_lastnode( blake2s_state *S ) +{ + S->f[1] = (uint32_t)-1; +} + +/* Some helper functions, not necessarily useful */ +static int blake2s_is_lastblock( const blake2s_state *S ) +{ + return S->f[0] != 0; +} + +static void blake2s_set_lastblock( blake2s_state *S ) +{ + if( S->last_node ) blake2s_set_lastnode( S ); + + S->f[0] = (uint32_t)-1; +} + +static void blake2s_increment_counter( blake2s_state *S, const uint32_t inc ) +{ + S->t[0] += inc; + S->t[1] += ( S->t[0] < inc ); +} + +static void blake2s_init0( blake2s_state *S ) +{ + size_t i; + memset( S, 0, sizeof( blake2s_state ) ); + + for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i]; +} + +/* init2 xors IV with input parameter block */ +int blake2s_init_param( blake2s_state *S, const blake2s_param *P ) +{ + const unsigned char *p = ( const unsigned char * )( P ); + size_t i; + + blake2s_init0( S ); + + /* IV XOR ParamBlock */ + for( i = 0; i < 8; ++i ) + S->h[i] ^= load32( &p[i * 4] ); + + S->outlen = P->digest_length; + return 0; +} + + +/* Sequential blake2s initialization */ +int blake2s_init( blake2s_state *S, size_t outlen ) +{ + blake2s_param P[1]; + + /* Move interval verification here? */ + if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; + + P->digest_length = (uint8_t)outlen; + P->key_length = 0; + P->fanout = 1; + P->depth = 1; + store32( &P->leaf_length, 0 ); + store32( &P->node_offset, 0 ); + store16( &P->xof_length, 0 ); + P->node_depth = 0; + P->inner_length = 0; + /* memset(P->reserved, 0, sizeof(P->reserved) ); */ + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + return blake2s_init_param( S, P ); +} + +int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ) +{ + blake2s_param P[1]; + + if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; + + if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1; + + P->digest_length = (uint8_t)outlen; + P->key_length = (uint8_t)keylen; + P->fanout = 1; + P->depth = 1; + store32( &P->leaf_length, 0 ); + store32( &P->node_offset, 0 ); + store16( &P->xof_length, 0 ); + P->node_depth = 0; + P->inner_length = 0; + /* memset(P->reserved, 0, sizeof(P->reserved) ); */ + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + + if( blake2s_init_param( S, P ) < 0 ) return -1; + + { + uint8_t block[BLAKE2S_BLOCKBYTES]; + memset( block, 0, BLAKE2S_BLOCKBYTES ); + memcpy( block, key, keylen ); + blake2s_update( S, block, BLAKE2S_BLOCKBYTES ); + secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ + } + return 0; +} + +#define G(r,i,a,b,c,d) \ + do { \ + a = a + b + m[blake2s_sigma[r][2*i+0]]; \ + d = rotr32(d ^ a, 16); \ + c = c + d; \ + b = rotr32(b ^ c, 12); \ + a = a + b + m[blake2s_sigma[r][2*i+1]]; \ + d = rotr32(d ^ a, 8); \ + c = c + d; \ + b = rotr32(b ^ c, 7); \ + } while(0) + +#define ROUND(r) \ + do { \ + G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ + G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ + G(r,2,v[ 2],v[ 6],v[10],v[14]); \ + G(r,3,v[ 3],v[ 7],v[11],v[15]); \ + G(r,4,v[ 0],v[ 5],v[10],v[15]); \ + G(r,5,v[ 1],v[ 6],v[11],v[12]); \ + G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ + G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ + } while(0) + +static void blake2s_compress( blake2s_state *S, const uint8_t in[BLAKE2S_BLOCKBYTES] ) +{ + uint32_t m[16]; + uint32_t v[16]; + size_t i; + + for( i = 0; i < 16; ++i ) { + m[i] = load32( in + i * sizeof( m[i] ) ); + } + + for( i = 0; i < 8; ++i ) { + v[i] = S->h[i]; + } + + v[ 8] = blake2s_IV[0]; + v[ 9] = blake2s_IV[1]; + v[10] = blake2s_IV[2]; + v[11] = blake2s_IV[3]; + v[12] = S->t[0] ^ blake2s_IV[4]; + v[13] = S->t[1] ^ blake2s_IV[5]; + v[14] = S->f[0] ^ blake2s_IV[6]; + v[15] = S->f[1] ^ blake2s_IV[7]; + + ROUND( 0 ); + ROUND( 1 ); + ROUND( 2 ); + ROUND( 3 ); + ROUND( 4 ); + ROUND( 5 ); + ROUND( 6 ); + ROUND( 7 ); + ROUND( 8 ); + ROUND( 9 ); + + for( i = 0; i < 8; ++i ) { + S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; + } +} + +#undef G +#undef ROUND + +int blake2s_update( blake2s_state *S, const void *pin, size_t inlen ) +{ + const unsigned char * in = (const unsigned char *)pin; + if( inlen > 0 ) + { + size_t left = S->buflen; + size_t fill = BLAKE2S_BLOCKBYTES - left; + if( inlen > fill ) + { + S->buflen = 0; + memcpy( S->buf + left, in, fill ); /* Fill buffer */ + blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); + blake2s_compress( S, S->buf ); /* Compress */ + in += fill; inlen -= fill; + while(inlen > BLAKE2S_BLOCKBYTES) { + blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES); + blake2s_compress( S, in ); + in += BLAKE2S_BLOCKBYTES; + inlen -= BLAKE2S_BLOCKBYTES; + } + } + memcpy( S->buf + S->buflen, in, inlen ); + S->buflen += inlen; + } + return 0; +} + +int blake2s_final( blake2s_state *S, void *out, size_t outlen ) +{ + uint8_t buffer[BLAKE2S_OUTBYTES] = {0}; + size_t i; + + if( out == NULL || outlen < S->outlen ) + return -1; + + if( blake2s_is_lastblock( S ) ) + return -1; + + blake2s_increment_counter( S, ( uint32_t )S->buflen ); + blake2s_set_lastblock( S ); + memset( S->buf + S->buflen, 0, BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */ + blake2s_compress( S, S->buf ); + + for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ + store32( buffer + sizeof( S->h[i] ) * i, S->h[i] ); + + memcpy( out, buffer, outlen ); + secure_zero_memory(buffer, sizeof(buffer)); + return 0; +} + +int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) +{ + blake2s_state S[1]; + + /* Verify parameters */ + if ( NULL == in && inlen > 0 ) return -1; + + if ( NULL == out ) return -1; + + if ( NULL == key && keylen > 0) return -1; + + if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; + + if( keylen > BLAKE2S_KEYBYTES ) return -1; + + if( keylen > 0 ) + { + if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1; + } + else + { + if( blake2s_init( S, outlen ) < 0 ) return -1; + } + + blake2s_update( S, ( const uint8_t * )in, inlen ); + blake2s_final( S, out, outlen ); + return 0; +} + +#if defined(SUPERCOP) +int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) +{ + return blake2s( out, BLAKE2S_OUTBYTES, in, inlen, NULL, 0 ); +} +#endif + +#if defined(BLAKE2S_SELFTEST) +#include +#include "blake2-kat.h" +int main( void ) +{ + uint8_t key[BLAKE2S_KEYBYTES]; + uint8_t buf[BLAKE2_KAT_LENGTH]; + size_t i, step; + + for( i = 0; i < BLAKE2S_KEYBYTES; ++i ) + key[i] = ( uint8_t )i; + + for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) + buf[i] = ( uint8_t )i; + + /* Test simple API */ + for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) + { + uint8_t hash[BLAKE2S_OUTBYTES]; + blake2s( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES ); + + if( 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) ) + { + goto fail; + } + } + + /* Test streaming API */ + for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) { + for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { + uint8_t hash[BLAKE2S_OUTBYTES]; + blake2s_state S; + uint8_t * p = buf; + size_t mlen = i; + int err = 0; + + if( (err = blake2s_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) { + goto fail; + } + + while (mlen >= step) { + if ( (err = blake2s_update(&S, p, step)) < 0 ) { + goto fail; + } + mlen -= step; + p += step; + } + if ( (err = blake2s_update(&S, p, mlen)) < 0) { + goto fail; + } + if ( (err = blake2s_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) { + goto fail; + } + + if (0 != memcmp(hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES)) { + goto fail; + } + } + } + + puts( "ok" ); + return 0; +fail: + puts("error"); + return -1; +} +#endif diff --git a/stratum/algos/bmw512.c b/stratum/algos/bmw512.c new file mode 100644 index 000000000..54e18cdba --- /dev/null +++ b/stratum/algos/bmw512.c @@ -0,0 +1,18 @@ +#include "bmw512.h" +#include +#include +#include +#include +#include "../sha3/sph_bmw.h" + + void bmw512_hash(const char* input, char* output, uint32_t len) +{ + sph_bmw512_context ctx_bmw; + uint32_t hashA[16]; + + sph_bmw512_init(&ctx_bmw); + sph_bmw512 (&ctx_bmw, input, len); + sph_bmw512_close(&ctx_bmw, hashA); + + memcpy(output, hashA, 32); +} \ No newline at end of file diff --git a/stratum/algos/bmw512.h b/stratum/algos/bmw512.h new file mode 100644 index 000000000..e58f0ced4 --- /dev/null +++ b/stratum/algos/bmw512.h @@ -0,0 +1,11 @@ +#ifdef __cplusplus +extern "C" { +#endif + + #include + + void bmw512_hash(const char* input, char* output, uint32_t len); + + #ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/stratum/algos/brg_endian.h b/stratum/algos/brg_endian.h new file mode 100644 index 000000000..7226eb3be --- /dev/null +++ b/stratum/algos/brg_endian.h @@ -0,0 +1,142 @@ +/* + --------------------------------------------------------------------------- + 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 + Changes for ARM 9/9/2010 +*/ + +#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) */ + +#if 0 +/* Include files where endian defines and byteswap functions may reside */ +#if defined( __sun ) +# include +#elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ ) +# include +#elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \ + defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ ) +# include +#elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ ) +# if !defined( __MINGW32__ ) && !defined( _AIX ) +# include +# if !defined( __BEOS__ ) +# include +# endif +# 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 defined(__arm__) +# ifdef __BIG_ENDIAN +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +# else +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +# endif +#elif 1 /* **** 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 132 or 134 in brg_endian.h to set the platform byte order +#endif + +#endif + +#endif diff --git a/stratum/algos/crypto/odocrypt.h b/stratum/algos/crypto/odocrypt.h new file mode 100644 index 000000000..11821c96d --- /dev/null +++ b/stratum/algos/crypto/odocrypt.h @@ -0,0 +1,97 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2018 The DigiByte developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef ODO_CRYPT +#define ODO_CRYPT + +#include + +class OdoCrypt +{ +public: + // Block size, in bytes + const static int DIGEST_SIZE = 80; + +private: + // Number of rounds. + const static int ROUNDS = 84; + // Odo utilizes two sbox sizes - 6-bit sboxes, which are ideally suited for + // FPGA logic elements, and 10-bit sboxes, which are ideally suited for FPGA + // RAM elements. + const static int SMALL_SBOX_WIDTH = 6; + const static int LARGE_SBOX_WIDTH = 10; + // The pboxes are constructed using 3 primitives, applied multiple times. + const static int PBOX_SUBROUNDS = 6; + // This constant should be a generator for the multiplicative group of + // integers modulo STATE_SIZE (3 or 7 for a STATE_SIZE of 10). It controls + // one part of the pbox step. + const static int PBOX_M = 3; + // The multiplicative inverse of PBOX_M modulo STATE_SIZE + const static int INV_PBOX_M = 7; + // This constant must be even. It controls the number of rotations used in + // the linear mixing step. + const static int ROTATION_COUNT = 6; + // Odo internally operates on 64-bit words. + const static int WORD_BITS = 64; + + const static int DIGEST_BITS = 8*DIGEST_SIZE; + const static int STATE_SIZE = DIGEST_BITS / WORD_BITS; + const static int SMALL_SBOX_COUNT = DIGEST_BITS / (SMALL_SBOX_WIDTH + LARGE_SBOX_WIDTH); + const static int LARGE_SBOX_COUNT = STATE_SIZE; + +public: + OdoCrypt(uint32_t key); + + void Encrypt(char cipher[DIGEST_SIZE], const char plain[DIGEST_SIZE]) const; + + // test-only, proves that this really is a permutation function + void Decrypt(char plain[DIGEST_SIZE], const char cipher[DIGEST_SIZE]) const; + +private: + struct Pbox + { + uint64_t mask[PBOX_SUBROUNDS][STATE_SIZE/2]; + int rotation[PBOX_SUBROUNDS-1][STATE_SIZE/2]; + }; + + uint8_t Sbox1[SMALL_SBOX_COUNT][1 << SMALL_SBOX_WIDTH]; + uint16_t Sbox2[LARGE_SBOX_COUNT][1 << LARGE_SBOX_WIDTH]; + Pbox Permutation[2]; + int Rotations[ROTATION_COUNT]; + uint16_t RoundKey[ROUNDS]; + + // Pack/unpack bytes into internal state + static void Unpack(uint64_t state[STATE_SIZE], const char bytes[DIGEST_SIZE]); + static void Pack(const uint64_t state[STATE_SIZE], char bytes[DIGEST_SIZE]); + + // Pre-mix the bits. Involution. After this step, 95% of the bits depend + // on a bit from the nonce. + static void PreMix(uint64_t state[STATE_SIZE]); + + // Non-linear substitution. + static void ApplySboxes( + uint64_t state[STATE_SIZE], + const uint8_t sbox1[SMALL_SBOX_COUNT][1 << SMALL_SBOX_WIDTH], + const uint16_t sbox2[LARGE_SBOX_COUNT][1 << LARGE_SBOX_WIDTH]); + + // ApplyPbox helpers + static void ApplyMaskedSwaps(uint64_t state[STATE_SIZE], const uint64_t mask[STATE_SIZE/2]); + static void ApplyWordShuffle(uint64_t state[STATE_SIZE], int m); + static void ApplyPboxRotations(uint64_t state[STATE_SIZE], const int rotation[STATE_SIZE/2]); + + // Permute the bits. + static void ApplyPbox(uint64_t state[STATE_SIZE], const Pbox& perm); + + // Inverse transform of ApplyPbox. Only used by Decrypt. + static void ApplyInvPbox(uint64_t state[STATE_SIZE], const Pbox& perm); + + // Linear mix step. + static void ApplyRotations(uint64_t state[STATE_SIZE], const int rotations[ROTATION_COUNT]); + + // Add round key. Involution. + static void ApplyRoundKey(uint64_t state[STATE_SIZE], int roundKey); +}; + +#endif diff --git a/stratum/algos/dedal.c b/stratum/algos/dedal.c new file mode 100644 index 000000000..640ac9ba4 --- /dev/null +++ b/stratum/algos/dedal.c @@ -0,0 +1,187 @@ +#include +#include +#include + +#include "dedal.h" +#include "../sha3/sph_blake.h" +#include "../sha3/sph_bmw.h" +#include "../sha3/sph_groestl.h" +#include "../sha3/sph_jh.h" +#include "../sha3/sph_keccak.h" +#include "../sha3/sph_skein.h" +#include "../sha3/sph_luffa.h" +#include "../sha3/sph_cubehash.h" +#include "../sha3/sph_shavite.h" +#include "../sha3/sph_simd.h" +#include "../sha3/sph_echo.h" +#include "../sha3/sph_hamsi.h" +#include "../sha3/sph_fugue.h" +#include "../sha3/sph_shabal.h" +#include "../sha3/sph_whirlpool.h" +#include "../sha3/sph_sha2.h" + +const uint8_t Kspeed[16] = { + 200, // BLAKE + 236, // BMW + 252, // SKEIN + 224, // KECCAK + 240, // SHA512 + 230, // SHABAL + 79, // WHIRLPOOL + 78, // LUFFA + 89, // CUBEHASH + 62, // SHAVITE + 59, // FUGUE + 119, // JH + 62, // HAMSI + 52, // ECHO + 22, // SIMD + 47 // GROESTL +}; + +static void get_hash_order(const uint32_t* prevblock, uint8_t* output, uint8_t* hashrounds) +{ + uint8_t* ord = output; + uint8_t hr = 0; + uint8_t* data = (uint8_t*)prevblock; + uint16_t tspeed = 0; + + for (uint8_t i = 0; i < 6; i++) { + ord[i] = data[i] % 16; + ord[i + 6] = data[i+1] >> 4; + tspeed += Kspeed[ord[i]] + Kspeed[ord[i + 6]]; + } + hr = tspeed + 920 >> 7; + + int8_t c = hr - 12; + for (uint8_t i = 0; i < c ; i++) { + if (i < 15) { + uint8_t j = i >> 1; + ord[i + 12] = (i & 1) ? data[j] % 6 : data[j] % 5; + } else { + ord[i + 12] = data[i - 15] % 4; + } + } + *hashrounds = hr; +} + +void dedal_hash(const char* input, char* output, uint32_t len) +{ + + unsigned char hash[128]; + + sph_blake512_context ctx_blake; + sph_bmw512_context ctx_bmw; + sph_groestl512_context ctx_groestl; + sph_jh512_context ctx_jh; + sph_keccak512_context ctx_keccak; + sph_skein512_context ctx_skein; + 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; + sph_hamsi512_context ctx_hamsi; + sph_fugue512_context ctx_fugue; + sph_shabal512_context ctx_shabal; + sph_whirlpool_context ctx_whirlpool; + sph_sha512_context ctx_sha512; + + const void *in = input; + int size = len; + uint32_t *in32 = (uint32_t*) input; + uint8_t hashorder[32] = {}; + uint8_t hashrounds = 0; + + get_hash_order(&in32[1], hashorder, &hashrounds); + + for (int i = 0; i < hashrounds; i++) + { + switch (hashorder[i]) + { + case 0: + sph_blake512_init(&ctx_blake); + sph_blake512(&ctx_blake, in, size); + sph_blake512_close(&ctx_blake, hash); + break; + case 1: + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, in, size); + sph_bmw512_close(&ctx_bmw, hash); + break; + case 2: + sph_skein512_init(&ctx_skein); + sph_skein512(&ctx_skein, in, size); + sph_skein512_close(&ctx_skein, hash); + break; + case 3: + sph_keccak512_init(&ctx_keccak); + sph_keccak512(&ctx_keccak, in, size); + sph_keccak512_close(&ctx_keccak, hash); + break; + case 4: + sph_sha512_init(&ctx_sha512); + sph_sha512(&ctx_sha512, in, size); + sph_sha512_close(&ctx_sha512, hash); + break; + case 5: + sph_shabal512_init(&ctx_shabal); + sph_shabal512(&ctx_shabal, in, size); + sph_shabal512_close(&ctx_shabal, hash); + break; + case 6: + sph_whirlpool_init(&ctx_whirlpool); + sph_whirlpool(&ctx_whirlpool, in, size); + sph_whirlpool_close(&ctx_whirlpool, hash); + break; + case 7: + sph_luffa512_init(&ctx_luffa); + sph_luffa512(&ctx_luffa, in, size); + sph_luffa512_close(&ctx_luffa, hash); + break; + case 8: + sph_cubehash512_init(&ctx_cubehash); + sph_cubehash512(&ctx_cubehash, in, size); + sph_cubehash512_close(&ctx_cubehash, hash); + break; + case 9: + sph_shavite512_init(&ctx_shavite); + sph_shavite512(&ctx_shavite, in, size); + sph_shavite512_close(&ctx_shavite, hash); + break; + case 10: + sph_fugue512_init(&ctx_fugue); + sph_fugue512(&ctx_fugue, in, size); + sph_fugue512_close(&ctx_fugue, hash); + break; + case 11: + sph_jh512_init(&ctx_jh); + sph_jh512(&ctx_jh, in, size); + sph_jh512_close(&ctx_jh, hash); + break; + case 12: + sph_hamsi512_init(&ctx_hamsi); + sph_hamsi512(&ctx_hamsi, in, size); + sph_hamsi512_close(&ctx_hamsi, hash); + break; + case 13: + sph_echo512_init(&ctx_echo); + sph_echo512(&ctx_echo, in, size); + sph_echo512_close(&ctx_echo, hash); + break; + case 14: + sph_simd512_init(&ctx_simd); + sph_simd512(&ctx_simd, in, size); + sph_simd512_close(&ctx_simd, hash); + break; + case 15: + sph_groestl512_init(&ctx_groestl); + sph_groestl512(&ctx_groestl, in, size); + sph_groestl512_close(&ctx_groestl, hash); + break; + } + in = (void*)hash; + size = 64; + } + memcpy(output, hash, 32); +} diff --git a/stratum/algos/dedal.h b/stratum/algos/dedal.h new file mode 100644 index 000000000..a3238f6ba --- /dev/null +++ b/stratum/algos/dedal.h @@ -0,0 +1,16 @@ +#ifndef DEDALHASH_H +#define DEDALHASH_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void dedal_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif // DEDALHASH_H diff --git a/stratum/algos/geek.c b/stratum/algos/geek.c new file mode 100644 index 000000000..6d05a6aff --- /dev/null +++ b/stratum/algos/geek.c @@ -0,0 +1,76 @@ +#include "geek.h" +#include +#include +#include +#include + +#include "../sha3/sph_blake.h" +#include "../sha3/sph_bmw.h" +#include "../sha3/sph_groestl.h" +#include "../sha3/sph_jh.h" +#include "../sha3/sph_keccak.h" +#include "../sha3/sph_skein.h" +#include "../sha3/sph_luffa.h" +#include "../sha3/sph_cubehash.h" +#include "../sha3/sph_shavite.h" +#include "../sha3/sph_simd.h" +#include "../sha3/sph_echo.h" +#include "../sha3/sph_hamsi.h" +#include "../sha3/sph_fugue.h" +#include "../sha3/sph_shabal.h" +#include "../sha3/sph_whirlpool.h" + +void geek_hash(const char* input, char* output, uint32_t len) +{ + sph_blake512_context ctx_blake; + sph_bmw512_context ctx_bmw; + sph_groestl512_context ctx_groestl; + sph_keccak512_context ctx_keccak; + sph_cubehash512_context ctx_cubehash1; + sph_echo512_context ctx_echo1; + sph_shabal512_context ctx_shabal1; + sph_simd512_context ctx_simd1; + sph_hamsi512_context ctx_hamsi1; + + + //these uint512 in the c++ source of the client are backed by an array of uint32 + uint32_t hashA[16], hashB[16]; + + sph_blake512_init(&ctx_blake); + sph_blake512 (&ctx_blake, input, len); + sph_blake512_close (&ctx_blake, hashA); + + sph_bmw512_init(&ctx_bmw); + sph_bmw512 (&ctx_bmw, hashA, 64); + sph_bmw512_close(&ctx_bmw, hashB); + + sph_echo512_init (&ctx_echo1); + sph_echo512 (&ctx_echo1, hashB, 64); + sph_echo512_close(&ctx_echo1, hashA); + + sph_shabal512_init (&ctx_shabal1); + sph_shabal512 (&ctx_shabal1, hashA, 64); + sph_shabal512_close(&ctx_shabal1, hashB); + + sph_groestl512_init(&ctx_groestl); + sph_groestl512 (&ctx_groestl, hashB, 64); + sph_groestl512_close(&ctx_groestl, hashA); + + sph_cubehash512_init (&ctx_cubehash1); + sph_cubehash512 (&ctx_cubehash1, hashA, 64); + sph_cubehash512_close(&ctx_cubehash1, hashB); + + sph_keccak512_init(&ctx_keccak); + sph_keccak512 (&ctx_keccak, hashB, 64); + sph_keccak512_close(&ctx_keccak, hashA); + + sph_hamsi512_init (&ctx_hamsi1); + sph_hamsi512 (&ctx_hamsi1, hashA, 64); + sph_hamsi512_close(&ctx_hamsi1, hashB); + + sph_simd512_init (&ctx_simd1); + sph_simd512 (&ctx_simd1, hashB, 64); + sph_simd512_close(&ctx_simd1, hashA); + + memcpy(output, hashA, 32); +} diff --git a/stratum/algos/geek.h b/stratum/algos/geek.h new file mode 100644 index 000000000..cca287f5f --- /dev/null +++ b/stratum/algos/geek.h @@ -0,0 +1,16 @@ +#ifndef GEEK_H +#define GEEK_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void geek_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/stratum/algos/gltalgos.c b/stratum/algos/gltalgos.c new file mode 100644 index 000000000..955b56d98 --- /dev/null +++ b/stratum/algos/gltalgos.c @@ -0,0 +1,470 @@ +#include "gltalgos.h" +#include +#include +#include +#include + +#include "blake2-ref/blake2.h" + +#include "../sha3/sph_blake.h" +#include "../sha3/sph_bmw.h" +#include "../sha3/sph_groestl.h" +#include "../sha3/sph_jh.h" +#include "../sha3/sph_keccak.h" +#include "../sha3/sph_skein.h" +#include "../sha3/sph_luffa.h" +#include "../sha3/sph_cubehash.h" +#include "../sha3/sph_shavite.h" +#include "../sha3/sph_simd.h" +#include "../sha3/sph_echo.h" +#include "../sha3/sph_hamsi.h" +#include "../sha3/sph_fugue.h" +#include "../sha3/sph_shabal.h" +#include "../sha3/sph_whirlpool.h" +#include "../sha3/sph_sha2.h" +#include "../sha3/sph_haval.h" +#include "../sha3/sph_gost.h" + + +void pawelhash_hash(const char* input, char* output, uint32_t len) +{ + sph_fugue512_context ctx_fugue; + sph_sha512_context ctx_sha2; + sph_skein512_context ctx_skein; + sph_jh512_context ctx_jh; + sph_keccak512_context ctx_keccak; + sph_luffa512_context ctx_luffa; + sph_whirlpool_context ctx_whirlpool; + sph_shabal512_context ctx_shabal; + sph_echo512_context ctx_echo; + sph_groestl512_context ctx_groestl; + sph_haval256_5_context ctx_haval; + sph_bmw512_context ctx_bmw; + sph_gost512_context ctx_gost; + + //these uint512 in the c++ source of the client are backed by an array of uint32 + uint32_t hashA[16], hashB[16]; + + sph_fugue512_init(&ctx_fugue); + sph_fugue512(&ctx_fugue, input, len); + sph_fugue512_close(&ctx_fugue, hashA); + + sph_sha512_init(&ctx_sha2); + sph_sha512(&ctx_sha2, hashA, 64); + sph_sha512_close(&ctx_sha2, hashB); + + sph_skein512_init(&ctx_skein); + sph_skein512(&ctx_skein, hashB, 64); + sph_skein512_close(&ctx_skein, hashA); + + sph_jh512_init(&ctx_jh); + sph_jh512(&ctx_jh, hashA, 64); + sph_jh512_close(&ctx_jh, hashB); + + sph_keccak512_init(&ctx_keccak); + sph_keccak512(&ctx_keccak, hashB, 64); + sph_keccak512_close(&ctx_keccak, hashA); + + sph_luffa512_init(&ctx_luffa); + sph_luffa512(&ctx_luffa, hashA, 64); + sph_luffa512_close(&ctx_luffa, hashB); + + sph_whirlpool_init(&ctx_whirlpool); + sph_whirlpool(&ctx_whirlpool, hashB, 64); + sph_whirlpool_close(&ctx_whirlpool, hashA); + + sph_shabal512_init(&ctx_shabal); + sph_shabal512(&ctx_shabal, hashA, 64); + sph_shabal512_close(&ctx_shabal, hashB); + + sph_echo512_init(&ctx_echo); + sph_echo512(&ctx_echo, hashB, 64); + sph_echo512_close(&ctx_echo, hashA); + + sph_groestl512_init(&ctx_groestl); + sph_groestl512(&ctx_groestl, hashA, 64); + sph_groestl512_close(&ctx_groestl, hashB); + + sph_haval256_5_init(&ctx_haval); + sph_haval256_5(&ctx_haval, hashB, 64); + sph_haval256_5_close(&ctx_haval, hashA); + + memset(&hashA[8], 0, 32); + + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, hashA, 64); + sph_bmw512_close(&ctx_bmw, hashB); + + sph_echo512_init(&ctx_echo); + sph_echo512(&ctx_echo, hashB, 64); + sph_echo512_close(&ctx_echo, hashA); + + sph_fugue512_init(&ctx_fugue); + sph_fugue512(&ctx_fugue, hashA, 64); + sph_fugue512_close(&ctx_fugue, hashB); + + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, hashB, 64); + sph_bmw512_close(&ctx_bmw, hashA); + + sph_gost512_init(&ctx_gost); + sph_gost512(&ctx_gost, hashA, 64); + sph_gost512_close(&ctx_gost, hashB); + + sph_shabal512_init(&ctx_shabal); + sph_shabal512(&ctx_shabal, hashB, 64); + sph_shabal512_close(&ctx_shabal, hashA); + + sph_whirlpool_init(&ctx_whirlpool); + sph_whirlpool(&ctx_whirlpool, hashA, 64); + sph_whirlpool_close(&ctx_whirlpool, hashB); + + sph_groestl512_init(&ctx_groestl); + sph_groestl512 (&ctx_groestl, hashB, 64); + sph_groestl512_close(&ctx_groestl, hashA); + + memcpy(output, hashA, 32); +} + +void jeonghash_hash(const char* input, char* output, uint32_t len) +{ + sph_simd512_context ctx_simd; + sph_hamsi512_context ctx_hamsi; + sph_shabal512_context ctx_shabal; + sph_blake512_context ctx_blake; + sph_bmw512_context ctx_bmw; + sph_sha512_context ctx_sha2; + sph_whirlpool_context ctx_whirlpool; + sph_skein512_context ctx_skein; + + //these uint512 in the c++ source of the client are backed by an array of uint32 + uint32_t hashA[16], hashB[16]; + + sph_simd512_init(&ctx_simd); + sph_simd512(&ctx_simd, input, len); + sph_simd512_close(&ctx_simd, hashA); + + sph_hamsi512_init(&ctx_hamsi); + sph_hamsi512(&ctx_hamsi, hashA, 64); + sph_hamsi512_close(&ctx_hamsi, hashB); + + sph_shabal512_init(&ctx_shabal); + sph_shabal512(&ctx_shabal, hashB, 64); + sph_shabal512_close(&ctx_shabal, hashA); + + sph_blake512_init(&ctx_blake); + sph_blake512(&ctx_blake, hashA, 64); + sph_blake512_close(&ctx_blake, hashB); + + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, hashB, 64); + sph_bmw512_close(&ctx_bmw, hashA); + + sph_sha512_init(&ctx_sha2); + sph_sha512(&ctx_sha2, hashA, 64); + sph_sha512_close(&ctx_sha2, hashB); + + sph_whirlpool_init(&ctx_whirlpool); + sph_whirlpool(&ctx_whirlpool, hashB, 64); + sph_whirlpool_close(&ctx_whirlpool, hashA); + + sph_skein512_init(&ctx_skein); + sph_skein512(&ctx_skein, hashA, 64); + sph_skein512_close(&ctx_skein, hashB); + + sph_skein512_init(&ctx_skein); + sph_skein512(&ctx_skein, hashB, 64); + sph_skein512_close(&ctx_skein, hashA); + + sph_whirlpool_init(&ctx_whirlpool); + sph_whirlpool(&ctx_whirlpool, hashA, 64); + sph_whirlpool_close(&ctx_whirlpool, hashB); + + sph_sha512_init(&ctx_sha2); + sph_sha512(&ctx_sha2, hashB, 64); + sph_sha512_close(&ctx_sha2, hashA); + + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, hashA, 64); + sph_bmw512_close(&ctx_bmw, hashB); + + sph_blake512_init(&ctx_blake); + sph_blake512(&ctx_blake, hashB, 64); + sph_blake512_close(&ctx_blake, hashA); + + sph_shabal512_init(&ctx_shabal); + sph_shabal512(&ctx_shabal, hashA, 64); + sph_shabal512_close(&ctx_shabal, hashB); + + sph_hamsi512_init(&ctx_hamsi); + sph_hamsi512(&ctx_hamsi, hashB, 64); + sph_hamsi512_close(&ctx_hamsi, hashA); + + sph_simd512_init(&ctx_simd); + sph_simd512(&ctx_simd, hashA, 64); + sph_simd512_close(&ctx_simd, hashB); + + sph_simd512_init(&ctx_simd); + sph_simd512(&ctx_simd, hashB, 64); + sph_simd512_close(&ctx_simd, hashA); + + sph_hamsi512_init(&ctx_hamsi); + sph_hamsi512(&ctx_hamsi, hashA, 64); + sph_hamsi512_close(&ctx_hamsi, hashB); + + sph_shabal512_init(&ctx_shabal); + sph_shabal512(&ctx_shabal, hashB, 64); + sph_shabal512_close(&ctx_shabal, hashA); + + sph_blake512_init(&ctx_blake); + sph_blake512(&ctx_blake, hashA, 64); + sph_blake512_close(&ctx_blake, hashB); + + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, hashB, 64); + sph_bmw512_close(&ctx_bmw, hashA); + + sph_sha512_init(&ctx_sha2); + sph_sha512(&ctx_sha2, hashA, 64); + sph_sha512_close(&ctx_sha2, hashB); + + sph_whirlpool_init(&ctx_whirlpool); + sph_whirlpool(&ctx_whirlpool, hashB, 64); + sph_whirlpool_close(&ctx_whirlpool, hashA); + + sph_skein512_init(&ctx_skein); + sph_skein512(&ctx_skein, hashA, 64); + sph_skein512_close(&ctx_skein, hashB); + + memcpy(output, hashB, 32); +} + +void astralhash_hash(const char* input, char* output, uint32_t len) +{ + sph_luffa512_context ctx_luffa; + sph_skein512_context ctx_skein; + sph_echo512_context ctx_echo; + sph_whirlpool_context ctx_whirlpool; + sph_bmw512_context ctx_bmw; + sph_blake512_context ctx_blake; + sph_shavite512_context ctx_shavite; + sph_fugue512_context ctx_fugue; + sph_hamsi512_context ctx_hamsi; + sph_haval256_5_context ctx_haval; + sph_sha512_context ctx_sha2; + + //these uint512 in the c++ source of the client are backed by an array of uint32 + uint32_t hashA[16], hashB[16]; + + sph_luffa512_init(&ctx_luffa); + sph_luffa512(&ctx_luffa, input, len); + sph_luffa512_close(&ctx_luffa, hashA); + + sph_skein512_init(&ctx_skein); + sph_skein512(&ctx_skein, hashA, 64); + sph_skein512_close(&ctx_skein, hashB); + + sph_echo512_init(&ctx_echo); + sph_echo512(&ctx_echo, hashB, 64); + sph_echo512_close(&ctx_echo, hashA); + + sph_whirlpool_init(&ctx_whirlpool); + sph_whirlpool(&ctx_whirlpool, hashA, 64); + sph_whirlpool_close(&ctx_whirlpool, hashB); + + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, hashB, 64); + sph_bmw512_close(&ctx_bmw, hashA); + + sph_blake512_init(&ctx_blake); + sph_blake512(&ctx_blake, hashA, 64); + sph_blake512_close(&ctx_blake, hashB); + + sph_shavite512_init(&ctx_shavite); + sph_shavite512(&ctx_shavite, hashB, 64); + sph_shavite512_close(&ctx_shavite, hashA); + + sph_skein512_init(&ctx_skein); + sph_skein512(&ctx_skein, hashA, 64); + sph_skein512_close(&ctx_skein, hashB); + + sph_whirlpool_init(&ctx_whirlpool); + sph_whirlpool(&ctx_whirlpool, hashB, 64); + sph_whirlpool_close(&ctx_whirlpool, hashA); + + sph_fugue512_init(&ctx_fugue); + sph_fugue512(&ctx_fugue, hashA, 64); + sph_fugue512_close(&ctx_fugue, hashB); + + sph_hamsi512_init(&ctx_hamsi); + sph_hamsi512(&ctx_hamsi, hashB, 64); + sph_hamsi512_close(&ctx_hamsi, hashA); + + sph_haval256_5_init(&ctx_haval); + sph_haval256_5(&ctx_haval, hashA, 64); + sph_haval256_5_close(&ctx_haval, hashB); + + memset(&hashB[8], 0, 32); + + sph_sha512_init(&ctx_sha2); + sph_sha512(&ctx_sha2, hashB, 64); + sph_sha512_close(&ctx_sha2, hashA); + + memcpy(output, hashA, 32); +} + +void padihash_hash(const char* input, char* output, uint32_t len) +{ + sph_sha512_context ctx_sha2; + sph_jh512_context ctx_jh; + sph_luffa512_context ctx_luffa; + sph_echo512_context ctx_echo; + sph_bmw512_context ctx_bmw; + sph_haval256_5_context ctx_haval; + sph_cubehash512_context ctx_cubehash; + sph_shabal512_context ctx_shabal; + + //these uint512 in the c++ source of the client are backed by an array of uint32 + uint32_t hashA[16], hashB[16]; + + sph_sha512_init(&ctx_sha2); + sph_sha512(&ctx_sha2, input, len); + sph_sha512_close(&ctx_sha2, hashA); + + sph_jh512_init(&ctx_jh); + sph_jh512(&ctx_jh, hashA, 64); + sph_jh512_close(&ctx_jh, hashB); + + sph_luffa512_init(&ctx_luffa); + sph_luffa512(&ctx_luffa, hashB, 64); + sph_luffa512_close(&ctx_luffa, hashA); + + sph_echo512_init(&ctx_echo); + sph_echo512(&ctx_echo, hashA, 64); + sph_echo512_close(&ctx_echo, hashB); + + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, hashB, 64); + sph_bmw512_close(&ctx_bmw, hashA); + + sph_haval256_5_init(&ctx_haval); + sph_haval256_5(&ctx_haval, hashA, 64); + sph_haval256_5_close(&ctx_haval, hashB); + + memset(&hashB[8], 0, 32); + + sph_cubehash512_init(&ctx_cubehash); + sph_cubehash512(&ctx_cubehash, hashB, 64); + sph_cubehash512_close(&ctx_cubehash, hashA); + + sph_shabal512_init(&ctx_shabal); + sph_shabal512(&ctx_shabal, hashA, 64); + sph_shabal512_close(&ctx_shabal, hashB); + + sph_sha512_init(&ctx_sha2); + sph_sha512(&ctx_sha2, hashB, 64); + sph_sha512_close(&ctx_sha2, hashA); + + sph_jh512_init(&ctx_jh); + sph_jh512(&ctx_jh, hashA, 64); + sph_jh512_close(&ctx_jh, hashB); + + sph_luffa512_init(&ctx_luffa); + sph_luffa512(&ctx_luffa, hashB, 64); + sph_luffa512_close(&ctx_luffa, hashA); + + sph_echo512_init(&ctx_echo); + sph_echo512(&ctx_echo, hashA, 64); + sph_echo512_close(&ctx_echo, hashB); + + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, hashB, 64); + sph_bmw512_close(&ctx_bmw, hashA); + + sph_haval256_5_init(&ctx_haval); + sph_haval256_5(&ctx_haval, hashA, 64); + sph_haval256_5_close(&ctx_haval, hashB); + + memset(&hashB[8], 0, 32); + + sph_cubehash512_init(&ctx_cubehash); + sph_cubehash512(&ctx_cubehash, hashB, 64); + sph_cubehash512_close(&ctx_cubehash, hashA); + + sph_shabal512_init(&ctx_shabal); + sph_shabal512(&ctx_shabal, hashA, 64); + sph_shabal512_close(&ctx_shabal, hashB); + + sph_shabal512_init(&ctx_shabal); + sph_shabal512(&ctx_shabal, hashB, 64); + sph_shabal512_close(&ctx_shabal, hashA); + + sph_cubehash512_init(&ctx_cubehash); + sph_cubehash512(&ctx_cubehash, hashA, 64); + sph_cubehash512_close(&ctx_cubehash, hashB); + + sph_haval256_5_init(&ctx_haval); + sph_haval256_5(&ctx_haval, hashB, 64); + sph_haval256_5_close(&ctx_haval, hashA); + + memset(&hashA[8], 0, 32); + + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, hashA, 64); + sph_bmw512_close(&ctx_bmw, hashB); + + sph_echo512_init(&ctx_echo); + sph_echo512(&ctx_echo, hashB, 64); + sph_echo512_close(&ctx_echo, hashA); + + sph_luffa512_init(&ctx_luffa); + sph_luffa512(&ctx_luffa, hashA, 64); + sph_luffa512_close(&ctx_luffa, hashB); + + sph_jh512_init(&ctx_jh); + sph_jh512(&ctx_jh, hashB, 64); + sph_jh512_close(&ctx_jh, hashA); + + sph_sha512_init(&ctx_sha2); + sph_sha512(&ctx_sha2, hashA, 64); + sph_sha512_close(&ctx_sha2, hashB); + + sph_jh512_init(&ctx_jh); + sph_jh512(&ctx_jh, hashB, 64); + sph_jh512_close(&ctx_jh, hashA); + + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, hashA, 64); + sph_bmw512_close(&ctx_bmw, hashB); + + memcpy(output, hashB, 32); +} + +void globalhash_hash(const char* input, char* output, uint32_t len) +{ + sph_gost512_context ctx_gost; + sph_blake512_context ctx_blake; + blake2b_state ctx_blake2b[1]; + blake2s_state ctx_blake2s[1]; + + //these uint512 in the c++ source of the client are backed by an array of uint32 + uint32_t hashA[16], hashB[16], finalhash[8]; // finalhash is a 256 unsigned integer + + sph_gost512_init(&ctx_gost); + sph_gost512 (&ctx_gost, input, len); + sph_gost512_close(&ctx_gost, hashA); + + sph_blake512_init(&ctx_blake); + sph_blake512(&ctx_blake, hashA, 64); + sph_blake512_close(&ctx_blake, hashB); + + blake2b_init( ctx_blake2b, BLAKE2B_OUTBYTES ); + blake2b_update( ctx_blake2b, hashB, 64 ); + blake2b_final( ctx_blake2b, hashA, BLAKE2B_OUTBYTES ); + + blake2s_init( ctx_blake2s, BLAKE2S_OUTBYTES ); + blake2s_update( ctx_blake2s, hashA, 64); + blake2s_final( ctx_blake2s, finalhash, BLAKE2S_OUTBYTES ); + + memcpy(output, finalhash, 32); +} \ No newline at end of file diff --git a/stratum/algos/gltalgos.h b/stratum/algos/gltalgos.h new file mode 100644 index 000000000..50d78a3f3 --- /dev/null +++ b/stratum/algos/gltalgos.h @@ -0,0 +1,20 @@ +#ifndef GLTALGOS_H +#define GLTALGOS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void pawelhash_hash(const char* input, char* output, uint32_t len); +void astralhash_hash(const char* input, char* output, uint32_t len); +void jeonghash_hash(const char* input, char* output, uint32_t len); +void padihash_hash(const char* input, char* output, uint32_t len); +void globalhash_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/stratum/algos/hsr14.c b/stratum/algos/hsr14.c index b31decdb4..fc2de95c4 100644 --- a/stratum/algos/hsr14.c +++ b/stratum/algos/hsr14.c @@ -16,8 +16,8 @@ #include "../sha3/sph_echo.h" #include "../sha3/sph_hamsi.h" #include "../sha3/sph_fugue.h" +#include "../sha3/sph_sm3.h" -#include "sm3.h" #include "common.h" @@ -87,7 +87,7 @@ void hsr_hash(const char* input, char* output, uint32_t len) sm3_init(&ctx_sm3); sm3_update(&ctx_sm3, hash, 64); memset(hash, 0, sizeof hash); - sm3_close(&ctx_sm3, hash); + sph_sm3_close(&ctx_sm3, hash); sph_hamsi512_init(&ctx_hamsi1); sph_hamsi512(&ctx_hamsi1, hash, 64); diff --git a/stratum/algos/insecure_memzero.h b/stratum/algos/insecure_memzero.h new file mode 100644 index 000000000..5a0ba75c4 --- /dev/null +++ b/stratum/algos/insecure_memzero.h @@ -0,0 +1 @@ +#define insecure_memzero(buf, len) /* empty */ diff --git a/stratum/algos/lane.c b/stratum/algos/lane.c new file mode 100644 index 000000000..ee2cd0576 --- /dev/null +++ b/stratum/algos/lane.c @@ -0,0 +1,2151 @@ +/* + * Copyright (c) 2008 Sebastiaan Indesteege + * + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Optimised ANSI-C implementation of LANE + */ + +#include "lane.h" + +#define T8(x) ((x) & 0xff) +#define B0(x) (T8((x) )) +#define B1(x) (T8((x) >> 8)) +#define B2(x) (T8((x) >> 16)) +#define B3(x) (T8((x) >> 24)) +#define MSB32(x) ((u32)((((u64)(x))>>32) & 0xffffffff)) +#define LSB32(x) ((u32)((((u64)(x)) ) & 0xffffffff)) +#ifdef LANE_BIG_ENDIAN +#define U8TO32_BIG(c) (((u32*)(c))[0]) +#define U32TO8_BIG(c, v) ((u32*)(c))[0]=v +#else +#define U8TO32_BIG(c) (((u32)T8(*((u8*)(c))) << 24) | \ + ((u32)T8(*(((u8*)(c)) + 1)) << 16) | \ + ((u32)T8(*(((u8*)(c)) + 2)) << 8) | \ + ((u32)T8(*(((u8*)(c)) + 3)))) +#define U32TO8_BIG(c, v) do { \ + u32 tmp_portable_h_x = (v); \ + u8 *tmp_portable_h_d = (c); \ + tmp_portable_h_d[0] = T8(tmp_portable_h_x >> 24); \ + tmp_portable_h_d[1] = T8(tmp_portable_h_x >> 16); \ + tmp_portable_h_d[2] = T8(tmp_portable_h_x >> 8); \ + tmp_portable_h_d[3] = T8(tmp_portable_h_x); \ + } while (0) +#endif /* LANE_BIG_ENDIAN */ + +static const u32 iv224[8] = { + 0xc8245a86U, 0x8d733102U, 0x314ddcb9U, 0xf60a7ef4U, + 0x57b8c917U, 0xeefeaec2U, 0xff4fc3beU, 0x87c4728eU +}; + +static const u32 iv256[8] = { + 0xbe292e17U, 0xbb541ff2U, 0xfe54b6f7U, 0x30b1c96aU, + 0x7b259268U, 0x8539bdf3U, 0x97c4bdd6U, 0x49763fb8U +}; + +static const u32 iv384[16] = { + 0x148922ceU, 0x548c3001U, 0x76978bc8U, 0x266e008cU, + 0x3dc60765U, 0xd85b09d9U, 0x4cb1c8d8U, 0xe2cab952U, + 0xdb72be8eU, 0x685f0783U, 0xfa436c3dU, 0x4b9acb90U, + 0x5088dd47U, 0x932f55a9U, 0xa0c415c6U, 0xdb6dd795U +}; + +static const u32 iv512[16] = { + 0x9b603481U, 0x1d5a931bU, 0x69c4e6e0U, 0x975e2681U, + 0xb863ba53U, 0x8d1be11bU, 0x77340080U, 0xd42c48a5U, + 0x3a3a1d61U, 0x1cf3a1c4U, 0xf0a30347U, 0x7e56a44aU, + 0x9530ee60U, 0xdadb05b6U, 0x3ae3ac7cU, 0xd732ac6aU +}; + +static const u32 T0[256] = { + 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, + 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, + 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, + 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, + 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, + 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, + 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, + 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, + 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, + 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, + 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, + 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, + 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, + 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, + 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, + 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, + 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, + 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, + 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, + 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, + 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, + 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, + 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, + 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, + 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, + 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, + 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, + 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, + 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, + 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, + 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, + 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, + 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, + 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, + 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, + 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, + 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, + 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, + 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, + 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, + 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, + 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, + 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, + 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, + 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, + 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, + 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, + 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, + 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, + 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, + 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, + 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, + 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, + 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, + 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, + 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, + 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, + 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, + 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, + 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, + 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, + 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, + 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, + 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, +}; +static const u32 T1[256] = { + 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, + 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, + 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, + 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, + 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, + 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, + 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, + 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, + 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, + 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, + 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, + 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, + 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, + 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, + 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, + 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, + 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, + 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, + 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, + 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, + 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, + 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, + 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, + 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, + 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, + 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, + 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, + 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, + 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, + 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, + 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, + 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, + 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, + 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, + 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, + 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, + 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, + 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, + 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, + 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, + 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, + 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, + 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, + 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, + 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, + 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, + 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, + 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, + 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, + 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, + 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, + 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, + 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, + 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, + 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, + 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, + 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, + 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, + 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, + 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, + 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, + 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, + 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, + 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, +}; +static const u32 T2[256] = { + 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, + 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, + 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, + 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, + 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, + 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, + 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, + 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, + 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, + 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, + 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, + 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, + 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, + 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, + 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, + 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, + 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, + 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, + 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, + 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, + 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, + 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, + 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, + 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, + 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, + 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, + 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, + 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, + 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, + 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, + 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, + 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, + 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, + 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, + 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, + 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, + 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, + 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, + 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, + 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, + 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, + 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, + 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, + 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, + 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, + 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, + 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, + 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, + 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, + 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, + 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, + 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, + 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, + 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, + 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, + 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, + 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, + 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, + 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, + 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, + 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, + 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, + 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, + 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, +}; +static const u32 T3[256] = { + 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, + 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, + 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, + 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, + 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, + 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, + 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, + 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, + 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, + 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, + 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, + 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, + 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, + 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, + 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, + 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, + 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, + 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, + 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, + 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, + 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, + 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, + 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, + 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, + 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, + 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, + 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, + 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, + 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, + 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, + 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, + 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, + 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, + 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, + 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, + 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, + 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, + 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, + 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, + 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, + 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, + 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, + 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, + 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, + 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, + 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, + 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, + 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, + 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, + 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, + 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, + 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, + 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, + 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, + 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, + 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, + 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, + 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, + 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, + 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, + 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, + 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, + 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, + 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, +}; + +static const u32 C[768] = { + 0x07fc703d, 0xd3fe381f, 0xb9ff1c0e, 0x5cff8e07, 0xfe7fc702, 0x7f3fe381, 0xef9ff1c1, 0xa7cff8e1, + 0x83e7fc71, 0x91f3fe39, 0x98f9ff1d, 0x9c7cff8f, 0x9e3e7fc6, 0x4f1f3fe3, 0xf78f9ff0, 0x7bc7cff8, + 0x3de3e7fc, 0x1ef1f3fe, 0x0f78f9ff, 0xd7bc7cfe, 0x6bde3e7f, 0xe5ef1f3e, 0x72f78f9f, 0xe97bc7ce, + 0x74bde3e7, 0xea5ef1f2, 0x752f78f9, 0xea97bc7d, 0xa54bde3f, 0x82a5ef1e, 0x4152f78f, 0xf0a97bc6, + 0x7854bde3, 0xec2a5ef0, 0x76152f78, 0x3b0a97bc, 0x1d854bde, 0x0ec2a5ef, 0xd76152f6, 0x6bb0a97b, + 0xe5d854bc, 0x72ec2a5e, 0x3976152f, 0xccbb0a96, 0x665d854b, 0xe32ec2a4, 0x71976152, 0x38cbb0a9, + 0xcc65d855, 0xb632ec2b, 0x8b197614, 0x458cbb0a, 0x22c65d85, 0xc1632ec3, 0xb0b19760, 0x5858cbb0, + 0x2c2c65d8, 0x161632ec, 0x0b0b1976, 0x05858cbb, 0xd2c2c65c, 0x6961632e, 0x34b0b197, 0xca5858ca, + 0x652c2c65, 0xe2961633, 0xa14b0b18, 0x50a5858c, 0x2852c2c6, 0x14296163, 0xda14b0b0, 0x6d0a5858, + 0x36852c2c, 0x1b429616, 0x0da14b0b, 0xd6d0a584, 0x6b6852c2, 0x35b42961, 0xcada14b1, 0xb56d0a59, + 0x8ab6852d, 0x955b4297, 0x9aada14a, 0x4d56d0a5, 0xf6ab6853, 0xab55b428, 0x55aada14, 0x2ad56d0a, + 0x156ab685, 0xdab55b43, 0xbd5aada0, 0x5ead56d0, 0x2f56ab68, 0x17ab55b4, 0x0bd5aada, 0x05ead56d, + 0xd2f56ab7, 0xb97ab55a, 0x5cbd5aad, 0xfe5ead57, 0xaf2f56aa, 0x5797ab55, 0xfbcbd5ab, 0xade5ead4, + 0x56f2f56a, 0x2b797ab5, 0xc5bcbd5b, 0xb2de5eac, 0x596f2f56, 0x2cb797ab, 0xc65bcbd4, 0x632de5ea, + 0x3196f2f5, 0xc8cb797b, 0xb465bcbc, 0x5a32de5e, 0x2d196f2f, 0xc68cb796, 0x63465bcb, 0xe1a32de4, + 0x70d196f2, 0x3868cb79, 0xcc3465bd, 0xb61a32df, 0x8b0d196e, 0x45868cb7, 0xf2c3465a, 0x7961a32d, + 0xecb0d197, 0xa65868ca, 0x532c3465, 0xf9961a33, 0xaccb0d18, 0x5665868c, 0x2b32c346, 0x159961a3, + 0xdaccb0d0, 0x6d665868, 0x36b32c34, 0x1b59961a, 0x0daccb0d, 0xd6d66587, 0xbb6b32c2, 0x5db59961, + 0xfedaccb1, 0xaf6d6659, 0x87b6b32d, 0x93db5997, 0x99edacca, 0x4cf6d665, 0xf67b6b33, 0xab3db598, + 0x559edacc, 0x2acf6d66, 0x1567b6b3, 0xdab3db58, 0x6d59edac, 0x36acf6d6, 0x1b567b6b, 0xddab3db4, + 0x6ed59eda, 0x376acf6d, 0xcbb567b7, 0xb5dab3da, 0x5aed59ed, 0xfd76acf7, 0xaebb567a, 0x575dab3d, + 0xfbaed59f, 0xadd76ace, 0x56ebb567, 0xfb75dab2, 0x7dbaed59, 0xeedd76ad, 0xa76ebb57, 0x83b75daa, + 0x41dbaed5, 0xf0edd76b, 0xa876ebb4, 0x543b75da, 0x2a1dbaed, 0xc50edd77, 0xb2876eba, 0x5943b75d, + 0xfca1dbaf, 0xae50edd6, 0x572876eb, 0xfb943b74, 0x7dca1dba, 0x3ee50edd, 0xcf72876f, 0xb7b943b6, + 0x5bdca1db, 0xfdee50ec, 0x7ef72876, 0x3f7b943b, 0xcfbdca1c, 0x67dee50e, 0x33ef7287, 0xc9f7b942, + 0x64fbdca1, 0xe27dee51, 0xa13ef729, 0x809f7b95, 0x904fbdcb, 0x9827dee4, 0x4c13ef72, 0x2609f7b9, + 0xc304fbdd, 0xb1827def, 0x88c13ef6, 0x44609f7b, 0xf2304fbc, 0x791827de, 0x3c8c13ef, 0xce4609f6, + 0x672304fb, 0xe391827c, 0x71c8c13e, 0x38e4609f, 0xcc72304e, 0x66391827, 0xe31c8c12, 0x718e4609, + 0xe8c72305, 0xa4639183, 0x8231c8c0, 0x4118e460, 0x208c7230, 0x10463918, 0x08231c8c, 0x04118e46, + 0x0208c723, 0xd1046390, 0x688231c8, 0x344118e4, 0x1a208c72, 0x0d104639, 0xd688231d, 0xbb44118f, + 0x8da208c6, 0x46d10463, 0xf3688230, 0x79b44118, 0x3cda208c, 0x1e6d1046, 0x0f368823, 0xd79b4410, + 0x6bcda208, 0x35e6d104, 0x1af36882, 0x0d79b441, 0xd6bcda21, 0xbb5e6d11, 0x8daf3689, 0x96d79b45, + 0x9b6bcda3, 0x9db5e6d0, 0x4edaf368, 0x276d79b4, 0x13b6bcda, 0x09db5e6d, 0xd4edaf37, 0xba76d79a, + 0x5d3b6bcd, 0xfe9db5e7, 0xaf4edaf2, 0x57a76d79, 0xfbd3b6bd, 0xade9db5f, 0x86f4edae, 0x437a76d7, + 0xf1bd3b6a, 0x78de9db5, 0xec6f4edb, 0xa637a76c, 0x531bd3b6, 0x298de9db, 0xc4c6f4ec, 0x62637a76, + 0x3131bd3b, 0xc898de9c, 0x644c6f4e, 0x322637a7, 0xc9131bd2, 0x64898de9, 0xe244c6f5, 0xa122637b, + 0x809131bc, 0x404898de, 0x20244c6f, 0xc0122636, 0x6009131b, 0xe004898c, 0x700244c6, 0x38012263, + 0xcc009130, 0x66004898, 0x3300244c, 0x19801226, 0x0cc00913, 0xd6600488, 0x6b300244, 0x35980122, + 0x1acc0091, 0xdd660049, 0xbeb30025, 0x8f598013, 0x97acc008, 0x4bd66004, 0x25eb3002, 0x12f59801, + 0xd97acc01, 0xbcbd6601, 0x8e5eb301, 0x972f5981, 0x9b97acc1, 0x9dcbd661, 0x9ee5eb31, 0x9f72f599, + 0x9fb97acd, 0x9fdcbd67, 0x9fee5eb2, 0x4ff72f59, 0xf7fb97ad, 0xabfdcbd7, 0x85fee5ea, 0x42ff72f5, + 0xf17fb97b, 0xa8bfdcbc, 0x545fee5e, 0x2a2ff72f, 0xc517fb96, 0x628bfdcb, 0xe145fee4, 0x70a2ff72, + 0x38517fb9, 0xcc28bfdd, 0xb6145fef, 0x8b0a2ff6, 0x458517fb, 0xf2c28bfc, 0x796145fe, 0x3cb0a2ff, + 0xce58517e, 0x672c28bf, 0xe396145e, 0x71cb0a2f, 0xe8e58516, 0x7472c28b, 0xea396144, 0x751cb0a2, + 0x3a8e5851, 0xcd472c29, 0xb6a39615, 0x8b51cb0b, 0x95a8e584, 0x4ad472c2, 0x256a3961, 0xc2b51cb1, + 0xb15a8e59, 0x88ad472d, 0x9456a397, 0x9a2b51ca, 0x4d15a8e5, 0xf68ad473, 0xab456a38, 0x55a2b51c, + 0x2ad15a8e, 0x1568ad47, 0xdab456a2, 0x6d5a2b51, 0xe6ad15a9, 0xa3568ad5, 0x81ab456b, 0x90d5a2b4, + 0x486ad15a, 0x243568ad, 0xc21ab457, 0xb10d5a2a, 0x5886ad15, 0xfc43568b, 0xae21ab44, 0x5710d5a2, + 0x2b886ad1, 0xc5c43569, 0xb2e21ab5, 0x89710d5b, 0x94b886ac, 0x4a5c4356, 0x252e21ab, 0xc29710d4, + 0x614b886a, 0x30a5c435, 0xc852e21b, 0xb429710c, 0x5a14b886, 0x2d0a5c43, 0xc6852e20, 0x63429710, + 0x31a14b88, 0x18d0a5c4, 0x0c6852e2, 0x06342971, 0xd31a14b9, 0xb98d0a5d, 0x8cc6852f, 0x96634296, + 0x4b31a14b, 0xf598d0a4, 0x7acc6852, 0x3d663429, 0xceb31a15, 0xb7598d0b, 0x8bacc684, 0x45d66342, + 0x22eb31a1, 0xc17598d1, 0xb0bacc69, 0x885d6635, 0x942eb31b, 0x9a17598c, 0x4d0bacc6, 0x2685d663, + 0xc342eb30, 0x61a17598, 0x30d0bacc, 0x18685d66, 0x0c342eb3, 0xd61a1758, 0x6b0d0bac, 0x358685d6, + 0x1ac342eb, 0xdd61a174, 0x6eb0d0ba, 0x3758685d, 0xcbac342f, 0xb5d61a16, 0x5aeb0d0b, 0xfd758684, + 0x7ebac342, 0x3f5d61a1, 0xcfaeb0d1, 0xb7d75869, 0x8bebac35, 0x95f5d61b, 0x9afaeb0c, 0x4d7d7586, + 0x26bebac3, 0xc35f5d60, 0x61afaeb0, 0x30d7d758, 0x186bebac, 0x0c35f5d6, 0x061afaeb, 0xd30d7d74, + 0x6986beba, 0x34c35f5d, 0xca61afaf, 0xb530d7d6, 0x5a986beb, 0xfd4c35f4, 0x7ea61afa, 0x3f530d7d, + 0xcfa986bf, 0xb7d4c35e, 0x5bea61af, 0xfdf530d6, 0x7efa986b, 0xef7d4c34, 0x77bea61a, 0x3bdf530d, + 0xcdefa987, 0xb6f7d4c2, 0x5b7bea61, 0xfdbdf531, 0xaedefa99, 0x876f7d4d, 0x93b7bea7, 0x99dbdf52, + 0x4cedefa9, 0xf676f7d5, 0xab3b7beb, 0x859dbdf4, 0x42cedefa, 0x21676f7d, 0xc0b3b7bf, 0xb059dbde, + 0x582cedef, 0xfc1676f6, 0x7e0b3b7b, 0xef059dbc, 0x7782cede, 0x3bc1676f, 0xcde0b3b6, 0x66f059db, + 0xe3782cec, 0x71bc1676, 0x38de0b3b, 0xcc6f059c, 0x663782ce, 0x331bc167, 0xc98de0b2, 0x64c6f059, + 0xe263782d, 0xa131bc17, 0x8098de0a, 0x404c6f05, 0xf0263783, 0xa8131bc0, 0x54098de0, 0x2a04c6f0, + 0x15026378, 0x0a8131bc, 0x054098de, 0x02a04c6f, 0xd1502636, 0x68a8131b, 0xe454098c, 0x722a04c6, + 0x39150263, 0xcc8a8130, 0x66454098, 0x3322a04c, 0x19915026, 0x0cc8a813, 0xd6645408, 0x6b322a04, + 0x35991502, 0x1acc8a81, 0xdd664541, 0xbeb322a1, 0x8f599151, 0x97acc8a9, 0x9bd66455, 0x9deb322b, + 0x9ef59914, 0x4f7acc8a, 0x27bd6645, 0xc3deb323, 0xb1ef5990, 0x58f7acc8, 0x2c7bd664, 0x163deb32, + 0x0b1ef599, 0xd58f7acd, 0xbac7bd67, 0x8d63deb2, 0x46b1ef59, 0xf358f7ad, 0xa9ac7bd7, 0x84d63dea, + 0x426b1ef5, 0xf1358f7b, 0xa89ac7bc, 0x544d63de, 0x2a26b1ef, 0xc51358f6, 0x6289ac7b, 0xe144d63c, + 0x70a26b1e, 0x3851358f, 0xcc289ac6, 0x66144d63, 0xe30a26b0, 0x71851358, 0x38c289ac, 0x1c6144d6, + 0x0e30a26b, 0xd7185134, 0x6b8c289a, 0x35c6144d, 0xcae30a27, 0xb5718512, 0x5ab8c289, 0xfd5c6145, + 0xaeae30a3, 0x87571850, 0x43ab8c28, 0x21d5c614, 0x10eae30a, 0x08757185, 0xd43ab8c3, 0xba1d5c60, + 0x5d0eae30, 0x2e875718, 0x1743ab8c, 0x0ba1d5c6, 0x05d0eae3, 0xd2e87570, 0x69743ab8, 0x34ba1d5c, + 0x1a5d0eae, 0x0d2e8757, 0xd69743aa, 0x6b4ba1d5, 0xe5a5d0eb, 0xa2d2e874, 0x5169743a, 0x28b4ba1d, + 0xc45a5d0f, 0xb22d2e86, 0x59169743, 0xfc8b4ba0, 0x7e45a5d0, 0x3f22d2e8, 0x1f916974, 0x0fc8b4ba, + 0x07e45a5d, 0xd3f22d2f, 0xb9f91696, 0x5cfc8b4b, 0xfe7e45a4, 0x7f3f22d2, 0x3f9f9169, 0xcfcfc8b5, + 0xb7e7e45b, 0x8bf3f22c, 0x45f9f916, 0x22fcfc8b, 0xc17e7e44, 0x60bf3f22, 0x305f9f91, 0xc82fcfc9, + 0xb417e7e5, 0x8a0bf3f3, 0x9505f9f8, 0x4a82fcfc, 0x25417e7e, 0x12a0bf3f, 0xd9505f9e, 0x6ca82fcf, + 0xe65417e6, 0x732a0bf3, 0xe99505f8, 0x74ca82fc, 0x3a65417e, 0x1d32a0bf, 0xde99505e, 0x6f4ca82f, + 0xe7a65416, 0x73d32a0b, 0xe9e99504, 0x74f4ca82, 0x3a7a6541, 0xcd3d32a1, 0xb69e9951, 0x8b4f4ca9, + 0x95a7a655, 0x9ad3d32b, 0x9d69e994, 0x4eb4f4ca, 0x275a7a65, 0xc3ad3d33, 0xb1d69e98, 0x58eb4f4c, + 0x2c75a7a6, 0x163ad3d3, 0xdb1d69e8, 0x6d8eb4f4, 0x36c75a7a, 0x1b63ad3d, 0xddb1d69f, 0xbed8eb4e, + 0x5f6c75a7, 0xffb63ad2, 0x7fdb1d69, 0xefed8eb5, 0xa7f6c75b, 0x83fb63ac, 0x41fdb1d6, 0x20fed8eb, + 0xc07f6c74, 0x603fb63a, 0x301fdb1d, 0xc80fed8f, 0xb407f6c6, 0x5a03fb63, 0xfd01fdb0, 0x7e80fed8, + 0x3f407f6c, 0x1fa03fb6, 0x0fd01fdb, 0xd7e80fec, 0x6bf407f6, 0x35fa03fb, 0xcafd01fc, 0x657e80fe, + 0x32bf407f, 0xc95fa03e, 0x64afd01f, 0xe257e80e, 0x712bf407, 0xe895fa02, 0x744afd01, 0xea257e81, + 0xa512bf41, 0x82895fa1, 0x9144afd1, 0x98a257e9, 0x9c512bf5, 0x9e2895fb, 0x9f144afc, 0x4f8a257e, + 0x27c512bf, 0xc3e2895e, 0x61f144af, 0xe0f8a256, 0x707c512b, 0xe83e2894, 0x741f144a, 0x3a0f8a25, + 0xcd07c513, 0xb683e288, 0x5b41f144, 0x2da0f8a2, 0x16d07c51, 0xdb683e29, 0xbdb41f15, 0x8eda0f8b, + 0x976d07c4, 0x4bb683e2, 0x25db41f1, 0xc2eda0f9, 0xb176d07d, 0x88bb683f, 0x945db41e, 0x4a2eda0f, + 0xf5176d06, 0x7a8bb683, 0xed45db40, 0x76a2eda0, 0x3b5176d0, 0x1da8bb68, 0x0ed45db4, 0x076a2eda, + 0x03b5176d, 0xd1da8bb7, 0xb8ed45da, 0x5c76a2ed, 0xfe3b5177, 0xaf1da8ba, 0x578ed45d, 0xfbc76a2f, + 0xade3b516, 0x56f1da8b, 0xfb78ed44, 0x7dbc76a2, 0x3ede3b51, 0xcf6f1da9, 0xb7b78ed5, 0x8bdbc76b, + 0x95ede3b4, 0x4af6f1da, 0x257b78ed, 0xc2bdbc77, 0xb15ede3a, 0x58af6f1d, 0xfc57b78f, 0xae2bdbc6, + 0x5715ede3, 0xfb8af6f0, 0x7dc57b78, 0x3ee2bdbc, 0x1f715ede, 0x0fb8af6f, 0xd7dc57b6, 0x6bee2bdb, +}; + +void lane256_compress(const u8 m[64], u32 h[8], const u32 ctrh, const u32 ctrl) +{ + u32 t0, t1, t2, t3, t4, t5, t6, t7; /* temp */ + u32 s00, s01, s02, s03, s04, s05, s06, s07; /* lane 0 */ + u32 s10, s11, s12, s13, s14, s15, s16, s17; /* lane 1 */ + u32 s20, s21, s22, s23, s24, s25, s26, s27; /* lane 2 */ + u32 s30, s31, s32, s33, s34, s35, s36, s37; /* lane 3 */ + u32 s40, s41, s42, s43, s44, s45, s46, s47; /* lane 4 */ + u32 s50, s51, s52, s53, s54, s55, s56, s57; /* lane 5 */ + u32 s60, s61, s62, s63, s64, s65, s66, s67; /* lane 6 */ + u32 s70, s71, s72, s73, s74, s75, s76, s77; /* lane 7 */ + + /* Message expansion */ + s30 = h[0]; + s31 = h[1]; + s32 = h[2]; + s33 = h[3]; + s34 = h[4]; + s35 = h[5]; + s36 = h[6]; + s37 = h[7]; + s40 = U8TO32_BIG(m + 0); + s41 = U8TO32_BIG(m + 4); + s42 = U8TO32_BIG(m + 8); + s43 = U8TO32_BIG(m + 12); + s44 = U8TO32_BIG(m + 16); + s45 = U8TO32_BIG(m + 20); + s46 = U8TO32_BIG(m + 24); + s47 = U8TO32_BIG(m + 28); + s50 = U8TO32_BIG(m + 32); + s51 = U8TO32_BIG(m + 36); + s52 = U8TO32_BIG(m + 40); + s53 = U8TO32_BIG(m + 44); + s54 = U8TO32_BIG(m + 48); + s55 = U8TO32_BIG(m + 52); + s56 = U8TO32_BIG(m + 56); + s57 = U8TO32_BIG(m + 60); + s00 = s30 ^ s40 ^ s44 ^ s50 ^ s54; + s01 = s31 ^ s41 ^ s45 ^ s51 ^ s55; + s02 = s32 ^ s42 ^ s46 ^ s52 ^ s56; + s03 = s33 ^ s43 ^ s47 ^ s53 ^ s57; + s04 = s34 ^ s40 ^ s50; + s05 = s35 ^ s41 ^ s51; + s06 = s36 ^ s42 ^ s52; + s07 = s37 ^ s43 ^ s53; + s10 = s00 ^ s34 ^ s44; + s11 = s01 ^ s35 ^ s45; + s12 = s02 ^ s36 ^ s46; + s13 = s03 ^ s37 ^ s47; + s14 = s30 ^ s44 ^ s50; + s15 = s31 ^ s45 ^ s51; + s16 = s32 ^ s46 ^ s52; + s17 = s33 ^ s47 ^ s53; + s20 = s00 ^ s34 ^ s54; + s21 = s01 ^ s35 ^ s55; + s22 = s02 ^ s36 ^ s56; + s23 = s03 ^ s37 ^ s57; + s24 = s30 ^ s40 ^ s54; + s25 = s31 ^ s41 ^ s55; + s26 = s32 ^ s42 ^ s56; + s27 = s33 ^ s43 ^ s57; + + /* Lane 0 */ + t0 = T0[B3(s00)] ^ T1[B2(s01)] ^ T2[B1(s02)] ^ T3[B0(s03)] ^ C[ 0]; + t1 = T0[B3(s01)] ^ T1[B2(s02)] ^ T2[B1(s03)] ^ T3[B0(s00)] ^ C[ 1]; + t4 = T0[B3(s02)] ^ T1[B2(s03)] ^ T2[B1(s00)] ^ T3[B0(s01)] ^ C[ 2]; + t5 = T0[B3(s03)] ^ T1[B2(s00)] ^ T2[B1(s01)] ^ T3[B0(s02)] ^ C[ 3] ^ ctrh; + t2 = T0[B3(s04)] ^ T1[B2(s05)] ^ T2[B1(s06)] ^ T3[B0(s07)] ^ C[ 4]; + t3 = T0[B3(s05)] ^ T1[B2(s06)] ^ T2[B1(s07)] ^ T3[B0(s04)] ^ C[ 5]; + t6 = T0[B3(s06)] ^ T1[B2(s07)] ^ T2[B1(s04)] ^ T3[B0(s05)] ^ C[ 6]; + t7 = T0[B3(s07)] ^ T1[B2(s04)] ^ T2[B1(s05)] ^ T3[B0(s06)] ^ C[ 7]; + + s00 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 8]; + s01 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 9]; + s04 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[10]; + s05 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[11] ^ ctrl; + s02 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[12]; + s03 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[13]; + s06 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[14]; + s07 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[15]; + + t0 = T0[B3(s00)] ^ T1[B2(s01)] ^ T2[B1(s02)] ^ T3[B0(s03)] ^ C[16]; + t1 = T0[B3(s01)] ^ T1[B2(s02)] ^ T2[B1(s03)] ^ T3[B0(s00)] ^ C[17]; + t4 = T0[B3(s02)] ^ T1[B2(s03)] ^ T2[B1(s00)] ^ T3[B0(s01)] ^ C[18]; + t5 = T0[B3(s03)] ^ T1[B2(s00)] ^ T2[B1(s01)] ^ T3[B0(s02)] ^ C[19] ^ ctrh; + t2 = T0[B3(s04)] ^ T1[B2(s05)] ^ T2[B1(s06)] ^ T3[B0(s07)] ^ C[20]; + t3 = T0[B3(s05)] ^ T1[B2(s06)] ^ T2[B1(s07)] ^ T3[B0(s04)] ^ C[21]; + t6 = T0[B3(s06)] ^ T1[B2(s07)] ^ T2[B1(s04)] ^ T3[B0(s05)] ^ C[22]; + t7 = T0[B3(s07)] ^ T1[B2(s04)] ^ T2[B1(s05)] ^ T3[B0(s06)] ^ C[23]; + + s00 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[24]; + s01 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[25]; + s04 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[26]; + s05 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[27] ^ ctrl; + s02 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[28]; + s03 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[29]; + s06 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[30]; + s07 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[31]; + + t0 = T0[B3(s00)] ^ T1[B2(s01)] ^ T2[B1(s02)] ^ T3[B0(s03)] ^ C[32]; + t1 = T0[B3(s01)] ^ T1[B2(s02)] ^ T2[B1(s03)] ^ T3[B0(s00)] ^ C[33]; + t4 = T0[B3(s02)] ^ T1[B2(s03)] ^ T2[B1(s00)] ^ T3[B0(s01)] ^ C[34]; + t5 = T0[B3(s03)] ^ T1[B2(s00)] ^ T2[B1(s01)] ^ T3[B0(s02)] ^ C[35] ^ ctrh; + t2 = T0[B3(s04)] ^ T1[B2(s05)] ^ T2[B1(s06)] ^ T3[B0(s07)] ^ C[36]; + t3 = T0[B3(s05)] ^ T1[B2(s06)] ^ T2[B1(s07)] ^ T3[B0(s04)] ^ C[37]; + t6 = T0[B3(s06)] ^ T1[B2(s07)] ^ T2[B1(s04)] ^ T3[B0(s05)] ^ C[38]; + t7 = T0[B3(s07)] ^ T1[B2(s04)] ^ T2[B1(s05)] ^ T3[B0(s06)] ^ C[39]; + + s60 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + s61 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + s64 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + s65 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + s62 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + s63 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + s66 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + s67 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + + /* Lane 1 */ + t0 = T0[B3(s10)] ^ T1[B2(s11)] ^ T2[B1(s12)] ^ T3[B0(s13)] ^ C[ 0+40]; + t1 = T0[B3(s11)] ^ T1[B2(s12)] ^ T2[B1(s13)] ^ T3[B0(s10)] ^ C[ 1+40]; + t4 = T0[B3(s12)] ^ T1[B2(s13)] ^ T2[B1(s10)] ^ T3[B0(s11)] ^ C[ 2+40]; + t5 = T0[B3(s13)] ^ T1[B2(s10)] ^ T2[B1(s11)] ^ T3[B0(s12)] ^ C[ 3+40] ^ ctrl; + t2 = T0[B3(s14)] ^ T1[B2(s15)] ^ T2[B1(s16)] ^ T3[B0(s17)] ^ C[ 4+40]; + t3 = T0[B3(s15)] ^ T1[B2(s16)] ^ T2[B1(s17)] ^ T3[B0(s14)] ^ C[ 5+40]; + t6 = T0[B3(s16)] ^ T1[B2(s17)] ^ T2[B1(s14)] ^ T3[B0(s15)] ^ C[ 6+40]; + t7 = T0[B3(s17)] ^ T1[B2(s14)] ^ T2[B1(s15)] ^ T3[B0(s16)] ^ C[ 7+40]; + + s10 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 8+40]; + s11 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 9+40]; + s14 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[10+40]; + s15 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[11+40] ^ ctrh; + s12 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[12+40]; + s13 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[13+40]; + s16 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[14+40]; + s17 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[15+40]; + + t0 = T0[B3(s10)] ^ T1[B2(s11)] ^ T2[B1(s12)] ^ T3[B0(s13)] ^ C[16+40]; + t1 = T0[B3(s11)] ^ T1[B2(s12)] ^ T2[B1(s13)] ^ T3[B0(s10)] ^ C[17+40]; + t4 = T0[B3(s12)] ^ T1[B2(s13)] ^ T2[B1(s10)] ^ T3[B0(s11)] ^ C[18+40]; + t5 = T0[B3(s13)] ^ T1[B2(s10)] ^ T2[B1(s11)] ^ T3[B0(s12)] ^ C[19+40] ^ ctrl; + t2 = T0[B3(s14)] ^ T1[B2(s15)] ^ T2[B1(s16)] ^ T3[B0(s17)] ^ C[20+40]; + t3 = T0[B3(s15)] ^ T1[B2(s16)] ^ T2[B1(s17)] ^ T3[B0(s14)] ^ C[21+40]; + t6 = T0[B3(s16)] ^ T1[B2(s17)] ^ T2[B1(s14)] ^ T3[B0(s15)] ^ C[22+40]; + t7 = T0[B3(s17)] ^ T1[B2(s14)] ^ T2[B1(s15)] ^ T3[B0(s16)] ^ C[23+40]; + + s10 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[24+40]; + s11 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[25+40]; + s14 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[26+40]; + s15 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[27+40] ^ ctrh; + s12 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[28+40]; + s13 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[29+40]; + s16 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[30+40]; + s17 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[31+40]; + + t0 = T0[B3(s10)] ^ T1[B2(s11)] ^ T2[B1(s12)] ^ T3[B0(s13)] ^ C[32+40]; + t1 = T0[B3(s11)] ^ T1[B2(s12)] ^ T2[B1(s13)] ^ T3[B0(s10)] ^ C[33+40]; + t4 = T0[B3(s12)] ^ T1[B2(s13)] ^ T2[B1(s10)] ^ T3[B0(s11)] ^ C[34+40]; + t5 = T0[B3(s13)] ^ T1[B2(s10)] ^ T2[B1(s11)] ^ T3[B0(s12)] ^ C[35+40] ^ ctrl; + t2 = T0[B3(s14)] ^ T1[B2(s15)] ^ T2[B1(s16)] ^ T3[B0(s17)] ^ C[36+40]; + t3 = T0[B3(s15)] ^ T1[B2(s16)] ^ T2[B1(s17)] ^ T3[B0(s14)] ^ C[37+40]; + t6 = T0[B3(s16)] ^ T1[B2(s17)] ^ T2[B1(s14)] ^ T3[B0(s15)] ^ C[38+40]; + t7 = T0[B3(s17)] ^ T1[B2(s14)] ^ T2[B1(s15)] ^ T3[B0(s16)] ^ C[39+40]; + + s60 ^= T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + s61 ^= T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + s64 ^= T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + s65 ^= T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + s62 ^= T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + s63 ^= T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + s66 ^= T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + s67 ^= T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + + /* Lane 2 */ + t0 = T0[B3(s20)] ^ T1[B2(s21)] ^ T2[B1(s22)] ^ T3[B0(s23)] ^ C[ 0+80]; + t1 = T0[B3(s21)] ^ T1[B2(s22)] ^ T2[B1(s23)] ^ T3[B0(s20)] ^ C[ 1+80]; + t4 = T0[B3(s22)] ^ T1[B2(s23)] ^ T2[B1(s20)] ^ T3[B0(s21)] ^ C[ 2+80]; + t5 = T0[B3(s23)] ^ T1[B2(s20)] ^ T2[B1(s21)] ^ T3[B0(s22)] ^ C[ 3+80] ^ ctrh; + t2 = T0[B3(s24)] ^ T1[B2(s25)] ^ T2[B1(s26)] ^ T3[B0(s27)] ^ C[ 4+80]; + t3 = T0[B3(s25)] ^ T1[B2(s26)] ^ T2[B1(s27)] ^ T3[B0(s24)] ^ C[ 5+80]; + t6 = T0[B3(s26)] ^ T1[B2(s27)] ^ T2[B1(s24)] ^ T3[B0(s25)] ^ C[ 6+80]; + t7 = T0[B3(s27)] ^ T1[B2(s24)] ^ T2[B1(s25)] ^ T3[B0(s26)] ^ C[ 7+80]; + + s20 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 8+80]; + s21 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 9+80]; + s24 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[10+80]; + s25 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[11+80] ^ ctrl; + s22 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[12+80]; + s23 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[13+80]; + s26 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[14+80]; + s27 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[15+80]; + + t0 = T0[B3(s20)] ^ T1[B2(s21)] ^ T2[B1(s22)] ^ T3[B0(s23)] ^ C[16+80]; + t1 = T0[B3(s21)] ^ T1[B2(s22)] ^ T2[B1(s23)] ^ T3[B0(s20)] ^ C[17+80]; + t4 = T0[B3(s22)] ^ T1[B2(s23)] ^ T2[B1(s20)] ^ T3[B0(s21)] ^ C[18+80]; + t5 = T0[B3(s23)] ^ T1[B2(s20)] ^ T2[B1(s21)] ^ T3[B0(s22)] ^ C[19+80] ^ ctrh; + t2 = T0[B3(s24)] ^ T1[B2(s25)] ^ T2[B1(s26)] ^ T3[B0(s27)] ^ C[20+80]; + t3 = T0[B3(s25)] ^ T1[B2(s26)] ^ T2[B1(s27)] ^ T3[B0(s24)] ^ C[21+80]; + t6 = T0[B3(s26)] ^ T1[B2(s27)] ^ T2[B1(s24)] ^ T3[B0(s25)] ^ C[22+80]; + t7 = T0[B3(s27)] ^ T1[B2(s24)] ^ T2[B1(s25)] ^ T3[B0(s26)] ^ C[23+80]; + + s20 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[24+80]; + s21 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[25+80]; + s24 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[26+80]; + s25 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[27+80] ^ ctrl; + s22 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[28+80]; + s23 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[29+80]; + s26 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[30+80]; + s27 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[31+80]; + + t0 = T0[B3(s20)] ^ T1[B2(s21)] ^ T2[B1(s22)] ^ T3[B0(s23)] ^ C[32+80]; + t1 = T0[B3(s21)] ^ T1[B2(s22)] ^ T2[B1(s23)] ^ T3[B0(s20)] ^ C[33+80]; + t4 = T0[B3(s22)] ^ T1[B2(s23)] ^ T2[B1(s20)] ^ T3[B0(s21)] ^ C[34+80]; + t5 = T0[B3(s23)] ^ T1[B2(s20)] ^ T2[B1(s21)] ^ T3[B0(s22)] ^ C[35+80] ^ ctrh; + t2 = T0[B3(s24)] ^ T1[B2(s25)] ^ T2[B1(s26)] ^ T3[B0(s27)] ^ C[36+80]; + t3 = T0[B3(s25)] ^ T1[B2(s26)] ^ T2[B1(s27)] ^ T3[B0(s24)] ^ C[37+80]; + t6 = T0[B3(s26)] ^ T1[B2(s27)] ^ T2[B1(s24)] ^ T3[B0(s25)] ^ C[38+80]; + t7 = T0[B3(s27)] ^ T1[B2(s24)] ^ T2[B1(s25)] ^ T3[B0(s26)] ^ C[39+80]; + + s60 ^= T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + s61 ^= T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + s64 ^= T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + s65 ^= T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + s62 ^= T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + s63 ^= T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + s66 ^= T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + s67 ^= T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + + /* Lane 3 */ + t0 = T0[B3(s30)] ^ T1[B2(s31)] ^ T2[B1(s32)] ^ T3[B0(s33)] ^ C[ 0+120]; + t1 = T0[B3(s31)] ^ T1[B2(s32)] ^ T2[B1(s33)] ^ T3[B0(s30)] ^ C[ 1+120]; + t4 = T0[B3(s32)] ^ T1[B2(s33)] ^ T2[B1(s30)] ^ T3[B0(s31)] ^ C[ 2+120]; + t5 = T0[B3(s33)] ^ T1[B2(s30)] ^ T2[B1(s31)] ^ T3[B0(s32)] ^ C[ 3+120] ^ ctrl; + t2 = T0[B3(s34)] ^ T1[B2(s35)] ^ T2[B1(s36)] ^ T3[B0(s37)] ^ C[ 4+120]; + t3 = T0[B3(s35)] ^ T1[B2(s36)] ^ T2[B1(s37)] ^ T3[B0(s34)] ^ C[ 5+120]; + t6 = T0[B3(s36)] ^ T1[B2(s37)] ^ T2[B1(s34)] ^ T3[B0(s35)] ^ C[ 6+120]; + t7 = T0[B3(s37)] ^ T1[B2(s34)] ^ T2[B1(s35)] ^ T3[B0(s36)] ^ C[ 7+120]; + + s30 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 8+120]; + s31 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 9+120]; + s34 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[10+120]; + s35 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[11+120] ^ ctrh; + s32 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[12+120]; + s33 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[13+120]; + s36 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[14+120]; + s37 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[15+120]; + + t0 = T0[B3(s30)] ^ T1[B2(s31)] ^ T2[B1(s32)] ^ T3[B0(s33)] ^ C[16+120]; + t1 = T0[B3(s31)] ^ T1[B2(s32)] ^ T2[B1(s33)] ^ T3[B0(s30)] ^ C[17+120]; + t4 = T0[B3(s32)] ^ T1[B2(s33)] ^ T2[B1(s30)] ^ T3[B0(s31)] ^ C[18+120]; + t5 = T0[B3(s33)] ^ T1[B2(s30)] ^ T2[B1(s31)] ^ T3[B0(s32)] ^ C[19+120] ^ ctrl; + t2 = T0[B3(s34)] ^ T1[B2(s35)] ^ T2[B1(s36)] ^ T3[B0(s37)] ^ C[20+120]; + t3 = T0[B3(s35)] ^ T1[B2(s36)] ^ T2[B1(s37)] ^ T3[B0(s34)] ^ C[21+120]; + t6 = T0[B3(s36)] ^ T1[B2(s37)] ^ T2[B1(s34)] ^ T3[B0(s35)] ^ C[22+120]; + t7 = T0[B3(s37)] ^ T1[B2(s34)] ^ T2[B1(s35)] ^ T3[B0(s36)] ^ C[23+120]; + + s30 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[24+120]; + s31 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[25+120]; + s34 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[26+120]; + s35 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[27+120] ^ ctrh; + s32 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[28+120]; + s33 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[29+120]; + s36 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[30+120]; + s37 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[31+120]; + + t0 = T0[B3(s30)] ^ T1[B2(s31)] ^ T2[B1(s32)] ^ T3[B0(s33)] ^ C[32+120]; + t1 = T0[B3(s31)] ^ T1[B2(s32)] ^ T2[B1(s33)] ^ T3[B0(s30)] ^ C[33+120]; + t4 = T0[B3(s32)] ^ T1[B2(s33)] ^ T2[B1(s30)] ^ T3[B0(s31)] ^ C[34+120]; + t5 = T0[B3(s33)] ^ T1[B2(s30)] ^ T2[B1(s31)] ^ T3[B0(s32)] ^ C[35+120] ^ ctrl; + t2 = T0[B3(s34)] ^ T1[B2(s35)] ^ T2[B1(s36)] ^ T3[B0(s37)] ^ C[36+120]; + t3 = T0[B3(s35)] ^ T1[B2(s36)] ^ T2[B1(s37)] ^ T3[B0(s34)] ^ C[37+120]; + t6 = T0[B3(s36)] ^ T1[B2(s37)] ^ T2[B1(s34)] ^ T3[B0(s35)] ^ C[38+120]; + t7 = T0[B3(s37)] ^ T1[B2(s34)] ^ T2[B1(s35)] ^ T3[B0(s36)] ^ C[39+120]; + + s70 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + s71 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + s74 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + s75 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + s72 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + s73 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + s76 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + s77 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + + /* Lane 4 */ + t0 = T0[B3(s40)] ^ T1[B2(s41)] ^ T2[B1(s42)] ^ T3[B0(s43)] ^ C[ 0+160]; + t1 = T0[B3(s41)] ^ T1[B2(s42)] ^ T2[B1(s43)] ^ T3[B0(s40)] ^ C[ 1+160]; + t4 = T0[B3(s42)] ^ T1[B2(s43)] ^ T2[B1(s40)] ^ T3[B0(s41)] ^ C[ 2+160]; + t5 = T0[B3(s43)] ^ T1[B2(s40)] ^ T2[B1(s41)] ^ T3[B0(s42)] ^ C[ 3+160] ^ ctrh; + t2 = T0[B3(s44)] ^ T1[B2(s45)] ^ T2[B1(s46)] ^ T3[B0(s47)] ^ C[ 4+160]; + t3 = T0[B3(s45)] ^ T1[B2(s46)] ^ T2[B1(s47)] ^ T3[B0(s44)] ^ C[ 5+160]; + t6 = T0[B3(s46)] ^ T1[B2(s47)] ^ T2[B1(s44)] ^ T3[B0(s45)] ^ C[ 6+160]; + t7 = T0[B3(s47)] ^ T1[B2(s44)] ^ T2[B1(s45)] ^ T3[B0(s46)] ^ C[ 7+160]; + + s40 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 8+160]; + s41 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 9+160]; + s44 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[10+160]; + s45 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[11+160] ^ ctrl; + s42 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[12+160]; + s43 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[13+160]; + s46 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[14+160]; + s47 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[15+160]; + + t0 = T0[B3(s40)] ^ T1[B2(s41)] ^ T2[B1(s42)] ^ T3[B0(s43)] ^ C[16+160]; + t1 = T0[B3(s41)] ^ T1[B2(s42)] ^ T2[B1(s43)] ^ T3[B0(s40)] ^ C[17+160]; + t4 = T0[B3(s42)] ^ T1[B2(s43)] ^ T2[B1(s40)] ^ T3[B0(s41)] ^ C[18+160]; + t5 = T0[B3(s43)] ^ T1[B2(s40)] ^ T2[B1(s41)] ^ T3[B0(s42)] ^ C[19+160] ^ ctrh; + t2 = T0[B3(s44)] ^ T1[B2(s45)] ^ T2[B1(s46)] ^ T3[B0(s47)] ^ C[20+160]; + t3 = T0[B3(s45)] ^ T1[B2(s46)] ^ T2[B1(s47)] ^ T3[B0(s44)] ^ C[21+160]; + t6 = T0[B3(s46)] ^ T1[B2(s47)] ^ T2[B1(s44)] ^ T3[B0(s45)] ^ C[22+160]; + t7 = T0[B3(s47)] ^ T1[B2(s44)] ^ T2[B1(s45)] ^ T3[B0(s46)] ^ C[23+160]; + + s40 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[24+160]; + s41 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[25+160]; + s44 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[26+160]; + s45 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[27+160] ^ ctrl; + s42 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[28+160]; + s43 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[29+160]; + s46 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[30+160]; + s47 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[31+160]; + + t0 = T0[B3(s40)] ^ T1[B2(s41)] ^ T2[B1(s42)] ^ T3[B0(s43)] ^ C[32+160]; + t1 = T0[B3(s41)] ^ T1[B2(s42)] ^ T2[B1(s43)] ^ T3[B0(s40)] ^ C[33+160]; + t4 = T0[B3(s42)] ^ T1[B2(s43)] ^ T2[B1(s40)] ^ T3[B0(s41)] ^ C[34+160]; + t5 = T0[B3(s43)] ^ T1[B2(s40)] ^ T2[B1(s41)] ^ T3[B0(s42)] ^ C[35+160] ^ ctrh; + t2 = T0[B3(s44)] ^ T1[B2(s45)] ^ T2[B1(s46)] ^ T3[B0(s47)] ^ C[36+160]; + t3 = T0[B3(s45)] ^ T1[B2(s46)] ^ T2[B1(s47)] ^ T3[B0(s44)] ^ C[37+160]; + t6 = T0[B3(s46)] ^ T1[B2(s47)] ^ T2[B1(s44)] ^ T3[B0(s45)] ^ C[38+160]; + t7 = T0[B3(s47)] ^ T1[B2(s44)] ^ T2[B1(s45)] ^ T3[B0(s46)] ^ C[39+160]; + + s70 ^= T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + s71 ^= T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + s74 ^= T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + s75 ^= T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + s72 ^= T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + s73 ^= T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + s76 ^= T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + s77 ^= T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + + /* Lane 5 */ + t0 = T0[B3(s50)] ^ T1[B2(s51)] ^ T2[B1(s52)] ^ T3[B0(s53)] ^ C[ 0+200]; + t1 = T0[B3(s51)] ^ T1[B2(s52)] ^ T2[B1(s53)] ^ T3[B0(s50)] ^ C[ 1+200]; + t4 = T0[B3(s52)] ^ T1[B2(s53)] ^ T2[B1(s50)] ^ T3[B0(s51)] ^ C[ 2+200]; + t5 = T0[B3(s53)] ^ T1[B2(s50)] ^ T2[B1(s51)] ^ T3[B0(s52)] ^ C[ 3+200] ^ ctrl; + t2 = T0[B3(s54)] ^ T1[B2(s55)] ^ T2[B1(s56)] ^ T3[B0(s57)] ^ C[ 4+200]; + t3 = T0[B3(s55)] ^ T1[B2(s56)] ^ T2[B1(s57)] ^ T3[B0(s54)] ^ C[ 5+200]; + t6 = T0[B3(s56)] ^ T1[B2(s57)] ^ T2[B1(s54)] ^ T3[B0(s55)] ^ C[ 6+200]; + t7 = T0[B3(s57)] ^ T1[B2(s54)] ^ T2[B1(s55)] ^ T3[B0(s56)] ^ C[ 7+200]; + + s50 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 8+200]; + s51 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 9+200]; + s54 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[10+200]; + s55 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[11+200] ^ ctrh; + s52 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[12+200]; + s53 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[13+200]; + s56 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[14+200]; + s57 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[15+200]; + + t0 = T0[B3(s50)] ^ T1[B2(s51)] ^ T2[B1(s52)] ^ T3[B0(s53)] ^ C[16+200]; + t1 = T0[B3(s51)] ^ T1[B2(s52)] ^ T2[B1(s53)] ^ T3[B0(s50)] ^ C[17+200]; + t4 = T0[B3(s52)] ^ T1[B2(s53)] ^ T2[B1(s50)] ^ T3[B0(s51)] ^ C[18+200]; + t5 = T0[B3(s53)] ^ T1[B2(s50)] ^ T2[B1(s51)] ^ T3[B0(s52)] ^ C[19+200] ^ ctrl; + t2 = T0[B3(s54)] ^ T1[B2(s55)] ^ T2[B1(s56)] ^ T3[B0(s57)] ^ C[20+200]; + t3 = T0[B3(s55)] ^ T1[B2(s56)] ^ T2[B1(s57)] ^ T3[B0(s54)] ^ C[21+200]; + t6 = T0[B3(s56)] ^ T1[B2(s57)] ^ T2[B1(s54)] ^ T3[B0(s55)] ^ C[22+200]; + t7 = T0[B3(s57)] ^ T1[B2(s54)] ^ T2[B1(s55)] ^ T3[B0(s56)] ^ C[23+200]; + + s50 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[24+200]; + s51 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[25+200]; + s54 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[26+200]; + s55 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[27+200] ^ ctrh; + s52 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[28+200]; + s53 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[29+200]; + s56 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[30+200]; + s57 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[31+200]; + + t0 = T0[B3(s50)] ^ T1[B2(s51)] ^ T2[B1(s52)] ^ T3[B0(s53)] ^ C[32+200]; + t1 = T0[B3(s51)] ^ T1[B2(s52)] ^ T2[B1(s53)] ^ T3[B0(s50)] ^ C[33+200]; + t4 = T0[B3(s52)] ^ T1[B2(s53)] ^ T2[B1(s50)] ^ T3[B0(s51)] ^ C[34+200]; + t5 = T0[B3(s53)] ^ T1[B2(s50)] ^ T2[B1(s51)] ^ T3[B0(s52)] ^ C[35+200] ^ ctrl; + t2 = T0[B3(s54)] ^ T1[B2(s55)] ^ T2[B1(s56)] ^ T3[B0(s57)] ^ C[36+200]; + t3 = T0[B3(s55)] ^ T1[B2(s56)] ^ T2[B1(s57)] ^ T3[B0(s54)] ^ C[37+200]; + t6 = T0[B3(s56)] ^ T1[B2(s57)] ^ T2[B1(s54)] ^ T3[B0(s55)] ^ C[38+200]; + t7 = T0[B3(s57)] ^ T1[B2(s54)] ^ T2[B1(s55)] ^ T3[B0(s56)] ^ C[39+200]; + + s70 ^= T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + s71 ^= T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + s74 ^= T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + s75 ^= T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + s72 ^= T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + s73 ^= T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + s76 ^= T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + s77 ^= T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + + /* Lane 6 */ + t0 = T0[B3(s60)] ^ T1[B2(s61)] ^ T2[B1(s62)] ^ T3[B0(s63)] ^ C[ 0+240]; + t1 = T0[B3(s61)] ^ T1[B2(s62)] ^ T2[B1(s63)] ^ T3[B0(s60)] ^ C[ 1+240]; + t4 = T0[B3(s62)] ^ T1[B2(s63)] ^ T2[B1(s60)] ^ T3[B0(s61)] ^ C[ 2+240]; + t5 = T0[B3(s63)] ^ T1[B2(s60)] ^ T2[B1(s61)] ^ T3[B0(s62)] ^ C[ 3+240] ^ ctrh; + t2 = T0[B3(s64)] ^ T1[B2(s65)] ^ T2[B1(s66)] ^ T3[B0(s67)] ^ C[ 4+240]; + t3 = T0[B3(s65)] ^ T1[B2(s66)] ^ T2[B1(s67)] ^ T3[B0(s64)] ^ C[ 5+240]; + t6 = T0[B3(s66)] ^ T1[B2(s67)] ^ T2[B1(s64)] ^ T3[B0(s65)] ^ C[ 6+240]; + t7 = T0[B3(s67)] ^ T1[B2(s64)] ^ T2[B1(s65)] ^ T3[B0(s66)] ^ C[ 7+240]; + + s60 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 8+240]; + s61 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 9+240]; + s64 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[10+240]; + s65 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[11+240] ^ ctrl; + s62 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[12+240]; + s63 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[13+240]; + s66 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[14+240]; + s67 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[15+240]; + + h[0] = T0[B3(s60)] ^ T1[B2(s61)] ^ T2[B1(s62)] ^ T3[B0(s63)]; + h[1] = T0[B3(s61)] ^ T1[B2(s62)] ^ T2[B1(s63)] ^ T3[B0(s60)]; + h[4] = T0[B3(s62)] ^ T1[B2(s63)] ^ T2[B1(s60)] ^ T3[B0(s61)]; + h[5] = T0[B3(s63)] ^ T1[B2(s60)] ^ T2[B1(s61)] ^ T3[B0(s62)]; + h[2] = T0[B3(s64)] ^ T1[B2(s65)] ^ T2[B1(s66)] ^ T3[B0(s67)]; + h[3] = T0[B3(s65)] ^ T1[B2(s66)] ^ T2[B1(s67)] ^ T3[B0(s64)]; + h[6] = T0[B3(s66)] ^ T1[B2(s67)] ^ T2[B1(s64)] ^ T3[B0(s65)]; + h[7] = T0[B3(s67)] ^ T1[B2(s64)] ^ T2[B1(s65)] ^ T3[B0(s66)]; + + /* Lane 7 */ + t0 = T0[B3(s70)] ^ T1[B2(s71)] ^ T2[B1(s72)] ^ T3[B0(s73)] ^ C[ 0+256]; + t1 = T0[B3(s71)] ^ T1[B2(s72)] ^ T2[B1(s73)] ^ T3[B0(s70)] ^ C[ 1+256]; + t4 = T0[B3(s72)] ^ T1[B2(s73)] ^ T2[B1(s70)] ^ T3[B0(s71)] ^ C[ 2+256]; + t5 = T0[B3(s73)] ^ T1[B2(s70)] ^ T2[B1(s71)] ^ T3[B0(s72)] ^ C[ 3+256] ^ ctrh; + t2 = T0[B3(s74)] ^ T1[B2(s75)] ^ T2[B1(s76)] ^ T3[B0(s77)] ^ C[ 4+256]; + t3 = T0[B3(s75)] ^ T1[B2(s76)] ^ T2[B1(s77)] ^ T3[B0(s74)] ^ C[ 5+256]; + t6 = T0[B3(s76)] ^ T1[B2(s77)] ^ T2[B1(s74)] ^ T3[B0(s75)] ^ C[ 6+256]; + t7 = T0[B3(s77)] ^ T1[B2(s74)] ^ T2[B1(s75)] ^ T3[B0(s76)] ^ C[ 7+256]; + + s70 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 8+256]; + s71 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 9+256]; + s74 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[10+256]; + s75 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[11+256] ^ ctrl; + s72 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[12+256]; + s73 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[13+256]; + s76 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[14+256]; + s77 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[15+256]; + + h[0] ^= T0[B3(s70)] ^ T1[B2(s71)] ^ T2[B1(s72)] ^ T3[B0(s73)]; + h[1] ^= T0[B3(s71)] ^ T1[B2(s72)] ^ T2[B1(s73)] ^ T3[B0(s70)]; + h[4] ^= T0[B3(s72)] ^ T1[B2(s73)] ^ T2[B1(s70)] ^ T3[B0(s71)]; + h[5] ^= T0[B3(s73)] ^ T1[B2(s70)] ^ T2[B1(s71)] ^ T3[B0(s72)]; + h[2] ^= T0[B3(s74)] ^ T1[B2(s75)] ^ T2[B1(s76)] ^ T3[B0(s77)]; + h[3] ^= T0[B3(s75)] ^ T1[B2(s76)] ^ T2[B1(s77)] ^ T3[B0(s74)]; + h[6] ^= T0[B3(s76)] ^ T1[B2(s77)] ^ T2[B1(s74)] ^ T3[B0(s75)]; + h[7] ^= T0[B3(s77)] ^ T1[B2(s74)] ^ T2[B1(s75)] ^ T3[B0(s76)]; +} + +void lane512_compress(const u8 m[128], u32 h[16], const u32 ctrh, const u32 ctrl) +{ + u32 t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, ta, tb, tc, td, te, tf; /* temp */ + u32 s00, s01, s02, s03, s04, s05, s06, s07, s08, s09, s0a, s0b, s0c, s0d, s0e, s0f; /* lane 0 */ + u32 s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s1a, s1b, s1c, s1d, s1e, s1f; /* lane 1 */ + u32 s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s2a, s2b, s2c, s2d, s2e, s2f; /* lane 2 */ + u32 s30, s31, s32, s33, s34, s35, s36, s37, s38, s39, s3a, s3b, s3c, s3d, s3e, s3f; /* lane 3 */ + u32 s40, s41, s42, s43, s44, s45, s46, s47, s48, s49, s4a, s4b, s4c, s4d, s4e, s4f; /* lane 4 */ + u32 s50, s51, s52, s53, s54, s55, s56, s57, s58, s59, s5a, s5b, s5c, s5d, s5e, s5f; /* lane 5 */ + u32 s60, s61, s62, s63, s64, s65, s66, s67, s68, s69, s6a, s6b, s6c, s6d, s6e, s6f; /* lane 6 */ + u32 s70, s71, s72, s73, s74, s75, s76, s77, s78, s79, s7a, s7b, s7c, s7d, s7e, s7f; /* lane 7 */ + + /* Message expansion */ + s30 = h[0]; + s31 = h[1]; + s32 = h[2]; + s33 = h[3]; + s34 = h[4]; + s35 = h[5]; + s36 = h[6]; + s37 = h[7]; + s38 = h[8]; + s39 = h[9]; + s3a = h[10]; + s3b = h[11]; + s3c = h[12]; + s3d = h[13]; + s3e = h[14]; + s3f = h[15]; + s40 = U8TO32_BIG(m + 0); + s41 = U8TO32_BIG(m + 4); + s42 = U8TO32_BIG(m + 8); + s43 = U8TO32_BIG(m + 12); + s44 = U8TO32_BIG(m + 16); + s45 = U8TO32_BIG(m + 20); + s46 = U8TO32_BIG(m + 24); + s47 = U8TO32_BIG(m + 28); + s48 = U8TO32_BIG(m + 32); + s49 = U8TO32_BIG(m + 36); + s4a = U8TO32_BIG(m + 40); + s4b = U8TO32_BIG(m + 44); + s4c = U8TO32_BIG(m + 48); + s4d = U8TO32_BIG(m + 52); + s4e = U8TO32_BIG(m + 56); + s4f = U8TO32_BIG(m + 60); + s50 = U8TO32_BIG(m + 64); + s51 = U8TO32_BIG(m + 68); + s52 = U8TO32_BIG(m + 72); + s53 = U8TO32_BIG(m + 76); + s54 = U8TO32_BIG(m + 80); + s55 = U8TO32_BIG(m + 84); + s56 = U8TO32_BIG(m + 88); + s57 = U8TO32_BIG(m + 92); + s58 = U8TO32_BIG(m + 96); + s59 = U8TO32_BIG(m + 100); + s5a = U8TO32_BIG(m + 104); + s5b = U8TO32_BIG(m + 108); + s5c = U8TO32_BIG(m + 112); + s5d = U8TO32_BIG(m + 116); + s5e = U8TO32_BIG(m + 120); + s5f = U8TO32_BIG(m + 124); + s00 = s30 ^ s40 ^ s48 ^ s50 ^ s58; + s01 = s31 ^ s41 ^ s49 ^ s51 ^ s59; + s02 = s32 ^ s42 ^ s4a ^ s52 ^ s5a; + s03 = s33 ^ s43 ^ s4b ^ s53 ^ s5b; + s04 = s34 ^ s44 ^ s4c ^ s54 ^ s5c; + s05 = s35 ^ s45 ^ s4d ^ s55 ^ s5d; + s06 = s36 ^ s46 ^ s4e ^ s56 ^ s5e; + s07 = s37 ^ s47 ^ s4f ^ s57 ^ s5f; + s08 = s38 ^ s40 ^ s50; + s09 = s39 ^ s41 ^ s51; + s0a = s3a ^ s42 ^ s52; + s0b = s3b ^ s43 ^ s53; + s0c = s3c ^ s44 ^ s54; + s0d = s3d ^ s45 ^ s55; + s0e = s3e ^ s46 ^ s56; + s0f = s3f ^ s47 ^ s57; + s10 = s00 ^ s38 ^ s48; + s11 = s01 ^ s39 ^ s49; + s12 = s02 ^ s3a ^ s4a; + s13 = s03 ^ s3b ^ s4b; + s14 = s04 ^ s3c ^ s4c; + s15 = s05 ^ s3d ^ s4d; + s16 = s06 ^ s3e ^ s4e; + s17 = s07 ^ s3f ^ s4f; + s18 = s30 ^ s48 ^ s50; + s19 = s31 ^ s49 ^ s51; + s1a = s32 ^ s4a ^ s52; + s1b = s33 ^ s4b ^ s53; + s1c = s34 ^ s4c ^ s54; + s1d = s35 ^ s4d ^ s55; + s1e = s36 ^ s4e ^ s56; + s1f = s37 ^ s4f ^ s57; + s20 = s00 ^ s38 ^ s58; + s21 = s01 ^ s39 ^ s59; + s22 = s02 ^ s3a ^ s5a; + s23 = s03 ^ s3b ^ s5b; + s24 = s04 ^ s3c ^ s5c; + s25 = s05 ^ s3d ^ s5d; + s26 = s06 ^ s3e ^ s5e; + s27 = s07 ^ s3f ^ s5f; + s28 = s30 ^ s40 ^ s58; + s29 = s31 ^ s41 ^ s59; + s2a = s32 ^ s42 ^ s5a; + s2b = s33 ^ s43 ^ s5b; + s2c = s34 ^ s44 ^ s5c; + s2d = s35 ^ s45 ^ s5d; + s2e = s36 ^ s46 ^ s5e; + s2f = s37 ^ s47 ^ s5f; + + /* Lane 0 */ + t0 = T0[B3(s00)] ^ T1[B2(s01)] ^ T2[B1(s02)] ^ T3[B0(s03)] ^ C[ 0]; + t4 = T0[B3(s01)] ^ T1[B2(s02)] ^ T2[B1(s03)] ^ T3[B0(s00)] ^ C[ 1]; + t8 = T0[B3(s02)] ^ T1[B2(s03)] ^ T2[B1(s00)] ^ T3[B0(s01)] ^ C[ 2]; + tc = T0[B3(s03)] ^ T1[B2(s00)] ^ T2[B1(s01)] ^ T3[B0(s02)] ^ C[ 3] ^ ctrh; + t1 = T0[B3(s04)] ^ T1[B2(s05)] ^ T2[B1(s06)] ^ T3[B0(s07)] ^ C[ 4]; + t5 = T0[B3(s05)] ^ T1[B2(s06)] ^ T2[B1(s07)] ^ T3[B0(s04)] ^ C[ 5]; + t9 = T0[B3(s06)] ^ T1[B2(s07)] ^ T2[B1(s04)] ^ T3[B0(s05)] ^ C[ 6]; + td = T0[B3(s07)] ^ T1[B2(s04)] ^ T2[B1(s05)] ^ T3[B0(s06)] ^ C[ 7]; + t2 = T0[B3(s08)] ^ T1[B2(s09)] ^ T2[B1(s0a)] ^ T3[B0(s0b)] ^ C[ 8]; + t6 = T0[B3(s09)] ^ T1[B2(s0a)] ^ T2[B1(s0b)] ^ T3[B0(s08)] ^ C[ 9]; + ta = T0[B3(s0a)] ^ T1[B2(s0b)] ^ T2[B1(s08)] ^ T3[B0(s09)] ^ C[ 10]; + te = T0[B3(s0b)] ^ T1[B2(s08)] ^ T2[B1(s09)] ^ T3[B0(s0a)] ^ C[ 11]; + t3 = T0[B3(s0c)] ^ T1[B2(s0d)] ^ T2[B1(s0e)] ^ T3[B0(s0f)] ^ C[ 12]; + t7 = T0[B3(s0d)] ^ T1[B2(s0e)] ^ T2[B1(s0f)] ^ T3[B0(s0c)] ^ C[ 13]; + tb = T0[B3(s0e)] ^ T1[B2(s0f)] ^ T2[B1(s0c)] ^ T3[B0(s0d)] ^ C[ 14]; + tf = T0[B3(s0f)] ^ T1[B2(s0c)] ^ T2[B1(s0d)] ^ T3[B0(s0e)] ^ C[ 15]; + + s00 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 16]; + s04 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 17]; + s08 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 18]; + s0c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 19] ^ ctrl; + s01 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 20]; + s05 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 21]; + s09 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 22]; + s0d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 23]; + s02 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 24]; + s06 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 25]; + s0a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 26]; + s0e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 27]; + s03 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 28]; + s07 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 29]; + s0b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 30]; + s0f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 31]; + + t0 = T0[B3(s00)] ^ T1[B2(s01)] ^ T2[B1(s02)] ^ T3[B0(s03)] ^ C[ 32]; + t4 = T0[B3(s01)] ^ T1[B2(s02)] ^ T2[B1(s03)] ^ T3[B0(s00)] ^ C[ 33]; + t8 = T0[B3(s02)] ^ T1[B2(s03)] ^ T2[B1(s00)] ^ T3[B0(s01)] ^ C[ 34]; + tc = T0[B3(s03)] ^ T1[B2(s00)] ^ T2[B1(s01)] ^ T3[B0(s02)] ^ C[ 35] ^ ctrh; + t1 = T0[B3(s04)] ^ T1[B2(s05)] ^ T2[B1(s06)] ^ T3[B0(s07)] ^ C[ 36]; + t5 = T0[B3(s05)] ^ T1[B2(s06)] ^ T2[B1(s07)] ^ T3[B0(s04)] ^ C[ 37]; + t9 = T0[B3(s06)] ^ T1[B2(s07)] ^ T2[B1(s04)] ^ T3[B0(s05)] ^ C[ 38]; + td = T0[B3(s07)] ^ T1[B2(s04)] ^ T2[B1(s05)] ^ T3[B0(s06)] ^ C[ 39]; + t2 = T0[B3(s08)] ^ T1[B2(s09)] ^ T2[B1(s0a)] ^ T3[B0(s0b)] ^ C[ 40]; + t6 = T0[B3(s09)] ^ T1[B2(s0a)] ^ T2[B1(s0b)] ^ T3[B0(s08)] ^ C[ 41]; + ta = T0[B3(s0a)] ^ T1[B2(s0b)] ^ T2[B1(s08)] ^ T3[B0(s09)] ^ C[ 42]; + te = T0[B3(s0b)] ^ T1[B2(s08)] ^ T2[B1(s09)] ^ T3[B0(s0a)] ^ C[ 43]; + t3 = T0[B3(s0c)] ^ T1[B2(s0d)] ^ T2[B1(s0e)] ^ T3[B0(s0f)] ^ C[ 44]; + t7 = T0[B3(s0d)] ^ T1[B2(s0e)] ^ T2[B1(s0f)] ^ T3[B0(s0c)] ^ C[ 45]; + tb = T0[B3(s0e)] ^ T1[B2(s0f)] ^ T2[B1(s0c)] ^ T3[B0(s0d)] ^ C[ 46]; + tf = T0[B3(s0f)] ^ T1[B2(s0c)] ^ T2[B1(s0d)] ^ T3[B0(s0e)] ^ C[ 47]; + + s00 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 48]; + s04 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 49]; + s08 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 50]; + s0c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 51] ^ ctrl; + s01 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 52]; + s05 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 53]; + s09 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 54]; + s0d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 55]; + s02 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 56]; + s06 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 57]; + s0a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 58]; + s0e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 59]; + s03 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 60]; + s07 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 61]; + s0b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 62]; + s0f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 63]; + + t0 = T0[B3(s00)] ^ T1[B2(s01)] ^ T2[B1(s02)] ^ T3[B0(s03)] ^ C[ 64]; + t4 = T0[B3(s01)] ^ T1[B2(s02)] ^ T2[B1(s03)] ^ T3[B0(s00)] ^ C[ 65]; + t8 = T0[B3(s02)] ^ T1[B2(s03)] ^ T2[B1(s00)] ^ T3[B0(s01)] ^ C[ 66]; + tc = T0[B3(s03)] ^ T1[B2(s00)] ^ T2[B1(s01)] ^ T3[B0(s02)] ^ C[ 67] ^ ctrh; + t1 = T0[B3(s04)] ^ T1[B2(s05)] ^ T2[B1(s06)] ^ T3[B0(s07)] ^ C[ 68]; + t5 = T0[B3(s05)] ^ T1[B2(s06)] ^ T2[B1(s07)] ^ T3[B0(s04)] ^ C[ 69]; + t9 = T0[B3(s06)] ^ T1[B2(s07)] ^ T2[B1(s04)] ^ T3[B0(s05)] ^ C[ 70]; + td = T0[B3(s07)] ^ T1[B2(s04)] ^ T2[B1(s05)] ^ T3[B0(s06)] ^ C[ 71]; + t2 = T0[B3(s08)] ^ T1[B2(s09)] ^ T2[B1(s0a)] ^ T3[B0(s0b)] ^ C[ 72]; + t6 = T0[B3(s09)] ^ T1[B2(s0a)] ^ T2[B1(s0b)] ^ T3[B0(s08)] ^ C[ 73]; + ta = T0[B3(s0a)] ^ T1[B2(s0b)] ^ T2[B1(s08)] ^ T3[B0(s09)] ^ C[ 74]; + te = T0[B3(s0b)] ^ T1[B2(s08)] ^ T2[B1(s09)] ^ T3[B0(s0a)] ^ C[ 75]; + t3 = T0[B3(s0c)] ^ T1[B2(s0d)] ^ T2[B1(s0e)] ^ T3[B0(s0f)] ^ C[ 76]; + t7 = T0[B3(s0d)] ^ T1[B2(s0e)] ^ T2[B1(s0f)] ^ T3[B0(s0c)] ^ C[ 77]; + tb = T0[B3(s0e)] ^ T1[B2(s0f)] ^ T2[B1(s0c)] ^ T3[B0(s0d)] ^ C[ 78]; + tf = T0[B3(s0f)] ^ T1[B2(s0c)] ^ T2[B1(s0d)] ^ T3[B0(s0e)] ^ C[ 79]; + + s00 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 80]; + s04 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 81]; + s08 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 82]; + s0c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 83] ^ ctrl; + s01 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 84]; + s05 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 85]; + s09 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 86]; + s0d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 87]; + s02 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 88]; + s06 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 89]; + s0a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 90]; + s0e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 91]; + s03 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 92]; + s07 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 93]; + s0b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 94]; + s0f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 95]; + + t0 = T0[B3(s00)] ^ T1[B2(s01)] ^ T2[B1(s02)] ^ T3[B0(s03)] ^ C[ 96]; + t4 = T0[B3(s01)] ^ T1[B2(s02)] ^ T2[B1(s03)] ^ T3[B0(s00)] ^ C[ 97]; + t8 = T0[B3(s02)] ^ T1[B2(s03)] ^ T2[B1(s00)] ^ T3[B0(s01)] ^ C[ 98]; + tc = T0[B3(s03)] ^ T1[B2(s00)] ^ T2[B1(s01)] ^ T3[B0(s02)] ^ C[ 99] ^ ctrh; + t1 = T0[B3(s04)] ^ T1[B2(s05)] ^ T2[B1(s06)] ^ T3[B0(s07)] ^ C[100]; + t5 = T0[B3(s05)] ^ T1[B2(s06)] ^ T2[B1(s07)] ^ T3[B0(s04)] ^ C[101]; + t9 = T0[B3(s06)] ^ T1[B2(s07)] ^ T2[B1(s04)] ^ T3[B0(s05)] ^ C[102]; + td = T0[B3(s07)] ^ T1[B2(s04)] ^ T2[B1(s05)] ^ T3[B0(s06)] ^ C[103]; + t2 = T0[B3(s08)] ^ T1[B2(s09)] ^ T2[B1(s0a)] ^ T3[B0(s0b)] ^ C[104]; + t6 = T0[B3(s09)] ^ T1[B2(s0a)] ^ T2[B1(s0b)] ^ T3[B0(s08)] ^ C[105]; + ta = T0[B3(s0a)] ^ T1[B2(s0b)] ^ T2[B1(s08)] ^ T3[B0(s09)] ^ C[106]; + te = T0[B3(s0b)] ^ T1[B2(s08)] ^ T2[B1(s09)] ^ T3[B0(s0a)] ^ C[107]; + t3 = T0[B3(s0c)] ^ T1[B2(s0d)] ^ T2[B1(s0e)] ^ T3[B0(s0f)] ^ C[108]; + t7 = T0[B3(s0d)] ^ T1[B2(s0e)] ^ T2[B1(s0f)] ^ T3[B0(s0c)] ^ C[109]; + tb = T0[B3(s0e)] ^ T1[B2(s0f)] ^ T2[B1(s0c)] ^ T3[B0(s0d)] ^ C[110]; + tf = T0[B3(s0f)] ^ T1[B2(s0c)] ^ T2[B1(s0d)] ^ T3[B0(s0e)] ^ C[111]; + + s60 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + s64 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + s68 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + s6c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + s61 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + s65 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + s69 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + s6d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + s62 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )]; + s66 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )]; + s6a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )]; + s6e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )]; + s63 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )]; + s67 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )]; + s6b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )]; + s6f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )]; + + /* Lane 1 */ + t0 = T0[B3(s10)] ^ T1[B2(s11)] ^ T2[B1(s12)] ^ T3[B0(s13)] ^ C[ 0+112]; + t4 = T0[B3(s11)] ^ T1[B2(s12)] ^ T2[B1(s13)] ^ T3[B0(s10)] ^ C[ 1+112]; + t8 = T0[B3(s12)] ^ T1[B2(s13)] ^ T2[B1(s10)] ^ T3[B0(s11)] ^ C[ 2+112]; + tc = T0[B3(s13)] ^ T1[B2(s10)] ^ T2[B1(s11)] ^ T3[B0(s12)] ^ C[ 3+112] ^ ctrl; + t1 = T0[B3(s14)] ^ T1[B2(s15)] ^ T2[B1(s16)] ^ T3[B0(s17)] ^ C[ 4+112]; + t5 = T0[B3(s15)] ^ T1[B2(s16)] ^ T2[B1(s17)] ^ T3[B0(s14)] ^ C[ 5+112]; + t9 = T0[B3(s16)] ^ T1[B2(s17)] ^ T2[B1(s14)] ^ T3[B0(s15)] ^ C[ 6+112]; + td = T0[B3(s17)] ^ T1[B2(s14)] ^ T2[B1(s15)] ^ T3[B0(s16)] ^ C[ 7+112]; + t2 = T0[B3(s18)] ^ T1[B2(s19)] ^ T2[B1(s1a)] ^ T3[B0(s1b)] ^ C[ 8+112]; + t6 = T0[B3(s19)] ^ T1[B2(s1a)] ^ T2[B1(s1b)] ^ T3[B0(s18)] ^ C[ 9+112]; + ta = T0[B3(s1a)] ^ T1[B2(s1b)] ^ T2[B1(s18)] ^ T3[B0(s19)] ^ C[ 10+112]; + te = T0[B3(s1b)] ^ T1[B2(s18)] ^ T2[B1(s19)] ^ T3[B0(s1a)] ^ C[ 11+112]; + t3 = T0[B3(s1c)] ^ T1[B2(s1d)] ^ T2[B1(s1e)] ^ T3[B0(s1f)] ^ C[ 12+112]; + t7 = T0[B3(s1d)] ^ T1[B2(s1e)] ^ T2[B1(s1f)] ^ T3[B0(s1c)] ^ C[ 13+112]; + tb = T0[B3(s1e)] ^ T1[B2(s1f)] ^ T2[B1(s1c)] ^ T3[B0(s1d)] ^ C[ 14+112]; + tf = T0[B3(s1f)] ^ T1[B2(s1c)] ^ T2[B1(s1d)] ^ T3[B0(s1e)] ^ C[ 15+112]; + + s10 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 16+112]; + s14 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 17+112]; + s18 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 18+112]; + s1c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 19+112] ^ ctrh; + s11 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 20+112]; + s15 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 21+112]; + s19 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 22+112]; + s1d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 23+112]; + s12 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 24+112]; + s16 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 25+112]; + s1a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 26+112]; + s1e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 27+112]; + s13 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 28+112]; + s17 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 29+112]; + s1b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 30+112]; + s1f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 31+112]; + + t0 = T0[B3(s10)] ^ T1[B2(s11)] ^ T2[B1(s12)] ^ T3[B0(s13)] ^ C[ 32+112]; + t4 = T0[B3(s11)] ^ T1[B2(s12)] ^ T2[B1(s13)] ^ T3[B0(s10)] ^ C[ 33+112]; + t8 = T0[B3(s12)] ^ T1[B2(s13)] ^ T2[B1(s10)] ^ T3[B0(s11)] ^ C[ 34+112]; + tc = T0[B3(s13)] ^ T1[B2(s10)] ^ T2[B1(s11)] ^ T3[B0(s12)] ^ C[ 35+112] ^ ctrl; + t1 = T0[B3(s14)] ^ T1[B2(s15)] ^ T2[B1(s16)] ^ T3[B0(s17)] ^ C[ 36+112]; + t5 = T0[B3(s15)] ^ T1[B2(s16)] ^ T2[B1(s17)] ^ T3[B0(s14)] ^ C[ 37+112]; + t9 = T0[B3(s16)] ^ T1[B2(s17)] ^ T2[B1(s14)] ^ T3[B0(s15)] ^ C[ 38+112]; + td = T0[B3(s17)] ^ T1[B2(s14)] ^ T2[B1(s15)] ^ T3[B0(s16)] ^ C[ 39+112]; + t2 = T0[B3(s18)] ^ T1[B2(s19)] ^ T2[B1(s1a)] ^ T3[B0(s1b)] ^ C[ 40+112]; + t6 = T0[B3(s19)] ^ T1[B2(s1a)] ^ T2[B1(s1b)] ^ T3[B0(s18)] ^ C[ 41+112]; + ta = T0[B3(s1a)] ^ T1[B2(s1b)] ^ T2[B1(s18)] ^ T3[B0(s19)] ^ C[ 42+112]; + te = T0[B3(s1b)] ^ T1[B2(s18)] ^ T2[B1(s19)] ^ T3[B0(s1a)] ^ C[ 43+112]; + t3 = T0[B3(s1c)] ^ T1[B2(s1d)] ^ T2[B1(s1e)] ^ T3[B0(s1f)] ^ C[ 44+112]; + t7 = T0[B3(s1d)] ^ T1[B2(s1e)] ^ T2[B1(s1f)] ^ T3[B0(s1c)] ^ C[ 45+112]; + tb = T0[B3(s1e)] ^ T1[B2(s1f)] ^ T2[B1(s1c)] ^ T3[B0(s1d)] ^ C[ 46+112]; + tf = T0[B3(s1f)] ^ T1[B2(s1c)] ^ T2[B1(s1d)] ^ T3[B0(s1e)] ^ C[ 47+112]; + + s10 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 48+112]; + s14 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 49+112]; + s18 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 50+112]; + s1c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 51+112] ^ ctrh; + s11 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 52+112]; + s15 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 53+112]; + s19 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 54+112]; + s1d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 55+112]; + s12 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 56+112]; + s16 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 57+112]; + s1a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 58+112]; + s1e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 59+112]; + s13 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 60+112]; + s17 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 61+112]; + s1b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 62+112]; + s1f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 63+112]; + + t0 = T0[B3(s10)] ^ T1[B2(s11)] ^ T2[B1(s12)] ^ T3[B0(s13)] ^ C[ 64+112]; + t4 = T0[B3(s11)] ^ T1[B2(s12)] ^ T2[B1(s13)] ^ T3[B0(s10)] ^ C[ 65+112]; + t8 = T0[B3(s12)] ^ T1[B2(s13)] ^ T2[B1(s10)] ^ T3[B0(s11)] ^ C[ 66+112]; + tc = T0[B3(s13)] ^ T1[B2(s10)] ^ T2[B1(s11)] ^ T3[B0(s12)] ^ C[ 67+112] ^ ctrl; + t1 = T0[B3(s14)] ^ T1[B2(s15)] ^ T2[B1(s16)] ^ T3[B0(s17)] ^ C[ 68+112]; + t5 = T0[B3(s15)] ^ T1[B2(s16)] ^ T2[B1(s17)] ^ T3[B0(s14)] ^ C[ 69+112]; + t9 = T0[B3(s16)] ^ T1[B2(s17)] ^ T2[B1(s14)] ^ T3[B0(s15)] ^ C[ 70+112]; + td = T0[B3(s17)] ^ T1[B2(s14)] ^ T2[B1(s15)] ^ T3[B0(s16)] ^ C[ 71+112]; + t2 = T0[B3(s18)] ^ T1[B2(s19)] ^ T2[B1(s1a)] ^ T3[B0(s1b)] ^ C[ 72+112]; + t6 = T0[B3(s19)] ^ T1[B2(s1a)] ^ T2[B1(s1b)] ^ T3[B0(s18)] ^ C[ 73+112]; + ta = T0[B3(s1a)] ^ T1[B2(s1b)] ^ T2[B1(s18)] ^ T3[B0(s19)] ^ C[ 74+112]; + te = T0[B3(s1b)] ^ T1[B2(s18)] ^ T2[B1(s19)] ^ T3[B0(s1a)] ^ C[ 75+112]; + t3 = T0[B3(s1c)] ^ T1[B2(s1d)] ^ T2[B1(s1e)] ^ T3[B0(s1f)] ^ C[ 76+112]; + t7 = T0[B3(s1d)] ^ T1[B2(s1e)] ^ T2[B1(s1f)] ^ T3[B0(s1c)] ^ C[ 77+112]; + tb = T0[B3(s1e)] ^ T1[B2(s1f)] ^ T2[B1(s1c)] ^ T3[B0(s1d)] ^ C[ 78+112]; + tf = T0[B3(s1f)] ^ T1[B2(s1c)] ^ T2[B1(s1d)] ^ T3[B0(s1e)] ^ C[ 79+112]; + + s10 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 80+112]; + s14 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 81+112]; + s18 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 82+112]; + s1c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 83+112] ^ ctrh; + s11 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 84+112]; + s15 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 85+112]; + s19 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 86+112]; + s1d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 87+112]; + s12 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 88+112]; + s16 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 89+112]; + s1a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 90+112]; + s1e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 91+112]; + s13 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 92+112]; + s17 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 93+112]; + s1b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 94+112]; + s1f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 95+112]; + + t0 = T0[B3(s10)] ^ T1[B2(s11)] ^ T2[B1(s12)] ^ T3[B0(s13)] ^ C[ 96+112]; + t4 = T0[B3(s11)] ^ T1[B2(s12)] ^ T2[B1(s13)] ^ T3[B0(s10)] ^ C[ 97+112]; + t8 = T0[B3(s12)] ^ T1[B2(s13)] ^ T2[B1(s10)] ^ T3[B0(s11)] ^ C[ 98+112]; + tc = T0[B3(s13)] ^ T1[B2(s10)] ^ T2[B1(s11)] ^ T3[B0(s12)] ^ C[ 99+112] ^ ctrl; + t1 = T0[B3(s14)] ^ T1[B2(s15)] ^ T2[B1(s16)] ^ T3[B0(s17)] ^ C[100+112]; + t5 = T0[B3(s15)] ^ T1[B2(s16)] ^ T2[B1(s17)] ^ T3[B0(s14)] ^ C[101+112]; + t9 = T0[B3(s16)] ^ T1[B2(s17)] ^ T2[B1(s14)] ^ T3[B0(s15)] ^ C[102+112]; + td = T0[B3(s17)] ^ T1[B2(s14)] ^ T2[B1(s15)] ^ T3[B0(s16)] ^ C[103+112]; + t2 = T0[B3(s18)] ^ T1[B2(s19)] ^ T2[B1(s1a)] ^ T3[B0(s1b)] ^ C[104+112]; + t6 = T0[B3(s19)] ^ T1[B2(s1a)] ^ T2[B1(s1b)] ^ T3[B0(s18)] ^ C[105+112]; + ta = T0[B3(s1a)] ^ T1[B2(s1b)] ^ T2[B1(s18)] ^ T3[B0(s19)] ^ C[106+112]; + te = T0[B3(s1b)] ^ T1[B2(s18)] ^ T2[B1(s19)] ^ T3[B0(s1a)] ^ C[107+112]; + t3 = T0[B3(s1c)] ^ T1[B2(s1d)] ^ T2[B1(s1e)] ^ T3[B0(s1f)] ^ C[108+112]; + t7 = T0[B3(s1d)] ^ T1[B2(s1e)] ^ T2[B1(s1f)] ^ T3[B0(s1c)] ^ C[109+112]; + tb = T0[B3(s1e)] ^ T1[B2(s1f)] ^ T2[B1(s1c)] ^ T3[B0(s1d)] ^ C[110+112]; + tf = T0[B3(s1f)] ^ T1[B2(s1c)] ^ T2[B1(s1d)] ^ T3[B0(s1e)] ^ C[111+112]; + + s60 ^= T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + s64 ^= T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + s68 ^= T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + s6c ^= T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + s61 ^= T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + s65 ^= T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + s69 ^= T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + s6d ^= T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + s62 ^= T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )]; + s66 ^= T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )]; + s6a ^= T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )]; + s6e ^= T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )]; + s63 ^= T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )]; + s67 ^= T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )]; + s6b ^= T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )]; + s6f ^= T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )]; + + /* Lane 2 */ + t0 = T0[B3(s20)] ^ T1[B2(s21)] ^ T2[B1(s22)] ^ T3[B0(s23)] ^ C[ 0+224]; + t4 = T0[B3(s21)] ^ T1[B2(s22)] ^ T2[B1(s23)] ^ T3[B0(s20)] ^ C[ 1+224]; + t8 = T0[B3(s22)] ^ T1[B2(s23)] ^ T2[B1(s20)] ^ T3[B0(s21)] ^ C[ 2+224]; + tc = T0[B3(s23)] ^ T1[B2(s20)] ^ T2[B1(s21)] ^ T3[B0(s22)] ^ C[ 3+224] ^ ctrh; + t1 = T0[B3(s24)] ^ T1[B2(s25)] ^ T2[B1(s26)] ^ T3[B0(s27)] ^ C[ 4+224]; + t5 = T0[B3(s25)] ^ T1[B2(s26)] ^ T2[B1(s27)] ^ T3[B0(s24)] ^ C[ 5+224]; + t9 = T0[B3(s26)] ^ T1[B2(s27)] ^ T2[B1(s24)] ^ T3[B0(s25)] ^ C[ 6+224]; + td = T0[B3(s27)] ^ T1[B2(s24)] ^ T2[B1(s25)] ^ T3[B0(s26)] ^ C[ 7+224]; + t2 = T0[B3(s28)] ^ T1[B2(s29)] ^ T2[B1(s2a)] ^ T3[B0(s2b)] ^ C[ 8+224]; + t6 = T0[B3(s29)] ^ T1[B2(s2a)] ^ T2[B1(s2b)] ^ T3[B0(s28)] ^ C[ 9+224]; + ta = T0[B3(s2a)] ^ T1[B2(s2b)] ^ T2[B1(s28)] ^ T3[B0(s29)] ^ C[ 10+224]; + te = T0[B3(s2b)] ^ T1[B2(s28)] ^ T2[B1(s29)] ^ T3[B0(s2a)] ^ C[ 11+224]; + t3 = T0[B3(s2c)] ^ T1[B2(s2d)] ^ T2[B1(s2e)] ^ T3[B0(s2f)] ^ C[ 12+224]; + t7 = T0[B3(s2d)] ^ T1[B2(s2e)] ^ T2[B1(s2f)] ^ T3[B0(s2c)] ^ C[ 13+224]; + tb = T0[B3(s2e)] ^ T1[B2(s2f)] ^ T2[B1(s2c)] ^ T3[B0(s2d)] ^ C[ 14+224]; + tf = T0[B3(s2f)] ^ T1[B2(s2c)] ^ T2[B1(s2d)] ^ T3[B0(s2e)] ^ C[ 15+224]; + + s20 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 16+224]; + s24 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 17+224]; + s28 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 18+224]; + s2c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 19+224] ^ ctrl; + s21 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 20+224]; + s25 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 21+224]; + s29 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 22+224]; + s2d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 23+224]; + s22 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 24+224]; + s26 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 25+224]; + s2a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 26+224]; + s2e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 27+224]; + s23 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 28+224]; + s27 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 29+224]; + s2b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 30+224]; + s2f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 31+224]; + + t0 = T0[B3(s20)] ^ T1[B2(s21)] ^ T2[B1(s22)] ^ T3[B0(s23)] ^ C[ 32+224]; + t4 = T0[B3(s21)] ^ T1[B2(s22)] ^ T2[B1(s23)] ^ T3[B0(s20)] ^ C[ 33+224]; + t8 = T0[B3(s22)] ^ T1[B2(s23)] ^ T2[B1(s20)] ^ T3[B0(s21)] ^ C[ 34+224]; + tc = T0[B3(s23)] ^ T1[B2(s20)] ^ T2[B1(s21)] ^ T3[B0(s22)] ^ C[ 35+224] ^ ctrh; + t1 = T0[B3(s24)] ^ T1[B2(s25)] ^ T2[B1(s26)] ^ T3[B0(s27)] ^ C[ 36+224]; + t5 = T0[B3(s25)] ^ T1[B2(s26)] ^ T2[B1(s27)] ^ T3[B0(s24)] ^ C[ 37+224]; + t9 = T0[B3(s26)] ^ T1[B2(s27)] ^ T2[B1(s24)] ^ T3[B0(s25)] ^ C[ 38+224]; + td = T0[B3(s27)] ^ T1[B2(s24)] ^ T2[B1(s25)] ^ T3[B0(s26)] ^ C[ 39+224]; + t2 = T0[B3(s28)] ^ T1[B2(s29)] ^ T2[B1(s2a)] ^ T3[B0(s2b)] ^ C[ 40+224]; + t6 = T0[B3(s29)] ^ T1[B2(s2a)] ^ T2[B1(s2b)] ^ T3[B0(s28)] ^ C[ 41+224]; + ta = T0[B3(s2a)] ^ T1[B2(s2b)] ^ T2[B1(s28)] ^ T3[B0(s29)] ^ C[ 42+224]; + te = T0[B3(s2b)] ^ T1[B2(s28)] ^ T2[B1(s29)] ^ T3[B0(s2a)] ^ C[ 43+224]; + t3 = T0[B3(s2c)] ^ T1[B2(s2d)] ^ T2[B1(s2e)] ^ T3[B0(s2f)] ^ C[ 44+224]; + t7 = T0[B3(s2d)] ^ T1[B2(s2e)] ^ T2[B1(s2f)] ^ T3[B0(s2c)] ^ C[ 45+224]; + tb = T0[B3(s2e)] ^ T1[B2(s2f)] ^ T2[B1(s2c)] ^ T3[B0(s2d)] ^ C[ 46+224]; + tf = T0[B3(s2f)] ^ T1[B2(s2c)] ^ T2[B1(s2d)] ^ T3[B0(s2e)] ^ C[ 47+224]; + + s20 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 48+224]; + s24 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 49+224]; + s28 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 50+224]; + s2c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 51+224] ^ ctrl; + s21 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 52+224]; + s25 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 53+224]; + s29 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 54+224]; + s2d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 55+224]; + s22 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 56+224]; + s26 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 57+224]; + s2a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 58+224]; + s2e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 59+224]; + s23 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 60+224]; + s27 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 61+224]; + s2b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 62+224]; + s2f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 63+224]; + + t0 = T0[B3(s20)] ^ T1[B2(s21)] ^ T2[B1(s22)] ^ T3[B0(s23)] ^ C[ 64+224]; + t4 = T0[B3(s21)] ^ T1[B2(s22)] ^ T2[B1(s23)] ^ T3[B0(s20)] ^ C[ 65+224]; + t8 = T0[B3(s22)] ^ T1[B2(s23)] ^ T2[B1(s20)] ^ T3[B0(s21)] ^ C[ 66+224]; + tc = T0[B3(s23)] ^ T1[B2(s20)] ^ T2[B1(s21)] ^ T3[B0(s22)] ^ C[ 67+224] ^ ctrh; + t1 = T0[B3(s24)] ^ T1[B2(s25)] ^ T2[B1(s26)] ^ T3[B0(s27)] ^ C[ 68+224]; + t5 = T0[B3(s25)] ^ T1[B2(s26)] ^ T2[B1(s27)] ^ T3[B0(s24)] ^ C[ 69+224]; + t9 = T0[B3(s26)] ^ T1[B2(s27)] ^ T2[B1(s24)] ^ T3[B0(s25)] ^ C[ 70+224]; + td = T0[B3(s27)] ^ T1[B2(s24)] ^ T2[B1(s25)] ^ T3[B0(s26)] ^ C[ 71+224]; + t2 = T0[B3(s28)] ^ T1[B2(s29)] ^ T2[B1(s2a)] ^ T3[B0(s2b)] ^ C[ 72+224]; + t6 = T0[B3(s29)] ^ T1[B2(s2a)] ^ T2[B1(s2b)] ^ T3[B0(s28)] ^ C[ 73+224]; + ta = T0[B3(s2a)] ^ T1[B2(s2b)] ^ T2[B1(s28)] ^ T3[B0(s29)] ^ C[ 74+224]; + te = T0[B3(s2b)] ^ T1[B2(s28)] ^ T2[B1(s29)] ^ T3[B0(s2a)] ^ C[ 75+224]; + t3 = T0[B3(s2c)] ^ T1[B2(s2d)] ^ T2[B1(s2e)] ^ T3[B0(s2f)] ^ C[ 76+224]; + t7 = T0[B3(s2d)] ^ T1[B2(s2e)] ^ T2[B1(s2f)] ^ T3[B0(s2c)] ^ C[ 77+224]; + tb = T0[B3(s2e)] ^ T1[B2(s2f)] ^ T2[B1(s2c)] ^ T3[B0(s2d)] ^ C[ 78+224]; + tf = T0[B3(s2f)] ^ T1[B2(s2c)] ^ T2[B1(s2d)] ^ T3[B0(s2e)] ^ C[ 79+224]; + + s20 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 80+224]; + s24 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 81+224]; + s28 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 82+224]; + s2c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 83+224] ^ ctrl; + s21 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 84+224]; + s25 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 85+224]; + s29 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 86+224]; + s2d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 87+224]; + s22 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 88+224]; + s26 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 89+224]; + s2a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 90+224]; + s2e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 91+224]; + s23 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 92+224]; + s27 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 93+224]; + s2b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 94+224]; + s2f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 95+224]; + + t0 = T0[B3(s20)] ^ T1[B2(s21)] ^ T2[B1(s22)] ^ T3[B0(s23)] ^ C[ 96+224]; + t4 = T0[B3(s21)] ^ T1[B2(s22)] ^ T2[B1(s23)] ^ T3[B0(s20)] ^ C[ 97+224]; + t8 = T0[B3(s22)] ^ T1[B2(s23)] ^ T2[B1(s20)] ^ T3[B0(s21)] ^ C[ 98+224]; + tc = T0[B3(s23)] ^ T1[B2(s20)] ^ T2[B1(s21)] ^ T3[B0(s22)] ^ C[ 99+224] ^ ctrh; + t1 = T0[B3(s24)] ^ T1[B2(s25)] ^ T2[B1(s26)] ^ T3[B0(s27)] ^ C[100+224]; + t5 = T0[B3(s25)] ^ T1[B2(s26)] ^ T2[B1(s27)] ^ T3[B0(s24)] ^ C[101+224]; + t9 = T0[B3(s26)] ^ T1[B2(s27)] ^ T2[B1(s24)] ^ T3[B0(s25)] ^ C[102+224]; + td = T0[B3(s27)] ^ T1[B2(s24)] ^ T2[B1(s25)] ^ T3[B0(s26)] ^ C[103+224]; + t2 = T0[B3(s28)] ^ T1[B2(s29)] ^ T2[B1(s2a)] ^ T3[B0(s2b)] ^ C[104+224]; + t6 = T0[B3(s29)] ^ T1[B2(s2a)] ^ T2[B1(s2b)] ^ T3[B0(s28)] ^ C[105+224]; + ta = T0[B3(s2a)] ^ T1[B2(s2b)] ^ T2[B1(s28)] ^ T3[B0(s29)] ^ C[106+224]; + te = T0[B3(s2b)] ^ T1[B2(s28)] ^ T2[B1(s29)] ^ T3[B0(s2a)] ^ C[107+224]; + t3 = T0[B3(s2c)] ^ T1[B2(s2d)] ^ T2[B1(s2e)] ^ T3[B0(s2f)] ^ C[108+224]; + t7 = T0[B3(s2d)] ^ T1[B2(s2e)] ^ T2[B1(s2f)] ^ T3[B0(s2c)] ^ C[109+224]; + tb = T0[B3(s2e)] ^ T1[B2(s2f)] ^ T2[B1(s2c)] ^ T3[B0(s2d)] ^ C[110+224]; + tf = T0[B3(s2f)] ^ T1[B2(s2c)] ^ T2[B1(s2d)] ^ T3[B0(s2e)] ^ C[111+224]; + + s60 ^= T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + s64 ^= T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + s68 ^= T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + s6c ^= T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + s61 ^= T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + s65 ^= T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + s69 ^= T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + s6d ^= T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + s62 ^= T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )]; + s66 ^= T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )]; + s6a ^= T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )]; + s6e ^= T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )]; + s63 ^= T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )]; + s67 ^= T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )]; + s6b ^= T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )]; + s6f ^= T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )]; + + /* Lane 3 */ + t0 = T0[B3(s30)] ^ T1[B2(s31)] ^ T2[B1(s32)] ^ T3[B0(s33)] ^ C[ 0+336]; + t4 = T0[B3(s31)] ^ T1[B2(s32)] ^ T2[B1(s33)] ^ T3[B0(s30)] ^ C[ 1+336]; + t8 = T0[B3(s32)] ^ T1[B2(s33)] ^ T2[B1(s30)] ^ T3[B0(s31)] ^ C[ 2+336]; + tc = T0[B3(s33)] ^ T1[B2(s30)] ^ T2[B1(s31)] ^ T3[B0(s32)] ^ C[ 3+336] ^ ctrl; + t1 = T0[B3(s34)] ^ T1[B2(s35)] ^ T2[B1(s36)] ^ T3[B0(s37)] ^ C[ 4+336]; + t5 = T0[B3(s35)] ^ T1[B2(s36)] ^ T2[B1(s37)] ^ T3[B0(s34)] ^ C[ 5+336]; + t9 = T0[B3(s36)] ^ T1[B2(s37)] ^ T2[B1(s34)] ^ T3[B0(s35)] ^ C[ 6+336]; + td = T0[B3(s37)] ^ T1[B2(s34)] ^ T2[B1(s35)] ^ T3[B0(s36)] ^ C[ 7+336]; + t2 = T0[B3(s38)] ^ T1[B2(s39)] ^ T2[B1(s3a)] ^ T3[B0(s3b)] ^ C[ 8+336]; + t6 = T0[B3(s39)] ^ T1[B2(s3a)] ^ T2[B1(s3b)] ^ T3[B0(s38)] ^ C[ 9+336]; + ta = T0[B3(s3a)] ^ T1[B2(s3b)] ^ T2[B1(s38)] ^ T3[B0(s39)] ^ C[ 10+336]; + te = T0[B3(s3b)] ^ T1[B2(s38)] ^ T2[B1(s39)] ^ T3[B0(s3a)] ^ C[ 11+336]; + t3 = T0[B3(s3c)] ^ T1[B2(s3d)] ^ T2[B1(s3e)] ^ T3[B0(s3f)] ^ C[ 12+336]; + t7 = T0[B3(s3d)] ^ T1[B2(s3e)] ^ T2[B1(s3f)] ^ T3[B0(s3c)] ^ C[ 13+336]; + tb = T0[B3(s3e)] ^ T1[B2(s3f)] ^ T2[B1(s3c)] ^ T3[B0(s3d)] ^ C[ 14+336]; + tf = T0[B3(s3f)] ^ T1[B2(s3c)] ^ T2[B1(s3d)] ^ T3[B0(s3e)] ^ C[ 15+336]; + + s30 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 16+336]; + s34 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 17+336]; + s38 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 18+336]; + s3c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 19+336] ^ ctrh; + s31 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 20+336]; + s35 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 21+336]; + s39 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 22+336]; + s3d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 23+336]; + s32 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 24+336]; + s36 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 25+336]; + s3a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 26+336]; + s3e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 27+336]; + s33 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 28+336]; + s37 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 29+336]; + s3b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 30+336]; + s3f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 31+336]; + + t0 = T0[B3(s30)] ^ T1[B2(s31)] ^ T2[B1(s32)] ^ T3[B0(s33)] ^ C[ 32+336]; + t4 = T0[B3(s31)] ^ T1[B2(s32)] ^ T2[B1(s33)] ^ T3[B0(s30)] ^ C[ 33+336]; + t8 = T0[B3(s32)] ^ T1[B2(s33)] ^ T2[B1(s30)] ^ T3[B0(s31)] ^ C[ 34+336]; + tc = T0[B3(s33)] ^ T1[B2(s30)] ^ T2[B1(s31)] ^ T3[B0(s32)] ^ C[ 35+336] ^ ctrl; + t1 = T0[B3(s34)] ^ T1[B2(s35)] ^ T2[B1(s36)] ^ T3[B0(s37)] ^ C[ 36+336]; + t5 = T0[B3(s35)] ^ T1[B2(s36)] ^ T2[B1(s37)] ^ T3[B0(s34)] ^ C[ 37+336]; + t9 = T0[B3(s36)] ^ T1[B2(s37)] ^ T2[B1(s34)] ^ T3[B0(s35)] ^ C[ 38+336]; + td = T0[B3(s37)] ^ T1[B2(s34)] ^ T2[B1(s35)] ^ T3[B0(s36)] ^ C[ 39+336]; + t2 = T0[B3(s38)] ^ T1[B2(s39)] ^ T2[B1(s3a)] ^ T3[B0(s3b)] ^ C[ 40+336]; + t6 = T0[B3(s39)] ^ T1[B2(s3a)] ^ T2[B1(s3b)] ^ T3[B0(s38)] ^ C[ 41+336]; + ta = T0[B3(s3a)] ^ T1[B2(s3b)] ^ T2[B1(s38)] ^ T3[B0(s39)] ^ C[ 42+336]; + te = T0[B3(s3b)] ^ T1[B2(s38)] ^ T2[B1(s39)] ^ T3[B0(s3a)] ^ C[ 43+336]; + t3 = T0[B3(s3c)] ^ T1[B2(s3d)] ^ T2[B1(s3e)] ^ T3[B0(s3f)] ^ C[ 44+336]; + t7 = T0[B3(s3d)] ^ T1[B2(s3e)] ^ T2[B1(s3f)] ^ T3[B0(s3c)] ^ C[ 45+336]; + tb = T0[B3(s3e)] ^ T1[B2(s3f)] ^ T2[B1(s3c)] ^ T3[B0(s3d)] ^ C[ 46+336]; + tf = T0[B3(s3f)] ^ T1[B2(s3c)] ^ T2[B1(s3d)] ^ T3[B0(s3e)] ^ C[ 47+336]; + + s30 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 48+336]; + s34 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 49+336]; + s38 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 50+336]; + s3c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 51+336] ^ ctrh; + s31 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 52+336]; + s35 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 53+336]; + s39 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 54+336]; + s3d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 55+336]; + s32 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 56+336]; + s36 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 57+336]; + s3a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 58+336]; + s3e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 59+336]; + s33 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 60+336]; + s37 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 61+336]; + s3b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 62+336]; + s3f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 63+336]; + + t0 = T0[B3(s30)] ^ T1[B2(s31)] ^ T2[B1(s32)] ^ T3[B0(s33)] ^ C[ 64+336]; + t4 = T0[B3(s31)] ^ T1[B2(s32)] ^ T2[B1(s33)] ^ T3[B0(s30)] ^ C[ 65+336]; + t8 = T0[B3(s32)] ^ T1[B2(s33)] ^ T2[B1(s30)] ^ T3[B0(s31)] ^ C[ 66+336]; + tc = T0[B3(s33)] ^ T1[B2(s30)] ^ T2[B1(s31)] ^ T3[B0(s32)] ^ C[ 67+336] ^ ctrl; + t1 = T0[B3(s34)] ^ T1[B2(s35)] ^ T2[B1(s36)] ^ T3[B0(s37)] ^ C[ 68+336]; + t5 = T0[B3(s35)] ^ T1[B2(s36)] ^ T2[B1(s37)] ^ T3[B0(s34)] ^ C[ 69+336]; + t9 = T0[B3(s36)] ^ T1[B2(s37)] ^ T2[B1(s34)] ^ T3[B0(s35)] ^ C[ 70+336]; + td = T0[B3(s37)] ^ T1[B2(s34)] ^ T2[B1(s35)] ^ T3[B0(s36)] ^ C[ 71+336]; + t2 = T0[B3(s38)] ^ T1[B2(s39)] ^ T2[B1(s3a)] ^ T3[B0(s3b)] ^ C[ 72+336]; + t6 = T0[B3(s39)] ^ T1[B2(s3a)] ^ T2[B1(s3b)] ^ T3[B0(s38)] ^ C[ 73+336]; + ta = T0[B3(s3a)] ^ T1[B2(s3b)] ^ T2[B1(s38)] ^ T3[B0(s39)] ^ C[ 74+336]; + te = T0[B3(s3b)] ^ T1[B2(s38)] ^ T2[B1(s39)] ^ T3[B0(s3a)] ^ C[ 75+336]; + t3 = T0[B3(s3c)] ^ T1[B2(s3d)] ^ T2[B1(s3e)] ^ T3[B0(s3f)] ^ C[ 76+336]; + t7 = T0[B3(s3d)] ^ T1[B2(s3e)] ^ T2[B1(s3f)] ^ T3[B0(s3c)] ^ C[ 77+336]; + tb = T0[B3(s3e)] ^ T1[B2(s3f)] ^ T2[B1(s3c)] ^ T3[B0(s3d)] ^ C[ 78+336]; + tf = T0[B3(s3f)] ^ T1[B2(s3c)] ^ T2[B1(s3d)] ^ T3[B0(s3e)] ^ C[ 79+336]; + + s30 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 80+336]; + s34 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 81+336]; + s38 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 82+336]; + s3c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 83+336] ^ ctrh; + s31 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 84+336]; + s35 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 85+336]; + s39 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 86+336]; + s3d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 87+336]; + s32 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 88+336]; + s36 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 89+336]; + s3a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 90+336]; + s3e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 91+336]; + s33 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 92+336]; + s37 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 93+336]; + s3b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 94+336]; + s3f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 95+336]; + + t0 = T0[B3(s30)] ^ T1[B2(s31)] ^ T2[B1(s32)] ^ T3[B0(s33)] ^ C[ 96+336]; + t4 = T0[B3(s31)] ^ T1[B2(s32)] ^ T2[B1(s33)] ^ T3[B0(s30)] ^ C[ 97+336]; + t8 = T0[B3(s32)] ^ T1[B2(s33)] ^ T2[B1(s30)] ^ T3[B0(s31)] ^ C[ 98+336]; + tc = T0[B3(s33)] ^ T1[B2(s30)] ^ T2[B1(s31)] ^ T3[B0(s32)] ^ C[ 99+336] ^ ctrl; + t1 = T0[B3(s34)] ^ T1[B2(s35)] ^ T2[B1(s36)] ^ T3[B0(s37)] ^ C[100+336]; + t5 = T0[B3(s35)] ^ T1[B2(s36)] ^ T2[B1(s37)] ^ T3[B0(s34)] ^ C[101+336]; + t9 = T0[B3(s36)] ^ T1[B2(s37)] ^ T2[B1(s34)] ^ T3[B0(s35)] ^ C[102+336]; + td = T0[B3(s37)] ^ T1[B2(s34)] ^ T2[B1(s35)] ^ T3[B0(s36)] ^ C[103+336]; + t2 = T0[B3(s38)] ^ T1[B2(s39)] ^ T2[B1(s3a)] ^ T3[B0(s3b)] ^ C[104+336]; + t6 = T0[B3(s39)] ^ T1[B2(s3a)] ^ T2[B1(s3b)] ^ T3[B0(s38)] ^ C[105+336]; + ta = T0[B3(s3a)] ^ T1[B2(s3b)] ^ T2[B1(s38)] ^ T3[B0(s39)] ^ C[106+336]; + te = T0[B3(s3b)] ^ T1[B2(s38)] ^ T2[B1(s39)] ^ T3[B0(s3a)] ^ C[107+336]; + t3 = T0[B3(s3c)] ^ T1[B2(s3d)] ^ T2[B1(s3e)] ^ T3[B0(s3f)] ^ C[108+336]; + t7 = T0[B3(s3d)] ^ T1[B2(s3e)] ^ T2[B1(s3f)] ^ T3[B0(s3c)] ^ C[109+336]; + tb = T0[B3(s3e)] ^ T1[B2(s3f)] ^ T2[B1(s3c)] ^ T3[B0(s3d)] ^ C[110+336]; + tf = T0[B3(s3f)] ^ T1[B2(s3c)] ^ T2[B1(s3d)] ^ T3[B0(s3e)] ^ C[111+336]; + + s70 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + s74 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + s78 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + s7c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + s71 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + s75 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + s79 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + s7d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + s72 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )]; + s76 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )]; + s7a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )]; + s7e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )]; + s73 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )]; + s77 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )]; + s7b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )]; + s7f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )]; + + /* Lane 4 */ + t0 = T0[B3(s40)] ^ T1[B2(s41)] ^ T2[B1(s42)] ^ T3[B0(s43)] ^ C[ 0+448]; + t4 = T0[B3(s41)] ^ T1[B2(s42)] ^ T2[B1(s43)] ^ T3[B0(s40)] ^ C[ 1+448]; + t8 = T0[B3(s42)] ^ T1[B2(s43)] ^ T2[B1(s40)] ^ T3[B0(s41)] ^ C[ 2+448]; + tc = T0[B3(s43)] ^ T1[B2(s40)] ^ T2[B1(s41)] ^ T3[B0(s42)] ^ C[ 3+448] ^ ctrh; + t1 = T0[B3(s44)] ^ T1[B2(s45)] ^ T2[B1(s46)] ^ T3[B0(s47)] ^ C[ 4+448]; + t5 = T0[B3(s45)] ^ T1[B2(s46)] ^ T2[B1(s47)] ^ T3[B0(s44)] ^ C[ 5+448]; + t9 = T0[B3(s46)] ^ T1[B2(s47)] ^ T2[B1(s44)] ^ T3[B0(s45)] ^ C[ 6+448]; + td = T0[B3(s47)] ^ T1[B2(s44)] ^ T2[B1(s45)] ^ T3[B0(s46)] ^ C[ 7+448]; + t2 = T0[B3(s48)] ^ T1[B2(s49)] ^ T2[B1(s4a)] ^ T3[B0(s4b)] ^ C[ 8+448]; + t6 = T0[B3(s49)] ^ T1[B2(s4a)] ^ T2[B1(s4b)] ^ T3[B0(s48)] ^ C[ 9+448]; + ta = T0[B3(s4a)] ^ T1[B2(s4b)] ^ T2[B1(s48)] ^ T3[B0(s49)] ^ C[ 10+448]; + te = T0[B3(s4b)] ^ T1[B2(s48)] ^ T2[B1(s49)] ^ T3[B0(s4a)] ^ C[ 11+448]; + t3 = T0[B3(s4c)] ^ T1[B2(s4d)] ^ T2[B1(s4e)] ^ T3[B0(s4f)] ^ C[ 12+448]; + t7 = T0[B3(s4d)] ^ T1[B2(s4e)] ^ T2[B1(s4f)] ^ T3[B0(s4c)] ^ C[ 13+448]; + tb = T0[B3(s4e)] ^ T1[B2(s4f)] ^ T2[B1(s4c)] ^ T3[B0(s4d)] ^ C[ 14+448]; + tf = T0[B3(s4f)] ^ T1[B2(s4c)] ^ T2[B1(s4d)] ^ T3[B0(s4e)] ^ C[ 15+448]; + + s40 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 16+448]; + s44 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 17+448]; + s48 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 18+448]; + s4c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 19+448] ^ ctrl; + s41 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 20+448]; + s45 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 21+448]; + s49 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 22+448]; + s4d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 23+448]; + s42 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 24+448]; + s46 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 25+448]; + s4a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 26+448]; + s4e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 27+448]; + s43 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 28+448]; + s47 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 29+448]; + s4b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 30+448]; + s4f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 31+448]; + + t0 = T0[B3(s40)] ^ T1[B2(s41)] ^ T2[B1(s42)] ^ T3[B0(s43)] ^ C[ 32+448]; + t4 = T0[B3(s41)] ^ T1[B2(s42)] ^ T2[B1(s43)] ^ T3[B0(s40)] ^ C[ 33+448]; + t8 = T0[B3(s42)] ^ T1[B2(s43)] ^ T2[B1(s40)] ^ T3[B0(s41)] ^ C[ 34+448]; + tc = T0[B3(s43)] ^ T1[B2(s40)] ^ T2[B1(s41)] ^ T3[B0(s42)] ^ C[ 35+448] ^ ctrh; + t1 = T0[B3(s44)] ^ T1[B2(s45)] ^ T2[B1(s46)] ^ T3[B0(s47)] ^ C[ 36+448]; + t5 = T0[B3(s45)] ^ T1[B2(s46)] ^ T2[B1(s47)] ^ T3[B0(s44)] ^ C[ 37+448]; + t9 = T0[B3(s46)] ^ T1[B2(s47)] ^ T2[B1(s44)] ^ T3[B0(s45)] ^ C[ 38+448]; + td = T0[B3(s47)] ^ T1[B2(s44)] ^ T2[B1(s45)] ^ T3[B0(s46)] ^ C[ 39+448]; + t2 = T0[B3(s48)] ^ T1[B2(s49)] ^ T2[B1(s4a)] ^ T3[B0(s4b)] ^ C[ 40+448]; + t6 = T0[B3(s49)] ^ T1[B2(s4a)] ^ T2[B1(s4b)] ^ T3[B0(s48)] ^ C[ 41+448]; + ta = T0[B3(s4a)] ^ T1[B2(s4b)] ^ T2[B1(s48)] ^ T3[B0(s49)] ^ C[ 42+448]; + te = T0[B3(s4b)] ^ T1[B2(s48)] ^ T2[B1(s49)] ^ T3[B0(s4a)] ^ C[ 43+448]; + t3 = T0[B3(s4c)] ^ T1[B2(s4d)] ^ T2[B1(s4e)] ^ T3[B0(s4f)] ^ C[ 44+448]; + t7 = T0[B3(s4d)] ^ T1[B2(s4e)] ^ T2[B1(s4f)] ^ T3[B0(s4c)] ^ C[ 45+448]; + tb = T0[B3(s4e)] ^ T1[B2(s4f)] ^ T2[B1(s4c)] ^ T3[B0(s4d)] ^ C[ 46+448]; + tf = T0[B3(s4f)] ^ T1[B2(s4c)] ^ T2[B1(s4d)] ^ T3[B0(s4e)] ^ C[ 47+448]; + + s40 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 48+448]; + s44 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 49+448]; + s48 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 50+448]; + s4c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 51+448] ^ ctrl; + s41 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 52+448]; + s45 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 53+448]; + s49 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 54+448]; + s4d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 55+448]; + s42 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 56+448]; + s46 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 57+448]; + s4a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 58+448]; + s4e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 59+448]; + s43 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 60+448]; + s47 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 61+448]; + s4b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 62+448]; + s4f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 63+448]; + + t0 = T0[B3(s40)] ^ T1[B2(s41)] ^ T2[B1(s42)] ^ T3[B0(s43)] ^ C[ 64+448]; + t4 = T0[B3(s41)] ^ T1[B2(s42)] ^ T2[B1(s43)] ^ T3[B0(s40)] ^ C[ 65+448]; + t8 = T0[B3(s42)] ^ T1[B2(s43)] ^ T2[B1(s40)] ^ T3[B0(s41)] ^ C[ 66+448]; + tc = T0[B3(s43)] ^ T1[B2(s40)] ^ T2[B1(s41)] ^ T3[B0(s42)] ^ C[ 67+448] ^ ctrh; + t1 = T0[B3(s44)] ^ T1[B2(s45)] ^ T2[B1(s46)] ^ T3[B0(s47)] ^ C[ 68+448]; + t5 = T0[B3(s45)] ^ T1[B2(s46)] ^ T2[B1(s47)] ^ T3[B0(s44)] ^ C[ 69+448]; + t9 = T0[B3(s46)] ^ T1[B2(s47)] ^ T2[B1(s44)] ^ T3[B0(s45)] ^ C[ 70+448]; + td = T0[B3(s47)] ^ T1[B2(s44)] ^ T2[B1(s45)] ^ T3[B0(s46)] ^ C[ 71+448]; + t2 = T0[B3(s48)] ^ T1[B2(s49)] ^ T2[B1(s4a)] ^ T3[B0(s4b)] ^ C[ 72+448]; + t6 = T0[B3(s49)] ^ T1[B2(s4a)] ^ T2[B1(s4b)] ^ T3[B0(s48)] ^ C[ 73+448]; + ta = T0[B3(s4a)] ^ T1[B2(s4b)] ^ T2[B1(s48)] ^ T3[B0(s49)] ^ C[ 74+448]; + te = T0[B3(s4b)] ^ T1[B2(s48)] ^ T2[B1(s49)] ^ T3[B0(s4a)] ^ C[ 75+448]; + t3 = T0[B3(s4c)] ^ T1[B2(s4d)] ^ T2[B1(s4e)] ^ T3[B0(s4f)] ^ C[ 76+448]; + t7 = T0[B3(s4d)] ^ T1[B2(s4e)] ^ T2[B1(s4f)] ^ T3[B0(s4c)] ^ C[ 77+448]; + tb = T0[B3(s4e)] ^ T1[B2(s4f)] ^ T2[B1(s4c)] ^ T3[B0(s4d)] ^ C[ 78+448]; + tf = T0[B3(s4f)] ^ T1[B2(s4c)] ^ T2[B1(s4d)] ^ T3[B0(s4e)] ^ C[ 79+448]; + + s40 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 80+448]; + s44 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 81+448]; + s48 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 82+448]; + s4c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 83+448] ^ ctrl; + s41 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 84+448]; + s45 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 85+448]; + s49 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 86+448]; + s4d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 87+448]; + s42 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 88+448]; + s46 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 89+448]; + s4a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 90+448]; + s4e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 91+448]; + s43 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 92+448]; + s47 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 93+448]; + s4b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 94+448]; + s4f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 95+448]; + + t0 = T0[B3(s40)] ^ T1[B2(s41)] ^ T2[B1(s42)] ^ T3[B0(s43)] ^ C[ 96+448]; + t4 = T0[B3(s41)] ^ T1[B2(s42)] ^ T2[B1(s43)] ^ T3[B0(s40)] ^ C[ 97+448]; + t8 = T0[B3(s42)] ^ T1[B2(s43)] ^ T2[B1(s40)] ^ T3[B0(s41)] ^ C[ 98+448]; + tc = T0[B3(s43)] ^ T1[B2(s40)] ^ T2[B1(s41)] ^ T3[B0(s42)] ^ C[ 99+448] ^ ctrh; + t1 = T0[B3(s44)] ^ T1[B2(s45)] ^ T2[B1(s46)] ^ T3[B0(s47)] ^ C[100+448]; + t5 = T0[B3(s45)] ^ T1[B2(s46)] ^ T2[B1(s47)] ^ T3[B0(s44)] ^ C[101+448]; + t9 = T0[B3(s46)] ^ T1[B2(s47)] ^ T2[B1(s44)] ^ T3[B0(s45)] ^ C[102+448]; + td = T0[B3(s47)] ^ T1[B2(s44)] ^ T2[B1(s45)] ^ T3[B0(s46)] ^ C[103+448]; + t2 = T0[B3(s48)] ^ T1[B2(s49)] ^ T2[B1(s4a)] ^ T3[B0(s4b)] ^ C[104+448]; + t6 = T0[B3(s49)] ^ T1[B2(s4a)] ^ T2[B1(s4b)] ^ T3[B0(s48)] ^ C[105+448]; + ta = T0[B3(s4a)] ^ T1[B2(s4b)] ^ T2[B1(s48)] ^ T3[B0(s49)] ^ C[106+448]; + te = T0[B3(s4b)] ^ T1[B2(s48)] ^ T2[B1(s49)] ^ T3[B0(s4a)] ^ C[107+448]; + t3 = T0[B3(s4c)] ^ T1[B2(s4d)] ^ T2[B1(s4e)] ^ T3[B0(s4f)] ^ C[108+448]; + t7 = T0[B3(s4d)] ^ T1[B2(s4e)] ^ T2[B1(s4f)] ^ T3[B0(s4c)] ^ C[109+448]; + tb = T0[B3(s4e)] ^ T1[B2(s4f)] ^ T2[B1(s4c)] ^ T3[B0(s4d)] ^ C[110+448]; + tf = T0[B3(s4f)] ^ T1[B2(s4c)] ^ T2[B1(s4d)] ^ T3[B0(s4e)] ^ C[111+448]; + + s70 ^= T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + s74 ^= T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + s78 ^= T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + s7c ^= T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + s71 ^= T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + s75 ^= T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + s79 ^= T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + s7d ^= T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + s72 ^= T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )]; + s76 ^= T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )]; + s7a ^= T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )]; + s7e ^= T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )]; + s73 ^= T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )]; + s77 ^= T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )]; + s7b ^= T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )]; + s7f ^= T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )]; + + /* Lane 5 */ + t0 = T0[B3(s50)] ^ T1[B2(s51)] ^ T2[B1(s52)] ^ T3[B0(s53)] ^ C[ 0+560]; + t4 = T0[B3(s51)] ^ T1[B2(s52)] ^ T2[B1(s53)] ^ T3[B0(s50)] ^ C[ 1+560]; + t8 = T0[B3(s52)] ^ T1[B2(s53)] ^ T2[B1(s50)] ^ T3[B0(s51)] ^ C[ 2+560]; + tc = T0[B3(s53)] ^ T1[B2(s50)] ^ T2[B1(s51)] ^ T3[B0(s52)] ^ C[ 3+560] ^ ctrl; + t1 = T0[B3(s54)] ^ T1[B2(s55)] ^ T2[B1(s56)] ^ T3[B0(s57)] ^ C[ 4+560]; + t5 = T0[B3(s55)] ^ T1[B2(s56)] ^ T2[B1(s57)] ^ T3[B0(s54)] ^ C[ 5+560]; + t9 = T0[B3(s56)] ^ T1[B2(s57)] ^ T2[B1(s54)] ^ T3[B0(s55)] ^ C[ 6+560]; + td = T0[B3(s57)] ^ T1[B2(s54)] ^ T2[B1(s55)] ^ T3[B0(s56)] ^ C[ 7+560]; + t2 = T0[B3(s58)] ^ T1[B2(s59)] ^ T2[B1(s5a)] ^ T3[B0(s5b)] ^ C[ 8+560]; + t6 = T0[B3(s59)] ^ T1[B2(s5a)] ^ T2[B1(s5b)] ^ T3[B0(s58)] ^ C[ 9+560]; + ta = T0[B3(s5a)] ^ T1[B2(s5b)] ^ T2[B1(s58)] ^ T3[B0(s59)] ^ C[ 10+560]; + te = T0[B3(s5b)] ^ T1[B2(s58)] ^ T2[B1(s59)] ^ T3[B0(s5a)] ^ C[ 11+560]; + t3 = T0[B3(s5c)] ^ T1[B2(s5d)] ^ T2[B1(s5e)] ^ T3[B0(s5f)] ^ C[ 12+560]; + t7 = T0[B3(s5d)] ^ T1[B2(s5e)] ^ T2[B1(s5f)] ^ T3[B0(s5c)] ^ C[ 13+560]; + tb = T0[B3(s5e)] ^ T1[B2(s5f)] ^ T2[B1(s5c)] ^ T3[B0(s5d)] ^ C[ 14+560]; + tf = T0[B3(s5f)] ^ T1[B2(s5c)] ^ T2[B1(s5d)] ^ T3[B0(s5e)] ^ C[ 15+560]; + + s50 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 16+560]; + s54 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 17+560]; + s58 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 18+560]; + s5c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 19+560] ^ ctrh; + s51 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 20+560]; + s55 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 21+560]; + s59 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 22+560]; + s5d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 23+560]; + s52 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 24+560]; + s56 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 25+560]; + s5a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 26+560]; + s5e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 27+560]; + s53 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 28+560]; + s57 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 29+560]; + s5b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 30+560]; + s5f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 31+560]; + + t0 = T0[B3(s50)] ^ T1[B2(s51)] ^ T2[B1(s52)] ^ T3[B0(s53)] ^ C[ 32+560]; + t4 = T0[B3(s51)] ^ T1[B2(s52)] ^ T2[B1(s53)] ^ T3[B0(s50)] ^ C[ 33+560]; + t8 = T0[B3(s52)] ^ T1[B2(s53)] ^ T2[B1(s50)] ^ T3[B0(s51)] ^ C[ 34+560]; + tc = T0[B3(s53)] ^ T1[B2(s50)] ^ T2[B1(s51)] ^ T3[B0(s52)] ^ C[ 35+560] ^ ctrl; + t1 = T0[B3(s54)] ^ T1[B2(s55)] ^ T2[B1(s56)] ^ T3[B0(s57)] ^ C[ 36+560]; + t5 = T0[B3(s55)] ^ T1[B2(s56)] ^ T2[B1(s57)] ^ T3[B0(s54)] ^ C[ 37+560]; + t9 = T0[B3(s56)] ^ T1[B2(s57)] ^ T2[B1(s54)] ^ T3[B0(s55)] ^ C[ 38+560]; + td = T0[B3(s57)] ^ T1[B2(s54)] ^ T2[B1(s55)] ^ T3[B0(s56)] ^ C[ 39+560]; + t2 = T0[B3(s58)] ^ T1[B2(s59)] ^ T2[B1(s5a)] ^ T3[B0(s5b)] ^ C[ 40+560]; + t6 = T0[B3(s59)] ^ T1[B2(s5a)] ^ T2[B1(s5b)] ^ T3[B0(s58)] ^ C[ 41+560]; + ta = T0[B3(s5a)] ^ T1[B2(s5b)] ^ T2[B1(s58)] ^ T3[B0(s59)] ^ C[ 42+560]; + te = T0[B3(s5b)] ^ T1[B2(s58)] ^ T2[B1(s59)] ^ T3[B0(s5a)] ^ C[ 43+560]; + t3 = T0[B3(s5c)] ^ T1[B2(s5d)] ^ T2[B1(s5e)] ^ T3[B0(s5f)] ^ C[ 44+560]; + t7 = T0[B3(s5d)] ^ T1[B2(s5e)] ^ T2[B1(s5f)] ^ T3[B0(s5c)] ^ C[ 45+560]; + tb = T0[B3(s5e)] ^ T1[B2(s5f)] ^ T2[B1(s5c)] ^ T3[B0(s5d)] ^ C[ 46+560]; + tf = T0[B3(s5f)] ^ T1[B2(s5c)] ^ T2[B1(s5d)] ^ T3[B0(s5e)] ^ C[ 47+560]; + + s50 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 48+560]; + s54 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 49+560]; + s58 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 50+560]; + s5c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 51+560] ^ ctrh; + s51 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 52+560]; + s55 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 53+560]; + s59 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 54+560]; + s5d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 55+560]; + s52 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 56+560]; + s56 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 57+560]; + s5a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 58+560]; + s5e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 59+560]; + s53 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 60+560]; + s57 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 61+560]; + s5b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 62+560]; + s5f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 63+560]; + + t0 = T0[B3(s50)] ^ T1[B2(s51)] ^ T2[B1(s52)] ^ T3[B0(s53)] ^ C[ 64+560]; + t4 = T0[B3(s51)] ^ T1[B2(s52)] ^ T2[B1(s53)] ^ T3[B0(s50)] ^ C[ 65+560]; + t8 = T0[B3(s52)] ^ T1[B2(s53)] ^ T2[B1(s50)] ^ T3[B0(s51)] ^ C[ 66+560]; + tc = T0[B3(s53)] ^ T1[B2(s50)] ^ T2[B1(s51)] ^ T3[B0(s52)] ^ C[ 67+560] ^ ctrl; + t1 = T0[B3(s54)] ^ T1[B2(s55)] ^ T2[B1(s56)] ^ T3[B0(s57)] ^ C[ 68+560]; + t5 = T0[B3(s55)] ^ T1[B2(s56)] ^ T2[B1(s57)] ^ T3[B0(s54)] ^ C[ 69+560]; + t9 = T0[B3(s56)] ^ T1[B2(s57)] ^ T2[B1(s54)] ^ T3[B0(s55)] ^ C[ 70+560]; + td = T0[B3(s57)] ^ T1[B2(s54)] ^ T2[B1(s55)] ^ T3[B0(s56)] ^ C[ 71+560]; + t2 = T0[B3(s58)] ^ T1[B2(s59)] ^ T2[B1(s5a)] ^ T3[B0(s5b)] ^ C[ 72+560]; + t6 = T0[B3(s59)] ^ T1[B2(s5a)] ^ T2[B1(s5b)] ^ T3[B0(s58)] ^ C[ 73+560]; + ta = T0[B3(s5a)] ^ T1[B2(s5b)] ^ T2[B1(s58)] ^ T3[B0(s59)] ^ C[ 74+560]; + te = T0[B3(s5b)] ^ T1[B2(s58)] ^ T2[B1(s59)] ^ T3[B0(s5a)] ^ C[ 75+560]; + t3 = T0[B3(s5c)] ^ T1[B2(s5d)] ^ T2[B1(s5e)] ^ T3[B0(s5f)] ^ C[ 76+560]; + t7 = T0[B3(s5d)] ^ T1[B2(s5e)] ^ T2[B1(s5f)] ^ T3[B0(s5c)] ^ C[ 77+560]; + tb = T0[B3(s5e)] ^ T1[B2(s5f)] ^ T2[B1(s5c)] ^ T3[B0(s5d)] ^ C[ 78+560]; + tf = T0[B3(s5f)] ^ T1[B2(s5c)] ^ T2[B1(s5d)] ^ T3[B0(s5e)] ^ C[ 79+560]; + + s50 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 80+560]; + s54 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 81+560]; + s58 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 82+560]; + s5c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 83+560] ^ ctrh; + s51 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 84+560]; + s55 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 85+560]; + s59 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 86+560]; + s5d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 87+560]; + s52 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 88+560]; + s56 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 89+560]; + s5a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 90+560]; + s5e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 91+560]; + s53 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 92+560]; + s57 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 93+560]; + s5b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 94+560]; + s5f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 95+560]; + + t0 = T0[B3(s50)] ^ T1[B2(s51)] ^ T2[B1(s52)] ^ T3[B0(s53)] ^ C[ 96+560]; + t4 = T0[B3(s51)] ^ T1[B2(s52)] ^ T2[B1(s53)] ^ T3[B0(s50)] ^ C[ 97+560]; + t8 = T0[B3(s52)] ^ T1[B2(s53)] ^ T2[B1(s50)] ^ T3[B0(s51)] ^ C[ 98+560]; + tc = T0[B3(s53)] ^ T1[B2(s50)] ^ T2[B1(s51)] ^ T3[B0(s52)] ^ C[ 99+560] ^ ctrl; + t1 = T0[B3(s54)] ^ T1[B2(s55)] ^ T2[B1(s56)] ^ T3[B0(s57)] ^ C[100+560]; + t5 = T0[B3(s55)] ^ T1[B2(s56)] ^ T2[B1(s57)] ^ T3[B0(s54)] ^ C[101+560]; + t9 = T0[B3(s56)] ^ T1[B2(s57)] ^ T2[B1(s54)] ^ T3[B0(s55)] ^ C[102+560]; + td = T0[B3(s57)] ^ T1[B2(s54)] ^ T2[B1(s55)] ^ T3[B0(s56)] ^ C[103+560]; + t2 = T0[B3(s58)] ^ T1[B2(s59)] ^ T2[B1(s5a)] ^ T3[B0(s5b)] ^ C[104+560]; + t6 = T0[B3(s59)] ^ T1[B2(s5a)] ^ T2[B1(s5b)] ^ T3[B0(s58)] ^ C[105+560]; + ta = T0[B3(s5a)] ^ T1[B2(s5b)] ^ T2[B1(s58)] ^ T3[B0(s59)] ^ C[106+560]; + te = T0[B3(s5b)] ^ T1[B2(s58)] ^ T2[B1(s59)] ^ T3[B0(s5a)] ^ C[107+560]; + t3 = T0[B3(s5c)] ^ T1[B2(s5d)] ^ T2[B1(s5e)] ^ T3[B0(s5f)] ^ C[108+560]; + t7 = T0[B3(s5d)] ^ T1[B2(s5e)] ^ T2[B1(s5f)] ^ T3[B0(s5c)] ^ C[109+560]; + tb = T0[B3(s5e)] ^ T1[B2(s5f)] ^ T2[B1(s5c)] ^ T3[B0(s5d)] ^ C[110+560]; + tf = T0[B3(s5f)] ^ T1[B2(s5c)] ^ T2[B1(s5d)] ^ T3[B0(s5e)] ^ C[111+560]; + + s70 ^= T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + s74 ^= T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + s78 ^= T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + s7c ^= T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + s71 ^= T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + s75 ^= T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + s79 ^= T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + s7d ^= T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + s72 ^= T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )]; + s76 ^= T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )]; + s7a ^= T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )]; + s7e ^= T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )]; + s73 ^= T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )]; + s77 ^= T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )]; + s7b ^= T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )]; + s7f ^= T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )]; + + /* Lane 6 */ + t0 = T0[B3(s60)] ^ T1[B2(s61)] ^ T2[B1(s62)] ^ T3[B0(s63)] ^ C[ 0+672]; + t4 = T0[B3(s61)] ^ T1[B2(s62)] ^ T2[B1(s63)] ^ T3[B0(s60)] ^ C[ 1+672]; + t8 = T0[B3(s62)] ^ T1[B2(s63)] ^ T2[B1(s60)] ^ T3[B0(s61)] ^ C[ 2+672]; + tc = T0[B3(s63)] ^ T1[B2(s60)] ^ T2[B1(s61)] ^ T3[B0(s62)] ^ C[ 3+672] ^ ctrh; + t1 = T0[B3(s64)] ^ T1[B2(s65)] ^ T2[B1(s66)] ^ T3[B0(s67)] ^ C[ 4+672]; + t5 = T0[B3(s65)] ^ T1[B2(s66)] ^ T2[B1(s67)] ^ T3[B0(s64)] ^ C[ 5+672]; + t9 = T0[B3(s66)] ^ T1[B2(s67)] ^ T2[B1(s64)] ^ T3[B0(s65)] ^ C[ 6+672]; + td = T0[B3(s67)] ^ T1[B2(s64)] ^ T2[B1(s65)] ^ T3[B0(s66)] ^ C[ 7+672]; + t2 = T0[B3(s68)] ^ T1[B2(s69)] ^ T2[B1(s6a)] ^ T3[B0(s6b)] ^ C[ 8+672]; + t6 = T0[B3(s69)] ^ T1[B2(s6a)] ^ T2[B1(s6b)] ^ T3[B0(s68)] ^ C[ 9+672]; + ta = T0[B3(s6a)] ^ T1[B2(s6b)] ^ T2[B1(s68)] ^ T3[B0(s69)] ^ C[ 10+672]; + te = T0[B3(s6b)] ^ T1[B2(s68)] ^ T2[B1(s69)] ^ T3[B0(s6a)] ^ C[ 11+672]; + t3 = T0[B3(s6c)] ^ T1[B2(s6d)] ^ T2[B1(s6e)] ^ T3[B0(s6f)] ^ C[ 12+672]; + t7 = T0[B3(s6d)] ^ T1[B2(s6e)] ^ T2[B1(s6f)] ^ T3[B0(s6c)] ^ C[ 13+672]; + tb = T0[B3(s6e)] ^ T1[B2(s6f)] ^ T2[B1(s6c)] ^ T3[B0(s6d)] ^ C[ 14+672]; + tf = T0[B3(s6f)] ^ T1[B2(s6c)] ^ T2[B1(s6d)] ^ T3[B0(s6e)] ^ C[ 15+672]; + + s60 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 16+672]; + s64 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 17+672]; + s68 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 18+672]; + s6c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 19+672] ^ ctrl; + s61 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 20+672]; + s65 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 21+672]; + s69 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 22+672]; + s6d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 23+672]; + s62 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 24+672]; + s66 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 25+672]; + s6a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 26+672]; + s6e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 27+672]; + s63 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 28+672]; + s67 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 29+672]; + s6b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 30+672]; + s6f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 31+672]; + + t0 = T0[B3(s60)] ^ T1[B2(s61)] ^ T2[B1(s62)] ^ T3[B0(s63)] ^ C[ 32+672]; + t4 = T0[B3(s61)] ^ T1[B2(s62)] ^ T2[B1(s63)] ^ T3[B0(s60)] ^ C[ 33+672]; + t8 = T0[B3(s62)] ^ T1[B2(s63)] ^ T2[B1(s60)] ^ T3[B0(s61)] ^ C[ 34+672]; + tc = T0[B3(s63)] ^ T1[B2(s60)] ^ T2[B1(s61)] ^ T3[B0(s62)] ^ C[ 35+672] ^ ctrh; + t1 = T0[B3(s64)] ^ T1[B2(s65)] ^ T2[B1(s66)] ^ T3[B0(s67)] ^ C[ 36+672]; + t5 = T0[B3(s65)] ^ T1[B2(s66)] ^ T2[B1(s67)] ^ T3[B0(s64)] ^ C[ 37+672]; + t9 = T0[B3(s66)] ^ T1[B2(s67)] ^ T2[B1(s64)] ^ T3[B0(s65)] ^ C[ 38+672]; + td = T0[B3(s67)] ^ T1[B2(s64)] ^ T2[B1(s65)] ^ T3[B0(s66)] ^ C[ 39+672]; + t2 = T0[B3(s68)] ^ T1[B2(s69)] ^ T2[B1(s6a)] ^ T3[B0(s6b)] ^ C[ 40+672]; + t6 = T0[B3(s69)] ^ T1[B2(s6a)] ^ T2[B1(s6b)] ^ T3[B0(s68)] ^ C[ 41+672]; + ta = T0[B3(s6a)] ^ T1[B2(s6b)] ^ T2[B1(s68)] ^ T3[B0(s69)] ^ C[ 42+672]; + te = T0[B3(s6b)] ^ T1[B2(s68)] ^ T2[B1(s69)] ^ T3[B0(s6a)] ^ C[ 43+672]; + t3 = T0[B3(s6c)] ^ T1[B2(s6d)] ^ T2[B1(s6e)] ^ T3[B0(s6f)] ^ C[ 44+672]; + t7 = T0[B3(s6d)] ^ T1[B2(s6e)] ^ T2[B1(s6f)] ^ T3[B0(s6c)] ^ C[ 45+672]; + tb = T0[B3(s6e)] ^ T1[B2(s6f)] ^ T2[B1(s6c)] ^ T3[B0(s6d)] ^ C[ 46+672]; + tf = T0[B3(s6f)] ^ T1[B2(s6c)] ^ T2[B1(s6d)] ^ T3[B0(s6e)] ^ C[ 47+672]; + + h[ 0] = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + h[ 4] = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + h[ 8] = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + h[12] = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + h[ 1] = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + h[ 5] = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + h[ 9] = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + h[13] = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + h[ 2] = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )]; + h[ 6] = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )]; + h[10] = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )]; + h[14] = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )]; + h[ 3] = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )]; + h[ 7] = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )]; + h[11] = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )]; + h[15] = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )]; + + /* Lane 7 */ + t0 = T0[B3(s70)] ^ T1[B2(s71)] ^ T2[B1(s72)] ^ T3[B0(s73)] ^ C[ 0+720]; + t4 = T0[B3(s71)] ^ T1[B2(s72)] ^ T2[B1(s73)] ^ T3[B0(s70)] ^ C[ 1+720]; + t8 = T0[B3(s72)] ^ T1[B2(s73)] ^ T2[B1(s70)] ^ T3[B0(s71)] ^ C[ 2+720]; + tc = T0[B3(s73)] ^ T1[B2(s70)] ^ T2[B1(s71)] ^ T3[B0(s72)] ^ C[ 3+720] ^ ctrl; + t1 = T0[B3(s74)] ^ T1[B2(s75)] ^ T2[B1(s76)] ^ T3[B0(s77)] ^ C[ 4+720]; + t5 = T0[B3(s75)] ^ T1[B2(s76)] ^ T2[B1(s77)] ^ T3[B0(s74)] ^ C[ 5+720]; + t9 = T0[B3(s76)] ^ T1[B2(s77)] ^ T2[B1(s74)] ^ T3[B0(s75)] ^ C[ 6+720]; + td = T0[B3(s77)] ^ T1[B2(s74)] ^ T2[B1(s75)] ^ T3[B0(s76)] ^ C[ 7+720]; + t2 = T0[B3(s78)] ^ T1[B2(s79)] ^ T2[B1(s7a)] ^ T3[B0(s7b)] ^ C[ 8+720]; + t6 = T0[B3(s79)] ^ T1[B2(s7a)] ^ T2[B1(s7b)] ^ T3[B0(s78)] ^ C[ 9+720]; + ta = T0[B3(s7a)] ^ T1[B2(s7b)] ^ T2[B1(s78)] ^ T3[B0(s79)] ^ C[ 10+720]; + te = T0[B3(s7b)] ^ T1[B2(s78)] ^ T2[B1(s79)] ^ T3[B0(s7a)] ^ C[ 11+720]; + t3 = T0[B3(s7c)] ^ T1[B2(s7d)] ^ T2[B1(s7e)] ^ T3[B0(s7f)] ^ C[ 12+720]; + t7 = T0[B3(s7d)] ^ T1[B2(s7e)] ^ T2[B1(s7f)] ^ T3[B0(s7c)] ^ C[ 13+720]; + tb = T0[B3(s7e)] ^ T1[B2(s7f)] ^ T2[B1(s7c)] ^ T3[B0(s7d)] ^ C[ 14+720]; + tf = T0[B3(s7f)] ^ T1[B2(s7c)] ^ T2[B1(s7d)] ^ T3[B0(s7e)] ^ C[ 15+720]; + + s70 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 16+720]; + s74 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 17+720]; + s78 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 18+720]; + s7c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 19+720] ^ ctrh; + s71 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 20+720]; + s75 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 21+720]; + s79 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 22+720]; + s7d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 23+720]; + s72 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 24+720]; + s76 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 25+720]; + s7a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 26+720]; + s7e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 27+720]; + s73 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 28+720]; + s77 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 29+720]; + s7b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 30+720]; + s7f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 31+720]; + + t0 = T0[B3(s70)] ^ T1[B2(s71)] ^ T2[B1(s72)] ^ T3[B0(s73)] ^ C[ 32+720]; + t4 = T0[B3(s71)] ^ T1[B2(s72)] ^ T2[B1(s73)] ^ T3[B0(s70)] ^ C[ 33+720]; + t8 = T0[B3(s72)] ^ T1[B2(s73)] ^ T2[B1(s70)] ^ T3[B0(s71)] ^ C[ 34+720]; + tc = T0[B3(s73)] ^ T1[B2(s70)] ^ T2[B1(s71)] ^ T3[B0(s72)] ^ C[ 35+720] ^ ctrl; + t1 = T0[B3(s74)] ^ T1[B2(s75)] ^ T2[B1(s76)] ^ T3[B0(s77)] ^ C[ 36+720]; + t5 = T0[B3(s75)] ^ T1[B2(s76)] ^ T2[B1(s77)] ^ T3[B0(s74)] ^ C[ 37+720]; + t9 = T0[B3(s76)] ^ T1[B2(s77)] ^ T2[B1(s74)] ^ T3[B0(s75)] ^ C[ 38+720]; + td = T0[B3(s77)] ^ T1[B2(s74)] ^ T2[B1(s75)] ^ T3[B0(s76)] ^ C[ 39+720]; + t2 = T0[B3(s78)] ^ T1[B2(s79)] ^ T2[B1(s7a)] ^ T3[B0(s7b)] ^ C[ 40+720]; + t6 = T0[B3(s79)] ^ T1[B2(s7a)] ^ T2[B1(s7b)] ^ T3[B0(s78)] ^ C[ 41+720]; + ta = T0[B3(s7a)] ^ T1[B2(s7b)] ^ T2[B1(s78)] ^ T3[B0(s79)] ^ C[ 42+720]; + te = T0[B3(s7b)] ^ T1[B2(s78)] ^ T2[B1(s79)] ^ T3[B0(s7a)] ^ C[ 43+720]; + t3 = T0[B3(s7c)] ^ T1[B2(s7d)] ^ T2[B1(s7e)] ^ T3[B0(s7f)] ^ C[ 44+720]; + t7 = T0[B3(s7d)] ^ T1[B2(s7e)] ^ T2[B1(s7f)] ^ T3[B0(s7c)] ^ C[ 45+720]; + tb = T0[B3(s7e)] ^ T1[B2(s7f)] ^ T2[B1(s7c)] ^ T3[B0(s7d)] ^ C[ 46+720]; + tf = T0[B3(s7f)] ^ T1[B2(s7c)] ^ T2[B1(s7d)] ^ T3[B0(s7e)] ^ C[ 47+720]; + + h[ 0] ^= T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + h[ 4] ^= T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + h[ 8] ^= T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + h[12] ^= T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + h[ 1] ^= T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + h[ 5] ^= T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + h[ 9] ^= T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + h[13] ^= T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + h[ 2] ^= T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )]; + h[ 6] ^= T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )]; + h[10] ^= T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )]; + h[14] ^= T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )]; + h[ 3] ^= T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )]; + h[ 7] ^= T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )]; + h[11] ^= T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )]; + h[15] ^= T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )]; +} + +HashReturn laneInit (hashState *state, int hashbitlen) +{ + if (hashbitlen != 224 && hashbitlen != 256 && hashbitlen != 384 && hashbitlen != 512) + return BAD_HASHBITLEN; + + state->hashbitlen = hashbitlen; + state->ctr = 0; + + switch (state->hashbitlen) { + case 224: + memcpy(state->h, iv224, 8*sizeof(u32)); + break; + case 256: default: + memcpy(state->h, iv256, 8*sizeof(u32)); + break; + case 384: + memcpy(state->h, iv384, 16*sizeof(u32)); + break; + case 512: + memcpy(state->h, iv512, 16*sizeof(u32)); + break; + } + + return SUCCESS; +} + +HashReturn laneUpdate (hashState *state, const BitSequence *data, DataLength databitlen) +{ + u64 buffill; + u64 bytes; + + switch (state->hashbitlen) { + case 224: case 256: default: + buffill = (state->ctr >> 3) & 0x3f; + bytes = databitlen >> 3; + + if (state->ctr & 0x7) + return BAD_DATABITLEN; /* Only the last call to Update() may contain a fractional byte */ + + /* Check if we have some stuff left in the buffer. If so, fill it, and process it */ + if (buffill) { + const u64 n = buffill + bytes > 64 ? 64-buffill : bytes; /* number of bytes to copy */ + memcpy(state->buffer + buffill, data, n); + state->ctr += n << 3; + if (buffill + n == 64) /* full buffer now */ + lane256_compress(state->buffer, state->h, MSB32(state->ctr), LSB32(state->ctr)); + data += n; + bytes -= n; + } + + /* Now process as many full blocks as we can directly from the input message */ + while (bytes >= 64) { + state->ctr += 64 << 3; + lane256_compress(data, state->h, MSB32(state->ctr), LSB32(state->ctr)); + data += 64; + bytes -= 64; + } + break; + + case 384: case 512: + buffill = (state->ctr >> 3) & 0x7f; + bytes = databitlen >> 3; + + if (state->ctr & 0x7) + return BAD_DATABITLEN; /* Only the last call to Update() may contain a fractional byte */ + + /* Check if we have some stuff left in the buffer. If so, fill it, and process it */ + if (buffill) { + const u64 n = buffill + bytes > 128 ? 128-buffill : bytes; /* number of bytes to copy */ + memcpy(state->buffer + buffill, data, n); + state->ctr += n << 3; + if (buffill + n == 128) /* full buffer now */ + lane512_compress(state->buffer, state->h, MSB32(state->ctr), LSB32(state->ctr)); + data += n; + bytes -= n; + } + + /* Now process as many full blocks as we can directly from the input message */ + while (bytes >= 128) { + state->ctr += 128 << 3; + lane512_compress(data, state->h, MSB32(state->ctr), LSB32(state->ctr)); + data += 128; + bytes -= 128; + } + break; + } + + /* And finally, save the last, incomplete message block */ + if (bytes || (databitlen & 0x7)) { + memcpy(state->buffer, data, databitlen & 0x7 ? bytes+1 : bytes); /* also copy partial byte */ + state->ctr += (bytes << 3) + (databitlen & 0x7); + } + + return SUCCESS; +} + +HashReturn laneFinal (hashState *state, BitSequence *hashval) +{ + + switch (state->hashbitlen) { + case 224: case 256: default: + /* do zero padding and compress last block, if there is some data in the buffer */ + if (state->ctr & 0x1ff) { + const u64 n = (((state->ctr & 0x1ff) - 1) >> 3) + 1; /* number of bytes in buffer that are (partially) filled */ + if (n < 64) + memset(state->buffer + n, 0, 64-n); + state->buffer[(state->ctr >> 3)&0x3f] &= ~(0xff >> (state->ctr & 0x7)); /* zero-pad partial byte */ + lane256_compress(state->buffer, state->h, MSB32(state->ctr), LSB32(state->ctr)); + } + + /* output transformation */ + memset(state->buffer, 0, 64); + state->buffer[0] = 0x00; /* flag byte 0x00: output transformation without seed */ + state->buffer[1] = T8(state->ctr >> 56); /* message length in big-endian */ + state->buffer[2] = T8(state->ctr >> 48); + state->buffer[3] = T8(state->ctr >> 40); + state->buffer[4] = T8(state->ctr >> 32); + state->buffer[5] = T8(state->ctr >> 24); + state->buffer[6] = T8(state->ctr >> 16); + state->buffer[7] = T8(state->ctr >> 8); + state->buffer[8] = T8(state->ctr >> 0); + lane256_compress(state->buffer, state->h, 0, 0); + + /* write back result */ + U32TO8_BIG(hashval, state->h[0]); + U32TO8_BIG(hashval+4, state->h[1]); + U32TO8_BIG(hashval+8, state->h[2]); + U32TO8_BIG(hashval+12, state->h[3]); + U32TO8_BIG(hashval+16, state->h[4]); + U32TO8_BIG(hashval+20, state->h[5]); + U32TO8_BIG(hashval+24, state->h[6]); + U32TO8_BIG(hashval+28, state->h[7]); + + break; + + case 384: case 512: + /* do zero padding and compress last block, if there is some data in the buffer */ + if (state->ctr & 0x3ff) { + const u64 n = (((state->ctr & 0x3ff) - 1) >> 3) + 1; /* number of bytes in buffer that are (partially) filled */ + if (n < 128) + memset(state->buffer + n, 0, 128-n); + state->buffer[(state->ctr >> 3)&0x7f] &= ~(0xff >> (state->ctr & 0x7)); /* zero-pad partial byte */ + lane512_compress(state->buffer, state->h, MSB32(state->ctr), LSB32(state->ctr)); + } + + /* output transformation */ + memset(state->buffer, 0, 128); + state->buffer[0] = 0x00; /* flag byte 0x00: output transformation without seed */ + state->buffer[1] = T8(state->ctr >> 56); /* message length in big-endian */ + state->buffer[2] = T8(state->ctr >> 48); + state->buffer[3] = T8(state->ctr >> 40); + state->buffer[4] = T8(state->ctr >> 32); + state->buffer[5] = T8(state->ctr >> 24); + state->buffer[6] = T8(state->ctr >> 16); + state->buffer[7] = T8(state->ctr >> 8); + state->buffer[8] = T8(state->ctr >> 0); + lane512_compress(state->buffer, state->h, 0, 0); + + /* write back result */ + U32TO8_BIG(hashval, state->h[0]); + U32TO8_BIG(hashval+4, state->h[1]); + U32TO8_BIG(hashval+8, state->h[2]); + U32TO8_BIG(hashval+12, state->h[3]); + U32TO8_BIG(hashval+16, state->h[4]); + U32TO8_BIG(hashval+20, state->h[5]); + U32TO8_BIG(hashval+24, state->h[6]); + U32TO8_BIG(hashval+28, state->h[7]); + U32TO8_BIG(hashval+32, state->h[8]); + U32TO8_BIG(hashval+36, state->h[9]); + U32TO8_BIG(hashval+40, state->h[10]); + U32TO8_BIG(hashval+44, state->h[11]); + U32TO8_BIG(hashval+48, state->h[12]); + U32TO8_BIG(hashval+52, state->h[13]); + U32TO8_BIG(hashval+56, state->h[14]); + U32TO8_BIG(hashval+60, state->h[15]); + + break; + } + + return SUCCESS; +} + +HashReturn laneHash (int hashbitlen, const BitSequence *data, DataLength databitlen, BitSequence *hashval) +{ + hashState state; + HashReturn hashReturn; + + if ((hashReturn = laneInit(&state, hashbitlen)) != SUCCESS) + return hashReturn; + if ((hashReturn = laneUpdate(&state, data, databitlen)) != SUCCESS) + return hashReturn; + if ((hashReturn = laneFinal(&state, hashval)) != SUCCESS) + return hashReturn; + return SUCCESS; +} diff --git a/stratum/algos/lane.h b/stratum/algos/lane.h new file mode 100644 index 000000000..1d935a171 --- /dev/null +++ b/stratum/algos/lane.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2008 Sebastiaan Indesteege + * + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Optimised ANSI-C implementation of LANE + */ + +#ifndef LANE_H +#define LANE_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include + +typedef unsigned char BitSequence; +typedef unsigned long long DataLength; + +typedef enum { SUCCESS = 0, FAIL = 1, BAD_HASHBITLEN = 2, BAD_DATABITLEN = 3 } HashReturn; + +typedef unsigned char u8; +typedef unsigned int u32; +typedef unsigned long long u64; + +typedef struct { + int hashbitlen; + u64 ctr; + u32 h[16]; + u8 buffer[128]; +} hashState; + +HashReturn laneInit (hashState *state, int hashbitlen); +HashReturn laneUpdate (hashState *state, const BitSequence *data, DataLength databitlen); +HashReturn laneFinal (hashState *state, BitSequence *hashval); +HashReturn laneHash (int hashbitlen, const BitSequence *data, DataLength databitlen, BitSequence *hashval); + +#if defined(__cplusplus) +} +#endif + +#endif /* LANE_H */ diff --git a/stratum/algos/lyra2re3.c b/stratum/algos/lyra2re3.c new file mode 100644 index 000000000..73a1b2d1e --- /dev/null +++ b/stratum/algos/lyra2re3.c @@ -0,0 +1,64 @@ +/*- + * Copyright 2009 Colin Percival, 2011 ArtForz, 2013 Neisklar, 2014 James Lovejoy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file was originally written by Colin Percival as part of the Tarsnap + * online backup system. + */ + +#include "lyra2re3.h" +#include +#include +#include +#include +#include "../sha3/sph_blake.h" +#include "../sha3/sph_cubehash.h" +#include "../sha3/sph_bmw.h" + +void lyra2re3_hash(const char* input, char* output, uint32_t len) +{ + sph_blake256_context ctx_blake; + sph_cubehash256_context ctx_cubehash; + sph_bmw256_context ctx_bmw; + + uint32_t hashA[8], hashB[8]; + + sph_blake256_init(&ctx_blake); + sph_blake256(&ctx_blake, input, 80); + sph_blake256_close (&ctx_blake, hashA); + + LYRA2_3(hashB, 32, hashA, 32, hashA, 32, 1, 4, 4); + + sph_cubehash256_init(&ctx_cubehash); + sph_cubehash256(&ctx_cubehash, hashB, 32); + sph_cubehash256_close(&ctx_cubehash, hashA); + + LYRA2_3(hashB, 32, hashA, 32, hashA, 32, 1, 4, 4); + + sph_bmw256_init(&ctx_bmw); + sph_bmw256(&ctx_bmw, hashB, 32); + sph_bmw256_close(&ctx_bmw, hashA); + + memcpy(output, hashA, 32); +} diff --git a/stratum/algos/lyra2re3.h b/stratum/algos/lyra2re3.h new file mode 100644 index 000000000..a8b0b5ee9 --- /dev/null +++ b/stratum/algos/lyra2re3.h @@ -0,0 +1,16 @@ +#ifndef LYRA2RE3_H +#define LYRA2RE3_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void lyra2re3_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/stratum/algos/lyra2v3.c b/stratum/algos/lyra2v3.c new file mode 100644 index 000000000..efc5ee2ff --- /dev/null +++ b/stratum/algos/lyra2v3.c @@ -0,0 +1,69 @@ +/*- + * Copyright 2009 Colin Percival, 2011 ArtForz, 2013 Neisklar, 2014 James Lovejoy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file was originally written by Colin Percival as part of the Tarsnap + * online backup system. + */ + +#include +#include +#include +#include + +#include "../sha3/sph_blake.h" +#include "../sha3/sph_cubehash.h" +#include "../sha3/sph_bmw.h" + +#include "Lyra2.h" + +void lyra2v3_hash(const char* input, char* output, uint32_t len) +{ + uint32_t hash[8], hashB[8]; + + sph_blake256_context ctx_blake; + sph_cubehash256_context ctx_cubehash; + sph_bmw256_context ctx_bmw; + + sph_blake256_set_rounds(14); + + sph_blake256_init(&ctx_blake); + sph_blake256(&ctx_blake, input, len); /* 80 */ + sph_blake256_close(&ctx_blake, hash); + + LYRA2_3(hashB, 32, hash, 32, hash, 32, 1, 4, 4); + + sph_cubehash256_init(&ctx_cubehash); + sph_cubehash256(&ctx_cubehash, hashB, 32); + sph_cubehash256_close(&ctx_cubehash, hash); + + LYRA2_3(hashB, 32, hash, 32, hash, 32, 1, 4, 4); + + sph_bmw256_init(&ctx_bmw); + sph_bmw256(&ctx_bmw, hashB, 32); + sph_bmw256_close(&ctx_bmw, hash); + + memcpy(output, hash, 32); +} + diff --git a/stratum/algos/lyra2v3.h b/stratum/algos/lyra2v3.h new file mode 100644 index 000000000..8cb341de7 --- /dev/null +++ b/stratum/algos/lyra2v3.h @@ -0,0 +1,16 @@ +#ifndef LYRA2V3_H +#define LYRA2V3_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void lyra2v3_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/stratum/algos/lyra2vc0ban.c b/stratum/algos/lyra2vc0ban.c new file mode 100644 index 000000000..3a22405d0 --- /dev/null +++ b/stratum/algos/lyra2vc0ban.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include "../sha3/sph_blake.h" +#include "../sha3/sph_cubehash.h" +#include "../sha3/sph_keccak.h" +#include "../sha3/sph_skein.h" +#include "../sha3/sph_bmw.h" +#include "Lyra2.h" + +void lyra2vc0ban_hash(const char* input, char* output, uint32_t len) +{ + uint32_t hashA[8], hashB[8]; + + sph_blake256_context ctx_blake; + sph_keccak256_context ctx_keccak; + sph_skein256_context ctx_skein; + sph_bmw256_context ctx_bmw; + sph_cubehash256_context ctx_cube; + + sph_blake256_set_rounds(14); + + sph_blake256_init(&ctx_blake); + sph_blake256(&ctx_blake, input, len); + sph_blake256_close(&ctx_blake, hashA); + + sph_cubehash256_init(&ctx_cube); + sph_cubehash256(&ctx_cube, hashA, 32); + sph_cubehash256_close(&ctx_cube, hashB); + + sph_cubehash256_init(&ctx_cube); + sph_cubehash256(&ctx_cube, hashB, 32); + sph_cubehash256_close(&ctx_cube, hashA); + + LYRA2(hashB, 32, hashA, 32, hashA, 32, 1, 4, 4); + + sph_skein256_init(&ctx_skein); + sph_skein256(&ctx_skein, hashB, 32); + sph_skein256_close(&ctx_skein, hashA); + + sph_keccak256_init(&ctx_keccak); + sph_keccak256(&ctx_keccak, hashA, 32); + sph_keccak256_close(&ctx_keccak, hashB); + + sph_bmw256_init(&ctx_bmw); + sph_bmw256(&ctx_bmw, hashB, 32); + sph_bmw256_close(&ctx_bmw, hashA); + + memcpy(output, hashA, 32); +} diff --git a/stratum/algos/lyra2vc0ban.h b/stratum/algos/lyra2vc0ban.h new file mode 100644 index 000000000..fc2f2db99 --- /dev/null +++ b/stratum/algos/lyra2vc0ban.h @@ -0,0 +1,16 @@ +#ifndef LYRA2VC0BAN_H +#define LYRA2VC0BAN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void lyra2vc0ban_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/stratum/algos/lyra2z330.c b/stratum/algos/lyra2z330.c new file mode 100644 index 000000000..2e718952a --- /dev/null +++ b/stratum/algos/lyra2z330.c @@ -0,0 +1,19 @@ +#include +#include +#include +#include + +#include "Lyra2-z.h" + +#define _ALIGN(x) __attribute__ ((aligned(x))) + +//extern uint64_t lyra2z330_height; + +void lyra2z330_hash(const char* input, char* output, uint32_t len) +{ + uint32_t _ALIGN(64) hash[8]; + + LYRA2z((void*)hash, 32, (void*)input, len, (void*)input, len, 2, 330, 256); + + memcpy(output, hash, 32); +} diff --git a/stratum/algos/lyra2z330.h b/stratum/algos/lyra2z330.h new file mode 100644 index 000000000..e61ec21bd --- /dev/null +++ b/stratum/algos/lyra2z330.h @@ -0,0 +1,18 @@ +#ifndef LYRA2Z330_H +#define LYRA2Z330_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void lyra2z330_hash(const char* input, char* output, uint32_t len); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/stratum/algos/lyra2zz.c b/stratum/algos/lyra2zz.c new file mode 100644 index 000000000..f1b14415c --- /dev/null +++ b/stratum/algos/lyra2zz.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include + +#include "Lyra2-zz.h" + +#include + +#define _ALIGN(x) __attribute__ ((aligned(x))) + +extern uint64_t lyra2z_height; + +void lyra2zz_hash(const char* input, char* output, uint32_t len) +{ + uint32_t _ALIGN(64) hashB[8], hash[8]; + sph_blake256_context ctx_blake; + + sph_blake256_set_rounds(14); + + sph_blake256_init(&ctx_blake); + sph_blake256(&ctx_blake, input, 112); + sph_blake256_close(&ctx_blake, hashB); + + LYRA2ZZ(hash, 32, hashB, 32, hashB, 32, 8, 8, 8); + + memcpy(output, hash, 32); +} diff --git a/stratum/algos/lyra2zz.h b/stratum/algos/lyra2zz.h new file mode 100644 index 000000000..ad524ec5e --- /dev/null +++ b/stratum/algos/lyra2zz.h @@ -0,0 +1,16 @@ +#ifndef LYRA2ZZ_H +#define LYRA2ZZ_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void lyra2zz_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/stratum/algos/makefile b/stratum/algos/makefile index d8edf0b44..2b454a4fd 100644 --- a/stratum/algos/makefile +++ b/stratum/algos/makefile @@ -8,21 +8,21 @@ CXXFLAGS = -O2 -I.. -march=native CFLAGS= $(CXXFLAGS) -std=gnu99 LDFLAGS=-O2 -lgmp -SOURCES=lyra2re.c lyra2v2.c Lyra2.c lyra2z.c Lyra2-z.c Sponge.c allium.c \ - c11.c x11.c x12.c x13.c hsr14.c sm3.c x14.c x15.c x17.c \ - x22i.c SWIFFTX/SWIFFTX.c \ - blake.c blakecoin.c blake2b.c blake2s.c jha.c keccak.c lbry.c tribus.c exosis.c \ - deep.c fresh.c groestl.c neoscrypt.c nist5.c quark.c qubit.c skein.c skein2.c \ - bitcore.c timetravel.c x11evo.c x16r.c x16s.c xevan.c bastion.c hmq17.c sonoa.c \ +SOURCES=lyra2re.c lyra2v2.c lyra2v3.c Lyra2.c lyra2z.c Lyra2-z.c lyra2zz.c Lyra2-zz.c lyra2z330.c lyra2vc0ban.c Sponge.c allium.c \ + c11.c x11.c x12.c x13.c hsr14.c x14.c x15.c x17.c x17r.c x18.c \ + x22i.c SWIFFTX/SWIFFTX.c lane.c x25x.c \ + blake.c blakecoin.c blake2b.c blake2s.c blake2-ref/blake2b.c blake2-ref/blake2s.c jha.c keccak.c lbry.c tribus.c exosis.c \ + deep.c fresh.c groestl.c neoscrypt.c nist5.c quark.c qubit.c skein.c skein2.c bmw512.c \ + bitcore.c timetravel.c x11evo.c x16r.c x16s.c x16rt.c x16rv2.c xevan.c bastion.c hmq17.c sonoa.c \ bmw.c luffa.c pentablake.c vitalium.c whirlpool.c whirlpoolx.c zr5.c \ - scrypt.c scryptn.c sha256.c sha256t.c sha256q.c \ - yescrypt.c yescrypt-opt.c sha256_Y.c \ + scrypt.c scryptn.c sha256.c sha256t.c sha256q.c sha256-d.c minotaur.c \ a5a.c a5amath.c m7m.c magimath.cpp velvet.c \ - argon2a.c blake2/blake2b.c ar2/argon2.c ar2/core.c ar2/encoding.c ar2/opt.c ar2/thread.c ar2/ar2-scrypt-jane.c \ - hive.c pomelo.c hex.c argon2d-dyn.c \ - phi.c phi2.c polytimos.c rainforest.c skunk.c sib.c veltor.c gost.c aergo.c lbk3.c + blake2/blake2b.c argon2d/argon2.c argon2d/core.c argon2d/encoding.c argon2d/opt.c argon2d/thread.c \ + hive.c pomelo.c hex.c argon2m.c argon2d.c geek.c balloon.c \ + phi.c phi2.c polytimos.c rainforest.c skunk.c sib.c veltor.c gost.c aergo.c x20r.c x21s.c lbk3.c pipehash.c gltalgos.c \ + yespower/yespower-platform.c yespower/yespower-combined.c sha256-P.c dedal.c phi1612.c bcd.c \ -OBJECTS=$(SOURCES:%.c=%.o) $(SOURCES:%.cpp=%.o) +OBJECTS=$(SOURCES:%.c=%.o) $(SOURCES:%.cpp=%.o) $(SOURCES:%.cc=%.o) OUTPUT=libalgos.a all: $(SOURCES) $(OUTPUT) diff --git a/stratum/algos/minotaur.c b/stratum/algos/minotaur.c new file mode 100644 index 000000000..b88f4b205 --- /dev/null +++ b/stratum/algos/minotaur.c @@ -0,0 +1,226 @@ +// Minotaur hash + +#include "minotaur.h" + +#include +#include +#include +#include + +#include "sha3/sph_blake.h" +#include "sha3/sph_bmw.h" +#include "sha3/sph_groestl.h" +#include "sha3/sph_jh.h" +#include "sha3/sph_keccak.h" +#include "sha3/sph_skein.h" +#include "sha3/sph_luffa.h" +#include "sha3/sph_cubehash.h" +#include "sha3/sph_shavite.h" +#include "sha3/sph_simd.h" +#include "sha3/sph_echo.h" +#include "sha3/sph_hamsi.h" +#include "sha3/sph_fugue.h" +#include "sha3/sph_shabal.h" +#include "sha3/sph_whirlpool.h" +#include "sha3/sph_sha2.h" + +#ifndef _MSC_VER +#define _ALIGN(x) __attribute__ ((aligned(x))) +#else +#define _ALIGN(x) __declspec(align(x)) +#endif + +// Config +#define MINOTAUR_ALGO_COUNT 16 + +typedef struct TortureNode TortureNode; +typedef struct TortureGarden TortureGarden; + +// Graph of hash algos plus SPH contexts +struct TortureGarden { + sph_blake512_context context_blake; + sph_bmw512_context context_bmw; + sph_cubehash512_context context_cubehash; + sph_echo512_context context_echo; + sph_fugue512_context context_fugue; + sph_groestl512_context context_groestl; + sph_hamsi512_context context_hamsi; + sph_jh512_context context_jh; + sph_keccak512_context context_keccak; + sph_luffa512_context context_luffa; + sph_shabal512_context context_shabal; + sph_shavite512_context context_shavite; + sph_simd512_context context_simd; + sph_skein512_context context_skein; + sph_whirlpool_context context_whirlpool; + sph_sha512_context context_sha2; + + struct TortureNode { + unsigned int algo; + TortureNode *childLeft; + TortureNode *childRight; + } nodes[22]; +}; + +// Get a 64-byte hash for given 64-byte input, using given TortureGarden contexts and given algo index +void get_hash(void *output, const void *input, TortureGarden *garden, unsigned int algo) +{ + unsigned char _ALIGN(64) hash[64]; + + switch (algo) { + case 0: + sph_blake512_init(&garden->context_blake); + sph_blake512(&garden->context_blake, input, 64); + sph_blake512_close(&garden->context_blake, hash); + break; + case 1: + sph_bmw512_init(&garden->context_bmw); + sph_bmw512(&garden->context_bmw, input, 64); + sph_bmw512_close(&garden->context_bmw, hash); + break; + case 2: + sph_cubehash512_init(&garden->context_cubehash); + sph_cubehash512(&garden->context_cubehash, input, 64); + sph_cubehash512_close(&garden->context_cubehash, hash); + break; + case 3: + sph_echo512_init(&garden->context_echo); + sph_echo512(&garden->context_echo, input, 64); + sph_echo512_close(&garden->context_echo, hash); + break; + case 4: + sph_fugue512_init(&garden->context_fugue); + sph_fugue512(&garden->context_fugue, input, 64); + sph_fugue512_close(&garden->context_fugue, hash); + break; + case 5: + sph_groestl512_init(&garden->context_groestl); + sph_groestl512(&garden->context_groestl, input, 64); + sph_groestl512_close(&garden->context_groestl, hash); + break; + case 6: + sph_hamsi512_init(&garden->context_hamsi); + sph_hamsi512(&garden->context_hamsi, input, 64); + sph_hamsi512_close(&garden->context_hamsi, hash); + break; + case 7: + sph_sha512_init(&garden->context_sha2); + sph_sha512(&garden->context_sha2, input, 64); + sph_sha512_close(&garden->context_sha2, hash); + break; + case 8: + sph_jh512_init(&garden->context_jh); + sph_jh512(&garden->context_jh, input, 64); + sph_jh512_close(&garden->context_jh, hash); + break; + case 9: + sph_keccak512_init(&garden->context_keccak); + sph_keccak512(&garden->context_keccak, input, 64); + sph_keccak512_close(&garden->context_keccak, hash); + break; + case 10: + sph_luffa512_init(&garden->context_luffa); + sph_luffa512(&garden->context_luffa, input, 64); + sph_luffa512_close(&garden->context_luffa, hash); + break; + case 11: + sph_shabal512_init(&garden->context_shabal); + sph_shabal512(&garden->context_shabal, input, 64); + sph_shabal512_close(&garden->context_shabal, hash); + break; + case 12: + sph_shavite512_init(&garden->context_shavite); + sph_shavite512(&garden->context_shavite, input, 64); + sph_shavite512_close(&garden->context_shavite, hash); + break; + case 13: + sph_simd512_init(&garden->context_simd); + sph_simd512(&garden->context_simd, input, 64); + sph_simd512_close(&garden->context_simd, hash); + break; + case 14: + sph_skein512_init(&garden->context_skein); + sph_skein512(&garden->context_skein, input, 64); + sph_skein512_close(&garden->context_skein, hash); + break; + case 15: + sph_whirlpool_init(&garden->context_whirlpool); + sph_whirlpool(&garden->context_whirlpool, input, 64); + sph_whirlpool_close(&garden->context_whirlpool, hash); + break; + } + + // Output the hash + memcpy(output, hash, 64); +} + +// Recursively traverse a given torture garden starting with a given hash and given node within the garden. The hash is overwritten with the final hash. +void traverse_garden(TortureGarden *garden, void *hash, TortureNode *node) +{ + unsigned char _ALIGN(64) partialHash[64]; + get_hash(partialHash, hash, garden, node->algo); + + if (partialHash[63] % 2 == 0) { // Last byte of output hash is even + if (node->childLeft != NULL) + traverse_garden(garden, partialHash, node->childLeft); + } else { // Last byte of output hash is odd + if (node->childRight != NULL) + traverse_garden(garden, partialHash, node->childRight); + } + + memcpy(hash, partialHash, 64); +} + +// Associate child nodes with a parent node +inline void link_nodes(TortureNode *parent, TortureNode *childLeft, TortureNode *childRight) +{ + parent->childLeft = childLeft; + parent->childRight = childRight; +} + +// Produce a 32-byte hash from 80-byte input data +void minotaur_hash(const char* input, char* output, uint32_t len) +{ + // Create torture garden nodes. Note that both sides of 19 and 20 lead to 21, and 21 has no children (to make traversal complete). + // Every path through the garden stops at 7 nodes. + TortureGarden garden; + link_nodes(&garden.nodes[0], &garden.nodes[1], &garden.nodes[2]); + link_nodes(&garden.nodes[1], &garden.nodes[3], &garden.nodes[4]); + link_nodes(&garden.nodes[2], &garden.nodes[5], &garden.nodes[6]); + link_nodes(&garden.nodes[3], &garden.nodes[7], &garden.nodes[8]); + link_nodes(&garden.nodes[4], &garden.nodes[9], &garden.nodes[10]); + link_nodes(&garden.nodes[5], &garden.nodes[11], &garden.nodes[12]); + link_nodes(&garden.nodes[6], &garden.nodes[13], &garden.nodes[14]); + link_nodes(&garden.nodes[7], &garden.nodes[15], &garden.nodes[16]); + link_nodes(&garden.nodes[8], &garden.nodes[15], &garden.nodes[16]); + link_nodes(&garden.nodes[9], &garden.nodes[15], &garden.nodes[16]); + link_nodes(&garden.nodes[10], &garden.nodes[15], &garden.nodes[16]); + link_nodes(&garden.nodes[11], &garden.nodes[17], &garden.nodes[18]); + link_nodes(&garden.nodes[12], &garden.nodes[17], &garden.nodes[18]); + link_nodes(&garden.nodes[13], &garden.nodes[17], &garden.nodes[18]); + link_nodes(&garden.nodes[14], &garden.nodes[17], &garden.nodes[18]); + link_nodes(&garden.nodes[15], &garden.nodes[19], &garden.nodes[20]); + link_nodes(&garden.nodes[16], &garden.nodes[19], &garden.nodes[20]); + link_nodes(&garden.nodes[17], &garden.nodes[19], &garden.nodes[20]); + link_nodes(&garden.nodes[18], &garden.nodes[19], &garden.nodes[20]); + link_nodes(&garden.nodes[19], &garden.nodes[21], &garden.nodes[21]); + link_nodes(&garden.nodes[20], &garden.nodes[21], &garden.nodes[21]); + garden.nodes[21].childLeft = NULL; + garden.nodes[21].childRight = NULL; + + // Find initial sha512 hash + unsigned char _ALIGN(64) hash[64]; + sph_sha512_init(&garden.context_sha2); + sph_sha512(&garden.context_sha2, input, 80); + sph_sha512_close(&garden.context_sha2, hash); + + // Assign algos to torture garden nodes based on initial hash + for (int i = 0; i < 22; i++) + garden.nodes[i].algo = hash[i] % MINOTAUR_ALGO_COUNT; + + // Send the initial hash through the torture garden + traverse_garden(&garden, hash, &garden.nodes[0]); + + // Truncate the result + memcpy(output, hash, len); +} diff --git a/stratum/algos/minotaur.h b/stratum/algos/minotaur.h new file mode 100644 index 000000000..5e6db8733 --- /dev/null +++ b/stratum/algos/minotaur.h @@ -0,0 +1,18 @@ +// Minotaur hash + +#ifndef MINOTAUR_H +#define MINOTAUR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void minotaur_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/stratum/algos/phi1612.c b/stratum/algos/phi1612.c new file mode 100644 index 000000000..cea04ff47 --- /dev/null +++ b/stratum/algos/phi1612.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "gost.h" + +#include "common.h" + +void phi1612_hash(const char* input, char* output, uint32_t len) +{ + sph_skein512_context ctx_skein; + sph_jh512_context ctx_jh; + sph_cubehash512_context ctx_cubehash; + sph_fugue512_context ctx_fugue; + sph_gost512_context ctx_gost; + sph_echo512_context ctx_echo; + + uint8_t _ALIGN(128) hash[64]; + + sph_skein512_init(&ctx_skein); + sph_skein512(&ctx_skein, input, len); + sph_skein512_close(&ctx_skein, (void*) hash); + + sph_jh512_init(&ctx_jh); + sph_jh512(&ctx_jh, (const void*) hash, 64); + sph_jh512_close(&ctx_jh, (void*) hash); + + sph_cubehash512_init(&ctx_cubehash); + sph_cubehash512(&ctx_cubehash, (const void*) hash, 64); + sph_cubehash512_close(&ctx_cubehash, (void*) hash); + + sph_fugue512_init(&ctx_fugue); + sph_fugue512(&ctx_fugue, (const void*) hash, 64); + sph_fugue512_close(&ctx_fugue, (void*) hash); + + sph_gost512_init(&ctx_gost); + sph_gost512(&ctx_gost, (const void*) hash, 64); + sph_gost512_close(&ctx_gost, (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); +} diff --git a/stratum/algos/phi1612.h b/stratum/algos/phi1612.h new file mode 100644 index 000000000..7b59354dd --- /dev/null +++ b/stratum/algos/phi1612.h @@ -0,0 +1,16 @@ +#ifndef PHI1612_H +#define PHI1612_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void phi1612_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/stratum/algos/pipehash.c b/stratum/algos/pipehash.c new file mode 100644 index 000000000..728e6c3f5 --- /dev/null +++ b/stratum/algos/pipehash.c @@ -0,0 +1,188 @@ +/* + * pipehash cryptographic hash function + * + * Copyright (c) 2018, uou pipe developer + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of the FreeBSD Project. + */ +#include "sha256.h" +#include +#include +//#include "sph_blake.h" +//#include "sph_groestl.h" +#include +#include +#include "pipehash.h" +#include +#include + + +void shift_left(unsigned char *data, unsigned int shift){ + unsigned char a[32]; + memcpy(a,data,32); + + memset(data,0,32); + + int k = shift / 8; + shift = shift % 8; + for (int i = 0; i < 32; i++) + { + if (i+k+1 < 32 && shift != 0) + data[i+k+1] |= (a[i] >> (8-shift)); + if (i+k < 32) + data[i+k] |= (a[i] << shift); + } +} + +void shift_right(unsigned char *data, unsigned int shift){ + unsigned char a[32]; + memcpy(a,data,32); + + memset(data,0,32); + + int k = shift / 8;//How bytes to shift + shift = shift % 8; //How bits to shift in current byte + for (int i = 0; i < 32; i++) + { + if (i-k-1 >= 0 && shift != 0) + data[i-k-1] |= (a[i] << (8-shift)); + if (i-k >= 0) + data[i-k] |= (a[i] >> shift); + } +} + +void or_op(unsigned char *data,int val){ + data[0] |= (int)val; +} + +int and_result_not_equ_zero(unsigned char *in1,unsigned char *in2){ + for (int i = 0; i < 32; i++){ + if(in1[i]&in2[i]) + return 1; + } + return 0; +} + + +/* Combine stop 64-bits from each hash into a single hash */ +void combine_hashes(unsigned char* hash1, unsigned char* hash2, unsigned char* hash3, unsigned char* hash4,unsigned char* output) +{ + unsigned char mask[32]; + memset(mask,0,32);mask[31]=0x80; + + unsigned char hash[4][32]; + memcpy(hash[0],hash1,32); + memcpy(hash[1],hash2,32); + memcpy(hash[2],hash3,32); + memcpy(hash[3],hash4,32); + + + /* Transpose first 64 bits of each hash into final */ + unsigned char final[32]={0}; + for (unsigned int i = 0; i < 64; i++) { + for (unsigned int j = 0; j < 4; j++) { + shift_left(final,1); + if (and_result_not_equ_zero(hash[j] , mask)) + or_op(final,1); + } + shift_right(mask,1); + } + + memcpy(output,final,32); +} + +/* Combines top 64-bits from each hash into a single hash */ +static void cpu_combine_hashes(uint32_t *out, const uint32_t *hash1, const uint32_t *hash2, const uint32_t *hash3, const uint32_t *hash4) +{ + const uint32_t *hash[4] = { hash1, hash2, hash3, hash4 }; + int bits; + unsigned int i; + uint32_t mask; + unsigned int k; + + /* Transpose first 64 bits of each hash into out */ + memset(out, 0, 32); + bits = 0; + for (i = 7; i >= 6; i--) { + for (mask = 0x80000000; mask; mask >>= 1) { + for (k = 0; k < 4; k++) { + out[(255 - bits) / 32] <<= 1; + if ((hash[k][i] & mask) != 0) + out[(255 - bits) / 32] |= 1; + bits++; + } + } + } +} + +void pipe_hash(const char *input,char *output,unsigned int len) +{ + unsigned char hash1[32]; + HEFTY1(input, len , hash1); + + /* HEFTY1 is new, so take an extra security measure to eliminate + * the possiblity of collisions: + * + * Hash(x) = SHA256(x + HEFTY1(x)) + * + * N.B. '+' is concatenation. + */ + unsigned char hash2[32]; + SHA256_CTX ctx; + SHA256_Init(&ctx); + SHA256_Update(&ctx,input,len); + SHA256_Update(&ctx, hash1, 32); + SHA256_Final(hash2, &ctx); + + /* Additional security: Do not rely on a single cryptographic hash + * function. Instead, combine the outputs of 4 of the most secure + * cryptographic hash functions-- SHA256, KECCAK512, GROESTL512 + * and BLAKE512. + */ + + unsigned char hash3[64]; + sph_keccak512_context keccakCtx; + sph_keccak512_init(&keccakCtx); + sph_keccak512(&keccakCtx,input,len); + sph_keccak512(&keccakCtx, hash1, 32); + sph_keccak512_close(&keccakCtx, (void *)hash3); + + unsigned char hash4[64]; + sph_groestl512_context groestlCtx; + sph_groestl512_init(&groestlCtx); + sph_groestl512(&groestlCtx,input,len); + sph_groestl512(&groestlCtx, hash1, 32); + sph_groestl512_close(&groestlCtx, (void *)hash4); + + unsigned char hash5[64]; + sph_blake512_context blakeCtx; + sph_blake512_init(&blakeCtx); + sph_blake512(&blakeCtx,input,len); + sph_blake512(&blakeCtx, hash1, 32); + sph_blake512_close(&blakeCtx, (void *)hash5); + + cpu_combine_hashes(output,hash2, hash3, hash4, hash5); +} diff --git a/stratum/algos/pipehash.h b/stratum/algos/pipehash.h new file mode 100644 index 000000000..3d9db3d14 --- /dev/null +++ b/stratum/algos/pipehash.h @@ -0,0 +1,50 @@ +/* + * PIPEHASH cryptographic hash function + * + * Copyright (c) 2018, UOU PIPE Developers + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of the FreeBSD Project. + */ + +#ifndef __PIPEHASH_H__ +#define __PIPEHASH_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef WIN32 +#include +#endif + +#include + +void pipe_hash(const char *input,char *output,unsigned int len); +#ifdef __cplusplus +} +#endif + +#endif /* __PIPEHASH_H__ */ diff --git a/stratum/algos/renesis.c b/stratum/algos/renesis.c new file mode 100644 index 000000000..f2f67d9cb --- /dev/null +++ b/stratum/algos/renesis.c @@ -0,0 +1,69 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// Copyright (c) 2018, hav0k Renesis Developers & Renesis Group +// This is the pre-fork hash for Renesis. +// http://renesis.io + +#include +#include +#include +#include + +#include "../sha3/sph_skein.h" +#include "../sha3/sph_keccak.h" +#include "../sha3/sph_simd.h" +#include "../sha3/sph_shavite.h" +#include "../sha3/sph_jh.h" +#include "../sha3/sph_cubehash.h" +#include "../sha3/sph_fugue.h" +#include "../sha3/sph_gost.h" + +void renesis_hash(const char* input, char* output, uint32_t len) +{ + sph_skein512_context ctx_skein; + sph_keccak512_context ctx_keccak; + sph_simd512_context ctx_simd; + sph_shavite512_context ctx_shavite; + sph_jh512_context ctx_jh; + sph_cubehash512_context ctx_cubehash; + sph_fugue512_context ctx_fugue; + sph_gost512_context ctx_gost; + + uint32_t hash[64]; + + sph_skein512_init(&ctx_skein); + sph_skein512 (&ctx_skein, input, len); + sph_skein512_close (&ctx_skein, hash); + + sph_keccak512_init(&ctx_keccak); + sph_keccak512 (&ctx_keccak, hash, 64); + sph_keccak512_close(&ctx_keccak, hash); + + sph_simd512_init (&ctx_simd); + sph_simd512 (&ctx_simd, hash, 64); + sph_simd512_close(&ctx_simd, hash); + + sph_shavite512_init (&ctx_shavite); + sph_shavite512 (&ctx_shavite, hash, 64); + sph_shavite512_close(&ctx_shavite, hash); + + sph_jh512_init(&ctx_jh); + sph_jh512 (&ctx_jh, hash, 64); + sph_jh512_close(&ctx_jh, hash); + + sph_cubehash512_init(&ctx_cubehash); + sph_cubehash512 (&ctx_cubehash, hash, 64); + sph_cubehash512_close(&ctx_cubehash, hash); + + sph_fugue512_init (&ctx_fugue); + sph_fugue512 (&ctx_fugue, hash, 64); + sph_fugue512_close (&ctx_fugue, hash); + + sph_gost512_init (&ctx_gost); + sph_gost512 (&ctx_gost, hash, 64); + sph_gost512_close(&ctx_gost, hash); + + memcpy(output, hash, 32); +} \ No newline at end of file diff --git a/stratum/algos/renesis.h b/stratum/algos/renesis.h new file mode 100644 index 000000000..c1ca11904 --- /dev/null +++ b/stratum/algos/renesis.h @@ -0,0 +1,16 @@ +#ifndef RENESIS_H +#define RENESIS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void renesis_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/stratum/algos/sha256-P.c b/stratum/algos/sha256-P.c new file mode 100644 index 000000000..bd14b171e --- /dev/null +++ b/stratum/algos/sha256-P.c @@ -0,0 +1,646 @@ +/*- + * Copyright 2005-2016 Colin Percival + * Copyright 2016-2018 Alexander Peslyak + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +#include "insecure_memzero.h" +#include "sysendian_yp.h" + +#include "sha256-P.h" + +#ifdef __ICC +/* Miscompile with icc 14.0.0 (at least), so don't use restrict there */ +#define restrict +#elif __STDC_VERSION__ >= 199901L +/* Have restrict */ +#elif defined(__GNUC__) +#define restrict __restrict +#else +#define restrict +#endif + +/* + * Encode a length len*2 vector of (uint32_t) into a length len*8 vector of + * (uint8_t) in big-endian form. + */ +static void +be32enc_vect(uint8_t * dst, const uint32_t * src, size_t len) +{ + + /* Encode vector, two words at a time. */ + do { + be32enc(&dst[0], src[0]); + be32enc(&dst[4], src[1]); + src += 2; + dst += 8; + } while (--len); +} + +/* + * Decode a big-endian length len*8 vector of (uint8_t) into a length + * len*2 vector of (uint32_t). + */ +static void +be32dec_vect(uint32_t * dst, const uint8_t * src, size_t len) +{ + + /* Decode vector, two words at a time. */ + do { + dst[0] = be32dec(&src[0]); + dst[1] = be32dec(&src[4]); + src += 8; + dst += 2; + } while (--len); +} + +/* SHA256 round constants. */ +static const uint32_t Krnd[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +/* Elementary functions used by SHA256 */ +#define Ch(x, y, z) ((x & (y ^ z)) ^ z) +#define Maj(x, y, z) ((x & (y | z)) | (y & z)) +#define SHR(x, n) (x >> n) +#define ROTR(x, n) ((x >> n) | (x << (32 - n))) +#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) +#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) +#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3)) +#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10)) + +/* SHA256 round function */ +#define RND(a, b, c, d, e, f, g, h, k) \ + h += S1(e) + Ch(e, f, g) + k; \ + d += h; \ + h += S0(a) + Maj(a, b, c); + +/* Adjusted round function for rotating state */ +#define RNDr(S, W, i, ii) \ + RND(S[(64 - i) % 8], S[(65 - i) % 8], \ + S[(66 - i) % 8], S[(67 - i) % 8], \ + S[(68 - i) % 8], S[(69 - i) % 8], \ + S[(70 - i) % 8], S[(71 - i) % 8], \ + W[i + ii] + Krnd[i + ii]) + +/* Message schedule computation */ +#define MSCH(W, ii, i) \ + W[i + ii + 16] = s1(W[i + ii + 14]) + W[i + ii + 9] + s0(W[i + ii + 1]) + W[i + ii] + +/* + * SHA256 block compression function. The 256-bit state is transformed via + * the 512-bit input block to produce a new state. + */ +static void +SHA256_Transform(uint32_t state[static restrict 8], + const uint8_t block[static restrict 64], + uint32_t W[static restrict 64], uint32_t S[static restrict 8]) +{ + int i; + + /* 1. Prepare the first part of the message schedule W. */ + be32dec_vect(W, block, 8); + + /* 2. Initialize working variables. */ + memcpy(S, state, 32); + + /* 3. Mix. */ + for (i = 0; i < 64; i += 16) { + RNDr(S, W, 0, i); + RNDr(S, W, 1, i); + RNDr(S, W, 2, i); + RNDr(S, W, 3, i); + RNDr(S, W, 4, i); + RNDr(S, W, 5, i); + RNDr(S, W, 6, i); + RNDr(S, W, 7, i); + RNDr(S, W, 8, i); + RNDr(S, W, 9, i); + RNDr(S, W, 10, i); + RNDr(S, W, 11, i); + RNDr(S, W, 12, i); + RNDr(S, W, 13, i); + RNDr(S, W, 14, i); + RNDr(S, W, 15, i); + + if (i == 48) + break; + MSCH(W, 0, i); + MSCH(W, 1, i); + MSCH(W, 2, i); + MSCH(W, 3, i); + MSCH(W, 4, i); + MSCH(W, 5, i); + MSCH(W, 6, i); + MSCH(W, 7, i); + MSCH(W, 8, i); + MSCH(W, 9, i); + MSCH(W, 10, i); + MSCH(W, 11, i); + MSCH(W, 12, i); + MSCH(W, 13, i); + MSCH(W, 14, i); + MSCH(W, 15, i); + } + + /* 4. Mix local working variables into global state. */ + state[0] += S[0]; + state[1] += S[1]; + state[2] += S[2]; + state[3] += S[3]; + state[4] += S[4]; + state[5] += S[5]; + state[6] += S[6]; + state[7] += S[7]; +} + +static const uint8_t PAD[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* Add padding and terminating bit-count. */ +static void +SHA256_Pad(SHA256_CTX * ctx, uint32_t tmp32[static restrict 72]) +{ + size_t r; + + /* Figure out how many bytes we have buffered. */ + r = (ctx->count >> 3) & 0x3f; + + /* Pad to 56 mod 64, transforming if we finish a block en route. */ + if (r < 56) { + /* Pad to 56 mod 64. */ + memcpy(&ctx->buf[r], PAD, 56 - r); + } else { + /* Finish the current block and mix. */ + memcpy(&ctx->buf[r], PAD, 64 - r); + SHA256_Transform(ctx->state, ctx->buf, &tmp32[0], &tmp32[64]); + + /* The start of the final block is all zeroes. */ + memset(&ctx->buf[0], 0, 56); + } + + /* Add the terminating bit-count. */ + be64enc(&ctx->buf[56], ctx->count); + + /* Mix in the final block. */ + SHA256_Transform(ctx->state, ctx->buf, &tmp32[0], &tmp32[64]); +} + +/* Magic initialization constants. */ +static const uint32_t initial_state[8] = { + 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, + 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 +}; + +/** + * SHA256_Init(ctx): + * Initialize the SHA256 context ${ctx}. + */ +void +SHA256_Init(SHA256_CTX * ctx) +{ + + /* Zero bits processed so far. */ + ctx->count = 0; + + /* Initialize state. */ + memcpy(ctx->state, initial_state, sizeof(initial_state)); +} + +/** + * SHA256_Update(ctx, in, len): + * Input ${len} bytes from ${in} into the SHA256 context ${ctx}. + */ +static void +_SHA256_Update(SHA256_CTX * ctx, const void * in, size_t len, + uint32_t tmp32[static restrict 72]) +{ + uint32_t r; + const uint8_t * src = in; + + /* Return immediately if we have nothing to do. */ + if (len == 0) + return; + + /* Number of bytes left in the buffer from previous updates. */ + r = (ctx->count >> 3) & 0x3f; + + /* Update number of bits. */ + ctx->count += (uint64_t)(len) << 3; + + /* Handle the case where we don't need to perform any transforms. */ + if (len < 64 - r) { + memcpy(&ctx->buf[r], src, len); + return; + } + + /* Finish the current block. */ + memcpy(&ctx->buf[r], src, 64 - r); + SHA256_Transform(ctx->state, ctx->buf, &tmp32[0], &tmp32[64]); + src += 64 - r; + len -= 64 - r; + + /* Perform complete blocks. */ + while (len >= 64) { + SHA256_Transform(ctx->state, src, &tmp32[0], &tmp32[64]); + src += 64; + len -= 64; + } + + /* Copy left over data into buffer. */ + memcpy(ctx->buf, src, len); +} + +/* Wrapper function for intermediate-values sanitization. */ +void +SHA256_Update(SHA256_CTX * ctx, const void * in, size_t len) +{ + uint32_t tmp32[72]; + + /* Call the real function. */ + _SHA256_Update(ctx, in, len, tmp32); + + /* Clean the stack. */ + insecure_memzero(tmp32, 288); +} + +/** + * SHA256_Final(digest, ctx): + * Output the SHA256 hash of the data input to the context ${ctx} into the + * buffer ${digest}. + */ +static void +_SHA256_Final(uint8_t digest[32], SHA256_CTX * ctx, + uint32_t tmp32[static restrict 72]) +{ + + /* Add padding. */ + SHA256_Pad(ctx, tmp32); + + /* Write the hash. */ + be32enc_vect(digest, ctx->state, 4); +} + +/* Wrapper function for intermediate-values sanitization. */ +void +SHA256_Final(uint8_t digest[32], SHA256_CTX * ctx) +{ + uint32_t tmp32[72]; + + /* Call the real function. */ + _SHA256_Final(digest, ctx, tmp32); + + /* Clear the context state. */ + insecure_memzero(ctx, sizeof(SHA256_CTX)); + + /* Clean the stack. */ + insecure_memzero(tmp32, 288); +} + +/** + * SHA256_Buf(in, len, digest): + * Compute the SHA256 hash of ${len} bytes from ${in} and write it to ${digest}. + */ +void +SHA256_Buf(const void * in, size_t len, uint8_t digest[32]) +{ + SHA256_CTX ctx; + uint32_t tmp32[72]; + + SHA256_Init(&ctx); + _SHA256_Update(&ctx, in, len, tmp32); + _SHA256_Final(digest, &ctx, tmp32); + + /* Clean the stack. */ + insecure_memzero(&ctx, sizeof(SHA256_CTX)); + insecure_memzero(tmp32, 288); +} + +/** + * HMAC_SHA256_Init(ctx, K, Klen): + * Initialize the HMAC-SHA256 context ${ctx} with ${Klen} bytes of key from + * ${K}. + */ +static void +_HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen, + uint32_t tmp32[static restrict 72], uint8_t pad[static restrict 64], + uint8_t khash[static restrict 32]) +{ + const uint8_t * K = _K; + size_t i; + + /* If Klen > 64, the key is really SHA256(K). */ + if (Klen > 64) { + SHA256_Init(&ctx->ictx); + _SHA256_Update(&ctx->ictx, K, Klen, tmp32); + _SHA256_Final(khash, &ctx->ictx, tmp32); + K = khash; + Klen = 32; + } + + /* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */ + SHA256_Init(&ctx->ictx); + memset(pad, 0x36, 64); + for (i = 0; i < Klen; i++) + pad[i] ^= K[i]; + _SHA256_Update(&ctx->ictx, pad, 64, tmp32); + + /* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */ + SHA256_Init(&ctx->octx); + memset(pad, 0x5c, 64); + for (i = 0; i < Klen; i++) + pad[i] ^= K[i]; + _SHA256_Update(&ctx->octx, pad, 64, tmp32); +} + +/* Wrapper function for intermediate-values sanitization. */ +void +HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen) +{ + uint32_t tmp32[72]; + uint8_t pad[64]; + uint8_t khash[32]; + + /* Call the real function. */ + _HMAC_SHA256_Init(ctx, _K, Klen, tmp32, pad, khash); + + /* Clean the stack. */ + insecure_memzero(tmp32, 288); + insecure_memzero(khash, 32); + insecure_memzero(pad, 64); +} + +/** + * HMAC_SHA256_Update(ctx, in, len): + * Input ${len} bytes from ${in} into the HMAC-SHA256 context ${ctx}. + */ +static void +_HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void * in, size_t len, + uint32_t tmp32[static restrict 72]) +{ + + /* Feed data to the inner SHA256 operation. */ + _SHA256_Update(&ctx->ictx, in, len, tmp32); +} + +/* Wrapper function for intermediate-values sanitization. */ +void +HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void * in, size_t len) +{ + uint32_t tmp32[72]; + + /* Call the real function. */ + _HMAC_SHA256_Update(ctx, in, len, tmp32); + + /* Clean the stack. */ + insecure_memzero(tmp32, 288); +} + +/** + * HMAC_SHA256_Final(digest, ctx): + * Output the HMAC-SHA256 of the data input to the context ${ctx} into the + * buffer ${digest}. + */ +static void +_HMAC_SHA256_Final(uint8_t digest[32], HMAC_SHA256_CTX * ctx, + uint32_t tmp32[static restrict 72], uint8_t ihash[static restrict 32]) +{ + + /* Finish the inner SHA256 operation. */ + _SHA256_Final(ihash, &ctx->ictx, tmp32); + + /* Feed the inner hash to the outer SHA256 operation. */ + _SHA256_Update(&ctx->octx, ihash, 32, tmp32); + + /* Finish the outer SHA256 operation. */ + _SHA256_Final(digest, &ctx->octx, tmp32); +} + +/* Wrapper function for intermediate-values sanitization. */ +void +HMAC_SHA256_Final(uint8_t digest[32], HMAC_SHA256_CTX * ctx) +{ + uint32_t tmp32[72]; + uint8_t ihash[32]; + + /* Call the real function. */ + _HMAC_SHA256_Final(digest, ctx, tmp32, ihash); + + /* Clean the stack. */ + insecure_memzero(tmp32, 288); + insecure_memzero(ihash, 32); +} + +/** + * HMAC_SHA256_Buf(K, Klen, in, len, digest): + * Compute the HMAC-SHA256 of ${len} bytes from ${in} using the key ${K} of + * length ${Klen}, and write the result to ${digest}. + */ +void +HMAC_SHA256_Buf(const void * K, size_t Klen, const void * in, size_t len, + uint8_t digest[32]) +{ + HMAC_SHA256_CTX ctx; + uint32_t tmp32[72]; + uint8_t tmp8[96]; + + _HMAC_SHA256_Init(&ctx, K, Klen, tmp32, &tmp8[0], &tmp8[64]); + _HMAC_SHA256_Update(&ctx, in, len, tmp32); + _HMAC_SHA256_Final(digest, &ctx, tmp32, &tmp8[0]); + + /* Clean the stack. */ + insecure_memzero(&ctx, sizeof(HMAC_SHA256_CTX)); + insecure_memzero(tmp32, 288); + insecure_memzero(tmp8, 96); +} + +/* Add padding and terminating bit-count, but don't invoke Transform yet. */ +static int +SHA256_Pad_Almost(SHA256_CTX * ctx, uint8_t len[static restrict 8], + uint32_t tmp32[static restrict 72]) +{ + uint32_t r; + + r = (ctx->count >> 3) & 0x3f; + if (r >= 56) + return -1; + + /* + * Convert length to a vector of bytes -- we do this now rather + * than later because the length will change after we pad. + */ + be64enc(len, ctx->count); + + /* Add 1--56 bytes so that the resulting length is 56 mod 64. */ + _SHA256_Update(ctx, PAD, 56 - r, tmp32); + + /* Add the terminating bit-count. */ + ctx->buf[63] = len[7]; + _SHA256_Update(ctx, len, 7, tmp32); + + return 0; +} + +/** + * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): + * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and + * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). + */ +void +YESPOWER_PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt, + size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen) +{ + HMAC_SHA256_CTX Phctx, PShctx, hctx; + uint32_t tmp32[72]; + union { + uint8_t tmp8[96]; + uint32_t state[8]; + } u; + size_t i; + uint8_t ivec[4]; + uint8_t U[32]; + uint8_t T[32]; + uint64_t j; + int k; + size_t clen; + + /* Sanity-check. */ + assert(dkLen <= 32 * (size_t)(UINT32_MAX)); + + if (c == 1 && (dkLen & 31) == 0 && (saltlen & 63) <= 51) { + uint32_t oldcount; + uint8_t * ivecp; + + /* Compute HMAC state after processing P and S. */ + _HMAC_SHA256_Init(&hctx, passwd, passwdlen, + tmp32, &u.tmp8[0], &u.tmp8[64]); + _HMAC_SHA256_Update(&hctx, salt, saltlen, tmp32); + + /* Prepare ictx padding. */ + oldcount = hctx.ictx.count & (0x3f << 3); + _HMAC_SHA256_Update(&hctx, "\0\0\0", 4, tmp32); + if ((hctx.ictx.count & (0x3f << 3)) < oldcount || + SHA256_Pad_Almost(&hctx.ictx, u.tmp8, tmp32)) + goto generic; /* Can't happen due to saltlen check */ + ivecp = hctx.ictx.buf + (oldcount >> 3); + + /* Prepare octx padding. */ + hctx.octx.count += 32 << 3; + SHA256_Pad_Almost(&hctx.octx, u.tmp8, tmp32); + + /* Iterate through the blocks. */ + for (i = 0; i * 32 < dkLen; i++) { + /* Generate INT(i + 1). */ + be32enc(ivecp, (uint32_t)(i + 1)); + + /* Compute U_1 = PRF(P, S || INT(i)). */ + memcpy(u.state, hctx.ictx.state, sizeof(u.state)); + SHA256_Transform(u.state, hctx.ictx.buf, + &tmp32[0], &tmp32[64]); + be32enc_vect(hctx.octx.buf, u.state, 4); + memcpy(u.state, hctx.octx.state, sizeof(u.state)); + SHA256_Transform(u.state, hctx.octx.buf, + &tmp32[0], &tmp32[64]); + be32enc_vect(&buf[i * 32], u.state, 4); + } + + goto cleanup; + } + +generic: + /* Compute HMAC state after processing P. */ + _HMAC_SHA256_Init(&Phctx, passwd, passwdlen, + tmp32, &u.tmp8[0], &u.tmp8[64]); + + /* Compute HMAC state after processing P and S. */ + memcpy(&PShctx, &Phctx, sizeof(HMAC_SHA256_CTX)); + _HMAC_SHA256_Update(&PShctx, salt, saltlen, tmp32); + + /* Iterate through the blocks. */ + for (i = 0; i * 32 < dkLen; i++) { + /* Generate INT(i + 1). */ + be32enc(ivec, (uint32_t)(i + 1)); + + /* Compute U_1 = PRF(P, S || INT(i)). */ + memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX)); + _HMAC_SHA256_Update(&hctx, ivec, 4, tmp32); + _HMAC_SHA256_Final(T, &hctx, tmp32, u.tmp8); + + if (c > 1) { + /* T_i = U_1 ... */ + memcpy(U, T, 32); + + for (j = 2; j <= c; j++) { + /* Compute U_j. */ + memcpy(&hctx, &Phctx, sizeof(HMAC_SHA256_CTX)); + _HMAC_SHA256_Update(&hctx, U, 32, tmp32); + _HMAC_SHA256_Final(U, &hctx, tmp32, u.tmp8); + + /* ... xor U_j ... */ + for (k = 0; k < 32; k++) + T[k] ^= U[k]; + } + } + + /* Copy as many bytes as necessary into buf. */ + clen = dkLen - i * 32; + if (clen > 32) + clen = 32; + memcpy(&buf[i * 32], T, clen); + } + + /* Clean the stack. */ + insecure_memzero(&Phctx, sizeof(HMAC_SHA256_CTX)); + insecure_memzero(&PShctx, sizeof(HMAC_SHA256_CTX)); + insecure_memzero(U, 32); + insecure_memzero(T, 32); + +cleanup: + insecure_memzero(&hctx, sizeof(HMAC_SHA256_CTX)); + insecure_memzero(tmp32, 288); + insecure_memzero(&u, sizeof(u)); +} diff --git a/stratum/algos/sha256-P.h b/stratum/algos/sha256-P.h new file mode 100644 index 000000000..17e491412 --- /dev/null +++ b/stratum/algos/sha256-P.h @@ -0,0 +1,129 @@ +/*- + * Copyright 2005-2016 Colin Percival + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _SHA256_H_ +#define _SHA256_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Use #defines in order to avoid namespace collisions with anyone else's + * SHA256 code (e.g., the code in OpenSSL). + */ +#define SHA256_Init libcperciva_SHA256_Init +#define SHA256_Update libcperciva_SHA256_Update +#define SHA256_Final libcperciva_SHA256_Final +#define SHA256_Buf libcperciva_SHA256_Buf +#define SHA256_CTX libcperciva_SHA256_CTX +#define HMAC_SHA256_Init libcperciva_HMAC_SHA256_Init +#define HMAC_SHA256_Update libcperciva_HMAC_SHA256_Update +#define HMAC_SHA256_Final libcperciva_HMAC_SHA256_Final +#define HMAC_SHA256_Buf libcperciva_HMAC_SHA256_Buf +#define HMAC_SHA256_CTX libcperciva_HMAC_SHA256_CTX + +/* Context structure for SHA256 operations. */ +typedef struct { + uint32_t state[8]; + uint64_t count; + uint8_t buf[64]; +} SHA256_CTX; + +/** + * SHA256_Init(ctx): + * Initialize the SHA256 context ${ctx}. + */ +void SHA256_Init(SHA256_CTX *); + +/** + * SHA256_Update(ctx, in, len): + * Input ${len} bytes from ${in} into the SHA256 context ${ctx}. + */ +void SHA256_Update(SHA256_CTX *, const void *, size_t); + +/** + * SHA256_Final(digest, ctx): + * Output the SHA256 hash of the data input to the context ${ctx} into the + * buffer ${digest}. + */ +void SHA256_Final(uint8_t[32], SHA256_CTX *); + +/** + * SHA256_Buf(in, len, digest): + * Compute the SHA256 hash of ${len} bytes from ${in} and write it to ${digest}. + */ +void SHA256_Buf(const void *, size_t, uint8_t[32]); + +/* Context structure for HMAC-SHA256 operations. */ +typedef struct { + SHA256_CTX ictx; + SHA256_CTX octx; +} HMAC_SHA256_CTX; + +/** + * HMAC_SHA256_Init(ctx, K, Klen): + * Initialize the HMAC-SHA256 context ${ctx} with ${Klen} bytes of key from + * ${K}. + */ +void HMAC_SHA256_Init(HMAC_SHA256_CTX *, const void *, size_t); + +/** + * HMAC_SHA256_Update(ctx, in, len): + * Input ${len} bytes from ${in} into the HMAC-SHA256 context ${ctx}. + */ +void HMAC_SHA256_Update(HMAC_SHA256_CTX *, const void *, size_t); + +/** + * HMAC_SHA256_Final(digest, ctx): + * Output the HMAC-SHA256 of the data input to the context ${ctx} into the + * buffer ${digest}. + */ +void HMAC_SHA256_Final(uint8_t[32], HMAC_SHA256_CTX *); + +/** + * HMAC_SHA256_Buf(K, Klen, in, len, digest): + * Compute the HMAC-SHA256 of ${len} bytes from ${in} using the key ${K} of + * length ${Klen}, and write the result to ${digest}. + */ +void HMAC_SHA256_Buf(const void *, size_t, const void *, size_t, uint8_t[32]); + +/** + * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): + * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and + * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). + */ +void YESPOWER_PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t, + uint64_t, uint8_t *, size_t); + +#ifdef __cplusplus +} +#endif + +#endif /* !_SHA256_H_ */ diff --git a/stratum/algos/sha256-d.c b/stratum/algos/sha256-d.c new file mode 100644 index 000000000..015adc363 --- /dev/null +++ b/stratum/algos/sha256-d.c @@ -0,0 +1,634 @@ +/* + * Copyright 2011 ArtForz + * Copyright 2011-2013 pooler + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. See COPYING for more details. + */ + +#include "sha256-d.h" + +#include +#include + + #if defined(__arm__) && defined(__APCS_32__) +#define EXTERN_SHA256 +#endif + + static const uint32_t sha256_h[8] = { + 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, + 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 +}; + + static const uint32_t sha256_k[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + + void sha256_init(uint32_t *state) +{ + memcpy(state, sha256_h, 32); +} + + /* Elementary functions used by SHA256 */ +#define Ch(x, y, z) ((x & (y ^ z)) ^ z) +#define Maj(x, y, z) ((x & (y | z)) | (y & z)) +#define ROTR(x, n) ((x >> n) | (x << (32 - n))) +#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) +#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) +#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ (x >> 3)) +#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ (x >> 10)) + + /* SHA256 round function */ +#define RND(a, b, c, d, e, f, g, h, k) \ + do { \ + t0 = h + S1(e) + Ch(e, f, g) + k; \ + t1 = S0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; \ + } while (0) + + /* Adjusted round function for rotating state */ +#define RNDr(S, W, i) \ + RND(S[(64 - i) % 8], S[(65 - i) % 8], \ + S[(66 - i) % 8], S[(67 - i) % 8], \ + S[(68 - i) % 8], S[(69 - i) % 8], \ + S[(70 - i) % 8], S[(71 - i) % 8], \ + W[i] + sha256_k[i]) + + #ifndef EXTERN_SHA256 + + /* + * SHA256 block compression function. The 256-bit state is transformed via + * the 512-bit input block to produce a new state. + */ +void sha256_transform(uint32_t *state, const uint32_t *block, int swap) +{ + uint32_t W[64]; + uint32_t S[8]; + uint32_t t0, t1; + int i; + + /* 1. Prepare message schedule W. */ + if (swap) { + for (i = 0; i < 16; i++) + W[i] = swab32(block[i]); + } else + memcpy(W, block, 64); + for (i = 16; i < 64; i += 2) { + W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; + W[i+1] = s1(W[i - 1]) + W[i - 6] + s0(W[i - 14]) + W[i - 15]; + } + + /* 2. Initialize working variables. */ + memcpy(S, state, 32); + + /* 3. Mix. */ + RNDr(S, W, 0); + RNDr(S, W, 1); + RNDr(S, W, 2); + RNDr(S, W, 3); + RNDr(S, W, 4); + RNDr(S, W, 5); + RNDr(S, W, 6); + RNDr(S, W, 7); + RNDr(S, W, 8); + RNDr(S, W, 9); + RNDr(S, W, 10); + RNDr(S, W, 11); + RNDr(S, W, 12); + RNDr(S, W, 13); + RNDr(S, W, 14); + RNDr(S, W, 15); + RNDr(S, W, 16); + RNDr(S, W, 17); + RNDr(S, W, 18); + RNDr(S, W, 19); + RNDr(S, W, 20); + RNDr(S, W, 21); + RNDr(S, W, 22); + RNDr(S, W, 23); + RNDr(S, W, 24); + RNDr(S, W, 25); + RNDr(S, W, 26); + RNDr(S, W, 27); + RNDr(S, W, 28); + RNDr(S, W, 29); + RNDr(S, W, 30); + RNDr(S, W, 31); + RNDr(S, W, 32); + RNDr(S, W, 33); + RNDr(S, W, 34); + RNDr(S, W, 35); + RNDr(S, W, 36); + RNDr(S, W, 37); + RNDr(S, W, 38); + RNDr(S, W, 39); + RNDr(S, W, 40); + RNDr(S, W, 41); + RNDr(S, W, 42); + RNDr(S, W, 43); + RNDr(S, W, 44); + RNDr(S, W, 45); + RNDr(S, W, 46); + RNDr(S, W, 47); + RNDr(S, W, 48); + RNDr(S, W, 49); + RNDr(S, W, 50); + RNDr(S, W, 51); + RNDr(S, W, 52); + RNDr(S, W, 53); + RNDr(S, W, 54); + RNDr(S, W, 55); + RNDr(S, W, 56); + RNDr(S, W, 57); + RNDr(S, W, 58); + RNDr(S, W, 59); + RNDr(S, W, 60); + RNDr(S, W, 61); + RNDr(S, W, 62); + RNDr(S, W, 63); + + /* 4. Mix local working variables into global state */ + for (i = 0; i < 8; i++) + state[i] += S[i]; +} + + #endif /* EXTERN_SHA256 */ + + + static const uint32_t sha256d_hash1[16] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x80000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000100 +}; + + static void sha256d_80_swap(uint32_t *hash, const uint32_t *data) +{ + uint32_t S[16]; + int i; + + sha256_init(S); + sha256_transform(S, data, 0); + sha256_transform(S, data + 16, 0); + memcpy(S + 8, sha256d_hash1 + 8, 32); + sha256_init(hash); + sha256_transform(hash, S, 0); + for (i = 0; i < 8; i++) + hash[i] = swab32(hash[i]); +} + + void sha256d(unsigned char *hash, const unsigned char *data, int len) +{ + uint32_t S[16], T[16]; + int i, r; + + sha256_init(S); + for (r = len; r > -9; r -= 64) { + if (r < 64) + memset(T, 0, 64); + memcpy(T, data + len - r, r > 64 ? 64 : (r < 0 ? 0 : r)); + if (r >= 0 && r < 64) + ((unsigned char *)T)[r] = 0x80; + for (i = 0; i < 16; i++) + T[i] = be32dec(T + i); + if (r < 56) + T[15] = 8 * len; + sha256_transform(S, T, 0); + } + memcpy(S + 8, sha256d_hash1 + 8, 32); + sha256_init(T); + sha256_transform(T, S, 0); + for (i = 0; i < 8; i++) + be32enc((uint32_t *)hash + i, T[i]); +} + + static inline void sha256d_preextend(uint32_t *W) +{ + W[16] = s1(W[14]) + W[ 9] + s0(W[ 1]) + W[ 0]; + W[17] = s1(W[15]) + W[10] + s0(W[ 2]) + W[ 1]; + W[18] = s1(W[16]) + W[11] + W[ 2]; + W[19] = s1(W[17]) + W[12] + s0(W[ 4]); + W[20] = W[13] + s0(W[ 5]) + W[ 4]; + W[21] = W[14] + s0(W[ 6]) + W[ 5]; + W[22] = W[15] + s0(W[ 7]) + W[ 6]; + W[23] = W[16] + s0(W[ 8]) + W[ 7]; + W[24] = W[17] + s0(W[ 9]) + W[ 8]; + W[25] = s0(W[10]) + W[ 9]; + W[26] = s0(W[11]) + W[10]; + W[27] = s0(W[12]) + W[11]; + W[28] = s0(W[13]) + W[12]; + W[29] = s0(W[14]) + W[13]; + W[30] = s0(W[15]) + W[14]; + W[31] = s0(W[16]) + W[15]; +} + + static inline void sha256d_prehash(uint32_t *S, const uint32_t *W) +{ + uint32_t t0, t1; + RNDr(S, W, 0); + RNDr(S, W, 1); + RNDr(S, W, 2); +} + + #ifdef EXTERN_SHA256 + + void sha256d_ms(uint32_t *hash, uint32_t *W, + const uint32_t *midstate, const uint32_t *prehash); + + #else + + static inline void sha256d_ms(uint32_t *hash, uint32_t *W, + const uint32_t *midstate, const uint32_t *prehash) +{ + uint32_t S[64]; + uint32_t t0, t1; + int i; + + S[18] = W[18]; + S[19] = W[19]; + S[20] = W[20]; + S[22] = W[22]; + S[23] = W[23]; + S[24] = W[24]; + S[30] = W[30]; + S[31] = W[31]; + + W[18] += s0(W[3]); + W[19] += W[3]; + W[20] += s1(W[18]); + W[21] = s1(W[19]); + W[22] += s1(W[20]); + W[23] += s1(W[21]); + W[24] += s1(W[22]); + W[25] = s1(W[23]) + W[18]; + W[26] = s1(W[24]) + W[19]; + W[27] = s1(W[25]) + W[20]; + W[28] = s1(W[26]) + W[21]; + W[29] = s1(W[27]) + W[22]; + W[30] += s1(W[28]) + W[23]; + W[31] += s1(W[29]) + W[24]; + for (i = 32; i < 64; i += 2) { + W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; + W[i+1] = s1(W[i - 1]) + W[i - 6] + s0(W[i - 14]) + W[i - 15]; + } + + memcpy(S, prehash, 32); + + RNDr(S, W, 3); + RNDr(S, W, 4); + RNDr(S, W, 5); + RNDr(S, W, 6); + RNDr(S, W, 7); + RNDr(S, W, 8); + RNDr(S, W, 9); + RNDr(S, W, 10); + RNDr(S, W, 11); + RNDr(S, W, 12); + RNDr(S, W, 13); + RNDr(S, W, 14); + RNDr(S, W, 15); + RNDr(S, W, 16); + RNDr(S, W, 17); + RNDr(S, W, 18); + RNDr(S, W, 19); + RNDr(S, W, 20); + RNDr(S, W, 21); + RNDr(S, W, 22); + RNDr(S, W, 23); + RNDr(S, W, 24); + RNDr(S, W, 25); + RNDr(S, W, 26); + RNDr(S, W, 27); + RNDr(S, W, 28); + RNDr(S, W, 29); + RNDr(S, W, 30); + RNDr(S, W, 31); + RNDr(S, W, 32); + RNDr(S, W, 33); + RNDr(S, W, 34); + RNDr(S, W, 35); + RNDr(S, W, 36); + RNDr(S, W, 37); + RNDr(S, W, 38); + RNDr(S, W, 39); + RNDr(S, W, 40); + RNDr(S, W, 41); + RNDr(S, W, 42); + RNDr(S, W, 43); + RNDr(S, W, 44); + RNDr(S, W, 45); + RNDr(S, W, 46); + RNDr(S, W, 47); + RNDr(S, W, 48); + RNDr(S, W, 49); + RNDr(S, W, 50); + RNDr(S, W, 51); + RNDr(S, W, 52); + RNDr(S, W, 53); + RNDr(S, W, 54); + RNDr(S, W, 55); + RNDr(S, W, 56); + RNDr(S, W, 57); + RNDr(S, W, 58); + RNDr(S, W, 59); + RNDr(S, W, 60); + RNDr(S, W, 61); + RNDr(S, W, 62); + RNDr(S, W, 63); + + for (i = 0; i < 8; i++) + S[i] += midstate[i]; + + W[18] = S[18]; + W[19] = S[19]; + W[20] = S[20]; + W[22] = S[22]; + W[23] = S[23]; + W[24] = S[24]; + W[30] = S[30]; + W[31] = S[31]; + + memcpy(S + 8, sha256d_hash1 + 8, 32); + S[16] = s1(sha256d_hash1[14]) + sha256d_hash1[ 9] + s0(S[ 1]) + S[ 0]; + S[17] = s1(sha256d_hash1[15]) + sha256d_hash1[10] + s0(S[ 2]) + S[ 1]; + S[18] = s1(S[16]) + sha256d_hash1[11] + s0(S[ 3]) + S[ 2]; + S[19] = s1(S[17]) + sha256d_hash1[12] + s0(S[ 4]) + S[ 3]; + S[20] = s1(S[18]) + sha256d_hash1[13] + s0(S[ 5]) + S[ 4]; + S[21] = s1(S[19]) + sha256d_hash1[14] + s0(S[ 6]) + S[ 5]; + S[22] = s1(S[20]) + sha256d_hash1[15] + s0(S[ 7]) + S[ 6]; + S[23] = s1(S[21]) + S[16] + s0(sha256d_hash1[ 8]) + S[ 7]; + S[24] = s1(S[22]) + S[17] + s0(sha256d_hash1[ 9]) + sha256d_hash1[ 8]; + S[25] = s1(S[23]) + S[18] + s0(sha256d_hash1[10]) + sha256d_hash1[ 9]; + S[26] = s1(S[24]) + S[19] + s0(sha256d_hash1[11]) + sha256d_hash1[10]; + S[27] = s1(S[25]) + S[20] + s0(sha256d_hash1[12]) + sha256d_hash1[11]; + S[28] = s1(S[26]) + S[21] + s0(sha256d_hash1[13]) + sha256d_hash1[12]; + S[29] = s1(S[27]) + S[22] + s0(sha256d_hash1[14]) + sha256d_hash1[13]; + S[30] = s1(S[28]) + S[23] + s0(sha256d_hash1[15]) + sha256d_hash1[14]; + S[31] = s1(S[29]) + S[24] + s0(S[16]) + sha256d_hash1[15]; + for (i = 32; i < 60; i += 2) { + S[i] = s1(S[i - 2]) + S[i - 7] + s0(S[i - 15]) + S[i - 16]; + S[i+1] = s1(S[i - 1]) + S[i - 6] + s0(S[i - 14]) + S[i - 15]; + } + S[60] = s1(S[58]) + S[53] + s0(S[45]) + S[44]; + + sha256_init(hash); + + RNDr(hash, S, 0); + RNDr(hash, S, 1); + RNDr(hash, S, 2); + RNDr(hash, S, 3); + RNDr(hash, S, 4); + RNDr(hash, S, 5); + RNDr(hash, S, 6); + RNDr(hash, S, 7); + RNDr(hash, S, 8); + RNDr(hash, S, 9); + RNDr(hash, S, 10); + RNDr(hash, S, 11); + RNDr(hash, S, 12); + RNDr(hash, S, 13); + RNDr(hash, S, 14); + RNDr(hash, S, 15); + RNDr(hash, S, 16); + RNDr(hash, S, 17); + RNDr(hash, S, 18); + RNDr(hash, S, 19); + RNDr(hash, S, 20); + RNDr(hash, S, 21); + RNDr(hash, S, 22); + RNDr(hash, S, 23); + RNDr(hash, S, 24); + RNDr(hash, S, 25); + RNDr(hash, S, 26); + RNDr(hash, S, 27); + RNDr(hash, S, 28); + RNDr(hash, S, 29); + RNDr(hash, S, 30); + RNDr(hash, S, 31); + RNDr(hash, S, 32); + RNDr(hash, S, 33); + RNDr(hash, S, 34); + RNDr(hash, S, 35); + RNDr(hash, S, 36); + RNDr(hash, S, 37); + RNDr(hash, S, 38); + RNDr(hash, S, 39); + RNDr(hash, S, 40); + RNDr(hash, S, 41); + RNDr(hash, S, 42); + RNDr(hash, S, 43); + RNDr(hash, S, 44); + RNDr(hash, S, 45); + RNDr(hash, S, 46); + RNDr(hash, S, 47); + RNDr(hash, S, 48); + RNDr(hash, S, 49); + RNDr(hash, S, 50); + RNDr(hash, S, 51); + RNDr(hash, S, 52); + RNDr(hash, S, 53); + RNDr(hash, S, 54); + RNDr(hash, S, 55); + RNDr(hash, S, 56); + + hash[2] += hash[6] + S1(hash[3]) + Ch(hash[3], hash[4], hash[5]) + + S[57] + sha256_k[57]; + hash[1] += hash[5] + S1(hash[2]) + Ch(hash[2], hash[3], hash[4]) + + S[58] + sha256_k[58]; + hash[0] += hash[4] + S1(hash[1]) + Ch(hash[1], hash[2], hash[3]) + + S[59] + sha256_k[59]; + hash[7] += hash[3] + S1(hash[0]) + Ch(hash[0], hash[1], hash[2]) + + S[60] + sha256_k[60] + + sha256_h[7]; +} + + #endif /* EXTERN_SHA256 */ + + #if HAVE_SHA256_4WAY + + void sha256d_ms_4way(uint32_t *hash, uint32_t *data, + const uint32_t *midstate, const uint32_t *prehash); + + static inline int scanhash_sha256d_4way(int thr_id, uint32_t *pdata, + const uint32_t *ptarget uint32_t max_nonce, unsigned long *hashes_done) +{ + uint32_t data[4 * 64] __attribute__((aligned(128))); + uint32_t hash[4 * 8] __attribute__((aligned(32))); + uint32_t midstate[4 * 8] __attribute__((aligned(32))); + uint32_t prehash[4 * 8] __attribute__((aligned(32))); + uint32_t n = pdata[19] - 1; + const uint32_t first_nonce = pdata[19]; + const uint32_t Htarg = ptarget[7]; + int i, j; + + memcpy(data, pdata + 16, 64); + sha256d_preextend(data); + for (i = 31; i >= 0; i--) + for (j = 0; j < 4; j++) + data[i * 4 + j] = data[i]; + + sha256_init(midstate); + sha256_transform(midstate, pdata, 0); + memcpy(prehash, midstate, 32); + sha256d_prehash(prehash, pdata + 16); + for (i = 7; i >= 0; i--) { + for (j = 0; j < 4; j++) { + midstate[i * 4 + j] = midstate[i]; + prehash[i * 4 + j] = prehash[i]; + } + } + + do { + for (i = 0; i < 4; i++) + data[4 * 3 + i] = ++n; + + sha256d_ms_4way(hash, data, midstate, prehash); + + for (i = 0; i < 4; i++) { + if (swab32(hash[4 * 7 + i]) <= Htarg) { + pdata[19] = data[4 * 3 + i]; + sha256d_80_swap(hash, pdata); + if (fulltest(hash, ptarget)) { + work_set_target_ratio(work, hash); + *hashes_done = n - first_nonce + 1; + return 1; + } + } + } + } while (n < max_nonce && !work_restart[thr_id].restart); + + *hashes_done = n - first_nonce + 1; + pdata[19] = n; + return 0; +} + + #endif /* HAVE_SHA256_4WAY */ + + #if HAVE_SHA256_8WAY + + void sha256d_ms_8way(uint32_t *hash, uint32_t *data, + const uint32_t *midstate, const uint32_t *prehash); + + static inline int scanhash_sha256d_8way(int thr_id, uint32_t *pdata, + const uint32_t *ptarget, uint32_t max_nonce, unsigned long *hashes_done) +{ + uint32_t data[8 * 64] __attribute__((aligned(128))); + uint32_t hash[8 * 8] __attribute__((aligned(32))); + uint32_t midstate[8 * 8] __attribute__((aligned(32))); + uint32_t prehash[8 * 8] __attribute__((aligned(32))); + uint32_t n = pdata[19] - 1; + const uint32_t first_nonce = pdata[19]; + const uint32_t Htarg = ptarget[7]; + int i, j; + + memcpy(data, pdata + 16, 64); + sha256d_preextend(data); + for (i = 31; i >= 0; i--) + for (j = 0; j < 8; j++) + data[i * 8 + j] = data[i]; + + sha256_init(midstate); + sha256_transform(midstate, pdata, 0); + memcpy(prehash, midstate, 32); + sha256d_prehash(prehash, pdata + 16); + for (i = 7; i >= 0; i--) { + for (j = 0; j < 8; j++) { + midstate[i * 8 + j] = midstate[i]; + prehash[i * 8 + j] = prehash[i]; + } + } + + do { + for (i = 0; i < 8; i++) + data[8 * 3 + i] = ++n; + + sha256d_ms_8way(hash, data, midstate, prehash); + + for (i = 0; i < 8; i++) { + if (swab32(hash[8 * 7 + i]) <= Htarg) { + pdata[19] = data[8 * 3 + i]; + sha256d_80_swap(hash, pdata); + if (fulltest(hash, ptarget)) { + *hashes_done = n - first_nonce + 1; + return 1; + } + } + } + } while (n < max_nonce && !work_restart[thr_id].restart); + + *hashes_done = n - first_nonce + 1; + pdata[19] = n; + return 0; +} + + #endif /* HAVE_SHA256_8WAY */ + + #if 0 +int scanhash_sha256d(int thr_id, struct work* work, uint32_t max_nonce, unsigned long *hashes_done) +{ + uint32_t _ALIGN(128) data[64]; + uint32_t hash[8]; + uint32_t midstate[8]; + uint32_t prehash[8]; + uint32_t *pdata = work->data; + uint32_t *ptarget = work->target; + uint32_t n = pdata[19] - 1; + const uint32_t first_nonce = pdata[19]; + const uint32_t Htarg = ptarget[7]; + + #if HAVE_SHA256_8WAY + if (sha256_use_8way()) + return scanhash_sha256d_8way(thr_id, pdata, ptarget, + max_nonce, hashes_done); +#endif +#if HAVE_SHA256_4WAY + if (sha256_use_4way()) + return scanhash_sha256d_4way(thr_id, pdata, ptarget, + max_nonce, hashes_done); +#endif + + memcpy(data, pdata + 16, 64); + sha256d_preextend(data); + + sha256_init(midstate); + sha256_transform(midstate, pdata, 0); + memcpy(prehash, midstate, 32); + sha256d_prehash(prehash, pdata + 16); + + do { + data[3] = ++n; + sha256d_ms(hash, data, midstate, prehash); + if (swab32(hash[7]) <= Htarg) { + pdata[19] = data[3]; + sha256d_80_swap(hash, pdata); + if (fulltest(hash, ptarget)) { + *hashes_done = n - first_nonce + 1; + return 1; + } + } + } while (n < max_nonce && !work_restart[thr_id].restart); + + *hashes_done = n - first_nonce + 1; + pdata[19] = n; + return 0; +} + + #endif \ No newline at end of file diff --git a/stratum/algos/sha256-d.h b/stratum/algos/sha256-d.h new file mode 100644 index 000000000..fd09d5cce --- /dev/null +++ b/stratum/algos/sha256-d.h @@ -0,0 +1,69 @@ +#ifndef __SHA2_H__ +#define __SHA2_H__ + + #ifdef __cplusplus +extern "C" { +#endif + + #include + + #define bswap_32(x) ((((x) << 24) & 0xff000000u) | (((x) << 8) & 0x00ff0000u) \ + | (((x) >> 8) & 0x0000ff00u) | (((x) >> 24) & 0x000000ffu)) + + #define bswap_64(x) (((uint64_t) bswap_32((uint32_t)((x) & 0xffffffffu)) << 32) \ + | (uint64_t) bswap_32((uint32_t)((x) >> 32))) + + static inline uint32_t be32dec(const void *pp) +{ + const uint8_t *p = (uint8_t const *)pp; + return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) + + ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24)); +} + + static inline void be32enc(void *pp, uint32_t x) +{ + uint8_t *p = (uint8_t *)pp; + p[3] = x & 0xff; + p[2] = (x >> 8) & 0xff; + p[1] = (x >> 16) & 0xff; + p[0] = (x >> 24) & 0xff; +} + + static inline uint32_t swab32(uint32_t v) +{ +#ifdef WANT_BUILTIN_BSWAP + return __builtin_bswap32(v); +#else + return bswap_32(v); +#endif +} + + static inline uint64_t swab64(uint64_t v) +{ +#ifdef WANT_BUILTIN_BSWAP + return __builtin_bswap64(v); +#else + return bswap_64(v); +#endif +} + + static inline void swab256(void *dest_p, const void *src_p) +{ + uint32_t *dest = (uint32_t *) dest_p; + const uint32_t *src = (const uint32_t *) src_p; + + dest[0] = swab32(src[7]); + dest[1] = swab32(src[6]); + dest[2] = swab32(src[5]); + dest[3] = swab32(src[4]); + dest[4] = swab32(src[3]); + dest[5] = swab32(src[2]); + dest[6] = swab32(src[1]); + dest[7] = swab32(src[0]); +} + + #ifdef __cplusplus +} +#endif + + #endif \ No newline at end of file diff --git a/stratum/algos/sysendian_yp.h b/stratum/algos/sysendian_yp.h new file mode 100644 index 000000000..52c1fe73b --- /dev/null +++ b/stratum/algos/sysendian_yp.h @@ -0,0 +1,94 @@ +/*- + * Copyright 2007-2014 Colin Percival + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _SYSENDIAN_H_ +#define _SYSENDIAN_H_ + +#include + +/* Avoid namespace collisions with BSD . */ +#define be32dec libcperciva_be32dec +#define be32enc libcperciva_be32enc +#define be64enc libcperciva_be64enc +#define le32dec libcperciva_le32dec +#define le32enc libcperciva_le32enc + +static inline uint32_t +be32dec(const void * pp) +{ + const uint8_t * p = (uint8_t const *)pp; + + return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) + + ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24)); +} + +static inline void +be32enc(void * pp, uint32_t x) +{ + uint8_t * p = (uint8_t *)pp; + + p[3] = x & 0xff; + p[2] = (x >> 8) & 0xff; + p[1] = (x >> 16) & 0xff; + p[0] = (x >> 24) & 0xff; +} + +static inline void +be64enc(void * pp, uint64_t x) +{ + uint8_t * p = (uint8_t *)pp; + + p[7] = x & 0xff; + p[6] = (x >> 8) & 0xff; + p[5] = (x >> 16) & 0xff; + p[4] = (x >> 24) & 0xff; + p[3] = (x >> 32) & 0xff; + p[2] = (x >> 40) & 0xff; + p[1] = (x >> 48) & 0xff; + p[0] = (x >> 56) & 0xff; +} + +static inline uint32_t +le32dec(const void * pp) +{ + const uint8_t * p = (uint8_t const *)pp; + + return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) + + ((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24)); +} + +static inline void +le32enc(void * pp, uint32_t x) +{ + uint8_t * p = (uint8_t *)pp; + + p[0] = x & 0xff; + p[1] = (x >> 8) & 0xff; + p[2] = (x >> 16) & 0xff; + p[3] = (x >> 24) & 0xff; +} + +#endif /* !_SYSENDIAN_H_ */ diff --git a/stratum/algos/x16rt.c b/stratum/algos/x16rt.c new file mode 100644 index 000000000..acd7fe35c --- /dev/null +++ b/stratum/algos/x16rt.c @@ -0,0 +1,193 @@ +#include +#include +#include + +#include "sha256-d.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" + +#define TIME_MASK 0xffffff80 + +enum Algo { + BLAKE = 0, + BMW, + GROESTL, + JH, + KECCAK, + SKEIN, + LUFFA, + CUBEHASH, + SHAVITE, + SIMD, + ECHO, + HAMSI, + FUGUE, + SHABAL, + WHIRLPOOL, + SHA512, + HASH_FUNC_COUNT +}; + +static void getAlgoString(const uint32_t* timeHash, char *output) +{ + char *sptr = output; + uint8_t* data = (uint8_t*)timeHash; + + for (uint8_t j = 0; j < HASH_FUNC_COUNT; j++) { + uint8_t b = (15 - j) >> 1; // 16 ascii hex chars, reversed + uint8_t algoDigit = (j & 1) ? data[b] & 0xF : data[b] >> 4; + + if (algoDigit >= 10) + sprintf(sptr, "%c", 'A' + (algoDigit - 10)); + else + sprintf(sptr, "%u", (uint32_t) algoDigit); + sptr++; + } + *sptr = '\0'; +} + +static void getTimeHash(const uint32_t timeStamp, void* timeHash) +{ + int32_t maskedTime = timeStamp & TIME_MASK; + sha256d((unsigned char*)timeHash, (const unsigned char*)&(maskedTime), sizeof(maskedTime)); +} + +void x16rt_hash(const char* input, char* output, uint32_t len) +{ + unsigned char hash[128]; + char hashOrder[HASH_FUNC_COUNT + 1] = { 0 }; + + sph_blake512_context ctx_blake; + sph_bmw512_context ctx_bmw; + sph_groestl512_context ctx_groestl; + sph_skein512_context ctx_skein; + sph_jh512_context ctx_jh; + sph_keccak512_context ctx_keccak; + 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; + sph_hamsi512_context ctx_hamsi; + sph_fugue512_context ctx_fugue; + sph_shabal512_context ctx_shabal; + sph_whirlpool_context ctx_whirlpool; + sph_sha512_context ctx_sha512; + + void *in = (void*) input; + int size = 80; + + uint32_t *in32 = (uint32_t*) input; + uint32_t ntime = in32[17]; + uint32_t timeHash[8]; + getTimeHash(ntime, &timeHash); + getAlgoString(&timeHash[0], hashOrder); + + for (int i = 0; i < 16; i++) + { + const char elem = hashOrder[i]; + const uint8_t algo = elem >= 'A' ? elem - 'A' + 10 : elem - '0'; + + switch (algo) { + case BLAKE: + sph_blake512_init(&ctx_blake); + sph_blake512(&ctx_blake, in, size); + sph_blake512_close(&ctx_blake, hash); + break; + case BMW: + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, in, size); + sph_bmw512_close(&ctx_bmw, hash); + break; + case GROESTL: + sph_groestl512_init(&ctx_groestl); + sph_groestl512(&ctx_groestl, in, size); + sph_groestl512_close(&ctx_groestl, hash); + break; + case SKEIN: + sph_skein512_init(&ctx_skein); + sph_skein512(&ctx_skein, in, size); + sph_skein512_close(&ctx_skein, hash); + break; + case JH: + sph_jh512_init(&ctx_jh); + sph_jh512(&ctx_jh, in, size); + sph_jh512_close(&ctx_jh, hash); + break; + case KECCAK: + sph_keccak512_init(&ctx_keccak); + sph_keccak512(&ctx_keccak, in, size); + sph_keccak512_close(&ctx_keccak, hash); + break; + case LUFFA: + sph_luffa512_init(&ctx_luffa); + sph_luffa512(&ctx_luffa, in, size); + sph_luffa512_close(&ctx_luffa, hash); + break; + case CUBEHASH: + sph_cubehash512_init(&ctx_cubehash); + sph_cubehash512(&ctx_cubehash, in, size); + sph_cubehash512_close(&ctx_cubehash, hash); + break; + case SHAVITE: + sph_shavite512_init(&ctx_shavite); + sph_shavite512(&ctx_shavite, in, size); + sph_shavite512_close(&ctx_shavite, hash); + break; + case SIMD: + sph_simd512_init(&ctx_simd); + sph_simd512(&ctx_simd, in, size); + sph_simd512_close(&ctx_simd, hash); + break; + case ECHO: + sph_echo512_init(&ctx_echo); + sph_echo512(&ctx_echo, in, size); + sph_echo512_close(&ctx_echo, hash); + break; + case HAMSI: + sph_hamsi512_init(&ctx_hamsi); + sph_hamsi512(&ctx_hamsi, in, size); + sph_hamsi512_close(&ctx_hamsi, hash); + break; + case FUGUE: + sph_fugue512_init(&ctx_fugue); + sph_fugue512(&ctx_fugue, in, size); + sph_fugue512_close(&ctx_fugue, hash); + break; + case SHABAL: + sph_shabal512_init(&ctx_shabal); + sph_shabal512(&ctx_shabal, in, size); + sph_shabal512_close(&ctx_shabal, hash); + break; + case WHIRLPOOL: + sph_whirlpool_init(&ctx_whirlpool); + sph_whirlpool(&ctx_whirlpool, in, size); + sph_whirlpool_close(&ctx_whirlpool, hash); + break; + case SHA512: + sph_sha512_init(&ctx_sha512); + sph_sha512(&ctx_sha512,(const void*) in, size); + sph_sha512_close(&ctx_sha512,(void*) hash); + break; + } + in = (void*) hash; + size = 64; + } + memcpy(output, hash, 32); +} \ No newline at end of file diff --git a/stratum/algos/x16rt.h b/stratum/algos/x16rt.h new file mode 100644 index 000000000..0e5b6b743 --- /dev/null +++ b/stratum/algos/x16rt.h @@ -0,0 +1,18 @@ +#ifndef X16RT_H +#define X16RT_H + + #ifdef __cplusplus +extern "C" { +#endif + + #include + + void x16rt_hash(const char* input, char* output, uint32_t len); + + void sha256d(unsigned char *hash, const unsigned char *data, int len); + + #ifdef __cplusplus +} +#endif + + #endif \ No newline at end of file diff --git a/stratum/algos/x16rv2.c b/stratum/algos/x16rv2.c new file mode 100644 index 000000000..7bb2bfe5a --- /dev/null +++ b/stratum/algos/x16rv2.c @@ -0,0 +1,195 @@ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" + +enum Algo { + BLAKE = 0, + BMW, + GROESTL, + JH, + KECCAK, + SKEIN, + LUFFA, + CUBEHASH, + SHAVITE, + SIMD, + ECHO, + HAMSI, + FUGUE, + SHABAL, + WHIRLPOOL, + SHA512, + HASH_FUNC_COUNT +}; + +static void getAlgoString(const uint8_t* prevblock, char *output) +{ + char *sptr = output; + + for (int j = 0; j < HASH_FUNC_COUNT; j++) { + char b = (15 - j) >> 1; // 16 ascii hex chars, reversed + uint8_t algoDigit = (j & 1) ? prevblock[b] & 0xF : prevblock[b] >> 4; + if (algoDigit >= 10) + sprintf(sptr, "%c", 'A' + (algoDigit - 10)); + else + sprintf(sptr, "%u", (uint32_t) algoDigit); + sptr++; + } + *sptr = '\0'; +} + +void x16rv2_hash(const char* input, char* output, uint32_t len) +{ + uint32_t hash[64/4]; + char hashOrder[HASH_FUNC_COUNT + 1] = { 0 }; + + sph_blake512_context ctx_blake; + sph_bmw512_context ctx_bmw; + sph_groestl512_context ctx_groestl; + sph_skein512_context ctx_skein; + sph_jh512_context ctx_jh; + sph_keccak512_context ctx_keccak; + 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; + sph_hamsi512_context ctx_hamsi; + sph_fugue512_context ctx_fugue; + sph_shabal512_context ctx_shabal; + sph_whirlpool_context ctx_whirlpool; + sph_sha512_context ctx_sha512; + sph_tiger_context ctx_tiger; + + void *in = (void*) input; + int size = len; + + getAlgoString(&input[4], hashOrder); + + for (int i = 0; i < 16; i++) + { + const char elem = hashOrder[i]; + const uint8_t algo = elem >= 'A' ? elem - 'A' + 10 : elem - '0'; + + switch (algo) { + case BLAKE: + sph_blake512_init(&ctx_blake); + sph_blake512(&ctx_blake, in, size); + sph_blake512_close(&ctx_blake, hash); + break; + case BMW: + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, in, size); + sph_bmw512_close(&ctx_bmw, hash); + break; + case GROESTL: + sph_groestl512_init(&ctx_groestl); + sph_groestl512(&ctx_groestl, in, size); + sph_groestl512_close(&ctx_groestl, hash); + break; + case SKEIN: + sph_skein512_init(&ctx_skein); + sph_skein512(&ctx_skein, in, size); + sph_skein512_close(&ctx_skein, hash); + break; + case JH: + sph_jh512_init(&ctx_jh); + sph_jh512(&ctx_jh, in, size); + sph_jh512_close(&ctx_jh, hash); + break; + case KECCAK: + sph_tiger_init(&ctx_tiger); + sph_tiger(&ctx_tiger, (const void*) in, size); + sph_tiger_close(&ctx_tiger, (void*) hash); + for (int j = 24; j < 64; ++j) ((uint8_t*)hash)[j] = 0; // Pad the 24 bytes to bring it to 64 bytes + + sph_keccak512_init(&ctx_keccak); + sph_keccak512(&ctx_keccak, hash, 64); + sph_keccak512_close(&ctx_keccak, hash); + break; + case LUFFA: + sph_tiger_init(&ctx_tiger); + sph_tiger(&ctx_tiger, (const void*) in, size); + sph_tiger_close(&ctx_tiger, (void*) hash); + for (int j = 24; j < 64; ++j) ((uint8_t*)hash)[j] = 0; // Pad the 24 bytes to bring it to 64 bytes + + sph_luffa512_init(&ctx_luffa); + sph_luffa512(&ctx_luffa, hash, 64); + sph_luffa512_close(&ctx_luffa, hash); + break; + case CUBEHASH: + sph_cubehash512_init(&ctx_cubehash); + sph_cubehash512(&ctx_cubehash, in, size); + sph_cubehash512_close(&ctx_cubehash, hash); + break; + case SHAVITE: + sph_shavite512_init(&ctx_shavite); + sph_shavite512(&ctx_shavite, in, size); + sph_shavite512_close(&ctx_shavite, hash); + break; + case SIMD: + sph_simd512_init(&ctx_simd); + sph_simd512(&ctx_simd, in, size); + sph_simd512_close(&ctx_simd, hash); + break; + case ECHO: + sph_echo512_init(&ctx_echo); + sph_echo512(&ctx_echo, in, size); + sph_echo512_close(&ctx_echo, hash); + break; + case HAMSI: + sph_hamsi512_init(&ctx_hamsi); + sph_hamsi512(&ctx_hamsi, in, size); + sph_hamsi512_close(&ctx_hamsi, hash); + break; + case FUGUE: + sph_fugue512_init(&ctx_fugue); + sph_fugue512(&ctx_fugue, in, size); + sph_fugue512_close(&ctx_fugue, hash); + break; + case SHABAL: + sph_shabal512_init(&ctx_shabal); + sph_shabal512(&ctx_shabal, in, size); + sph_shabal512_close(&ctx_shabal, hash); + break; + case WHIRLPOOL: + sph_whirlpool_init(&ctx_whirlpool); + sph_whirlpool(&ctx_whirlpool, in, size); + sph_whirlpool_close(&ctx_whirlpool, hash); + break; + case SHA512: + sph_tiger_init(&ctx_tiger); + sph_tiger(&ctx_tiger, (const void*) in, size); + sph_tiger_close(&ctx_tiger, (void*) hash); + for (int j = 24; j < 64; ++j) ((uint8_t*)hash)[j] = 0; // Pad the 24 bytes to bring it to 64 bytes + + sph_sha512_init(&ctx_sha512); + sph_sha512(&ctx_sha512,(const void*) hash, 64); + sph_sha512_close(&ctx_sha512,(void*) hash); + break; + } + in = (void*) hash; + size = 64; + } + memcpy(output, hash, 32); +} diff --git a/stratum/algos/x16rv2.h b/stratum/algos/x16rv2.h new file mode 100644 index 000000000..9ff2bf4a4 --- /dev/null +++ b/stratum/algos/x16rv2.h @@ -0,0 +1,16 @@ +#ifndef X16RV2_H +#define X16RV2_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void x16rv2_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/stratum/algos/x17r.c b/stratum/algos/x17r.c new file mode 100644 index 000000000..29c07a525 --- /dev/null +++ b/stratum/algos/x17r.c @@ -0,0 +1,224 @@ +/** + * x17r algo implementation + * + * modifyed by wubei@fusionsilicon.com 2018 + */ + +#include +#include + +#include +#include +#include + +#include "sha3/sph_blake.h" +#include "sha3/sph_bmw.h" +#include "sha3/sph_groestl.h" +#include "sha3/sph_jh.h" +#include "sha3/sph_keccak.h" +#include "sha3/sph_skein.h" +#include "sha3/sph_luffa.h" +#include "sha3/sph_cubehash.h" +#include "sha3/sph_shavite.h" +#include "sha3/sph_simd.h" +#include "sha3/sph_echo.h" +#include "sha3/sph_hamsi.h" +#include "sha3/sph_fugue.h" +#include "sha3/sph_shabal.h" +#include "sha3/sph_whirlpool.h" +#include "sha3/sph_sha2.h" +#include "sha3/sph_haval.h" + +#include "common.h" + +#ifndef _MSC_VER +#define _ALIGN(x) __attribute__ ((aligned(x))) +#else +#define _ALIGN(x) __declspec(align(x)) +#endif + +enum Algo { + BLAKE = 0, + BMW, + GROESTL, + JH, + KECCAK, + SKEIN, + LUFFA, + CUBEHASH, + SHAVITE, + SIMD, + ECHO, + HAMSI, + FUGUE, + SHABAL, + WHIRLPOOL, + SHA512, + HAVAL,// + HASH_FUNC_COUNT +}; + +static void getAlgoString(const uint8_t* prevblock, char *output) +{ + char *sptr = output; + for (int j = 0; j < HASH_FUNC_COUNT; j++) { + //uint8_t b = (16 - j) >> 1; // 16 first ascii hex chars (lsb in uint256) + //printf ("the prevblock is %d\n",prevblock[j]); + //uint8_t algoDigit = (j & 1) ? (prevblock[b] & 0xF) : prevblock[b] >> 4;// + uint8_t algoDigit = prevblock[j] % HASH_FUNC_COUNT; + + //printf ("the algoDigit is %d\n",algoDigit); + if (algoDigit >= 10) + sprintf(sptr, "%c", 'A' + (algoDigit - 10)); + else + sprintf(sptr, "%u", (uint32_t) algoDigit); + sptr++; + } + *sptr = '\0'; +} + + +//uint32_t s_ntime = UINT32_MAX; +void x17r_hash(const char* input, char* output, uint32_t len) +{ + uint32_t s_ntime = UINT32_MAX; + char hashOrder[HASH_FUNC_COUNT + 1] = { 0 }; + + char* bytes_swap = NULL; + bytes_swap = (char *)malloc(len); + if (len >= 180) { + memcpy(bytes_swap, (char *)input, 140); + memcpy(bytes_swap+140, (char *)input+144, len-144); + memcpy(bytes_swap+len-4, (char *)input+140, 4); + } else { + memcpy(bytes_swap, (char *)input, len); + } + + uint32_t _ALIGN(128) hash[64/4]; + + sph_blake512_context ctx_blake; + sph_bmw512_context ctx_bmw; + sph_groestl512_context ctx_groestl; + sph_skein512_context ctx_skein; + sph_jh512_context ctx_jh; + sph_keccak512_context ctx_keccak; + sph_luffa512_context ctx_luffa1; + sph_cubehash512_context ctx_cubehash1; + sph_shavite512_context ctx_shavite1; + sph_simd512_context ctx_simd1; + sph_echo512_context ctx_echo1; + sph_hamsi512_context ctx_hamsi1; + sph_fugue512_context ctx_fugue1; + sph_shabal512_context ctx_shabal1; + sph_whirlpool_context ctx_whirlpool1; + sph_sha512_context ctx_sha512; + sph_haval256_5_context ctx_haval;// + + memset((char*)&hash, 0, 64); + void *in = (void*) bytes_swap; + int size = len; + + if (s_ntime == UINT32_MAX) { + const uint8_t* in8 = (uint8_t*) bytes_swap; + getAlgoString(&in8[4], hashOrder); + } + + for (int i = 0; i < 17; i++)// + { + const char elem = hashOrder[i]; + const uint8_t algo = elem >= 'A' ? elem - 'A' + 10 : elem - '0'; + //printf ("the algo is %d\n",algo); + switch (algo) { + case BLAKE: + sph_blake512_init(&ctx_blake); + sph_blake512(&ctx_blake, in, size); + sph_blake512_close(&ctx_blake, hash); + break; + case BMW: + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, in, size); + sph_bmw512_close(&ctx_bmw, hash); + break; + case GROESTL: + sph_groestl512_init(&ctx_groestl); + sph_groestl512(&ctx_groestl, in, size); + sph_groestl512_close(&ctx_groestl, hash); + break; + case SKEIN: + sph_skein512_init(&ctx_skein); + sph_skein512(&ctx_skein, in, size); + sph_skein512_close(&ctx_skein, hash); + break; + case JH: + sph_jh512_init(&ctx_jh); + sph_jh512(&ctx_jh, in, size); + sph_jh512_close(&ctx_jh, hash); + break; + case KECCAK: + sph_keccak512_init(&ctx_keccak); + sph_keccak512(&ctx_keccak, in, size); + sph_keccak512_close(&ctx_keccak, hash); + break; + case LUFFA: + sph_luffa512_init(&ctx_luffa1); + sph_luffa512(&ctx_luffa1, in, size); + sph_luffa512_close(&ctx_luffa1, hash); + break; + case CUBEHASH: + sph_cubehash512_init(&ctx_cubehash1); + sph_cubehash512(&ctx_cubehash1, in, size); + sph_cubehash512_close(&ctx_cubehash1, hash); + break; + case SHAVITE: + sph_shavite512_init(&ctx_shavite1); + sph_shavite512(&ctx_shavite1, in, size); + sph_shavite512_close(&ctx_shavite1, hash); + break; + case SIMD: + sph_simd512_init(&ctx_simd1); + sph_simd512(&ctx_simd1, in, size); + sph_simd512_close(&ctx_simd1, hash); + break; + case ECHO: + sph_echo512_init(&ctx_echo1); + sph_echo512(&ctx_echo1, in, size); + sph_echo512_close(&ctx_echo1, hash); + break; + case HAMSI: + sph_hamsi512_init(&ctx_hamsi1); + sph_hamsi512(&ctx_hamsi1, in, size); + sph_hamsi512_close(&ctx_hamsi1, hash); + break; + case FUGUE: + sph_fugue512_init(&ctx_fugue1); + sph_fugue512(&ctx_fugue1, in, size); + sph_fugue512_close(&ctx_fugue1, hash); + break; + case SHABAL: + sph_shabal512_init(&ctx_shabal1); + sph_shabal512(&ctx_shabal1, in, size); + sph_shabal512_close(&ctx_shabal1, hash); + break; + case WHIRLPOOL: + sph_whirlpool_init(&ctx_whirlpool1); + sph_whirlpool(&ctx_whirlpool1, in, size); + sph_whirlpool_close(&ctx_whirlpool1, hash); + break; + case SHA512: + sph_sha512_init(&ctx_sha512); + sph_sha512(&ctx_sha512,(const void*) in, size); + sph_sha512_close(&ctx_sha512,(void*) hash); + break; + case HAVAL: + sph_haval256_5_init(&ctx_haval); + sph_haval256_5(&ctx_haval, (const void*)in, size); + sph_haval256_5_close(&ctx_haval, hash); + memset(hash+8,0x00000000,32); + break; + } + in = (void*) hash; + size = 64; + } + memcpy(output, hash, 32); + free(bytes_swap); +} diff --git a/stratum/algos/x17r.h b/stratum/algos/x17r.h new file mode 100644 index 000000000..d71377542 --- /dev/null +++ b/stratum/algos/x17r.h @@ -0,0 +1,18 @@ +#ifndef X17R_H +#define X17R_H + +#ifdef __cplusplus +extern "C"{ +#endif + +#include + +#include + +void x17r_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/stratum/algos/x18.c b/stratum/algos/x18.c new file mode 100644 index 000000000..5387e4923 --- /dev/null +++ b/stratum/algos/x18.c @@ -0,0 +1,123 @@ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define _ALIGN(x) __attribute__ ((aligned(x))) + +void x18_hash(const char* input, char* output, uint32_t len) +{ + sph_blake512_context ctx_blake; + sph_bmw512_context ctx_bmw; + sph_groestl512_context ctx_groestl; + sph_jh512_context ctx_jh; + sph_keccak512_context ctx_keccak; + sph_skein512_context ctx_skein; + 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; + sph_hamsi512_context ctx_hamsi; + sph_fugue512_context ctx_fugue; + sph_shabal512_context ctx_shabal; + sph_whirlpool_context ctx_whirlpool; + sph_sha512_context ctx_sha2; + sph_haval256_5_context ctx_haval; + sph_gost512_context ctx_gost; + + //these uint512 in the c++ source of the client are backed by an array of uint32 + uint32_t _ALIGN(64) hashA[16], hashB[16]; + + sph_blake512_init(&ctx_blake); + sph_blake512 (&ctx_blake, input, len); + sph_blake512_close (&ctx_blake, hashA); + + sph_bmw512_init(&ctx_bmw); + sph_bmw512 (&ctx_bmw, hashA, 64); + sph_bmw512_close(&ctx_bmw, hashB); + + sph_groestl512_init(&ctx_groestl); + sph_groestl512 (&ctx_groestl, hashB, 64); + sph_groestl512_close(&ctx_groestl, hashA); + + sph_skein512_init(&ctx_skein); + sph_skein512 (&ctx_skein, hashA, 64); + sph_skein512_close (&ctx_skein, hashB); + + sph_jh512_init(&ctx_jh); + sph_jh512 (&ctx_jh, hashB, 64); + sph_jh512_close(&ctx_jh, hashA); + + sph_keccak512_init(&ctx_keccak); + sph_keccak512 (&ctx_keccak, hashA, 64); + sph_keccak512_close(&ctx_keccak, hashB); + + sph_luffa512_init (&ctx_luffa); + sph_luffa512 (&ctx_luffa, hashB, 64); + sph_luffa512_close (&ctx_luffa, hashA); + + sph_cubehash512_init (&ctx_cubehash); + sph_cubehash512 (&ctx_cubehash, hashA, 64); + sph_cubehash512_close(&ctx_cubehash, hashB); + + sph_shavite512_init (&ctx_shavite); + sph_shavite512 (&ctx_shavite, hashB, 64); + sph_shavite512_close(&ctx_shavite, hashA); + + sph_simd512_init (&ctx_simd); + sph_simd512 (&ctx_simd, hashA, 64); + sph_simd512_close(&ctx_simd, hashB); + + sph_echo512_init (&ctx_echo); + sph_echo512 (&ctx_echo, hashB, 64); + sph_echo512_close(&ctx_echo, hashA); + + sph_hamsi512_init (&ctx_hamsi); + sph_hamsi512 (&ctx_hamsi, hashA, 64); + sph_hamsi512_close(&ctx_hamsi, hashB); + + sph_fugue512_init (&ctx_fugue); + sph_fugue512 (&ctx_fugue, hashB, 64); + sph_fugue512_close(&ctx_fugue, hashA); + + sph_shabal512_init (&ctx_shabal); + sph_shabal512 (&ctx_shabal, hashA, 64); + sph_shabal512_close(&ctx_shabal, hashB); + + sph_whirlpool_init (&ctx_whirlpool); + sph_whirlpool (&ctx_whirlpool, hashB, 64); + sph_whirlpool_close(&ctx_whirlpool, hashA); + + sph_sha512_init (&ctx_sha2); + sph_sha512 (&ctx_sha2, hashA, 64); + sph_sha512_close(&ctx_sha2, hashB); + + sph_haval256_5_init (&ctx_haval); + sph_haval256_5 (&ctx_haval, hashB, 64); + sph_haval256_5_close(&ctx_haval, hashA); + + sph_gost512_init (&ctx_gost); + sph_gost512 (&ctx_gost, hashA, 64); + sph_gost512_close(&ctx_gost, hashB); + + memcpy(output, hashB, 32); +} diff --git a/stratum/algos/x18.h b/stratum/algos/x18.h new file mode 100644 index 000000000..1a97b3ccb --- /dev/null +++ b/stratum/algos/x18.h @@ -0,0 +1,16 @@ +#ifndef X18_H +#define X18_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void x18_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/stratum/algos/x20r.c b/stratum/algos/x20r.c new file mode 100644 index 000000000..fa5a02d9a --- /dev/null +++ b/stratum/algos/x20r.c @@ -0,0 +1,217 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define _ALIGN(x) __attribute__ ((aligned(x))) + + enum Algo { + BLAKE = 0, + BMW, + GROESTL, + JH, + KECCAK, + SKEIN, + LUFFA, + CUBEHASH, + SHAVITE, + SIMD, + ECHO, + HAMSI, + FUGUE, + SHABAL, + WHIRLPOOL, + SHA512, + HAVAL, // 256-bits output + GOST, + RADIOGATUN, // 256-bits output + PANAMA, // 256-bits output + HASH_FUNC_COUNT +}; + +static __thread uint32_t s_ntime = UINT32_MAX; +static __thread char hashOrder[HASH_FUNC_COUNT + 1] = { 0 }; + +static void getAlgoString(const uint8_t* prevblock, char *output) +{ + char *sptr = output; + + for (int j = 0; j < HASH_FUNC_COUNT; j++) { + char b = (19 - j) >> 1; // 16 ascii hex chars, reversed + uint8_t algoDigit = (j & 1) ? prevblock[b] & 0xF : prevblock[b] >> 4; + if (algoDigit >= 10) + sprintf(sptr, "%c", 'A' + (algoDigit - 10)); + else + sprintf(sptr, "%u", (uint32_t) algoDigit); + sptr++; + } + *sptr = '\0'; +} + +void x20r_hash(const char* input, char* output, uint32_t len) +{ + uint32_t _ALIGN(128) hash[64/4]; + + sph_blake512_context ctx_blake; + sph_bmw512_context ctx_bmw; + sph_groestl512_context ctx_groestl; + sph_skein512_context ctx_skein; + sph_jh512_context ctx_jh; + sph_keccak512_context ctx_keccak; + 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; + sph_hamsi512_context ctx_hamsi; + sph_fugue512_context ctx_fugue; + sph_shabal512_context ctx_shabal; + sph_whirlpool_context ctx_whirlpool; + sph_sha512_context ctx_sha512; + sph_haval256_5_context ctx_haval; + sph_gost512_context ctx_gost; + sph_radiogatun64_context ctx_radiogatun; + sph_panama_context ctx_panama; + + void *in = (void*) input; + int size = len; + + if (s_ntime == UINT32_MAX) { + const uint8_t* in8 = (uint8_t*) input; + getAlgoString(&in8[4], hashOrder); + } + + for (int i = 0; i < 20; i++) + { + const char elem = hashOrder[i]; + const uint8_t algo = elem >= 'A' ? elem - 'A' + 10 : elem - '0'; + + switch (algo) { + case BLAKE: + sph_blake512_init(&ctx_blake); + sph_blake512(&ctx_blake, in, size); + sph_blake512_close(&ctx_blake, hash); + break; + case BMW: + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, in, size); + sph_bmw512_close(&ctx_bmw, hash); + break; + case GROESTL: + sph_groestl512_init(&ctx_groestl); + sph_groestl512(&ctx_groestl, in, size); + sph_groestl512_close(&ctx_groestl, hash); + break; + case SKEIN: + sph_skein512_init(&ctx_skein); + sph_skein512(&ctx_skein, in, size); + sph_skein512_close(&ctx_skein, hash); + break; + case JH: + sph_jh512_init(&ctx_jh); + sph_jh512(&ctx_jh, in, size); + sph_jh512_close(&ctx_jh, hash); + break; + case KECCAK: + sph_keccak512_init(&ctx_keccak); + sph_keccak512(&ctx_keccak, in, size); + sph_keccak512_close(&ctx_keccak, hash); + break; + case LUFFA: + sph_luffa512_init(&ctx_luffa); + sph_luffa512(&ctx_luffa, in, size); + sph_luffa512_close(&ctx_luffa, hash); + break; + case CUBEHASH: + sph_cubehash512_init(&ctx_cubehash); + sph_cubehash512(&ctx_cubehash, in, size); + sph_cubehash512_close(&ctx_cubehash, hash); + break; + case SHAVITE: + sph_shavite512_init(&ctx_shavite); + sph_shavite512(&ctx_shavite, in, size); + sph_shavite512_close(&ctx_shavite, hash); + break; + case SIMD: + sph_simd512_init(&ctx_simd); + sph_simd512(&ctx_simd, in, size); + sph_simd512_close(&ctx_simd, hash); + break; + case ECHO: + sph_echo512_init(&ctx_echo); + sph_echo512(&ctx_echo, in, size); + sph_echo512_close(&ctx_echo, hash); + break; + case HAMSI: + sph_hamsi512_init(&ctx_hamsi); + sph_hamsi512(&ctx_hamsi, in, size); + sph_hamsi512_close(&ctx_hamsi, hash); + break; + case FUGUE: + sph_fugue512_init(&ctx_fugue); + sph_fugue512(&ctx_fugue, in, size); + sph_fugue512_close(&ctx_fugue, hash); + break; + case SHABAL: + sph_shabal512_init(&ctx_shabal); + sph_shabal512(&ctx_shabal, in, size); + sph_shabal512_close(&ctx_shabal, hash); + break; + case WHIRLPOOL: + sph_whirlpool_init(&ctx_whirlpool); + sph_whirlpool(&ctx_whirlpool, in, size); + sph_whirlpool_close(&ctx_whirlpool, hash); + break; + case SHA512: + sph_sha512_init(&ctx_sha512); + sph_sha512(&ctx_sha512,(const void*) in, size); + sph_sha512_close(&ctx_sha512,(void*) hash); + break; + case HAVAL: + sph_haval256_5_init(&ctx_haval); + sph_haval256_5(&ctx_haval, in, size); + sph_haval256_5_close(&ctx_haval, hash); + memset(&hash[8], 0, 32); + break; + case GOST: + sph_gost512_init(&ctx_gost); + sph_gost512(&ctx_gost, in, size); + sph_gost512_close(&ctx_gost, hash); + break; + case RADIOGATUN: + sph_radiogatun64_init(&ctx_radiogatun); + sph_radiogatun64(&ctx_radiogatun, in, size); + sph_radiogatun64_close(&ctx_radiogatun, hash); + memset(&hash[8], 0, 32); + break; + case PANAMA: + sph_panama_init(&ctx_panama); + sph_panama(&ctx_panama, in, size); + sph_panama_close(&ctx_panama, hash); + memset(&hash[8], 0, 32); + break; + } + in = (void*) hash; + size = 64; + } + memcpy(output, hash, 32); +} diff --git a/stratum/algos/x20r.h b/stratum/algos/x20r.h new file mode 100644 index 000000000..6f75b7fb9 --- /dev/null +++ b/stratum/algos/x20r.h @@ -0,0 +1,16 @@ +#ifndef X20R_H +#define X20R_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void x20r_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/stratum/algos/x21s.c b/stratum/algos/x21s.c new file mode 100644 index 000000000..269826a5e --- /dev/null +++ b/stratum/algos/x21s.c @@ -0,0 +1,188 @@ +#include +#include +#include + #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gost.h" +#include "Lyra2.h" +#include "common.h" + enum Algo { + BLAKE = 0, + BMW, + GROESTL, + JH, + KECCAK, + SKEIN, + LUFFA, + CUBEHASH, + SHAVITE, + SIMD, + ECHO, + HAMSI, + FUGUE, + SHABAL, + WHIRLPOOL, + SHA512, + HASH_FUNC_COUNT +}; +static void getAlgoString(const uint8_t* prevblock, char *output) +{ + strcpy(output, "0123456789ABCDEF"); + for(int i = 0; i < 16; i++){ + uint8_t b = (15 - i) >> 1; // 16 ascii hex chars, reversed + uint8_t algoDigit = (i & 1) ? prevblock[b] & 0xF : prevblock[b] >> 4; + int offset = algoDigit; + // insert the nth character at the front + char oldVal = output[offset]; + for(int j=offset; j-->0;) { + output[j+1] = output[j]; + } + output[0] = oldVal; + } +} + void x21s_hash(const char* input, char* output, uint32_t len) { + uint32_t hash[64/4]; + char hashOrder[HASH_FUNC_COUNT + 1] = { 0 }; + sph_blake512_context ctx_blake; + sph_bmw512_context ctx_bmw; + sph_groestl512_context ctx_groestl; + sph_jh512_context ctx_jh; + sph_keccak512_context ctx_keccak; + sph_skein512_context ctx_skein; + 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; + sph_hamsi512_context ctx_hamsi; + sph_fugue512_context ctx_fugue; + sph_shabal512_context ctx_shabal; + sph_whirlpool_context ctx_whirlpool; + sph_sha512_context ctx_sha512; + sph_haval256_5_context ctx_haval; + sph_tiger_context ctx_tiger; + sph_gost512_context ctx_gost; + sph_sha256_context ctx_sha; + void *in = (void*) input; + int size = len; + getAlgoString(&input[4], hashOrder); + for (int i = 0; i < 16; i++) + { + const char elem = hashOrder[i]; + const uint8_t algo = elem >= 'A' ? elem - 'A' + 10 : elem - '0'; + switch (algo) { + case BLAKE: + sph_blake512_init(&ctx_blake); + sph_blake512(&ctx_blake, in, size); + sph_blake512_close(&ctx_blake, hash); + break; + case BMW: + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, in, size); + sph_bmw512_close(&ctx_bmw, hash); + break; + case GROESTL: + sph_groestl512_init(&ctx_groestl); + sph_groestl512(&ctx_groestl, in, size); + sph_groestl512_close(&ctx_groestl, hash); + break; + case SKEIN: + sph_skein512_init(&ctx_skein); + sph_skein512(&ctx_skein, in, size); + sph_skein512_close(&ctx_skein, hash); + break; + case JH: + sph_jh512_init(&ctx_jh); + sph_jh512(&ctx_jh, in, size); + sph_jh512_close(&ctx_jh, hash); + break; + case KECCAK: + sph_keccak512_init(&ctx_keccak); + sph_keccak512(&ctx_keccak, in, size); + sph_keccak512_close(&ctx_keccak, hash); + break; + case LUFFA: + sph_luffa512_init(&ctx_luffa); + sph_luffa512(&ctx_luffa, in, size); + sph_luffa512_close(&ctx_luffa, hash); + break; + case CUBEHASH: + sph_cubehash512_init(&ctx_cubehash); + sph_cubehash512(&ctx_cubehash, in, size); + sph_cubehash512_close(&ctx_cubehash, hash); + break; + case SHAVITE: + sph_shavite512_init(&ctx_shavite); + sph_shavite512(&ctx_shavite, in, size); + sph_shavite512_close(&ctx_shavite, hash); + break; + case SIMD: + sph_simd512_init(&ctx_simd); + sph_simd512(&ctx_simd, in, size); + sph_simd512_close(&ctx_simd, hash); + break; + case ECHO: + sph_echo512_init(&ctx_echo); + sph_echo512(&ctx_echo, in, size); + sph_echo512_close(&ctx_echo, hash); + break; + case HAMSI: + sph_hamsi512_init(&ctx_hamsi); + sph_hamsi512(&ctx_hamsi, in, size); + sph_hamsi512_close(&ctx_hamsi, hash); + break; + case FUGUE: + sph_fugue512_init(&ctx_fugue); + sph_fugue512(&ctx_fugue, in, size); + sph_fugue512_close(&ctx_fugue, hash); + break; + case SHABAL: + sph_shabal512_init(&ctx_shabal); + sph_shabal512(&ctx_shabal, in, size); + sph_shabal512_close(&ctx_shabal, hash); + break; + case WHIRLPOOL: + sph_whirlpool_init(&ctx_whirlpool); + sph_whirlpool(&ctx_whirlpool, in, size); + sph_whirlpool_close(&ctx_whirlpool, hash); + break; + case SHA512: + sph_sha512_init(&ctx_sha512); + sph_sha512(&ctx_sha512,(const void*) in, size); + sph_sha512_close(&ctx_sha512,(void*) hash); + break; + } + in = (void*) hash; + size = 64; + } + sph_haval256_5_init(&ctx_haval); + sph_haval256_5(&ctx_haval,(const void*) hash, 64); + sph_haval256_5_close(&ctx_haval,hash); + sph_tiger_init(&ctx_tiger); + sph_tiger (&ctx_tiger, (const void*) hash, 64); + sph_tiger_close(&ctx_tiger, (void*) hash); + LYRA2((void*) hash, 32, (const void*) hash, 32, (const void*) hash, 32, 1, 4, 4); + sph_gost512_init(&ctx_gost); + sph_gost512 (&ctx_gost, (const void*) hash, 64); + sph_gost512_close(&ctx_gost, (void*) hash); + sph_sha256_init(&ctx_sha); + sph_sha256 (&ctx_sha, (const void*) hash, 64); + sph_sha256_close(&ctx_sha, (void*) hash); + memcpy(output, hash, 32); +} diff --git a/stratum/algos/x21s.h b/stratum/algos/x21s.h new file mode 100644 index 000000000..2f26a7ea3 --- /dev/null +++ b/stratum/algos/x21s.h @@ -0,0 +1,16 @@ +#ifndef X21S_H +#define X21S_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void x21s_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/stratum/algos/x22i.c b/stratum/algos/x22i.c index 02a1aa3d5..c530e15c3 100644 --- a/stratum/algos/x22i.c +++ b/stratum/algos/x22i.c @@ -144,3 +144,18 @@ void x22i_hash(const char* input, char* output, uint32_t len) memcpy(output, hash, 32); } + +void hexlify(char *hex, const unsigned char *bin, int len) +{ + hex[0] = 0; + for(int i=0; i < len; i++) + sprintf(hex+strlen(hex), "%02x", bin[i]); +} + +void x22i_hash_hex(const char *input, char *output, unsigned int len) +{ + char output1[32]; + + x22i_hash(input, output1, len); + hexlify(output, (unsigned char *)output1, 32); +} diff --git a/stratum/algos/x22i.h b/stratum/algos/x22i.h index 502b8941f..ae6b13b82 100644 --- a/stratum/algos/x22i.h +++ b/stratum/algos/x22i.h @@ -8,6 +8,7 @@ extern "C" { #include void x22i_hash(const char* input, char* output, uint32_t len); +void x22i_hash_hex(const char *input, char *output, unsigned int len); #ifdef __cplusplus } diff --git a/stratum/algos/x25x.c b/stratum/algos/x25x.c new file mode 100644 index 000000000..0b3076d11 --- /dev/null +++ b/stratum/algos/x25x.c @@ -0,0 +1,174 @@ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "SWIFFTX/SWIFFTX.h" +#include "lane.h" +#include "gost.h" +#include "Lyra2.h" + +#include "common.h" + +void x25x_hash(const char* input, char* output, uint32_t len) +{ + sph_blake512_context ctx_blake; + sph_bmw512_context ctx_bmw; + sph_groestl512_context ctx_groestl; + sph_jh512_context ctx_jh; + sph_keccak512_context ctx_keccak; + sph_skein512_context ctx_skein; + 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; + sph_hamsi512_context ctx_hamsi; + sph_fugue512_context ctx_fugue; + sph_shabal512_context ctx_shabal; + sph_whirlpool_context ctx_whirlpool; + sph_sha512_context ctx_sha512; + sph_haval256_5_context ctx_haval; + sph_tiger_context ctx_tiger; + sph_gost512_context ctx_gost; + sph_sha256_context ctx_sha; + sph_panama_context ctx_panama; + +// unsigned char _ALIGN(128) hash[25][64] = { [0 ... 24] = { [0 ... 63] = 0 } }; + unsigned char _ALIGN(128) hash[25][64] = { 0 }; + + sph_blake512_init(&ctx_blake); + sph_blake512(&ctx_blake, input, len); + sph_blake512_close (&ctx_blake, &hash[0]); + + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, &hash[0], 64); + sph_bmw512_close(&ctx_bmw, &hash[1]); + + sph_groestl512_init(&ctx_groestl); + sph_groestl512(&ctx_groestl, &hash[1], 64); + sph_groestl512_close(&ctx_groestl, &hash[2]); + + sph_skein512_init(&ctx_skein); + sph_skein512(&ctx_skein, &hash[2], 64); + sph_skein512_close(&ctx_skein, &hash[3]); + + sph_jh512_init(&ctx_jh); + sph_jh512(&ctx_jh, &hash[3], 64); + sph_jh512_close(&ctx_jh, &hash[4]); + + sph_keccak512_init(&ctx_keccak); + sph_keccak512(&ctx_keccak, &hash[4], 64); + sph_keccak512_close(&ctx_keccak, &hash[5]); + + sph_luffa512_init(&ctx_luffa); + sph_luffa512(&ctx_luffa, &hash[5], 64); + sph_luffa512_close (&ctx_luffa, &hash[6]); + + sph_cubehash512_init(&ctx_cubehash); + sph_cubehash512(&ctx_cubehash, &hash[6], 64); + sph_cubehash512_close(&ctx_cubehash, &hash[7]); + + sph_shavite512_init(&ctx_shavite); + sph_shavite512(&ctx_shavite, &hash[7], 64); + sph_shavite512_close(&ctx_shavite, &hash[8]); + + sph_simd512_init(&ctx_simd); + sph_simd512(&ctx_simd, &hash[8], 64); + sph_simd512_close(&ctx_simd, &hash[9]); + + sph_echo512_init(&ctx_echo); + sph_echo512(&ctx_echo, &hash[9], 64); + sph_echo512_close(&ctx_echo, &hash[10]); + + sph_hamsi512_init(&ctx_hamsi); + sph_hamsi512(&ctx_hamsi, &hash[10], 64); + sph_hamsi512_close(&ctx_hamsi, &hash[11]); + + sph_fugue512_init(&ctx_fugue); + sph_fugue512(&ctx_fugue, &hash[11], 64); + sph_fugue512_close(&ctx_fugue, &hash[12]); + + sph_shabal512_init(&ctx_shabal); + sph_shabal512(&ctx_shabal, (const void*) &hash[12], 64); + sph_shabal512_close(&ctx_shabal, &hash[13]); + + sph_whirlpool_init(&ctx_whirlpool); + sph_whirlpool (&ctx_whirlpool, (const void*) &hash[13], 64); + sph_whirlpool_close(&ctx_whirlpool, &hash[14]); + + sph_sha512_init(&ctx_sha512); + sph_sha512(&ctx_sha512,(const void*) &hash[14], 64); + sph_sha512_close(&ctx_sha512,(void*) &hash[15]); + + unsigned char temp[SWIFFTX_OUTPUT_BLOCK_SIZE] = {0}; + InitializeSWIFFTX(); + ComputeSingleSWIFFTX((unsigned char*)&hash[12], temp, false); + memcpy((unsigned char*)&hash[16], temp, 64); + + sph_haval256_5_init(&ctx_haval); + sph_haval256_5(&ctx_haval,(const void*) &hash[16], 64); + sph_haval256_5_close(&ctx_haval,&hash[17]); + + sph_tiger_init(&ctx_tiger); + sph_tiger (&ctx_tiger, (const void*) &hash[17], 64); + sph_tiger_close(&ctx_tiger, (void*) &hash[18]); + + LYRA2((void*) &hash[19], 32, (const void*) &hash[18], 32, (const void*) &hash[18], 32, 1, 4, 4); + + sph_gost512_init(&ctx_gost); + sph_gost512 (&ctx_gost, (const void*) &hash[19], 64); + sph_gost512_close(&ctx_gost, (void*) &hash[20]); + + sph_sha256_init(&ctx_sha); + sph_sha256 (&ctx_sha, (const void*) &hash[20], 64); + sph_sha256_close(&ctx_sha, (void*) &hash[21]); + + sph_panama_init(&ctx_panama); + sph_panama (&ctx_panama, (const void*) &hash[21], 64 ); + sph_panama_close(&ctx_panama, (void*) &hash[22]); + + laneHash(512, (const BitSequence*) &hash[22], 512, (BitSequence*) &hash[23]); + + // NEW simple shuffle algorithm, instead of just reversing + #define X25X_SHUFFLE_BLOCKS (24 /* number of algos so far */ * 64 /* output bytes per algo */ / 2 /* block size */) + #define X25X_SHUFFLE_ROUNDS 12 + + static const uint16_t x25x_round_const[X25X_SHUFFLE_ROUNDS] = { + 0x142c, 0x5830, 0x678c, 0xe08c, + 0x3c67, 0xd50d, 0xb1d8, 0xecb2, + 0xd7ee, 0x6783, 0xfa6c, 0x4b9c + }; + + uint16_t* block_pointer = (uint16_t*)hash; + for (int r = 0; r < X25X_SHUFFLE_ROUNDS; r++) { + for (int i = 0; i < X25X_SHUFFLE_BLOCKS; i++) { + uint16_t block_value = block_pointer[X25X_SHUFFLE_BLOCKS - i - 1]; + block_pointer[i] ^= block_pointer[block_value % X25X_SHUFFLE_BLOCKS] + (x25x_round_const[r] << (i % 16)); + } + } + + blake2s_simple((uint8_t*)&hash[24], (const void*)(&hash[0]), 64 * 24); + + memcpy(output, &hash[24], 32); +} diff --git a/stratum/algos/x25x.h b/stratum/algos/x25x.h new file mode 100644 index 000000000..31dd18d30 --- /dev/null +++ b/stratum/algos/x25x.h @@ -0,0 +1,11 @@ +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void x25x_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif diff --git a/stratum/algos/yescrypt-opt.c b/stratum/algos/yescrypt-opt.c deleted file mode 100644 index c96190bab..000000000 --- a/stratum/algos/yescrypt-opt.c +++ /dev/null @@ -1,970 +0,0 @@ -/*- - * Copyright 2009 Colin Percival - * Copyright 2013,2014 Alexander Peslyak - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file was originally written by Colin Percival as part of the Tarsnap - * online backup system. - */ - -#include -#include -#include - -#include "sha256_Y.h" -#include "sysendian.h" - -#include "yescrypt-platform.c" - -static inline uint32_t -le32dec(const void *pp) -{ - const uint8_t *p = (uint8_t const *)pp; - - return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) + - ((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24)); -} - -static inline void -le32enc(void *pp, uint32_t x) -{ - uint8_t * p = (uint8_t *)pp; - - p[0] = x & 0xff; - p[1] = (x >> 8) & 0xff; - p[2] = (x >> 16) & 0xff; - p[3] = (x >> 24) & 0xff; -} - -static inline void -blkcpy(uint64_t * dest, const uint64_t * src, size_t count) -{ - do { - *dest++ = *src++; *dest++ = *src++; - *dest++ = *src++; *dest++ = *src++; - } while (count -= 4); -} - -static inline void -blkxor(uint64_t * dest, const uint64_t * src, size_t count) -{ - do { - *dest++ ^= *src++; *dest++ ^= *src++; - *dest++ ^= *src++; *dest++ ^= *src++; - } while (count -= 4); -} - -typedef union { - uint32_t w[16]; - uint64_t d[8]; -} salsa20_blk_t; - -static inline void -salsa20_simd_shuffle(const salsa20_blk_t * Bin, salsa20_blk_t * Bout) -{ -#define COMBINE(out, in1, in2) \ - Bout->d[out] = Bin->w[in1 * 2] | ((uint64_t)Bin->w[in2 * 2 + 1] << 32); - COMBINE(0, 0, 2) - COMBINE(1, 5, 7) - COMBINE(2, 2, 4) - COMBINE(3, 7, 1) - COMBINE(4, 4, 6) - COMBINE(5, 1, 3) - COMBINE(6, 6, 0) - COMBINE(7, 3, 5) -#undef COMBINE -} - -static inline void -salsa20_simd_unshuffle(const salsa20_blk_t * Bin, salsa20_blk_t * Bout) -{ -#define COMBINE(out, in1, in2) \ - Bout->w[out * 2] = Bin->d[in1]; \ - Bout->w[out * 2 + 1] = Bin->d[in2] >> 32; - COMBINE(0, 0, 6) - COMBINE(1, 5, 3) - COMBINE(2, 2, 0) - COMBINE(3, 7, 5) - COMBINE(4, 4, 2) - COMBINE(5, 1, 7) - COMBINE(6, 6, 4) - COMBINE(7, 3, 1) -#undef COMBINE -} - -/** - * salsa20_8(B): - * Apply the salsa20/8 core to the provided block. - */ -static void -salsa20_8(uint64_t B[8]) -{ - size_t i; - salsa20_blk_t X; -#define x X.w - - salsa20_simd_unshuffle((const salsa20_blk_t *)B, &X); - - for (i = 0; i < 8; i += 2) { -#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) - /* Operate on columns */ - x[ 4] ^= R(x[ 0]+x[12], 7); x[ 8] ^= R(x[ 4]+x[ 0], 9); - x[12] ^= R(x[ 8]+x[ 4],13); x[ 0] ^= R(x[12]+x[ 8],18); - - x[ 9] ^= R(x[ 5]+x[ 1], 7); x[13] ^= R(x[ 9]+x[ 5], 9); - x[ 1] ^= R(x[13]+x[ 9],13); x[ 5] ^= R(x[ 1]+x[13],18); - - x[14] ^= R(x[10]+x[ 6], 7); x[ 2] ^= R(x[14]+x[10], 9); - x[ 6] ^= R(x[ 2]+x[14],13); x[10] ^= R(x[ 6]+x[ 2],18); - - x[ 3] ^= R(x[15]+x[11], 7); x[ 7] ^= R(x[ 3]+x[15], 9); - x[11] ^= R(x[ 7]+x[ 3],13); x[15] ^= R(x[11]+x[ 7],18); - - /* Operate on rows */ - x[ 1] ^= R(x[ 0]+x[ 3], 7); x[ 2] ^= R(x[ 1]+x[ 0], 9); - x[ 3] ^= R(x[ 2]+x[ 1],13); x[ 0] ^= R(x[ 3]+x[ 2],18); - - x[ 6] ^= R(x[ 5]+x[ 4], 7); x[ 7] ^= R(x[ 6]+x[ 5], 9); - x[ 4] ^= R(x[ 7]+x[ 6],13); x[ 5] ^= R(x[ 4]+x[ 7],18); - - x[11] ^= R(x[10]+x[ 9], 7); x[ 8] ^= R(x[11]+x[10], 9); - x[ 9] ^= R(x[ 8]+x[11],13); x[10] ^= R(x[ 9]+x[ 8],18); - - x[12] ^= R(x[15]+x[14], 7); x[13] ^= R(x[12]+x[15], 9); - x[14] ^= R(x[13]+x[12],13); x[15] ^= R(x[14]+x[13],18); -#undef R - } -#undef x - - { - salsa20_blk_t Y; - salsa20_simd_shuffle(&X, &Y); - for (i = 0; i < 16; i += 4) { - ((salsa20_blk_t *)B)->w[i] += Y.w[i]; - ((salsa20_blk_t *)B)->w[i + 1] += Y.w[i + 1]; - ((salsa20_blk_t *)B)->w[i + 2] += Y.w[i + 2]; - ((salsa20_blk_t *)B)->w[i + 3] += Y.w[i + 3]; - } - } -} - -/** - * blockmix_salsa8(Bin, Bout, X, r): - * Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r - * bytes in length; the output Bout must also be the same size. The - * temporary space X must be 64 bytes. - */ -static void -blockmix_salsa8(const uint64_t * Bin, uint64_t * Bout, uint64_t * X, size_t r) -{ - size_t i; - - /* 1: X <-- B_{2r - 1} */ - blkcpy(X, &Bin[(2 * r - 1) * 8], 8); - - /* 2: for i = 0 to 2r - 1 do */ - for (i = 0; i < 2 * r; i += 2) { - /* 3: X <-- H(X \xor B_i) */ - blkxor(X, &Bin[i * 8], 8); - salsa20_8(X); - - /* 4: Y_i <-- X */ - /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ - blkcpy(&Bout[i * 4], X, 8); - - /* 3: X <-- H(X \xor B_i) */ - blkxor(X, &Bin[i * 8 + 8], 8); - salsa20_8(X); - - /* 4: Y_i <-- X */ - /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ - blkcpy(&Bout[i * 4 + r * 8], X, 8); - } -} - -/* These are tunable */ -#define S_BITS 8 -#define S_SIMD 2 -#define S_P 4 -#define S_ROUNDS 6 - -/* Number of S-boxes. Not tunable, hard-coded in a few places. */ -#define S_N 2 - -/* Derived values. Not tunable on their own. */ -#define S_SIZE1 (1 << S_BITS) -#define S_MASK ((S_SIZE1 - 1) * S_SIMD * 8) -#define S_MASK2 (((uint64_t)S_MASK << 32) | S_MASK) -#define S_SIZE_ALL (S_N * S_SIZE1 * S_SIMD) -#define S_P_SIZE (S_P * S_SIMD) -#define S_MIN_R ((S_P * S_SIMD + 15) / 16) - -/** - * pwxform(B): - * Transform the provided block using the provided S-boxes. - */ -static void -block_pwxform(uint64_t * B, const uint64_t * S) -{ - uint64_t (*X)[S_SIMD] = (uint64_t (*)[S_SIMD])B; - const uint8_t *S0 = (const uint8_t *)S; - const uint8_t *S1 = (const uint8_t *)(S + S_SIZE1 * S_SIMD); - size_t i, j; -#if S_SIMD > 2 - size_t k; -#endif - - for (j = 0; j < S_P; j++) { - uint64_t *Xj = X[j]; - uint64_t x0 = Xj[0]; -#if S_SIMD > 1 - uint64_t x1 = Xj[1]; -#endif - - for (i = 0; i < S_ROUNDS; i++) { - uint64_t x = x0 & S_MASK2; - const uint64_t *p0, *p1; - - p0 = (const uint64_t *)(S0 + (uint32_t)x); - p1 = (const uint64_t *)(S1 + (x >> 32)); - - x0 = (uint64_t)(x0 >> 32) * (uint32_t)x0; - x0 += p0[0]; - x0 ^= p1[0]; - -#if S_SIMD > 1 - x1 = (uint64_t)(x1 >> 32) * (uint32_t)x1; - x1 += p0[1]; - x1 ^= p1[1]; -#endif - -#if S_SIMD > 2 - for (k = 2; k < S_SIMD; k++) { - x = Xj[k]; - - x = (uint64_t)(x >> 32) * (uint32_t)x; - x += p0[k]; - x ^= p1[k]; - - Xj[k] = x; - } -#endif - } - - Xj[0] = x0; -#if S_SIMD > 1 - Xj[1] = x1; -#endif - } -} - -/** - * blockmix_pwxform(Bin, Bout, S, r): - * Compute Bout = BlockMix_pwxform{salsa20/8, S, r}(Bin). The input Bin must - * be 128r bytes in length; the output Bout must also be the same size. - * - * S lacks const qualifier to match blockmix_salsa8()'s prototype, which we - * need to refer to both functions via the same function pointers. - */ -static void -blockmix_pwxform(const uint64_t * Bin, uint64_t * Bout, uint64_t * S, size_t r) -{ - size_t r1, r2, i; - - /* Convert 128-byte blocks to (S_P_SIZE * 64-bit) blocks */ - r1 = r * 128 / (S_P_SIZE * 8); - - /* X <-- B_{r1 - 1} */ - blkcpy(Bout, &Bin[(r1 - 1) * S_P_SIZE], S_P_SIZE); - - /* X <-- X \xor B_i */ - blkxor(Bout, Bin, S_P_SIZE); - - /* X <-- H'(X) */ - /* B'_i <-- X */ - block_pwxform(Bout, S); - - /* for i = 0 to r1 - 1 do */ - for (i = 1; i < r1; i++) { - /* X <-- X \xor B_i */ - blkcpy(&Bout[i * S_P_SIZE], &Bout[(i - 1) * S_P_SIZE], - S_P_SIZE); - blkxor(&Bout[i * S_P_SIZE], &Bin[i * S_P_SIZE], S_P_SIZE); - - /* X <-- H'(X) */ - /* B'_i <-- X */ - block_pwxform(&Bout[i * S_P_SIZE], S); - } - - /* Handle partial blocks */ - if (i * S_P_SIZE < r * 16) - blkcpy(&Bout[i * S_P_SIZE], &Bin[i * S_P_SIZE], - r * 16 - i * S_P_SIZE); - - i = (r1 - 1) * S_P_SIZE / 8; - /* Convert 128-byte blocks to 64-byte blocks */ - r2 = r * 2; - - /* B'_i <-- H(B'_i) */ - salsa20_8(&Bout[i * 8]); - i++; - - for (; i < r2; i++) { - /* B'_i <-- H(B'_i \xor B'_{i-1}) */ - blkxor(&Bout[i * 8], &Bout[(i - 1) * 8], 8); - salsa20_8(&Bout[i * 8]); - } -} - -/** - * integerify(B, r): - * Return the result of parsing B_{2r-1} as a little-endian integer. - */ -static inline uint64_t -integerify(const uint64_t * B, size_t r) -{ -/* - * Our 64-bit words are in host byte order, and word 6 holds the second 32-bit - * word of B_{2r-1} due to SIMD shuffling. The 64-bit value we return is also - * in host byte order, as it should be. - */ - const uint64_t * X = &B[(2 * r - 1) * 8]; - uint32_t lo = X[0]; - uint32_t hi = X[6] >> 32; - return ((uint64_t)hi << 32) + lo; -} - -/** - * smix1(B, r, N, flags, V, NROM, shared, XY, S): - * Compute first loop of B = SMix_r(B, N). The input B must be 128r bytes in - * length; the temporary storage V must be 128rN bytes in length; the temporary - * storage XY must be 256r + 64 bytes in length. The value N must be even and - * no smaller than 2. - */ -static void -smix1(uint64_t * B, size_t r, uint64_t N, yescrypt_flags_t flags, - uint64_t * V, uint64_t NROM, const yescrypt_shared_t * shared, - uint64_t * XY, uint64_t * S) -{ - void (*blockmix)(const uint64_t *, uint64_t *, uint64_t *, size_t) = - (S ? blockmix_pwxform : blockmix_salsa8); - const uint64_t * VROM = shared->shared1.aligned; - uint32_t VROM_mask = shared->mask1; - size_t s = 16 * r; - uint64_t * X = V; - uint64_t * Y = &XY[s]; - uint64_t * Z = S ? S : &XY[2 * s]; - uint64_t n, i, j; - size_t k; - - /* 1: X <-- B */ - /* 3: V_i <-- X */ - for (i = 0; i < 2 * r; i++) { - const salsa20_blk_t *src = (const salsa20_blk_t *)&B[i * 8]; - salsa20_blk_t *tmp = (salsa20_blk_t *)Y; - salsa20_blk_t *dst = (salsa20_blk_t *)&X[i * 8]; - for (k = 0; k < 16; k++) - tmp->w[k] = le32dec(&src->w[k]); - salsa20_simd_shuffle(tmp, dst); - } - - /* 4: X <-- H(X) */ - /* 3: V_i <-- X */ - blockmix(X, Y, Z, r); - blkcpy(&V[s], Y, s); - - X = XY; - - if (NROM && (VROM_mask & 1)) { - if ((1 & VROM_mask) == 1) { - /* j <-- Integerify(X) mod NROM */ - j = integerify(Y, r) & (NROM - 1); - - /* X <-- H(X \xor VROM_j) */ - blkxor(Y, &VROM[j * s], s); - } - - blockmix(Y, X, Z, r); - - /* 2: for i = 0 to N - 1 do */ - for (n = 1, i = 2; i < N; i += 2) { - /* 3: V_i <-- X */ - blkcpy(&V[i * s], X, s); - - if ((i & (i - 1)) == 0) - n <<= 1; - - /* j <-- Wrap(Integerify(X), i) */ - j = integerify(X, r) & (n - 1); - j += i - n; - - /* X <-- X \xor V_j */ - blkxor(X, &V[j * s], s); - - /* 4: X <-- H(X) */ - blockmix(X, Y, Z, r); - - /* 3: V_i <-- X */ - blkcpy(&V[(i + 1) * s], Y, s); - - j = integerify(Y, r); - if (((i + 1) & VROM_mask) == 1) { - /* j <-- Integerify(X) mod NROM */ - j &= NROM - 1; - - /* X <-- H(X \xor VROM_j) */ - blkxor(Y, &VROM[j * s], s); - } else { - /* j <-- Wrap(Integerify(X), i) */ - j &= n - 1; - j += i + 1 - n; - - /* X <-- H(X \xor V_j) */ - blkxor(Y, &V[j * s], s); - } - - blockmix(Y, X, Z, r); - } - } else { - yescrypt_flags_t rw = flags & YESCRYPT_RW; - - /* 4: X <-- H(X) */ - blockmix(Y, X, Z, r); - - /* 2: for i = 0 to N - 1 do */ - for (n = 1, i = 2; i < N; i += 2) { - /* 3: V_i <-- X */ - blkcpy(&V[i * s], X, s); - - if (rw) { - if ((i & (i - 1)) == 0) - n <<= 1; - - /* j <-- Wrap(Integerify(X), i) */ - j = integerify(X, r) & (n - 1); - j += i - n; - - /* X <-- X \xor V_j */ - blkxor(X, &V[j * s], s); - } - - /* 4: X <-- H(X) */ - blockmix(X, Y, Z, r); - - /* 3: V_i <-- X */ - blkcpy(&V[(i + 1) * s], Y, s); - - if (rw) { - /* j <-- Wrap(Integerify(X), i) */ - j = integerify(Y, r) & (n - 1); - j += (i + 1) - n; - - /* X <-- X \xor V_j */ - blkxor(Y, &V[j * s], s); - } - - /* 4: X <-- H(X) */ - blockmix(Y, X, Z, r); - } - } - - /* B' <-- X */ - for (i = 0; i < 2 * r; i++) { - const salsa20_blk_t *src = (const salsa20_blk_t *)&X[i * 8]; - salsa20_blk_t *tmp = (salsa20_blk_t *)Y; - salsa20_blk_t *dst = (salsa20_blk_t *)&B[i * 8]; - for (k = 0; k < 16; k++) - le32enc(&tmp->w[k], src->w[k]); - salsa20_simd_unshuffle(tmp, dst); - } -} - -/** - * smix2(B, r, N, Nloop, flags, V, NROM, shared, XY, S): - * Compute second loop of B = SMix_r(B, N). The input B must be 128r bytes in - * length; the temporary storage V must be 128rN bytes in length; the temporary - * storage XY must be 256r + 64 bytes in length. The value N must be a - * power of 2 greater than 1. The value Nloop must be even. - */ -static void -smix2(uint64_t * B, size_t r, uint64_t N, uint64_t Nloop, - yescrypt_flags_t flags, - uint64_t * V, uint64_t NROM, const yescrypt_shared_t * shared, - uint64_t * XY, uint64_t * S) -{ - void (*blockmix)(const uint64_t *, uint64_t *, uint64_t *, size_t) = - (S ? blockmix_pwxform : blockmix_salsa8); - const uint64_t * VROM = shared->shared1.aligned; - uint32_t VROM_mask = shared->mask1 | 1; - size_t s = 16 * r; - yescrypt_flags_t rw = flags & YESCRYPT_RW; - uint64_t * X = XY; - uint64_t * Y = &XY[s]; - uint64_t * Z = S ? S : &XY[2 * s]; - uint64_t i, j; - size_t k; - - if (Nloop == 0) - return; - - /* X <-- B' */ - for (i = 0; i < 2 * r; i++) { - const salsa20_blk_t *src = (const salsa20_blk_t *)&B[i * 8]; - salsa20_blk_t *tmp = (salsa20_blk_t *)Y; - salsa20_blk_t *dst = (salsa20_blk_t *)&X[i * 8]; - for (k = 0; k < 16; k++) - tmp->w[k] = le32dec(&src->w[k]); - salsa20_simd_shuffle(tmp, dst); - } - - if (NROM) { - /* 6: for i = 0 to N - 1 do */ - for (i = 0; i < Nloop; i += 2) { - /* 7: j <-- Integerify(X) mod N */ - j = integerify(X, r) & (N - 1); - - /* 8: X <-- H(X \xor V_j) */ - blkxor(X, &V[j * s], s); - /* V_j <-- Xprev \xor V_j */ - if (rw) - blkcpy(&V[j * s], X, s); - blockmix(X, Y, Z, r); - - j = integerify(Y, r); - if (((i + 1) & VROM_mask) == 1) { - /* j <-- Integerify(X) mod NROM */ - j &= NROM - 1; - - /* X <-- H(X \xor VROM_j) */ - blkxor(Y, &VROM[j * s], s); - } else { - /* 7: j <-- Integerify(X) mod N */ - j &= N - 1; - - /* 8: X <-- H(X \xor V_j) */ - blkxor(Y, &V[j * s], s); - /* V_j <-- Xprev \xor V_j */ - if (rw) - blkcpy(&V[j * s], Y, s); - } - - blockmix(Y, X, Z, r); - } - } else { - /* 6: for i = 0 to N - 1 do */ - i = Nloop / 2; - do { - /* 7: j <-- Integerify(X) mod N */ - j = integerify(X, r) & (N - 1); - - /* 8: X <-- H(X \xor V_j) */ - blkxor(X, &V[j * s], s); - /* V_j <-- Xprev \xor V_j */ - if (rw) - blkcpy(&V[j * s], X, s); - blockmix(X, Y, Z, r); - - /* 7: j <-- Integerify(X) mod N */ - j = integerify(Y, r) & (N - 1); - - /* 8: X <-- H(X \xor V_j) */ - blkxor(Y, &V[j * s], s); - /* V_j <-- Xprev \xor V_j */ - if (rw) - blkcpy(&V[j * s], Y, s); - blockmix(Y, X, Z, r); - } while (--i); - } - - /* 10: B' <-- X */ - for (i = 0; i < 2 * r; i++) { - const salsa20_blk_t *src = (const salsa20_blk_t *)&X[i * 8]; - salsa20_blk_t *tmp = (salsa20_blk_t *)Y; - salsa20_blk_t *dst = (salsa20_blk_t *)&B[i * 8]; - for (k = 0; k < 16; k++) - le32enc(&tmp->w[k], src->w[k]); - salsa20_simd_unshuffle(tmp, dst); - } -} - -/** - * p2floor(x): - * Largest power of 2 not greater than argument. - */ -static uint64_t -p2floor(uint64_t x) -{ - uint64_t y; - while ((y = x & (x - 1))) - x = y; - return x; -} - -/** - * smix(B, r, N, p, t, flags, V, NROM, shared, XY, S): - * Compute B = SMix_r(B, N). The input B must be 128rp bytes in length; the - * temporary storage V must be 128rN bytes in length; the temporary storage - * XY must be 256r+64 or (256r+64)*p bytes in length (the larger size is - * required with OpenMP-enabled builds). The value N must be a power of 2 - * greater than 1. - */ -static void -smix(uint64_t * B, size_t r, uint64_t N, uint32_t p, uint32_t t, - yescrypt_flags_t flags, - uint64_t * V, uint64_t NROM, const yescrypt_shared_t * shared, - uint64_t * XY, uint64_t * S) -{ - size_t s = 16 * r; - uint64_t Nchunk = N / p, Nloop_all, Nloop_rw; - uint32_t i; - - Nloop_all = Nchunk; - if (flags & YESCRYPT_RW) { - if (t <= 1) { - if (t) - Nloop_all *= 2; /* 2/3 */ - Nloop_all = (Nloop_all + 2) / 3; /* 1/3, round up */ - } else { - Nloop_all *= t - 1; - } - } else if (t) { - if (t == 1) - Nloop_all += (Nloop_all + 1) / 2; /* 1.5, round up */ - Nloop_all *= t; - } - - Nloop_rw = 0; - if (flags & __YESCRYPT_INIT_SHARED) - Nloop_rw = Nloop_all; - else if (flags & YESCRYPT_RW) - Nloop_rw = Nloop_all / p; - - Nchunk &= ~(uint64_t)1; /* round down to even */ - Nloop_all++; Nloop_all &= ~(uint64_t)1; /* round up to even */ - Nloop_rw &= ~(uint64_t)1; /* round down to even */ - -#ifdef _OPENMP -#pragma omp parallel if (p > 1) default(none) private(i) shared(B, r, N, p, flags, V, NROM, shared, XY, S, s, Nchunk, Nloop_all, Nloop_rw) - { -#pragma omp for -#endif - for (i = 0; i < p; i++) { - uint64_t Vchunk = i * Nchunk; - uint64_t * Bp = &B[i * s]; - uint64_t * Vp = &V[Vchunk * s]; -#ifdef _OPENMP - uint64_t * XYp = &XY[i * (2 * s + 8)]; -#else - uint64_t * XYp = XY; -#endif - uint64_t Np = (i < p - 1) ? Nchunk : (N - Vchunk); - uint64_t * Sp = S ? &S[i * S_SIZE_ALL] : S; - if (Sp) - smix1(Bp, 1, S_SIZE_ALL / 16, - flags & ~YESCRYPT_PWXFORM, - Sp, NROM, shared, XYp, NULL); - if (!(flags & __YESCRYPT_INIT_SHARED_2)) - smix1(Bp, r, Np, flags, Vp, NROM, shared, XYp, Sp); - smix2(Bp, r, p2floor(Np), Nloop_rw, flags, Vp, - NROM, shared, XYp, Sp); - } - - if (Nloop_all > Nloop_rw) { -#ifdef _OPENMP -#pragma omp for -#endif - for (i = 0; i < p; i++) { - uint64_t * Bp = &B[i * s]; -#ifdef _OPENMP - uint64_t * XYp = &XY[i * (2 * s + 8)]; -#else - uint64_t * XYp = XY; -#endif - uint64_t * Sp = S ? &S[i * S_SIZE_ALL] : S; - smix2(Bp, r, N, Nloop_all - Nloop_rw, - flags & ~YESCRYPT_RW, V, NROM, shared, XYp, Sp); - } - } -#ifdef _OPENMP - } -#endif -} - -/** - * yescrypt_kdf(shared, local, passwd, passwdlen, salt, saltlen, - * N, r, p, t, flags, buf, buflen): - * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, - * p, buflen), or a revision of scrypt as requested by flags and shared, and - * write the result into buf. The parameters r, p, and buflen must satisfy - * r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N must be a power - * of 2 greater than 1. - * - * t controls computation time while not affecting peak memory usage. shared - * and flags may request special modes as described in yescrypt.h. local is - * the thread-local data structure, allowing to preserve and reuse a memory - * allocation across calls, thereby reducing its overhead. - * - * Return 0 on success; or -1 on error. - */ -int -yescrypt_kdf(const yescrypt_shared_t * shared, yescrypt_local_t * local, - const uint8_t * passwd, size_t passwdlen, - const uint8_t * salt, size_t saltlen, - uint64_t N, uint32_t r, uint32_t p, uint32_t t, yescrypt_flags_t flags, - uint8_t * buf, size_t buflen) -{ - yescrypt_region_t tmp; - uint64_t NROM; - size_t B_size, V_size, XY_size, need; - uint64_t * B, * V, * XY, * S; - uint64_t sha256[4]; - - /* - * YESCRYPT_PARALLEL_SMIX is a no-op at p = 1 for its intended purpose, - * so don't let it have side-effects. Without this adjustment, it'd - * enable the SHA-256 password pre-hashing and output post-hashing, - * because any deviation from classic scrypt implies those. - */ - if (p == 1) - flags &= ~YESCRYPT_PARALLEL_SMIX; - - /* Sanity-check parameters */ - if (flags & ~YESCRYPT_KNOWN_FLAGS) { - errno = EINVAL; - return -1; - } -#if SIZE_MAX > UINT32_MAX - if (buflen > (((uint64_t)(1) << 32) - 1) * 32) { - errno = EFBIG; - return -1; - } -#endif - if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) { - errno = EFBIG; - return -1; - } - if (((N & (N - 1)) != 0) || (N <= 1) || (r < 1) || (p < 1)) { - errno = EINVAL; - return -1; - } - if ((flags & YESCRYPT_PARALLEL_SMIX) && (N / p <= 1)) { - errno = EINVAL; - return -1; - } -#if S_MIN_R > 1 - if ((flags & YESCRYPT_PWXFORM) && (r < S_MIN_R)) { - errno = EINVAL; - return -1; - } -#endif - if ((p > SIZE_MAX / ((size_t)256 * r + 64)) || -#if SIZE_MAX / 256 <= UINT32_MAX - (r > SIZE_MAX / 256) || -#endif - (N > SIZE_MAX / 128 / r)) { - errno = ENOMEM; - return -1; - } - if (N > UINT64_MAX / ((uint64_t)t + 1)) { - errno = EFBIG; - return -1; - } -#ifdef _OPENMP - if (!(flags & YESCRYPT_PARALLEL_SMIX) && - (N > SIZE_MAX / 128 / (r * p))) { - errno = ENOMEM; - return -1; - } -#endif - if ((flags & YESCRYPT_PWXFORM) && -#ifndef _OPENMP - (flags & YESCRYPT_PARALLEL_SMIX) && -#endif - p > SIZE_MAX / (S_SIZE_ALL * sizeof(*S))) { - errno = ENOMEM; - return -1; - } - - NROM = 0; - if (shared->shared1.aligned) { - NROM = shared->shared1.aligned_size / ((size_t)128 * r); - if (((NROM & (NROM - 1)) != 0) || (NROM <= 1) || - !(flags & YESCRYPT_RW)) { - errno = EINVAL; - return -1; - } - } - - /* Allocate memory */ - V = NULL; - V_size = (size_t)128 * r * N; -#ifdef _OPENMP - if (!(flags & YESCRYPT_PARALLEL_SMIX)) - V_size *= p; -#endif - need = V_size; - if (flags & __YESCRYPT_INIT_SHARED) { - if (local->aligned_size < need) { - if (local->base || local->aligned || - local->base_size || local->aligned_size) { - errno = EINVAL; - return -1; - } - if (!alloc_region(local, need)) - return -1; - } - V = (uint64_t *)local->aligned; - need = 0; - } - B_size = (size_t)128 * r * p; - need += B_size; - if (need < B_size) { - errno = ENOMEM; - return -1; - } - XY_size = (size_t)256 * r + 64; -#ifdef _OPENMP - XY_size *= p; -#endif - need += XY_size; - if (need < XY_size) { - errno = ENOMEM; - return -1; - } - if (flags & YESCRYPT_PWXFORM) { - size_t S_size = S_SIZE_ALL * sizeof(*S); -#ifdef _OPENMP - S_size *= p; -#else - if (flags & YESCRYPT_PARALLEL_SMIX) - S_size *= p; -#endif - need += S_size; - if (need < S_size) { - errno = ENOMEM; - return -1; - } - } - if (flags & __YESCRYPT_INIT_SHARED) { - if (!alloc_region(&tmp, need)) - return -1; - B = (uint64_t *)tmp.aligned; - XY = (uint64_t *)((uint8_t *)B + B_size); - } else { - init_region(&tmp); - if (local->aligned_size < need) { - if (free_region(local)) - return -1; - if (!alloc_region(local, need)) - return -1; - } - B = (uint64_t *)local->aligned; - V = (uint64_t *)((uint8_t *)B + B_size); - XY = (uint64_t *)((uint8_t *)V + V_size); - } - S = NULL; - if (flags & YESCRYPT_PWXFORM) - S = (uint64_t *)((uint8_t *)XY + XY_size); - - if (t || flags) { - SHA256_CTX_Y ctx; - SHA256_Init_Y(&ctx); - SHA256_Update_Y(&ctx, passwd, passwdlen); - SHA256_Final_Y((uint8_t *)sha256, &ctx); - passwd = (uint8_t *)sha256; - passwdlen = sizeof(sha256); - } - - /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */ - PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, - (uint8_t *)B, B_size); - - if (t || flags) - blkcpy(sha256, B, sizeof(sha256) / sizeof(sha256[0])); - - if (p == 1 || (flags & YESCRYPT_PARALLEL_SMIX)) { - smix(B, r, N, p, t, flags, V, NROM, shared, XY, S); - } else { - uint32_t i; - - /* 2: for i = 0 to p - 1 do */ -#ifdef _OPENMP -#pragma omp parallel for default(none) private(i) shared(B, r, N, p, t, flags, V, NROM, shared, XY, S) -#endif - for (i = 0; i < p; i++) { - /* 3: B_i <-- MF(B_i, N) */ -#ifdef _OPENMP - smix(&B[(size_t)16 * r * i], r, N, 1, t, flags, - &V[(size_t)16 * r * i * N], - NROM, shared, - &XY[((size_t)32 * r + 8) * i], - S ? &S[S_SIZE_ALL * i] : S); -#else - smix(&B[(size_t)16 * r * i], r, N, 1, t, flags, V, - NROM, shared, XY, S); -#endif - } - } - - /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */ - PBKDF2_SHA256(passwd, passwdlen, (uint8_t *)B, B_size, 1, buf, buflen); - - /* - * Except when computing classic scrypt, allow all computation so far - * to be performed on the client. The final steps below match those of - * SCRAM (RFC 5802), so that an extension of SCRAM (with the steps so - * far in place of SCRAM's use of PBKDF2 and with SHA-256 in place of - * SCRAM's use of SHA-1) would be usable with yescrypt hashes. - */ - if ((t || flags) && buflen == sizeof(sha256)) { - /* Compute ClientKey */ - { - HMAC_SHA256_CTX_Y ctx; - HMAC_SHA256_Init_Y(&ctx, buf, buflen); - if (r == 32) { // yescryptR32 - HMAC_SHA256_Update_Y(&ctx, "WaviBanana", 10); - } else - if (r == 16) { // yescryptR16 - HMAC_SHA256_Update_Y(&ctx, "Client Key", 10); - } - else { // yescrypt - HMAC_SHA256_Update_Y(&ctx, salt, saltlen); - } - HMAC_SHA256_Final_Y((uint8_t *)sha256, &ctx); - } - /* Compute StoredKey */ - { - SHA256_CTX_Y ctx; - SHA256_Init_Y(&ctx); - SHA256_Update_Y(&ctx, (uint8_t *)sha256, sizeof(sha256)); - SHA256_Final_Y(buf, &ctx); - } - } - - if (free_region(&tmp)) - return -1; - - /* Success! */ - return 0; -} diff --git a/stratum/algos/yescrypt.c b/stratum/algos/yescrypt.c deleted file mode 100644 index 2959dfa4b..000000000 --- a/stratum/algos/yescrypt.c +++ /dev/null @@ -1,366 +0,0 @@ -/*- - * Copyright 2013,2014 Alexander Peslyak - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include - -#include "yescrypt.h" - -#define BYTES2CHARS(bytes) \ - ((((bytes) * 8) + 5) / 6) - -#define HASH_SIZE 32 /* bytes */ -#define HASH_LEN BYTES2CHARS(HASH_SIZE) /* base-64 chars */ -#define YESCRYPT_FLAGS (YESCRYPT_RW | YESCRYPT_PWXFORM) - -static const char * const itoa64 = - "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - -static uint8_t* encode64_uint32(uint8_t* dst, size_t dstlen, uint32_t src, uint32_t srcbits) -{ - uint32_t bit; - - for (bit = 0; bit < srcbits; bit += 6) { - if (dstlen < 1) - return NULL; - *dst++ = itoa64[src & 0x3f]; - dstlen--; - src >>= 6; - } - - return dst; -} - -static uint8_t* encode64(uint8_t* dst, size_t dstlen, const uint8_t* src, size_t srclen) -{ - size_t i; - - for (i = 0; i < srclen; ) { - uint8_t * dnext; - uint32_t value = 0, bits = 0; - do { - value |= (uint32_t)src[i++] << bits; - bits += 8; - } while (bits < 24 && i < srclen); - dnext = encode64_uint32(dst, dstlen, value, bits); - if (!dnext) - return NULL; - dstlen -= dnext - dst; - dst = dnext; - } - - return dst; -} - -static int decode64_one(uint32_t* dst, uint8_t src) -{ - const char * ptr = strchr(itoa64, src); - if (ptr) { - *dst = ptr - itoa64; - return 0; - } - *dst = 0; - return -1; -} - -static const uint8_t* decode64_uint32(uint32_t* dst, uint32_t dstbits, const uint8_t* src) -{ - uint32_t bit; - uint32_t value; - - value = 0; - for (bit = 0; bit < dstbits; bit += 6) { - uint32_t one; - if (decode64_one(&one, *src)) { - *dst = 0; - return NULL; - } - src++; - value |= one << bit; - } - - *dst = value; - return src; -} - -uint8_t* yescrypt_r(const yescrypt_shared_t* shared, yescrypt_local_t* local, - const uint8_t* passwd, size_t passwdlen, const uint8_t* setting, uint8_t* buf, size_t buflen) -{ - uint8_t hash[HASH_SIZE]; - const uint8_t * src, * salt; - uint8_t * dst; - size_t prefixlen, saltlen, need; - uint8_t version; - uint64_t N; - uint32_t r, p; - yescrypt_flags_t flags = YESCRYPT_WORM; - - printf("pass1 ..."); - fflush(stdout); - - if (setting[0] != '$' || setting[1] != '7') { - printf("died$7 ..."); - fflush(stdout); - return NULL; - } - - printf("died80 ..."); - fflush(stdout); - - src = setting + 2; - - printf("hello '%p'\n", (char *)src); - fflush(stdout); - - switch ((version = *src)) { - case '$': - printf("died2 ..."); - fflush(stdout); - break; - case 'X': - src++; - flags = YESCRYPT_RW; - printf("died3 ..."); - fflush(stdout); - break; - default: - printf("died4 ..."); - fflush(stdout); - return NULL; - } - - printf("pass2 ..."); - fflush(stdout); - - if (*src != '$') { - uint32_t decoded_flags; - if (decode64_one(&decoded_flags, *src)) { - printf("died5 ..."); - fflush(stdout); - return NULL; - } - flags = decoded_flags; - if (*++src != '$') { - printf("died6 ..."); - fflush(stdout); - return NULL; - } - } - - src++; - - { - uint32_t N_log2; - if (decode64_one(&N_log2, *src)) { - printf("died7 ..."); - return NULL; - } - src++; - N = (uint64_t)1 << N_log2; - } - - src = decode64_uint32(&r, 30, src); - if (!src) { - printf("died6 ..."); - return NULL; - } - - src = decode64_uint32(&p, 30, src); - if (!src) { - printf("died7 ..."); - return NULL; - } - - prefixlen = src - setting; - - salt = src; - src = (uint8_t *)strrchr((char *)salt, '$'); - if (src) - saltlen = src - salt; - else - saltlen = strlen((char *)salt); - - need = prefixlen + saltlen + 1 + HASH_LEN + 1; - if (need > buflen || need < saltlen) { - printf("'%d %d %d'", (int) need, (int) buflen, (int) saltlen); - printf("died8killbuf ..."); - fflush(stdout); - return NULL; - } - - if (yescrypt_kdf(shared, local, passwd, passwdlen, salt, saltlen, N, r, p, 0, flags, hash, sizeof(hash))) { - printf("died10 ..."); - fflush(stdout); - return NULL; - } - - dst = buf; - memcpy(dst, setting, prefixlen + saltlen); - dst += prefixlen + saltlen; - *dst++ = '$'; - - dst = encode64(dst, buflen - (dst - buf), hash, sizeof(hash)); - /* Could zeroize hash[] here, but yescrypt_kdf() doesn't zeroize its - * memory allocations yet anyway. */ - if (!dst || dst >= buf + buflen) { /* Can't happen */ - printf("died11 ..."); - return NULL; - } - - *dst = 0; /* NUL termination */ - - printf("died12 ..."); - fflush(stdout); - - return buf; -} - -uint8_t* yescrypt(const uint8_t* passwd, const uint8_t* setting) -{ - static uint8_t buf[4 + 1 + 5 + 5 + BYTES2CHARS(32) + 1 + HASH_LEN + 1]; - yescrypt_shared_t shared; - yescrypt_local_t local; - uint8_t * retval; - - if (yescrypt_init_shared(&shared, NULL, 0, - 0, 0, 0, YESCRYPT_SHARED_DEFAULTS, 0, NULL, 0)) - return NULL; - if (yescrypt_init_local(&local)) { - yescrypt_free_shared(&shared); - return NULL; - } - retval = yescrypt_r(&shared, &local, - passwd, 80, setting, buf, sizeof(buf)); - //printf("hashse='%s'\n", (char *)retval); - if (yescrypt_free_local(&local)) { - yescrypt_free_shared(&shared); - return NULL; - } - if (yescrypt_free_shared(&shared)) - return NULL; - return retval; -} - -uint8_t* yescrypt_gensalt_r(uint32_t N_log2, uint32_t r, uint32_t p, yescrypt_flags_t flags, - const uint8_t* src, size_t srclen, uint8_t* buf, size_t buflen) -{ - uint8_t * dst; - size_t prefixlen = 3 + 1 + 5 + 5; - size_t saltlen = BYTES2CHARS(srclen); - size_t need; - - if (p == 1) - flags &= ~YESCRYPT_PARALLEL_SMIX; - - if (flags) { - if (flags & ~0x3f) - return NULL; - - prefixlen++; - if (flags != YESCRYPT_RW) - prefixlen++; - } - - need = prefixlen + saltlen + 1; - if (need > buflen || need < saltlen || saltlen < srclen) - return NULL; - - if (N_log2 > 63 || ((uint64_t)r * (uint64_t)p >= (1U << 30))) - return NULL; - - dst = buf; - *dst++ = '$'; - *dst++ = '7'; - if (flags) { - *dst++ = 'X'; /* eXperimental, subject to change */ - if (flags != YESCRYPT_RW) - *dst++ = itoa64[flags]; - } - *dst++ = '$'; - - *dst++ = itoa64[N_log2]; - - dst = encode64_uint32(dst, buflen - (dst - buf), r, 30); - if (!dst) /* Can't happen */ - return NULL; - - dst = encode64_uint32(dst, buflen - (dst - buf), p, 30); - if (!dst) /* Can't happen */ - return NULL; - - dst = encode64(dst, buflen - (dst - buf), src, srclen); - if (!dst || dst >= buf + buflen) /* Can't happen */ - return NULL; - - *dst = 0; /* NUL termination */ - - return buf; -} - -uint8_t* yescrypt_gensalt(uint32_t N_log2, uint32_t r, uint32_t p, yescrypt_flags_t flags, - const uint8_t * src, size_t srclen) -{ - static uint8_t buf[4 + 1 + 5 + 5 + BYTES2CHARS(32) + 1]; - return yescrypt_gensalt_r(N_log2, r, p, flags, src, srclen, - buf, sizeof(buf)); -} - -static int yescrypt_bsty(const uint8_t * passwd, size_t passwdlen, - const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p, - uint8_t * buf, size_t buflen) -{ - yescrypt_shared_t shared; - yescrypt_local_t local; - int retval; - - if (yescrypt_init_shared(&shared, NULL, 0, - 0, 0, 0, YESCRYPT_SHARED_DEFAULTS, 0, NULL, 0)) - return -1; - if (yescrypt_init_local(&local)) { - yescrypt_free_shared(&shared); - return -1; - } - - retval = yescrypt_kdf(&shared, &local, - passwd, passwdlen, salt, saltlen, N, r, p, 0, YESCRYPT_FLAGS, - buf, buflen); - - yescrypt_free_local(&local); - yescrypt_free_shared(&shared); - - return retval; -} - -/* main hash 80 bytes input */ -void yescrypt_hash(const char *input, char *output, uint32_t len) -{ - yescrypt_bsty((uint8_t*)input, len, (uint8_t*)input, len, 2048, 8, 1, (uint8_t*)output, 32); -} - -void yescryptR16_hash(const char *input, char *output, uint32_t len) -{ - yescrypt_bsty((uint8_t*)input, len, (uint8_t*)input, len, 4096, 16, 1, (uint8_t*)output, 32); -} - -void yescryptR32_hash(const char *input, char *output, uint32_t len) -{ - yescrypt_bsty((uint8_t*)input, len, (uint8_t*)input, len, 4096, 32, 1, (uint8_t*)output, 32); -} diff --git a/stratum/algos/yescrypt.h b/stratum/algos/yescrypt.h deleted file mode 100644 index 8e87c7bee..000000000 --- a/stratum/algos/yescrypt.h +++ /dev/null @@ -1,374 +0,0 @@ -/*- - * Copyright 2009 Colin Percival - * Copyright 2013,2014 Alexander Peslyak - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file was originally written by Colin Percival as part of the Tarsnap - * online backup system. - */ - -#ifndef YESCRYPT_H -#define YESCRYPT_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include /* for size_t */ - -void yescrypt_hash(const char* input, char* output, uint32_t len); -void yescryptR16_hash(const char* input, char* output, uint32_t len); -void yescryptR32_hash(const char* input, char* output, uint32_t len); - -/** - * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen): - * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, - * p, buflen) and write the result into buf. The parameters r, p, and buflen - * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N - * must be a power of 2 greater than 1. - * - * Return 0 on success; or -1 on error. - * - * MT-safe as long as buf is local to the thread. - */ -extern int crypto_scrypt(const uint8_t * __passwd, size_t __passwdlen, - const uint8_t * __salt, size_t __saltlen, - uint64_t __N, uint32_t __r, uint32_t __p, - uint8_t * __buf, size_t __buflen); - -/** - * Internal type used by the memory allocator. Please do not use it directly. - * Use yescrypt_shared_t and yescrypt_local_t as appropriate instead, since - * they might differ from each other in a future version. - */ -typedef struct { - void * base, * aligned; - size_t base_size, aligned_size; -} yescrypt_region_t; - -/** - * Types for shared (ROM) and thread-local (RAM) data structures. - */ -typedef yescrypt_region_t yescrypt_shared1_t; -typedef struct { - yescrypt_shared1_t shared1; - uint32_t mask1; -} yescrypt_shared_t; -typedef yescrypt_region_t yescrypt_local_t; - -/** - * Possible values for yescrypt_init_shared()'s flags argument. - */ -typedef enum { - YESCRYPT_SHARED_DEFAULTS = 0, - YESCRYPT_SHARED_PREALLOCATED = 0x100 -} yescrypt_init_shared_flags_t; - -/** - * Possible values for the flags argument of yescrypt_kdf(), - * yescrypt_gensalt_r(), yescrypt_gensalt(). These may be OR'ed together, - * except that YESCRYPT_WORM and YESCRYPT_RW are mutually exclusive. - * Please refer to the description of yescrypt_kdf() below for the meaning of - * these flags. - */ -typedef enum { -/* public */ - YESCRYPT_WORM = 0, - YESCRYPT_RW = 1, - YESCRYPT_PARALLEL_SMIX = 2, - YESCRYPT_PWXFORM = 4, -/* private */ - __YESCRYPT_INIT_SHARED_1 = 0x10000, - __YESCRYPT_INIT_SHARED_2 = 0x20000, - __YESCRYPT_INIT_SHARED = 0x30000 -} yescrypt_flags_t; - -#define YESCRYPT_KNOWN_FLAGS \ - (YESCRYPT_RW | YESCRYPT_PARALLEL_SMIX | YESCRYPT_PWXFORM | \ - __YESCRYPT_INIT_SHARED) - -/** - * yescrypt_init_shared(shared, param, paramlen, N, r, p, flags, mask, - * buf, buflen): - * Optionally allocate memory for and initialize the shared (ROM) data - * structure. The parameters N, r, and p must satisfy the same conditions as - * with crypto_scrypt(). param and paramlen specify a local parameter with - * which the ROM is seeded. If buf is not NULL, then it is used to return - * buflen bytes of message digest for the initialized ROM (the caller may use - * this to verify that the ROM has been computed in the same way that it was on - * a previous run). - * - * Return 0 on success; or -1 on error. - * - * If bit YESCRYPT_SHARED_PREALLOCATED in flags is set, then memory for the - * ROM is assumed to have been preallocated by the caller, with - * shared->shared1.aligned being the start address of the ROM and - * shared->shared1.aligned_size being its size (which must be consistent with - * N, r, and p). This may be used e.g. when the ROM is to be placed in a SysV - * shared memory segment allocated by the caller. - * - * mask controls the frequency of ROM accesses by yescrypt_kdf(). Normally it - * should be set to 1, to interleave RAM and ROM accesses, which works well - * when both regions reside in the machine's RAM anyway. Other values may be - * used e.g. when the ROM is memory-mapped from a disk file. Recommended mask - * values are powers of 2 minus 1 or minus 2. Here's the effect of some mask - * values: - * mask value ROM accesses in SMix 1st loop ROM accesses in SMix 2nd loop - * 0 0 1/2 - * 1 1/2 1/2 - * 2 0 1/4 - * 3 1/4 1/4 - * 6 0 1/8 - * 7 1/8 1/8 - * 14 0 1/16 - * 15 1/16 1/16 - * 1022 0 1/1024 - * 1023 1/1024 1/1024 - * - * Actual computation of the ROM contents may be avoided, if you don't intend - * to use a ROM but need a dummy shared structure, by calling this function - * with NULL, 0, 0, 0, 0, YESCRYPT_SHARED_DEFAULTS, 0, NULL, 0 for the - * arguments starting with param and on. - * - * MT-safe as long as shared is local to the thread. - */ -extern int yescrypt_init_shared(yescrypt_shared_t * __shared, - const uint8_t * __param, size_t __paramlen, - uint64_t __N, uint32_t __r, uint32_t __p, - yescrypt_init_shared_flags_t __flags, uint32_t __mask, - uint8_t * __buf, size_t __buflen); - -/** - * yescrypt_free_shared(shared): - * Free memory that had been allocated with yescrypt_init_shared(). - * - * Return 0 on success; or -1 on error. - * - * MT-safe as long as shared is local to the thread. - */ -extern int yescrypt_free_shared(yescrypt_shared_t * __shared); - -/** - * yescrypt_init_local(local): - * Initialize the thread-local (RAM) data structure. Actual memory allocation - * is currently fully postponed until a call to yescrypt_kdf() or yescrypt_r(). - * - * Return 0 on success; or -1 on error. - * - * MT-safe as long as local is local to the thread. - */ -extern int yescrypt_init_local(yescrypt_local_t * __local); - -/** - * yescrypt_free_local(local): - * Free memory that may have been allocated for an initialized thread-local - * (RAM) data structure. - * - * Return 0 on success; or -1 on error. - * - * MT-safe as long as local is local to the thread. - */ -extern int yescrypt_free_local(yescrypt_local_t * __local); - -/** - * yescrypt_kdf(shared, local, passwd, passwdlen, salt, saltlen, - * N, r, p, t, flags, buf, buflen): - * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, - * p, buflen), or a revision of scrypt as requested by flags and shared, and - * write the result into buf. The parameters N, r, p, and buflen must satisfy - * the same conditions as with crypto_scrypt(). t controls computation time - * while not affecting peak memory usage. shared and flags may request - * special modes as described below. local is the thread-local data - * structure, allowing to preserve and reuse a memory allocation across calls, - * thereby reducing its overhead. - * - * Return 0 on success; or -1 on error. - * - * t controls computation time. t = 0 is optimal in terms of achieving the - * highest area-time for ASIC attackers. Thus, higher computation time, if - * affordable, is best achieved by increasing N rather than by increasing t. - * However, if the higher memory usage (which goes along with higher N) is not - * affordable, or if fine-tuning of the time is needed (recall that N must be a - * power of 2), then t = 1 or above may be used to increase time while staying - * at the same peak memory usage. t = 1 increases the time by 25% and - * decreases the normalized area-time to 96% of optimal. (Of course, in - * absolute terms the area-time increases with higher t. It's just that it - * would increase slightly more with higher N*r rather than with higher t.) - * t = 2 increases the time by another 20% and decreases the normalized - * area-time to 89% of optimal. Thus, these two values are reasonable to use - * for fine-tuning. Values of t higher than 2 result in further increase in - * time while reducing the efficiency much further (e.g., down to around 50% of - * optimal for t = 5, which runs 3 to 4 times slower than t = 0, with exact - * numbers varying by the flags settings). - * - * Classic scrypt is available by setting t = 0 and flags to YESCRYPT_WORM and - * passing a dummy shared structure (see the description of - * yescrypt_init_shared() above for how to produce one). In this mode, the - * thread-local memory region (RAM) is first sequentially written to and then - * randomly read from. This algorithm is friendly towards time-memory - * tradeoffs (TMTO), available both to defenders (albeit not in this - * implementation) and to attackers. - * - * Setting YESCRYPT_RW adds extra random reads and writes to the thread-local - * memory region (RAM), which makes TMTO a lot less efficient. This may be - * used to slow down the kinds of attackers who would otherwise benefit from - * classic scrypt's efficient TMTO. Since classic scrypt's TMTO allows not - * only for the tradeoff, but also for a decrease of attacker's area-time (by - * up to a constant factor), setting YESCRYPT_RW substantially increases the - * cost of attacks in area-time terms as well. Yet another benefit of it is - * that optimal area-time is reached at an earlier time than with classic - * scrypt, and t = 0 actually corresponds to this earlier completion time, - * resulting in quicker hash computations (and thus in higher request rate - * capacity). Due to these properties, YESCRYPT_RW should almost always be - * set, except when compatibility with classic scrypt or TMTO-friendliness are - * desired. - * - * YESCRYPT_PARALLEL_SMIX moves parallelism that is present with p > 1 to a - * lower level as compared to where it is in classic scrypt. This reduces - * flexibility for efficient computation (for both attackers and defenders) by - * requiring that, short of resorting to TMTO, the full amount of memory be - * allocated as needed for the specified p, regardless of whether that - * parallelism is actually being fully made use of or not. (For comparison, a - * single instance of classic scrypt may be computed in less memory without any - * CPU time overhead, but in more real time, by not making full use of the - * parallelism.) This may be desirable when the defender has enough memory - * with sufficiently low latency and high bandwidth for efficient full parallel - * execution, yet the required memory size is high enough that some likely - * attackers might end up being forced to choose between using higher latency - * memory than they could use otherwise (waiting for data longer) or using TMTO - * (waiting for data more times per one hash computation). The area-time cost - * for other kinds of attackers (who would use the same memory type and TMTO - * factor or no TMTO either way) remains roughly the same, given the same - * running time for the defender. In the TMTO-friendly YESCRYPT_WORM mode, as - * long as the defender has enough memory that is just as fast as the smaller - * per-thread regions would be, doesn't expect to ever need greater - * flexibility (except possibly via TMTO), and doesn't need backwards - * compatibility with classic scrypt, there are no other serious drawbacks to - * this setting. In the YESCRYPT_RW mode, which is meant to discourage TMTO, - * this new approach to parallelization makes TMTO less inefficient. (This is - * an unfortunate side-effect of avoiding some random writes, as we have to in - * order to allow for parallel threads to access a common memory region without - * synchronization overhead.) Thus, in this mode this setting poses an extra - * tradeoff of its own (higher area-time cost for a subset of attackers vs. - * better TMTO resistance). Setting YESCRYPT_PARALLEL_SMIX also changes the - * way the running time is to be controlled from N*r*p (for classic scrypt) to - * N*r (in this modification). All of this applies only when p > 1. For - * p = 1, this setting is a no-op. - * - * Passing a real shared structure, with ROM contents previously computed by - * yescrypt_init_shared(), enables the use of ROM and requires YESCRYPT_RW for - * the thread-local RAM region. In order to allow for initialization of the - * ROM to be split into a separate program, the shared->shared1.aligned and - * shared->shared1.aligned_size fields may be set by the caller of - * yescrypt_kdf() manually rather than with yescrypt_init_shared(). - * - * local must be initialized with yescrypt_init_local(). - * - * MT-safe as long as local and buf are local to the thread. - */ -extern int yescrypt_kdf(const yescrypt_shared_t * __shared, - yescrypt_local_t * __local, - const uint8_t * __passwd, size_t __passwdlen, - const uint8_t * __salt, size_t __saltlen, - uint64_t __N, uint32_t __r, uint32_t __p, uint32_t __t, - yescrypt_flags_t __flags, - uint8_t * __buf, size_t __buflen); - -/** - * yescrypt_r(shared, local, passwd, passwdlen, setting, buf, buflen): - * Compute and encode an scrypt or enhanced scrypt hash of passwd given the - * parameters and salt value encoded in setting. If the shared structure is - * not dummy, a ROM is used and YESCRYPT_RW is required. Otherwise, whether to - * use the YESCRYPT_WORM (classic scrypt) or YESCRYPT_RW (time-memory tradeoff - * discouraging modification) is determined by the setting string. shared and - * local must be initialized as described above for yescrypt_kdf(). buf must - * be large enough (as indicated by buflen) to hold the encoded hash string. - * - * Return the encoded hash string on success; or NULL on error. - * - * MT-safe as long as local and buf are local to the thread. - */ -extern uint8_t * yescrypt_r(const yescrypt_shared_t * __shared, - yescrypt_local_t * __local, - const uint8_t * __passwd, size_t __passwdlen, - const uint8_t * __setting, - uint8_t * __buf, size_t __buflen); - -/** - * yescrypt(passwd, setting): - * Compute and encode an scrypt or enhanced scrypt hash of passwd given the - * parameters and salt value encoded in setting. Whether to use the - * YESCRYPT_WORM (classic scrypt) or YESCRYPT_RW (time-memory tradeoff - * discouraging modification) is determined by the setting string. - * - * Return the encoded hash string on success; or NULL on error. - * - * This is a crypt(3)-like interface, which is simpler to use than - * yescrypt_r(), but it is not MT-safe, it does not allow for the use of a ROM, - * and it is slower than yescrypt_r() for repeated calls because it allocates - * and frees memory on each call. - * - * MT-unsafe. - */ -extern uint8_t * yescrypt(const uint8_t * __passwd, const uint8_t * __setting); - -/** - * yescrypt_gensalt_r(N_log2, r, p, flags, src, srclen, buf, buflen): - * Generate a setting string for use with yescrypt_r() and yescrypt() by - * encoding into it the parameters N_log2 (which is to be set to base 2 - * logarithm of the desired value for N), r, p, flags, and a salt given by src - * (of srclen bytes). buf must be large enough (as indicated by buflen) to - * hold the setting string. - * - * Return the setting string on success; or NULL on error. - * - * MT-safe as long as buf is local to the thread. - */ -extern uint8_t * yescrypt_gensalt_r( - uint32_t __N_log2, uint32_t __r, uint32_t __p, - yescrypt_flags_t __flags, - const uint8_t * __src, size_t __srclen, - uint8_t * __buf, size_t __buflen); - -/** - * yescrypt_gensalt(N_log2, r, p, flags, src, srclen): - * Generate a setting string for use with yescrypt_r() and yescrypt(). This - * function is the same as yescrypt_gensalt_r() except that it uses a static - * buffer and thus is not MT-safe. - * - * Return the setting string on success; or NULL on error. - * - * MT-unsafe. - */ -extern uint8_t * yescrypt_gensalt( - uint32_t __N_log2, uint32_t __r, uint32_t __p, - yescrypt_flags_t __flags, - const uint8_t * __src, size_t __srclen); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/stratum/algos/yespower/insecure_memzero.h b/stratum/algos/yespower/insecure_memzero.h new file mode 100644 index 000000000..5a0ba75c4 --- /dev/null +++ b/stratum/algos/yespower/insecure_memzero.h @@ -0,0 +1 @@ +#define insecure_memzero(buf, len) /* empty */ diff --git a/stratum/algos/yespower/sha256.h b/stratum/algos/yespower/sha256.h new file mode 100644 index 000000000..6210502ff --- /dev/null +++ b/stratum/algos/yespower/sha256.h @@ -0,0 +1,129 @@ +/*- + * Copyright 2005-2016 Colin Percival + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _SHA256_H_ +#define _SHA256_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Use #defines in order to avoid namespace collisions with anyone else's + * SHA256 code (e.g., the code in OpenSSL). + */ +#define SHA256_Init libcperciva_SHA256_Init +#define SHA256_Update libcperciva_SHA256_Update +#define SHA256_Final libcperciva_SHA256_Final +#define SHA256_Buf libcperciva_SHA256_Buf +#define SHA256_CTX libcperciva_SHA256_CTX +#define HMAC_SHA256_Init libcperciva_HMAC_SHA256_Init +#define HMAC_SHA256_Update libcperciva_HMAC_SHA256_Update +#define HMAC_SHA256_Final libcperciva_HMAC_SHA256_Final +#define HMAC_SHA256_Buf libcperciva_HMAC_SHA256_Buf +#define HMAC_SHA256_CTX libcperciva_HMAC_SHA256_CTX + +/* Context structure for SHA256 operations. */ +typedef struct { + uint32_t state[8]; + uint64_t count; + uint8_t buf[64]; +} SHA256_CTX; + +/** + * SHA256_Init(ctx): + * Initialize the SHA256 context ${ctx}. + */ +void SHA256_Init(SHA256_CTX *); + +/** + * SHA256_Update(ctx, in, len): + * Input ${len} bytes from ${in} into the SHA256 context ${ctx}. + */ +void SHA256_Update(SHA256_CTX *, const void *, size_t); + +/** + * SHA256_Final(digest, ctx): + * Output the SHA256 hash of the data input to the context ${ctx} into the + * buffer ${digest}. + */ +void SHA256_Final(uint8_t[32], SHA256_CTX *); + +/** + * SHA256_Buf(in, len, digest): + * Compute the SHA256 hash of ${len} bytes from ${in} and write it to ${digest}. + */ +void SHA256_Buf(const void *, size_t, uint8_t[32]); + +/* Context structure for HMAC-SHA256 operations. */ +typedef struct { + SHA256_CTX ictx; + SHA256_CTX octx; +} HMAC_SHA256_CTX; + +/** + * HMAC_SHA256_Init(ctx, K, Klen): + * Initialize the HMAC-SHA256 context ${ctx} with ${Klen} bytes of key from + * ${K}. + */ +void HMAC_SHA256_Init(HMAC_SHA256_CTX *, const void *, size_t); + +/** + * HMAC_SHA256_Update(ctx, in, len): + * Input ${len} bytes from ${in} into the HMAC-SHA256 context ${ctx}. + */ +void HMAC_SHA256_Update(HMAC_SHA256_CTX *, const void *, size_t); + +/** + * HMAC_SHA256_Final(digest, ctx): + * Output the HMAC-SHA256 of the data input to the context ${ctx} into the + * buffer ${digest}. + */ +void HMAC_SHA256_Final(uint8_t[32], HMAC_SHA256_CTX *); + +/** + * HMAC_SHA256_Buf(K, Klen, in, len, digest): + * Compute the HMAC-SHA256 of ${len} bytes from ${in} using the key ${K} of + * length ${Klen}, and write the result to ${digest}. + */ +void HMAC_SHA256_Buf(const void *, size_t, const void *, size_t, uint8_t[32]); + +/** + * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): + * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and + * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). + */ +void PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t, + uint64_t, uint8_t *, size_t); + +#ifdef __cplusplus +} +#endif + +#endif /* !_SHA256_H_ */ diff --git a/stratum/algos/yespower/sysendian.h b/stratum/algos/yespower/sysendian.h new file mode 100644 index 000000000..52c1fe73b --- /dev/null +++ b/stratum/algos/yespower/sysendian.h @@ -0,0 +1,94 @@ +/*- + * Copyright 2007-2014 Colin Percival + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _SYSENDIAN_H_ +#define _SYSENDIAN_H_ + +#include + +/* Avoid namespace collisions with BSD . */ +#define be32dec libcperciva_be32dec +#define be32enc libcperciva_be32enc +#define be64enc libcperciva_be64enc +#define le32dec libcperciva_le32dec +#define le32enc libcperciva_le32enc + +static inline uint32_t +be32dec(const void * pp) +{ + const uint8_t * p = (uint8_t const *)pp; + + return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) + + ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24)); +} + +static inline void +be32enc(void * pp, uint32_t x) +{ + uint8_t * p = (uint8_t *)pp; + + p[3] = x & 0xff; + p[2] = (x >> 8) & 0xff; + p[1] = (x >> 16) & 0xff; + p[0] = (x >> 24) & 0xff; +} + +static inline void +be64enc(void * pp, uint64_t x) +{ + uint8_t * p = (uint8_t *)pp; + + p[7] = x & 0xff; + p[6] = (x >> 8) & 0xff; + p[5] = (x >> 16) & 0xff; + p[4] = (x >> 24) & 0xff; + p[3] = (x >> 32) & 0xff; + p[2] = (x >> 40) & 0xff; + p[1] = (x >> 48) & 0xff; + p[0] = (x >> 56) & 0xff; +} + +static inline uint32_t +le32dec(const void * pp) +{ + const uint8_t * p = (uint8_t const *)pp; + + return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) + + ((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24)); +} + +static inline void +le32enc(void * pp, uint32_t x) +{ + uint8_t * p = (uint8_t *)pp; + + p[0] = x & 0xff; + p[1] = (x >> 8) & 0xff; + p[2] = (x >> 16) & 0xff; + p[3] = (x >> 24) & 0xff; +} + +#endif /* !_SYSENDIAN_H_ */ diff --git a/stratum/algos/yespower/yespower-combined.c b/stratum/algos/yespower/yespower-combined.c new file mode 100644 index 000000000..7d2ab0cdd --- /dev/null +++ b/stratum/algos/yespower/yespower-combined.c @@ -0,0 +1,1168 @@ +#include +#include +#include +#include +#include + +#include "sha256.h" +#include "sysendian.h" +#include "yespower.h" +#include "insecure_memzero.h" + +#ifdef __ICC +/* Miscompile with icc 14.0.0 (at least), so don't use restrict there */ +#define restrict +#elif __STDC_VERSION__ >= 199901L +/* Have restrict */ +#elif defined(__GNUC__) +#define restrict __restrict +#else +#define restrict +#endif + +/* + * Encode a length len*2 vector of (uint32_t) into a length len*8 vector of + * (uint8_t) in big-endian form. + */ +static void +be32enc_vect(uint8_t * dst, const uint32_t * src, size_t len) +{ + + /* Encode vector, two words at a time. */ + do { + be32enc(&dst[0], src[0]); + be32enc(&dst[4], src[1]); + src += 2; + dst += 8; + } while (--len); +} + +/* + * Decode a big-endian length len*8 vector of (uint8_t) into a length + * len*2 vector of (uint32_t). + */ +static void +be32dec_vect(uint32_t * dst, const uint8_t * src, size_t len) +{ + + /* Decode vector, two words at a time. */ + do { + dst[0] = be32dec(&src[0]); + dst[1] = be32dec(&src[4]); + src += 8; + dst += 2; + } while (--len); +} + +/* SHA256 round constants. */ +static const uint32_t Krnd[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +/* Elementary functions used by SHA256 */ +#define Ch(x, y, z) ((x & (y ^ z)) ^ z) +#define Maj(x, y, z) ((x & (y | z)) | (y & z)) +#define SHR(x, n) (x >> n) +#define ROTR(x, n) ((x >> n) | (x << (32 - n))) +#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) +#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) +#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3)) +#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10)) + +/* SHA256 round function */ +#define RND(a, b, c, d, e, f, g, h, k) \ + h += S1(e) + Ch(e, f, g) + k; \ + d += h; \ + h += S0(a) + Maj(a, b, c); + +/* Adjusted round function for rotating state */ +#define RNDr(S, W, i, ii) \ + RND(S[(64 - i) % 8], S[(65 - i) % 8], \ + S[(66 - i) % 8], S[(67 - i) % 8], \ + S[(68 - i) % 8], S[(69 - i) % 8], \ + S[(70 - i) % 8], S[(71 - i) % 8], \ + W[i + ii] + Krnd[i + ii]) + +/* Message schedule computation */ +#define MSCH(W, ii, i) \ + W[i + ii + 16] = s1(W[i + ii + 14]) + W[i + ii + 9] + s0(W[i + ii + 1]) + W[i + ii] + +/* + * SHA256 block compression function. The 256-bit state is transformed via + * the 512-bit input block to produce a new state. + */ +static void +SHA256_Transform(uint32_t state[static restrict 8], + const uint8_t block[static restrict 64], + uint32_t W[static restrict 64], uint32_t S[static restrict 8]) +{ + int i; + + /* 1. Prepare the first part of the message schedule W. */ + be32dec_vect(W, block, 8); + + /* 2. Initialize working variables. */ + memcpy(S, state, 32); + + /* 3. Mix. */ + for (i = 0; i < 64; i += 16) { + RNDr(S, W, 0, i); + RNDr(S, W, 1, i); + RNDr(S, W, 2, i); + RNDr(S, W, 3, i); + RNDr(S, W, 4, i); + RNDr(S, W, 5, i); + RNDr(S, W, 6, i); + RNDr(S, W, 7, i); + RNDr(S, W, 8, i); + RNDr(S, W, 9, i); + RNDr(S, W, 10, i); + RNDr(S, W, 11, i); + RNDr(S, W, 12, i); + RNDr(S, W, 13, i); + RNDr(S, W, 14, i); + RNDr(S, W, 15, i); + + if (i == 48) + break; + MSCH(W, 0, i); + MSCH(W, 1, i); + MSCH(W, 2, i); + MSCH(W, 3, i); + MSCH(W, 4, i); + MSCH(W, 5, i); + MSCH(W, 6, i); + MSCH(W, 7, i); + MSCH(W, 8, i); + MSCH(W, 9, i); + MSCH(W, 10, i); + MSCH(W, 11, i); + MSCH(W, 12, i); + MSCH(W, 13, i); + MSCH(W, 14, i); + MSCH(W, 15, i); + } + + /* 4. Mix local working variables into global state. */ + state[0] += S[0]; + state[1] += S[1]; + state[2] += S[2]; + state[3] += S[3]; + state[4] += S[4]; + state[5] += S[5]; + state[6] += S[6]; + state[7] += S[7]; +} + +static const uint8_t PAD[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* Add padding and terminating bit-count. */ +static void +SHA256_Pad(SHA256_CTX * ctx, uint32_t tmp32[static restrict 72]) +{ + size_t r; + + /* Figure out how many bytes we have buffered. */ + r = (ctx->count >> 3) & 0x3f; + + /* Pad to 56 mod 64, transforming if we finish a block en route. */ + if (r < 56) { + /* Pad to 56 mod 64. */ + memcpy(&ctx->buf[r], PAD, 56 - r); + } else { + /* Finish the current block and mix. */ + memcpy(&ctx->buf[r], PAD, 64 - r); + SHA256_Transform(ctx->state, ctx->buf, &tmp32[0], &tmp32[64]); + + /* The start of the final block is all zeroes. */ + memset(&ctx->buf[0], 0, 56); + } + + /* Add the terminating bit-count. */ + be64enc(&ctx->buf[56], ctx->count); + + /* Mix in the final block. */ + SHA256_Transform(ctx->state, ctx->buf, &tmp32[0], &tmp32[64]); +} + +/* Magic initialization constants. */ +static const uint32_t initial_state[8] = { + 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, + 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 +}; + +/** + * SHA256_Init(ctx): + * Initialize the SHA256 context ${ctx}. + */ +void +SHA256_Init(SHA256_CTX * ctx) +{ + + /* Zero bits processed so far. */ + ctx->count = 0; + + /* Initialize state. */ + memcpy(ctx->state, initial_state, sizeof(initial_state)); +} + +/** + * SHA256_Update(ctx, in, len): + * Input ${len} bytes from ${in} into the SHA256 context ${ctx}. + */ +static void +_SHA256_Update(SHA256_CTX * ctx, const void * in, size_t len, + uint32_t tmp32[static restrict 72]) +{ + uint32_t r; + const uint8_t * src = in; + + /* Return immediately if we have nothing to do. */ + if (len == 0) + return; + + /* Number of bytes left in the buffer from previous updates. */ + r = (ctx->count >> 3) & 0x3f; + + /* Update number of bits. */ + ctx->count += (uint64_t)(len) << 3; + + /* Handle the case where we don't need to perform any transforms. */ + if (len < 64 - r) { + memcpy(&ctx->buf[r], src, len); + return; + } + + /* Finish the current block. */ + memcpy(&ctx->buf[r], src, 64 - r); + SHA256_Transform(ctx->state, ctx->buf, &tmp32[0], &tmp32[64]); + src += 64 - r; + len -= 64 - r; + + /* Perform complete blocks. */ + while (len >= 64) { + SHA256_Transform(ctx->state, src, &tmp32[0], &tmp32[64]); + src += 64; + len -= 64; + } + + /* Copy left over data into buffer. */ + memcpy(ctx->buf, src, len); +} + +/* Wrapper function for intermediate-values sanitization. */ +void +SHA256_Update(SHA256_CTX * ctx, const void * in, size_t len) +{ + uint32_t tmp32[72]; + + /* Call the real function. */ + _SHA256_Update(ctx, in, len, tmp32); + + /* Clean the stack. */ + insecure_memzero(tmp32, 288); +} + +/** + * SHA256_Final(digest, ctx): + * Output the SHA256 hash of the data input to the context ${ctx} into the + * buffer ${digest}. + */ +static void +_SHA256_Final(uint8_t digest[32], SHA256_CTX * ctx, + uint32_t tmp32[static restrict 72]) +{ + + /* Add padding. */ + SHA256_Pad(ctx, tmp32); + + /* Write the hash. */ + be32enc_vect(digest, ctx->state, 4); +} + +/* Wrapper function for intermediate-values sanitization. */ +void +SHA256_Final(uint8_t digest[32], SHA256_CTX * ctx) +{ + uint32_t tmp32[72]; + + /* Call the real function. */ + _SHA256_Final(digest, ctx, tmp32); + + /* Clear the context state. */ + insecure_memzero(ctx, sizeof(SHA256_CTX)); + + /* Clean the stack. */ + insecure_memzero(tmp32, 288); +} + +/** + * SHA256_Buf(in, len, digest): + * Compute the SHA256 hash of ${len} bytes from ${in} and write it to ${digest}. + */ +void +SHA256_Buf(const void * in, size_t len, uint8_t digest[32]) +{ + SHA256_CTX ctx; + uint32_t tmp32[72]; + + SHA256_Init(&ctx); + _SHA256_Update(&ctx, in, len, tmp32); + _SHA256_Final(digest, &ctx, tmp32); + + /* Clean the stack. */ + insecure_memzero(&ctx, sizeof(SHA256_CTX)); + insecure_memzero(tmp32, 288); +} + +/** + * HMAC_SHA256_Init(ctx, K, Klen): + * Initialize the HMAC-SHA256 context ${ctx} with ${Klen} bytes of key from + * ${K}. + */ +static void +_HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen, + uint32_t tmp32[static restrict 72], uint8_t pad[static restrict 64], + uint8_t khash[static restrict 32]) +{ + const uint8_t * K = _K; + size_t i; + + /* If Klen > 64, the key is really SHA256(K). */ + if (Klen > 64) { + SHA256_Init(&ctx->ictx); + _SHA256_Update(&ctx->ictx, K, Klen, tmp32); + _SHA256_Final(khash, &ctx->ictx, tmp32); + K = khash; + Klen = 32; + } + + /* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */ + SHA256_Init(&ctx->ictx); + memset(pad, 0x36, 64); + for (i = 0; i < Klen; i++) + pad[i] ^= K[i]; + _SHA256_Update(&ctx->ictx, pad, 64, tmp32); + + /* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */ + SHA256_Init(&ctx->octx); + memset(pad, 0x5c, 64); + for (i = 0; i < Klen; i++) + pad[i] ^= K[i]; + _SHA256_Update(&ctx->octx, pad, 64, tmp32); +} + +/* Wrapper function for intermediate-values sanitization. */ +void +HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen) +{ + uint32_t tmp32[72]; + uint8_t pad[64]; + uint8_t khash[32]; + + /* Call the real function. */ + _HMAC_SHA256_Init(ctx, _K, Klen, tmp32, pad, khash); + + /* Clean the stack. */ + insecure_memzero(tmp32, 288); + insecure_memzero(khash, 32); + insecure_memzero(pad, 64); +} + +/** + * HMAC_SHA256_Update(ctx, in, len): + * Input ${len} bytes from ${in} into the HMAC-SHA256 context ${ctx}. + */ +static void +_HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void * in, size_t len, + uint32_t tmp32[static restrict 72]) +{ + + /* Feed data to the inner SHA256 operation. */ + _SHA256_Update(&ctx->ictx, in, len, tmp32); +} + +/* Wrapper function for intermediate-values sanitization. */ +void +HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void * in, size_t len) +{ + uint32_t tmp32[72]; + + /* Call the real function. */ + _HMAC_SHA256_Update(ctx, in, len, tmp32); + + /* Clean the stack. */ + insecure_memzero(tmp32, 288); +} + +/** + * HMAC_SHA256_Final(digest, ctx): + * Output the HMAC-SHA256 of the data input to the context ${ctx} into the + * buffer ${digest}. + */ +static void +_HMAC_SHA256_Final(uint8_t digest[32], HMAC_SHA256_CTX * ctx, + uint32_t tmp32[static restrict 72], uint8_t ihash[static restrict 32]) +{ + + /* Finish the inner SHA256 operation. */ + _SHA256_Final(ihash, &ctx->ictx, tmp32); + + /* Feed the inner hash to the outer SHA256 operation. */ + _SHA256_Update(&ctx->octx, ihash, 32, tmp32); + + /* Finish the outer SHA256 operation. */ + _SHA256_Final(digest, &ctx->octx, tmp32); +} + +/* Wrapper function for intermediate-values sanitization. */ +void +HMAC_SHA256_Final(uint8_t digest[32], HMAC_SHA256_CTX * ctx) +{ + uint32_t tmp32[72]; + uint8_t ihash[32]; + + /* Call the real function. */ + _HMAC_SHA256_Final(digest, ctx, tmp32, ihash); + + /* Clean the stack. */ + insecure_memzero(tmp32, 288); + insecure_memzero(ihash, 32); +} + +/** + * HMAC_SHA256_Buf(K, Klen, in, len, digest): + * Compute the HMAC-SHA256 of ${len} bytes from ${in} using the key ${K} of + * length ${Klen}, and write the result to ${digest}. + */ +void +HMAC_SHA256_Buf(const void * K, size_t Klen, const void * in, size_t len, + uint8_t digest[32]) +{ + HMAC_SHA256_CTX ctx; + uint32_t tmp32[72]; + uint8_t tmp8[96]; + + _HMAC_SHA256_Init(&ctx, K, Klen, tmp32, &tmp8[0], &tmp8[64]); + _HMAC_SHA256_Update(&ctx, in, len, tmp32); + _HMAC_SHA256_Final(digest, &ctx, tmp32, &tmp8[0]); + + /* Clean the stack. */ + insecure_memzero(&ctx, sizeof(HMAC_SHA256_CTX)); + insecure_memzero(tmp32, 288); + insecure_memzero(tmp8, 96); +} + +/* Add padding and terminating bit-count, but don't invoke Transform yet. */ +static int +SHA256_Pad_Almost(SHA256_CTX * ctx, uint8_t len[static restrict 8], + uint32_t tmp32[static restrict 72]) +{ + uint32_t r; + + r = (ctx->count >> 3) & 0x3f; + if (r >= 56) + return -1; + + /* + * Convert length to a vector of bytes -- we do this now rather + * than later because the length will change after we pad. + */ + be64enc(len, ctx->count); + + /* Add 1--56 bytes so that the resulting length is 56 mod 64. */ + _SHA256_Update(ctx, PAD, 56 - r, tmp32); + + /* Add the terminating bit-count. */ + ctx->buf[63] = len[7]; + _SHA256_Update(ctx, len, 7, tmp32); + + return 0; +} + +/** + * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): + * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and + * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). + */ +void +PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt, + size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen) +{ + HMAC_SHA256_CTX Phctx, PShctx, hctx; + uint32_t tmp32[72]; + union { + uint8_t tmp8[96]; + uint32_t state[8]; + } u; + size_t i; + uint8_t ivec[4]; + uint8_t U[32]; + uint8_t T[32]; + uint64_t j; + int k; + size_t clen; + + /* Sanity-check. */ + assert(dkLen <= 32 * (size_t)(UINT32_MAX)); + + if (c == 1 && (dkLen & 31) == 0 && (saltlen & 63) <= 51) { + uint32_t oldcount; + uint8_t * ivecp; + + /* Compute HMAC state after processing P and S. */ + _HMAC_SHA256_Init(&hctx, passwd, passwdlen, + tmp32, &u.tmp8[0], &u.tmp8[64]); + _HMAC_SHA256_Update(&hctx, salt, saltlen, tmp32); + + /* Prepare ictx padding. */ + oldcount = hctx.ictx.count & (0x3f << 3); + _HMAC_SHA256_Update(&hctx, "\0\0\0", 4, tmp32); + if ((hctx.ictx.count & (0x3f << 3)) < oldcount || + SHA256_Pad_Almost(&hctx.ictx, u.tmp8, tmp32)) + goto generic; /* Can't happen due to saltlen check */ + ivecp = hctx.ictx.buf + (oldcount >> 3); + + /* Prepare octx padding. */ + hctx.octx.count += 32 << 3; + SHA256_Pad_Almost(&hctx.octx, u.tmp8, tmp32); + + /* Iterate through the blocks. */ + for (i = 0; i * 32 < dkLen; i++) { + /* Generate INT(i + 1). */ + be32enc(ivecp, (uint32_t)(i + 1)); + + /* Compute U_1 = PRF(P, S || INT(i)). */ + memcpy(u.state, hctx.ictx.state, sizeof(u.state)); + SHA256_Transform(u.state, hctx.ictx.buf, + &tmp32[0], &tmp32[64]); + be32enc_vect(hctx.octx.buf, u.state, 4); + memcpy(u.state, hctx.octx.state, sizeof(u.state)); + SHA256_Transform(u.state, hctx.octx.buf, + &tmp32[0], &tmp32[64]); + be32enc_vect(&buf[i * 32], u.state, 4); + } + + goto cleanup; + } + +generic: + /* Compute HMAC state after processing P. */ + _HMAC_SHA256_Init(&Phctx, passwd, passwdlen, + tmp32, &u.tmp8[0], &u.tmp8[64]); + + /* Compute HMAC state after processing P and S. */ + memcpy(&PShctx, &Phctx, sizeof(HMAC_SHA256_CTX)); + _HMAC_SHA256_Update(&PShctx, salt, saltlen, tmp32); + + /* Iterate through the blocks. */ + for (i = 0; i * 32 < dkLen; i++) { + /* Generate INT(i + 1). */ + be32enc(ivec, (uint32_t)(i + 1)); + + /* Compute U_1 = PRF(P, S || INT(i)). */ + memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX)); + _HMAC_SHA256_Update(&hctx, ivec, 4, tmp32); + _HMAC_SHA256_Final(T, &hctx, tmp32, u.tmp8); + + if (c > 1) { + /* T_i = U_1 ... */ + memcpy(U, T, 32); + + for (j = 2; j <= c; j++) { + /* Compute U_j. */ + memcpy(&hctx, &Phctx, sizeof(HMAC_SHA256_CTX)); + _HMAC_SHA256_Update(&hctx, U, 32, tmp32); + _HMAC_SHA256_Final(U, &hctx, tmp32, u.tmp8); + + /* ... xor U_j ... */ + for (k = 0; k < 32; k++) + T[k] ^= U[k]; + } + } + + /* Copy as many bytes as necessary into buf. */ + clen = dkLen - i * 32; + if (clen > 32) + clen = 32; + memcpy(&buf[i * 32], T, clen); + } + + /* Clean the stack. */ + insecure_memzero(&Phctx, sizeof(HMAC_SHA256_CTX)); + insecure_memzero(&PShctx, sizeof(HMAC_SHA256_CTX)); + insecure_memzero(U, 32); + insecure_memzero(T, 32); + +cleanup: + insecure_memzero(&hctx, sizeof(HMAC_SHA256_CTX)); + insecure_memzero(tmp32, 288); + insecure_memzero(&u, sizeof(u)); +} + +static void blkcpy(uint32_t *dst, const uint32_t *src, size_t count) +{ + do { + *dst++ = *src++; + } while (--count); +} + +static void blkxor(uint32_t *dst, const uint32_t *src, size_t count) +{ + do { + *dst++ ^= *src++; + } while (--count); +} + +/** + * salsa20(B): + * Apply the Salsa20 core to the provided block. + */ +static void salsa20(uint32_t B[16], uint32_t rounds) +{ + uint32_t x[16]; + size_t i; + + /* SIMD unshuffle */ + for (i = 0; i < 16; i++) + x[i * 5 % 16] = B[i]; + + for (i = 0; i < rounds; i += 2) { +#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) + /* Operate on columns */ + x[ 4] ^= R(x[ 0]+x[12], 7); x[ 8] ^= R(x[ 4]+x[ 0], 9); + x[12] ^= R(x[ 8]+x[ 4],13); x[ 0] ^= R(x[12]+x[ 8],18); + + x[ 9] ^= R(x[ 5]+x[ 1], 7); x[13] ^= R(x[ 9]+x[ 5], 9); + x[ 1] ^= R(x[13]+x[ 9],13); x[ 5] ^= R(x[ 1]+x[13],18); + + x[14] ^= R(x[10]+x[ 6], 7); x[ 2] ^= R(x[14]+x[10], 9); + x[ 6] ^= R(x[ 2]+x[14],13); x[10] ^= R(x[ 6]+x[ 2],18); + + x[ 3] ^= R(x[15]+x[11], 7); x[ 7] ^= R(x[ 3]+x[15], 9); + x[11] ^= R(x[ 7]+x[ 3],13); x[15] ^= R(x[11]+x[ 7],18); + + /* Operate on rows */ + x[ 1] ^= R(x[ 0]+x[ 3], 7); x[ 2] ^= R(x[ 1]+x[ 0], 9); + x[ 3] ^= R(x[ 2]+x[ 1],13); x[ 0] ^= R(x[ 3]+x[ 2],18); + + x[ 6] ^= R(x[ 5]+x[ 4], 7); x[ 7] ^= R(x[ 6]+x[ 5], 9); + x[ 4] ^= R(x[ 7]+x[ 6],13); x[ 5] ^= R(x[ 4]+x[ 7],18); + + x[11] ^= R(x[10]+x[ 9], 7); x[ 8] ^= R(x[11]+x[10], 9); + x[ 9] ^= R(x[ 8]+x[11],13); x[10] ^= R(x[ 9]+x[ 8],18); + + x[12] ^= R(x[15]+x[14], 7); x[13] ^= R(x[12]+x[15], 9); + x[14] ^= R(x[13]+x[12],13); x[15] ^= R(x[14]+x[13],18); +#undef R + } + + /* SIMD shuffle */ + for (i = 0; i < 16; i++) + B[i] += x[i * 5 % 16]; +} + +/** + * blockmix_salsa(B): + * Compute B = BlockMix_{salsa20, 1}(B). The input B must be 128 bytes in + * length. + */ +static void blockmix_salsa(uint32_t *B, uint32_t rounds) +{ + uint32_t X[16]; + size_t i; + + /* 1: X <-- B_{2r - 1} */ + blkcpy(X, &B[16], 16); + + /* 2: for i = 0 to 2r - 1 do */ + for (i = 0; i < 2; i++) { + /* 3: X <-- H(X xor B_i) */ + blkxor(X, &B[i * 16], 16); + salsa20(X, rounds); + + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + blkcpy(&B[i * 16], X, 16); + } +} + +/* + * These are tunable, but they must meet certain constraints and are part of + * what defines a yespower version. + */ +#define PWXsimple 2 +#define PWXgather 4 +/* Version 0.5 */ +#define PWXrounds_0_5 6 +#define Swidth_0_5 8 +/* Version 1.0 */ +#define PWXrounds_1_0 3 +#define Swidth_1_0 11 + +/* Derived values. Not tunable on their own. */ +#define PWXbytes (PWXgather * PWXsimple * 8) +#define PWXwords (PWXbytes / sizeof(uint32_t)) +#define rmin ((PWXbytes + 127) / 128) + +/* Runtime derived values. Not tunable on their own. */ +#define Swidth_to_Sbytes1(Swidth) ((1 << Swidth) * PWXsimple * 8) +#define Swidth_to_Smask(Swidth) (((1 << Swidth) - 1) * PWXsimple * 8) + +typedef struct { + yespower_version_t version; + uint32_t salsa20_rounds; + uint32_t PWXrounds, Swidth, Sbytes, Smask; + uint32_t *S; + uint32_t (*S0)[2], (*S1)[2], (*S2)[2]; + size_t w; +} pwxform_ctx_t; + +/** + * pwxform(B): + * Transform the provided block using the provided S-boxes. + */ +static void pwxform(uint32_t *B, pwxform_ctx_t *ctx) +{ + uint32_t (*X)[PWXsimple][2] = (uint32_t (*)[PWXsimple][2])B; + uint32_t (*S0)[2] = ctx->S0, (*S1)[2] = ctx->S1, (*S2)[2] = ctx->S2; + uint32_t Smask = ctx->Smask; + size_t w = ctx->w; + size_t i, j, k; + + /* 1: for i = 0 to PWXrounds - 1 do */ + for (i = 0; i < ctx->PWXrounds; i++) { + /* 2: for j = 0 to PWXgather - 1 do */ + for (j = 0; j < PWXgather; j++) { + uint32_t xl = X[j][0][0]; + uint32_t xh = X[j][0][1]; + uint32_t (*p0)[2], (*p1)[2]; + + /* 3: p0 <-- (lo(B_{j,0}) & Smask) / (PWXsimple * 8) */ + p0 = S0 + (xl & Smask) / sizeof(*S0); + /* 4: p1 <-- (hi(B_{j,0}) & Smask) / (PWXsimple * 8) */ + p1 = S1 + (xh & Smask) / sizeof(*S1); + + /* 5: for k = 0 to PWXsimple - 1 do */ + for (k = 0; k < PWXsimple; k++) { + uint64_t x, s0, s1; + + /* 6: B_{j,k} <-- (hi(B_{j,k}) * lo(B_{j,k}) + S0_{p0,k}) xor S1_{p1,k} */ + s0 = ((uint64_t)p0[k][1] << 32) + p0[k][0]; + s1 = ((uint64_t)p1[k][1] << 32) + p1[k][0]; + + xl = X[j][k][0]; + xh = X[j][k][1]; + + x = (uint64_t)xh * xl; + x += s0; + x ^= s1; + + X[j][k][0] = x; + X[j][k][1] = x >> 32; + } + + if (ctx->version != YESPOWER_0_5 && + (i == 0 || j < PWXgather / 2)) { + if (j & 1) { + for (k = 0; k < PWXsimple; k++) { + S1[w][0] = X[j][k][0]; + S1[w][1] = X[j][k][1]; + w++; + } + } else { + for (k = 0; k < PWXsimple; k++) { + S0[w + k][0] = X[j][k][0]; + S0[w + k][1] = X[j][k][1]; + } + } + } + } + } + + if (ctx->version != YESPOWER_0_5) { + /* 14: (S0, S1, S2) <-- (S2, S0, S1) */ + ctx->S0 = S2; + ctx->S1 = S0; + ctx->S2 = S1; + /* 15: w <-- w mod 2^Swidth */ + ctx->w = w & ((1 << ctx->Swidth) * PWXsimple - 1); + } +} + +/** + * blockmix_pwxform(B, ctx, r): + * Compute B = BlockMix_pwxform{salsa20, ctx, r}(B). The input B must be + * 128r bytes in length. + */ +static void blockmix_pwxform(uint32_t *B, pwxform_ctx_t *ctx, size_t r) +{ + uint32_t X[PWXwords]; + size_t r1, i; + + /* Convert 128-byte blocks to PWXbytes blocks */ + /* 1: r_1 <-- 128r / PWXbytes */ + r1 = 128 * r / PWXbytes; + + /* 2: X <-- B'_{r_1 - 1} */ + blkcpy(X, &B[(r1 - 1) * PWXwords], PWXwords); + + /* 3: for i = 0 to r_1 - 1 do */ + for (i = 0; i < r1; i++) { + /* 4: if r_1 > 1 */ + if (r1 > 1) { + /* 5: X <-- X xor B'_i */ + blkxor(X, &B[i * PWXwords], PWXwords); + } + + /* 7: X <-- pwxform(X) */ + pwxform(X, ctx); + + /* 8: B'_i <-- X */ + blkcpy(&B[i * PWXwords], X, PWXwords); + } + + /* 10: i <-- floor((r_1 - 1) * PWXbytes / 64) */ + i = (r1 - 1) * PWXbytes / 64; + + /* 11: B_i <-- H(B_i) */ + salsa20(&B[i * 16], ctx->salsa20_rounds); + +#if 1 /* No-op with our current pwxform settings, but do it to make sure */ + /* 12: for i = i + 1 to 2r - 1 do */ + for (i++; i < 2 * r; i++) { + /* 13: B_i <-- H(B_i xor B_{i-1}) */ + blkxor(&B[i * 16], &B[(i - 1) * 16], 16); + salsa20(&B[i * 16], ctx->salsa20_rounds); + } +#endif +} + +/** + * integerify(B, r): + * Return the result of parsing B_{2r-1} as a little-endian integer. + */ +static uint32_t integerify(const uint32_t *B, size_t r) +{ +/* + * Our 32-bit words are in host byte order. Also, they are SIMD-shuffled, but + * we only care about the least significant 32 bits anyway. + */ + const uint32_t *X = &B[(2 * r - 1) * 16]; + return X[0]; +} + +/** + * p2floor(x): + * Largest power of 2 not greater than argument. + */ +static uint32_t p2floor(uint32_t x) +{ + uint32_t y; + while ((y = x & (x - 1))) + x = y; + return x; +} + +/** + * wrap(x, i): + * Wrap x to the range 0 to i-1. + */ +static uint32_t wrap(uint32_t x, uint32_t i) +{ + uint32_t n = p2floor(i); + return (x & (n - 1)) + (i - n); +} + +/** + * smix1(B, r, N, V, X, ctx): + * Compute first loop of B = SMix_r(B, N). The input B must be 128r bytes in + * length; the temporary storage V must be 128rN bytes in length; the temporary + * storage X must be 128r bytes in length. + */ +static void smix1(uint32_t *B, size_t r, uint32_t N, + uint32_t *V, uint32_t *X, pwxform_ctx_t *ctx) +{ + size_t s = 32 * r; + uint32_t i, j; + size_t k; + + /* 1: X <-- B */ + for (k = 0; k < 2 * r; k++) + for (i = 0; i < 16; i++) + X[k * 16 + i] = le32dec(&B[k * 16 + (i * 5 % 16)]); + + if (ctx->version != YESPOWER_0_5) { + for (k = 1; k < r; k++) { + blkcpy(&X[k * 32], &X[(k - 1) * 32], 32); + blockmix_pwxform(&X[k * 32], ctx, 1); + } + } + + /* 2: for i = 0 to N - 1 do */ + for (i = 0; i < N; i++) { + /* 3: V_i <-- X */ + blkcpy(&V[i * s], X, s); + + if (i > 1) { + /* j <-- Wrap(Integerify(X), i) */ + j = wrap(integerify(X, r), i); + + /* X <-- X xor V_j */ + blkxor(X, &V[j * s], s); + } + + /* 4: X <-- H(X) */ + if (V != ctx->S) + blockmix_pwxform(X, ctx, r); + else + blockmix_salsa(X, ctx->salsa20_rounds); + } + + /* B' <-- X */ + for (k = 0; k < 2 * r; k++) + for (i = 0; i < 16; i++) + le32enc(&B[k * 16 + (i * 5 % 16)], X[k * 16 + i]); +} + +/** + * smix2(B, r, N, Nloop, V, X, ctx): + * Compute second loop of B = SMix_r(B, N). The input B must be 128r bytes in + * length; the temporary storage V must be 128rN bytes in length; the temporary + * storage X must be 128r bytes in length. The value N must be a power of 2 + * greater than 1. + */ +static void smix2(uint32_t *B, size_t r, uint32_t N, uint32_t Nloop, + uint32_t *V, uint32_t *X, pwxform_ctx_t *ctx) +{ + size_t s = 32 * r; + uint32_t i, j; + size_t k; + + /* X <-- B */ + for (k = 0; k < 2 * r; k++) + for (i = 0; i < 16; i++) + X[k * 16 + i] = le32dec(&B[k * 16 + (i * 5 % 16)]); + + /* 6: for i = 0 to N - 1 do */ + for (i = 0; i < Nloop; i++) { + /* 7: j <-- Integerify(X) mod N */ + j = integerify(X, r) & (N - 1); + + /* 8.1: X <-- X xor V_j */ + blkxor(X, &V[j * s], s); + /* V_j <-- X */ + if (Nloop != 2) + blkcpy(&V[j * s], X, s); + + /* 8.2: X <-- H(X) */ + blockmix_pwxform(X, ctx, r); + } + + /* 10: B' <-- X */ + for (k = 0; k < 2 * r; k++) + for (i = 0; i < 16; i++) + le32enc(&B[k * 16 + (i * 5 % 16)], X[k * 16 + i]); +} + +/** + * smix(B, r, N, p, t, V, X, ctx): + * Compute B = SMix_r(B, N). The input B must be 128rp bytes in length; the + * temporary storage V must be 128rN bytes in length; the temporary storage + * X must be 128r bytes in length. The value N must be a power of 2 and at + * least 16. + */ +static void smix(uint32_t *B, size_t r, uint32_t N, + uint32_t *V, uint32_t *X, pwxform_ctx_t *ctx) +{ + uint32_t Nloop_all = (N + 2) / 3; /* 1/3, round up */ + uint32_t Nloop_rw = Nloop_all; + + Nloop_all++; Nloop_all &= ~(uint32_t)1; /* round up to even */ + if (ctx->version == YESPOWER_0_5) { + Nloop_rw &= ~(uint32_t)1; /* round down to even */ + } else { + Nloop_rw++; Nloop_rw &= ~(uint32_t)1; /* round up to even */ + } + + smix1(B, 1, ctx->Sbytes / 128, ctx->S, X, ctx); + smix1(B, r, N, V, X, ctx); + smix2(B, r, N, Nloop_rw /* must be > 2 */, V, X, ctx); + smix2(B, r, N, Nloop_all - Nloop_rw /* 0 or 2 */, V, X, ctx); +} + +/** + * yespower(local, src, srclen, params, dst): + * Compute yespower(src[0 .. srclen - 1], N, r), to be checked for "< target". + * + * Return 0 on success; or -1 on error. + */ +int yespower(yespower_local_t *local, + const uint8_t *src, size_t srclen, + const yespower_params_t *params, yespower_binary_t *dst) +{ + yespower_version_t version = params->version; + uint32_t N = params->N; + uint32_t r = params->r; + const uint8_t *pers = params->pers; + size_t perslen = params->perslen; + int retval = -1; + size_t B_size, V_size; + uint32_t *B, *V, *X, *S; + pwxform_ctx_t ctx; + uint32_t sha256[8]; + + /* Sanity-check parameters */ + if ((version != YESPOWER_0_5 && version != YESPOWER_1_0) || + N < 1024 || N > 512 * 1024 || r < 8 || r > 32 || + (N & (N - 1)) != 0 || r < rmin || + (!pers && perslen)) { + errno = EINVAL; + return -1; + } + + /* Allocate memory */ + B_size = (size_t)128 * r; + V_size = B_size * N; + if ((V = malloc(V_size)) == NULL) + return -1; + if ((B = malloc(B_size)) == NULL) + goto free_V; + if ((X = malloc(B_size)) == NULL) + goto free_B; + ctx.version = version; + if (version == YESPOWER_0_5) { + ctx.salsa20_rounds = 8; + ctx.PWXrounds = PWXrounds_0_5; + ctx.Swidth = Swidth_0_5; + ctx.Sbytes = 2 * Swidth_to_Sbytes1(ctx.Swidth); + } else { + ctx.salsa20_rounds = 2; + ctx.PWXrounds = PWXrounds_1_0; + ctx.Swidth = Swidth_1_0; + ctx.Sbytes = 3 * Swidth_to_Sbytes1(ctx.Swidth); + } + if ((S = malloc(ctx.Sbytes)) == NULL) + goto free_X; + ctx.S = S; + ctx.S0 = (uint32_t (*)[2])S; + ctx.S1 = ctx.S0 + (1 << ctx.Swidth) * PWXsimple; + ctx.S2 = ctx.S1 + (1 << ctx.Swidth) * PWXsimple; + ctx.Smask = Swidth_to_Smask(ctx.Swidth); + ctx.w = 0; + + SHA256_Buf(src, srclen, (uint8_t *)sha256); + + if (version != YESPOWER_0_5) { + if (pers) { + src = pers; + srclen = perslen; + } else { + srclen = 0; + } + } + + /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */ + PBKDF2_SHA256((uint8_t *)sha256, sizeof(sha256), + src, srclen, 1, (uint8_t *)B, B_size); + + blkcpy(sha256, B, sizeof(sha256) / sizeof(sha256[0])); + + /* 3: B_i <-- MF(B_i, N) */ + smix(B, r, N, V, X, &ctx); + + if (version == YESPOWER_0_5) { + /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */ + PBKDF2_SHA256((uint8_t *)sha256, sizeof(sha256), + (uint8_t *)B, B_size, 1, (uint8_t *)dst, sizeof(*dst)); + + if (pers) { + HMAC_SHA256_Buf(dst, sizeof(*dst), pers, perslen, + (uint8_t *)sha256); + SHA256_Buf(sha256, sizeof(sha256), (uint8_t *)dst); + } + } else { + HMAC_SHA256_Buf((uint8_t *)B + B_size - 64, 64, + sha256, sizeof(sha256), (uint8_t *)dst); + } + + /* Success! */ + retval = 0; + + /* Free memory */ + free(S); +free_X: + free(X); +free_B: + free(B); +free_V: + free(V); + + return retval; +} + +int yespower_tls(const uint8_t *src, size_t srclen, + const yespower_params_t *params, yespower_binary_t *dst) +{ +/* The reference implementation doesn't use thread-local storage */ + return yespower(NULL, src, srclen, params, dst); +} + +int yespower_init_local(yespower_local_t *local) +{ +/* The reference implementation doesn't use the local structure */ + local->base = local->aligned = NULL; + local->base_size = local->aligned_size = 0; + return 0; +} + +int yespower_free_local(yespower_local_t *local) +{ +/* The reference implementation frees its memory in yespower() */ + (void)local; /* unused */ + return 0; +} + +void yespower_hash(const char* input, char* output, uint32_t len) +{ + yespower_params_t yespower_1_0_sugarchain = { + .version = YESPOWER_1_0, + .N = 2048, + .r = 32, + .pers = (const uint8_t *)"Satoshi Nakamoto 31/Oct/2008 Proof-of-work is essentially one-CPU-one-vote", + .perslen = 74 + }; + yespower_tls(input, 80, &yespower_1_0_sugarchain, (yespower_binary_t *)output); +} + +void yespowerurx_hash(const char* input, char* output, uint32_t len) +{ + yespower_params_t yespower_1_0_uraniumx = { + .version = YESPOWER_1_0, + .N = 2048, + .r = 32, + .pers = (const uint8_t *)"UraniumX", + .perslen = 8 + }; + yespower_tls( input, 80, &yespower_1_0_uraniumx, (yespower_binary_t *)output); +} diff --git a/stratum/algos/yescrypt-platform.c b/stratum/algos/yespower/yespower-platform.c similarity index 54% rename from stratum/algos/yescrypt-platform.c rename to stratum/algos/yespower/yespower-platform.c index 0f86ca9aa..d577c29de 100644 --- a/stratum/algos/yescrypt-platform.c +++ b/stratum/algos/yespower/yespower-platform.c @@ -1,5 +1,5 @@ /*- - * Copyright 2013,2014 Alexander Peslyak + * Copyright 2013-2018 Alexander Peslyak * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -18,8 +18,12 @@ * SUCH DAMAGE. */ +#ifdef __unix__ #include -#include "yescrypt.h" +#endif + +#include "yespower.h" + #define HUGEPAGE_THRESHOLD (12 * 1024 * 1024) #ifdef __x86_64__ @@ -28,11 +32,10 @@ #undef HUGEPAGE_SIZE #endif -static void * -alloc_region(yescrypt_region_t * region, size_t size) +static void *alloc_region(yespower_region_t *region, size_t size) { size_t base_size = size; - uint8_t * base, * aligned; + uint8_t *base, *aligned; #ifdef MAP_ANON int flags = #ifdef MAP_NOCORE @@ -54,8 +57,7 @@ alloc_region(yescrypt_region_t * region, size_t size) base = mmap(NULL, new_size, PROT_READ | PROT_WRITE, flags, -1, 0); if (base != MAP_FAILED) { base_size = new_size; - } else - if (flags & MAP_HUGETLB) { + } else if (flags & MAP_HUGETLB) { flags &= ~MAP_HUGETLB; base = mmap(NULL, size, PROT_READ | PROT_WRITE, flags, -1, 0); } @@ -86,15 +88,13 @@ alloc_region(yescrypt_region_t * region, size_t size) return aligned; } -static inline void -init_region(yescrypt_region_t * region) +static inline void init_region(yespower_region_t *region) { region->base = region->aligned = NULL; region->base_size = region->aligned_size = 0; } -static int -free_region(yescrypt_region_t * region) +static int free_region(yespower_region_t *region) { if (region->base) { #ifdef MAP_ANON @@ -107,85 +107,3 @@ free_region(yescrypt_region_t * region) init_region(region); return 0; } - -int -yescrypt_init_shared(yescrypt_shared_t * shared, - const uint8_t * param, size_t paramlen, - uint64_t N, uint32_t r, uint32_t p, - yescrypt_init_shared_flags_t flags, uint32_t mask, - uint8_t * buf, size_t buflen) -{ - yescrypt_shared1_t * shared1 = &shared->shared1; - yescrypt_shared_t dummy, half1, half2; - uint8_t salt[32]; - - if (flags & YESCRYPT_SHARED_PREALLOCATED) { - if (!shared1->aligned || !shared1->aligned_size) - return -1; - } else { - init_region(shared1); - } - shared->mask1 = 1; - if (!param && !paramlen && !N && !r && !p && !buf && !buflen) - return 0; - - init_region(&dummy.shared1); - dummy.mask1 = 1; - if (yescrypt_kdf(&dummy, shared1, - param, paramlen, NULL, 0, N, r, p, 0, - YESCRYPT_RW | YESCRYPT_PARALLEL_SMIX | __YESCRYPT_INIT_SHARED_1, - salt, sizeof(salt))) - goto out; - - half1 = half2 = *shared; - half1.shared1.aligned_size /= 2; - half2.shared1.aligned += half1.shared1.aligned_size; - half2.shared1.aligned_size = half1.shared1.aligned_size; - N /= 2; - - if (p > 1 && yescrypt_kdf(&half1, &half2.shared1, - param, paramlen, salt, sizeof(salt), N, r, p, 0, - YESCRYPT_RW | YESCRYPT_PARALLEL_SMIX | __YESCRYPT_INIT_SHARED_2, - salt, sizeof(salt))) - goto out; - - if (yescrypt_kdf(&half2, &half1.shared1, - param, paramlen, salt, sizeof(salt), N, r, p, 0, - YESCRYPT_RW | YESCRYPT_PARALLEL_SMIX | __YESCRYPT_INIT_SHARED_1, - salt, sizeof(salt))) - goto out; - - if (yescrypt_kdf(&half1, &half2.shared1, - param, paramlen, salt, sizeof(salt), N, r, p, 0, - YESCRYPT_RW | YESCRYPT_PARALLEL_SMIX | __YESCRYPT_INIT_SHARED_1, - buf, buflen)) - goto out; - - shared->mask1 = mask; - - return 0; - -out: - if (!(flags & YESCRYPT_SHARED_PREALLOCATED)) - free_region(shared1); - return -1; -} - -int -yescrypt_free_shared(yescrypt_shared_t * shared) -{ - return free_region(&shared->shared1); -} - -int -yescrypt_init_local(yescrypt_local_t * local) -{ - init_region(local); - return 0; -} - -int -yescrypt_free_local(yescrypt_local_t * local) -{ - return free_region(local); -} diff --git a/stratum/algos/yespower/yespower.h b/stratum/algos/yespower/yespower.h new file mode 100644 index 000000000..7b54932b5 --- /dev/null +++ b/stratum/algos/yespower/yespower.h @@ -0,0 +1,133 @@ +/*- + * Copyright 2009 Colin Percival + * Copyright 2013-2018 Alexander Peslyak + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file was originally written by Colin Percival as part of the Tarsnap + * online backup system. + */ +#ifndef _YESPOWER_H_ +#define _YESPOWER_H_ + +#include +#include /* for size_t */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Internal type used by the memory allocator. Please do not use it directly. + * Use yespower_local_t instead. + */ +typedef struct { + void *base, *aligned; + size_t base_size, aligned_size; +} yespower_region_t; + +/** + * Type for thread-local (RAM) data structure. + */ +typedef yespower_region_t yespower_local_t; + +/* + * Type for yespower algorithm version numbers. + */ +typedef enum { YESPOWER_0_5 = 5, YESPOWER_1_0 = 10 } yespower_version_t; + +/** + * yespower parameters combined into one struct. + */ +typedef struct { + yespower_version_t version; + uint32_t N, r; + const uint8_t *pers; + size_t perslen; +} yespower_params_t; + +/** + * A 256-bit yespower hash. + */ +typedef struct { + unsigned char uc[32]; +} yespower_binary_t; + +/** + * yespower_init_local(local): + * Initialize the thread-local (RAM) data structure. Actual memory allocation + * is currently fully postponed until a call to yespower(). + * + * Return 0 on success; or -1 on error. + * + * MT-safe as long as local is local to the thread. + */ +extern int yespower_init_local(yespower_local_t *local); + +/** + * yespower_free_local(local): + * Free memory that may have been allocated for an initialized thread-local + * (RAM) data structure. + * + * Return 0 on success; or -1 on error. + * + * MT-safe as long as local is local to the thread. + */ +extern int yespower_free_local(yespower_local_t *local); + +/** + * yespower(local, src, srclen, params, dst): + * Compute yespower(src[0 .. srclen - 1], N, r), to be checked for "< target". + * local is the thread-local data structure, allowing to preserve and reuse a + * memory allocation across calls, thereby reducing processing overhead. + * + * Return 0 on success; or -1 on error. + * + * local must be initialized with yespower_init_local(). + * + * MT-safe as long as local and dst are local to the thread. + */ +extern int yespower(yespower_local_t *local, + const uint8_t *src, size_t srclen, + const yespower_params_t *params, yespower_binary_t *dst); + +/** + * yespower_tls(src, srclen, params, dst): + * Compute yespower(src[0 .. srclen - 1], N, r), to be checked for "< target". + * The memory allocation is maintained internally using thread-local storage. + * + * Return 0 on success; or -1 on error. + * + * MT-safe as long as dst is local to the thread. + */ +extern int yespower_tls(const uint8_t *src, size_t srclen, + const yespower_params_t *params, yespower_binary_t *dst); + +void yespower_hash(const char* input, char* output, uint32_t len); +void yespowerurx_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif /* !_YESPOWER_H_ */ diff --git a/stratum/client.cpp b/stratum/client.cpp index 3c2bd94ca..a8e1a82b1 100644 --- a/stratum/client.cpp +++ b/stratum/client.cpp @@ -48,8 +48,11 @@ bool client_subscribe(YAAMP_CLIENT *client, json_value *json_params) if (json_params->u.array.values[0]->u.string.ptr) strncpy(client->version, json_params->u.array.values[0]->u.string.ptr, 1023); - if(strstr(client->version, "NiceHash") || strstr(client->version, "proxy") || strstr(client->version, "/3.")) - client->reconnectable = false; + if (strstr(client->version, "NiceHash")) + client->difficulty_actual = g_stratum_nicehash_difficulty; + + if(strstr(client->version, "proxy") || strstr(client->version, "/3.")) + client->reconnectable = false; if(strstr(client->version, "ccminer")) client->stats = true; if(strstr(client->version, "cpuminer-multi")) client->stats = true; @@ -229,11 +232,6 @@ bool client_authorize(YAAMP_CLIENT *client, json_value *json_params) } } - if (!is_base58(client->username)) { - clientlog(client, "bad mining address %s", client->username); - return false; - } - bool reset = client_initialize_multialgo(client); if(reset) return false; @@ -261,19 +259,6 @@ bool client_authorize(YAAMP_CLIENT *client, json_value *json_params) CommonUnlock(&g_db_mutex); } - // when auto exchange is disabled, only authorize good wallet address... - if (!g_autoexchange && !client_validate_user_address(client)) { - - clientlog(client, "bad mining address %s", client->username); - client_send_result(client, "false"); - - CommonLock(&g_db_mutex); - db_clear_worker(g_db, client); - CommonUnlock(&g_db_mutex); - - return false; - } - client_send_result(client, "true"); client_send_difficulty(client, client->difficulty_actual); @@ -671,4 +656,3 @@ void *client_thread(void *p) pthread_exit(NULL); } - diff --git a/stratum/client.h b/stratum/client.h index c58260b04..128e70d52 100644 --- a/stratum/client.h +++ b/stratum/client.h @@ -31,8 +31,8 @@ struct YAAMP_CLIENT_ALGO #define YAAMP_JOB_MAXHISTORY 16 -#define MIN_ADDRESS_LEN 30 /* BTC len can be as few as 26 chars, but gen. 33 or 34 */ -#define MAX_ADDRESS_LEN 35 /* DCR */ +#define MIN_ADDRESS_LEN 3 /* BTC len can be as few as 26 chars, but gen. 33 or 34 */ +#define MAX_ADDRESS_LEN 98 /* BITC */ class YAAMP_CLIENT: public YAAMP_OBJECT { diff --git a/stratum/client_difficulty.cpp b/stratum/client_difficulty.cpp index e3d34cb08..416559503 100644 --- a/stratum/client_difficulty.cpp +++ b/stratum/client_difficulty.cpp @@ -39,7 +39,6 @@ void client_change_difficulty(YAAMP_CLIENT *client, double difficulty) if(difficulty == client->difficulty_actual) return; uint64_t user_target = diff_to_target(difficulty); - if(user_target >= YAAMP_MINDIFF && user_target <= YAAMP_MAXDIFF) { client->difficulty_actual = difficulty; client_send_difficulty(client, difficulty); @@ -59,6 +58,12 @@ void client_adjust_difficulty(YAAMP_CLIENT *client) else if(client->difficulty_fixed) return; + else if(client->shares_per_minute > 75) + client_change_difficulty(client, client->difficulty_actual*3.5); + + else if(client->shares_per_minute > 50) + client_change_difficulty(client, client->difficulty_actual*3); + else if(client->shares_per_minute > 25) client_change_difficulty(client, client->difficulty_actual*2); @@ -77,7 +82,7 @@ int client_send_difficulty(YAAMP_CLIENT *client, double difficulty) if(difficulty >= 1) client_call(client, "mining.set_difficulty", "[%.0f]", difficulty); else - client_call(client, "mining.set_difficulty", "[%.3f]", difficulty); + client_call(client, "mining.set_difficulty", "[%0.8f]", difficulty); return 0; } @@ -98,9 +103,3 @@ void client_initialize_difficulty(YAAMP_CLIENT *client) } } - - - - - - diff --git a/stratum/client_submit.cpp b/stratum/client_submit.cpp index 055c349e7..b387eb67a 100644 --- a/stratum/client_submit.cpp +++ b/stratum/client_submit.cpp @@ -28,6 +28,10 @@ void build_submit_values(YAAMP_JOB_VALUES *submitvalues, YAAMP_JOB_TEMPLATE *tem string merkleroot = merkle_with_first(templ->txsteps, doublehash); ser_string_be(merkleroot.c_str(), submitvalues->merkleroot_be, 8); + if(templ->isbitcash) { + sprintf(submitvalues->coinbase, "%s%s%s%s", templ->coinforsubmitb1, nonce1, nonce2, templ->coinforsubmitb2); + } + #ifdef MERKLE_DEBUGLOG printf("merkle root %s\n", merkleroot.c_str()); #endif @@ -39,7 +43,14 @@ void build_submit_values(YAAMP_JOB_VALUES *submitvalues, YAAMP_JOB_TEMPLATE *tem sprintf(submitvalues->header, "%s%s%s%s%s%s%s", templ->version, templ->prevhash_be, submitvalues->merkleroot_be, ntime, templ->nbits, nonce, templ->extradata_be); ser_string_be(submitvalues->header, submitvalues->header_be, 36); // 80+64 / sizeof(u32) - } else { + } else if (templ->needpriceinfo) + { + sprintf(submitvalues->header, "%s%s%s%s%s%s", templ->version, templ->prevhash_be, submitvalues->merkleroot_be, + ntime, templ->nbits, nonce); + ser_string_be(submitvalues->header, submitvalues->header_be, 20); + sprintf(submitvalues->header_be, "%s%s", submitvalues->header_be, templ->priceinfo); + } else + { sprintf(submitvalues->header, "%s%s%s%s%s%s", templ->version, templ->prevhash_be, submitvalues->merkleroot_be, ntime, templ->nbits, nonce); ser_string_be(submitvalues->header, submitvalues->header_be, 20); @@ -267,6 +278,10 @@ static void client_do_submit(YAAMP_CLIENT *client, YAAMP_JOB *job, YAAMP_JOB_VAL merkle_hash((char *)submitvalues->header_bin, doublehash2, strlen(submitvalues->header_be)/2); + // isnt perfect, but it works + if(strcmp(coind->symbol, "SIN") == 0) + x22i_hash_hex((char *)submitvalues->header_bin, doublehash2, strlen(submitvalues->header_be)/2); + char hash1[1024]; memset(hash1, 0, 1024); @@ -337,18 +352,6 @@ void client_submit_error(YAAMP_CLIENT *client, YAAMP_JOB *job, int id, const cha object_unlock(job); } -static bool ntime_valid_range(const char ntimehex[]) -{ - time_t rawtime = 0; - uint32_t ntime = 0; - if (strlen(ntimehex) != 8) return false; - sscanf(ntimehex, "%8x", &ntime); - if (ntime < 0x5b000000 || ntime > 0x60000000) // 14 Jan 2021 - return false; - time(&rawtime); - return (abs(rawtime - ntime) < (30 * 60)); -} - static bool valid_string_params(json_value *json_params) { for(int p=0; p < json_params->u.array.length; p++) { @@ -431,8 +434,8 @@ bool client_submit(YAAMP_CLIENT *client, json_value *json_params) if(strcmp(ntime, templ->ntime)) { - if (!ishexa(ntime, 8) || !ntime_valid_range(ntime)) { - client_submit_error(client, job, 23, "Invalid time rolling", extranonce2, ntime, nonce); + if (!ishexa(ntime, 8)) { + client_submit_error(client, job, 23, "Invalid ntime", extranonce2, ntime, nonce); return true; } // dont allow algos permutations change over time (can lead to different speeds) @@ -497,29 +500,17 @@ bool client_submit(YAAMP_CLIENT *client, json_value *json_params) lyra2z_height = templ->height; } - // minimum hash diff begins with 0000, for all... - uint8_t pfx = submitvalues.hash_bin[30] | submitvalues.hash_bin[31]; - if(pfx) { - if (g_debuglog_hash) { - debuglog("Possible %s error, hash starts with %02x%02x%02x%02x\n", g_current_algo->name, - (int) submitvalues.hash_bin[31], (int) submitvalues.hash_bin[30], - (int) submitvalues.hash_bin[29], (int) submitvalues.hash_bin[28]); - } - client_submit_error(client, job, 25, "Invalid share", extranonce2, ntime, nonce); - return true; - } + uint64_t hash_int = * (uint64_t *) &submitvalues.hash_bin[24]; + uint64_t user_target = share_to_target(client->difficulty_actual) * g_current_algo->diff_multiplier; + uint64_t coin_target = decode_compact(templ->nbits) / 0x10000; - uint64_t hash_int = get_hash_difficulty(submitvalues.hash_bin); - uint64_t user_target = diff_to_target(client->difficulty_actual); - uint64_t coin_target = decode_compact(templ->nbits); - if (templ->nbits && !coin_target) coin_target = 0xFFFF000000000000ULL; +if (g_debuglog_hash) { + debuglog("hash %016lx \n", hash_int); + debuglog("shar %016lx \n", user_target); + debuglog("coin %016lx \n", coin_target); +} - if (g_debuglog_hash) { - debuglog("%016llx actual\n", hash_int); - debuglog("%016llx target\n", user_target); - debuglog("%016llx coin\n", coin_target); - } - if(hash_int > user_target && hash_int > coin_target) + if(hash_int > user_target) { client_submit_error(client, job, 26, "Low difficulty share", extranonce2, ntime, nonce); return true; diff --git a/stratum/coinbase.cpp b/stratum/coinbase.cpp index 9bf0a2bd3..21a515a72 100644 --- a/stratum/coinbase.cpp +++ b/stratum/coinbase.cpp @@ -27,6 +27,19 @@ static void p2sh_pack_tx(YAAMP_COIND *coind, char *data, json_int_t amount, char strcat(data, coinb2_part); } +static void script_pack_tx(YAAMP_COIND *coind, char *data, json_int_t amount, const char *script) +{ + char evalue[32]; + char coinb2_part[256]; + char coinb2_len[4]; + encode_tx_value(evalue, amount); + sprintf(coinb2_part, "%s", script); + sprintf(coinb2_len, "%02x", (unsigned int)(strlen(coinb2_part) >> 1) & 0xFF); + strcat(data, evalue); + strcat(data, coinb2_len); + strcat(data, coinb2_part); +} + static void job_pack_tx(YAAMP_COIND *coind, char *data, json_int_t amount, char *key) { int ol = strlen(data); @@ -82,6 +95,48 @@ void coinbase_aux(YAAMP_JOB_TEMPLATE *templ, char *aux_script) void coinbase_create(YAAMP_COIND *coind, YAAMP_JOB_TEMPLATE *templ, json_value *json_result) { + templ->isbitcash = false; + if(strcmp(coind->symbol, "BITC") == 0) { + char *params = (char *)malloc(4096); + if (params) { + unsigned char price_bin[1024]; + unsigned char pricehash_bin[1024]; + char pricehash_hex[1024]; + char pricehash_be[1024]; + + if (templ->needpriceinfo && strlen(templ->priceinfo) > 0 && strlen(templ->priceinfo) < 1000) { + binlify(price_bin, templ->priceinfo); + + int price_len = strlen(templ->priceinfo)/2; + sha256_double_hash((char *)price_bin, (char *)pricehash_bin, price_len); + + hexlify(pricehash_hex, pricehash_bin, 32); + string_be(pricehash_hex, pricehash_be); + + sprintf(params, "[\"%s\", %i, \"%s\"]", coind->wallet, templ->height, pricehash_be); + } else { + sprintf(params, "[\"%s\", %i]", coind->wallet, templ->height); + } + //std::cout << "Params:" << params << std::endl; + json_value *json = rpc_call(&coind->rpc, "createcoinbaseforaddress", params); + + free(params); + if (json) { + json_value *json_result = json_get_object(json, "result"); + if (json_result) { + sprintf(templ->coinb1, "%s", json_get_string(json_result, "coinbaseforhashpart1")); + templ->coinb1[strlen(templ->coinb1) - 16] = '\0'; + sprintf(templ->coinb2, "%s", json_get_string(json_result, "coinbaseforhashpart2")); + + sprintf(templ->coinforsubmitb1, "%s", json_get_string(json_result, "coinbasepart1")); + templ->coinforsubmitb1[strlen(templ->coinforsubmitb1) - 16] = '\0'; + sprintf(templ->coinforsubmitb2, "%s", json_get_string(json_result, "coinbasepart2")); + templ->isbitcash = true; + } + } + } + return; + } char eheight[32], etime[32]; char entime[32] = { 0 }; char commitment[128] = { 0 }; @@ -94,10 +149,14 @@ void coinbase_create(YAAMP_COIND *coind, YAAMP_JOB_TEMPLATE *templ, json_value * if(coind->txmessage) strcpy(eversion1, "02000000"); + const char *coinbase_payload = json_get_string(json_result, "coinbase_payload"); + if(coinbase_payload && strlen(coinbase_payload) > 0) + strcpy(eversion1, "03000500"); + char script1[4*1024]; sprintf(script1, "%s%s%s08", eheight, templ->flags, etime); - char script2[32] = "7969696d7000"; // "yiimp\0" in hex ascii + char script2[32] = "746865706f6f6c2e6c6966655c30"; // "thepool.life\0" in hex ascii if(!coind->pos && !coind->isaux && templ->auxs_size) coinbase_aux(templ, script2); @@ -185,39 +244,133 @@ void coinbase_create(YAAMP_COIND *coind, YAAMP_JOB_TEMPLATE *templ, json_value * //debuglog("%s %d dests %s\n", coind->symbol, npayees, script_dests); return; } + + else if(strcmp(coind->symbol, "IDX") == 0) + { + char script_dests[2048] = { 0 }; + char script_payee[128] = { 0 }; + char payees[3]; + int npayees = (templ->has_segwit_txs) ? 2 : 1; + json_value* indexnode; + indexnode = json_get_object(json_result, "indexnode"); + if(!indexnode && json_get_bool(json_result, "indexnode_payments")) { + coind->oldmasternodes = true; + debuglog("%s is using old indexnodes rpc keys\n", coind->symbol); + return; + } + if (indexnode) { + bool started; + started = json_get_bool(json_result, "indexnode_payments_started"); + const char *payee = json_get_string(indexnode, "payee"); + json_int_t amount = json_get_int(indexnode, "amount"); + if (!payee) + debuglog("coinbase_create failed to get Indexnode payee\n"); + + if (!amount) + debuglog("coinbase_create failed to get Indexnode amount\n"); + + if (!started) + debuglog("coinbase_create failed to get Indexnode started\n"); + + if (payee && amount && started) { + npayees++; + base58_decode(payee, script_payee); + job_pack_tx(coind, script_dests, amount, script_payee); + //debuglog("%s indexnode found %s %u\n", coind->symbol, payee, amount); + } + } + sprintf(payees, "%02x", npayees); + strcat(templ->coinb2, payees); + if (templ->has_segwit_txs) strcat(templ->coinb2, commitment); + strcat(templ->coinb2, script_dests); + job_pack_tx(coind, templ->coinb2, available, NULL); + strcat(templ->coinb2, "00000000"); // locktime + coind->reward = (double)available/100000000*coind->reward_mul; + //debuglog("%s %d dests %s\n", coind->symbol, npayees, script_dests); + return; + } + + + else if(strcmp(coind->symbol, "GXX") == 0) { + char script_payee[1024]; + + bool znode_masternode_enabled = json_get_bool(json_result, "xnode_payments_started"); + if (znode_masternode_enabled == true) { + json_value* znode_masternode = json_get_object(json_result, "xnode"); + const char *payee = json_get_string(znode_masternode, "payee"); + json_int_t amount = json_get_int(znode_masternode, "amount"); + if (payee && amount) { + //debuglog("xnode payee: %s\n", payee); + strcat(templ->coinb2, "04"); + job_pack_tx(coind, templ->coinb2, available, NULL); + + base58_decode(payee, script_payee); + job_pack_tx(coind, templ->coinb2, amount, script_payee); + } + } else { + strcat(templ->coinb2, "03"); + job_pack_tx(coind, templ->coinb2, available, NULL); + } + + base58_decode("HU9t1QEp5J8udekCqFUEajD5TeigPqtfDZ", script_payee); + job_pack_tx(coind, templ->coinb2, 2 * 100000000, script_payee); + + base58_decode("HLFmojjH6qLBTh5EXtbY9j9v4BCkNpmt95", script_payee); + job_pack_tx(coind, templ->coinb2, 1.5 * 100000000, script_payee); + + strcat(templ->coinb2, "00000000"); // locktime + coind->reward = (double)available/100000000*coind->reward_mul; + + return; + } + else if(strcmp(coind->symbol, "LTCR") == 0) { if (coind->charity_percent <= 0) coind->charity_percent = 10; if (strlen(coind->charity_address) == 0) sprintf(coind->charity_address, "BCDrF1hWdKTmrjXXVFTezPjKBmGigmaXg5"); } - else if(strcmp(coind->symbol, "XZC") == 0) { - char script_payee[1024]; - if (coind->charity_percent <= 0) - coind->charity_percent = 25; // wrong coinbase 40 instead of 40 + 10 = 50 - - json_int_t charity_amount = (available * coind->charity_percent) / 100; + else if(strcmp(coind->symbol, "GEEK") == 0) { + if (coind->charity_percent <= 0) + coind->charity_percent = 2.5; if (strlen(coind->charity_address) == 0) - sprintf(coind->charity_address, "aHu897ivzmeFuLNB6956X6gyGeVNHUBRgD"); + sprintf(coind->charity_address, "GRpdbSh3Z2FMjJH96CFPK5TzEb47Zg6FFR"); + } - strcat(templ->coinb2, "06"); - job_pack_tx(coind, templ->coinb2, available, NULL); - base58_decode("aCAgTPgtYcA4EysU4UKC86EQd5cTtHtCcr", script_payee); - job_pack_tx(coind, templ->coinb2, charity_amount/5, script_payee); - base58_decode(coind->charity_address, script_payee); // may change - job_pack_tx(coind, templ->coinb2, charity_amount/5, script_payee); - base58_decode("aQ18FBVFtnueucZKeVg4srhmzbpAeb1KoN", script_payee); - job_pack_tx(coind, templ->coinb2, charity_amount/5, script_payee); - base58_decode("a1HwTdCmQV3NspP2QqCGpehoFpi8NY4Zg3", script_payee); - job_pack_tx(coind, templ->coinb2, charity_amount/5, script_payee); - base58_decode("a1kCCGddf5pMXSipLVD9hBG2MGGVNaJ15U", script_payee); - job_pack_tx(coind, templ->coinb2, charity_amount/5, script_payee); - strcat(templ->coinb2, "00000000"); // locktime + else if(strcmp(coind->symbol, "XZC") == 0) { + char script_payee[1024]; + bool znode_masternode_enabled = json_get_bool(json_result, "znode_payments_started"); + if (znode_masternode_enabled == true) { + json_value* znode_masternode = json_get_object(json_result, "znode"); + const char *payee = json_get_string(znode_masternode, "payee"); + json_int_t amount = json_get_int(znode_masternode, "amount"); + if (payee && amount) { + //debuglog("znode payee: %s\n", payee); + strcat(templ->coinb2, "06"); + job_pack_tx(coind, templ->coinb2, available, NULL); + base58_decode(payee, script_payee); + job_pack_tx(coind, templ->coinb2, amount, script_payee); + } + } else { + strcat(templ->coinb2, "06"); + job_pack_tx(coind, templ->coinb2, available, NULL); + } + base58_decode("aCAgTPgtYcA4EysU4UKC86EQd5cTtHtCcr", script_payee); + job_pack_tx(coind, templ->coinb2, 1 * 100000000, script_payee); + base58_decode("aHu897ivzmeFuLNB6956X6gyGeVNHUBRgD", script_payee); + job_pack_tx(coind, templ->coinb2, 1 * 100000000, script_payee); + base58_decode("aQ18FBVFtnueucZKeVg4srhmzbpAeb1KoN", script_payee); + job_pack_tx(coind, templ->coinb2, 1 * 100000000, script_payee); + base58_decode("a1HwTdCmQV3NspP2QqCGpehoFpi8NY4Zg3", script_payee); + job_pack_tx(coind, templ->coinb2, 3 * 100000000, script_payee); + base58_decode("a1kCCGddf5pMXSipLVD9hBG2MGGVNaJ15U", script_payee); + job_pack_tx(coind, templ->coinb2, 1 * 100000000, script_payee); + strcat(templ->coinb2, "00000000"); // locktime + coind->reward = (double)available/100000000*coind->reward_mul; + return; + } - coind->reward = (double)available/100000000*coind->reward_mul; - return; - } else if(strcmp("DCR", coind->rpcencoding) == 0) { coind->reward_mul = 6; // coinbase value is wrong, reward_mul should be 6 coind->charity_percent = 0; @@ -226,6 +379,65 @@ void coinbase_create(YAAMP_COIND *coind, YAAMP_JOB_TEMPLATE *templ, json_value * if (strlen(coind->charity_address) == 0 && !strcmp(coind->symbol, "DCR")) sprintf(coind->charity_address, "Dcur2mcGjmENx4DhNqDctW5wJCVyT3Qeqkx"); } + + else if(strcmp(coind->symbol, "HXX") == 0) { + char script_payee[1024]; + bool znode_masternode_enabled = json_get_bool(json_result, "xnode_payments_started"); + if (znode_masternode_enabled == true) { + json_value* znode_masternode = json_get_object(json_result, "xnode"); + const char *payee = json_get_string(znode_masternode, "payee"); + json_int_t amount = json_get_int(znode_masternode, "amount"); + if (payee && amount) { + //debuglog("bznode payee: %s\n", payee); + strcat(templ->coinb2, "06"); + job_pack_tx(coind, templ->coinb2, available, NULL); + base58_decode(payee, script_payee); + job_pack_tx(coind, templ->coinb2, amount, script_payee); + } + } else { + strcat(templ->coinb2, "05"); + job_pack_tx(coind, templ->coinb2, available, NULL); + } + base58_decode("HE7NSv3jevUAPjwsLGpoYSz9ftzV9S36Xq", script_payee); + job_pack_tx(coind, templ->coinb2, 0.1 * 100000000, script_payee); + base58_decode("HNdzbEtifr2nTd3VBvUWqJLc35ZFXr2EYo", script_payee); + job_pack_tx(coind, templ->coinb2, 0.1 * 100000000, script_payee); + base58_decode("HG1utYiVhkgBNz5ezrVpsjABxmMdVdcQe5", script_payee); + job_pack_tx(coind, templ->coinb2, 0.1 * 100000000, script_payee); + base58_decode("H94j1zMAbWwHWcEq8hUogAMALpVzj34M6Q", script_payee); + job_pack_tx(coind, templ->coinb2, 0.3 * 100000000, script_payee); + strcat(templ->coinb2, "00000000"); // locktime + coind->reward = (double)available/100000000*coind->reward_mul; + return; + } + + else if(strcmp(coind->symbol, "BZX") == 0) { + char script_payee[1024]; + bool znode_masternode_enabled = json_get_bool(json_result, "bznode_payments_started"); + if (znode_masternode_enabled == true) { + json_value* znode_masternode = json_get_object(json_result, "bznode"); + const char *payee = json_get_string(znode_masternode, "payee"); + json_int_t amount = json_get_int(znode_masternode, "amount"); + if (payee && amount) { + //debuglog("bznode payee: %s\n", payee); + strcat(templ->coinb2, "04"); + job_pack_tx(coind, templ->coinb2, available, NULL); + base58_decode(payee, script_payee); + job_pack_tx(coind, templ->coinb2, amount, script_payee); + } + } else { + strcat(templ->coinb2, "03"); + job_pack_tx(coind, templ->coinb2, available, NULL); + } + base58_decode("XWfdnGbXnBxeegrPJEvnYaNuwf6DXCruMX", script_payee); + job_pack_tx(coind, templ->coinb2, 6.75 * 100000000, script_payee); + base58_decode("XQ4WEZTFP83gVhhLBKavwopz7U84JucR8w", script_payee); + job_pack_tx(coind, templ->coinb2, 2.25 * 100000000, script_payee); + strcat(templ->coinb2, "00000000"); // locktime + coind->reward = (double)available/100000000*coind->reward_mul; + return; + } + else if(strcmp(coind->symbol, "STAK") == 0) { char script_payee[512] = { 0 }; char payees[4]; @@ -285,6 +497,136 @@ void coinbase_create(YAAMP_COIND *coind, YAAMP_JOB_TEMPLATE *templ, json_value * coind->reward = (double)available / 100000000 * coind->reward_mul; return; } + else if(strcmp(coind->symbol, "TUX") == 0) { + char script_payee[1024]; + char charity_payee[256] = { 0 }; + const char *payee = json_get_string(json_result, "donation_payee"); + if(payee != NULL){ + sprintf(coind->charity_address, "%s", payee); + } else { + sprintf(coind->charity_address, "%s", ""); + } + + if(strlen(coind->charity_address) > 0){ + char script_payee[1024]; + char charity_payee[256] = { 0 }; + sprintf(charity_payee, "%s", coind->charity_address); + if (strlen(charity_payee) == 0) + stratumlog("ERROR %s has no charity_address set!\n", coind->name); + + base58_decode(charity_payee, script_payee); + + json_int_t charity_amount = json_get_int(json_result, "donation_amount"); + coind->charity_amount = charity_amount; + + if (templ->has_segwit_txs) { + strcat(templ->coinb2, "03"); // 3 outputs (nulldata + fees + miner) + strcat(templ->coinb2, commitment); + } else { + strcat(templ->coinb2, "02"); + } + job_pack_tx(coind, templ->coinb2, available, NULL); + + char echarity_amount[32]; + encode_tx_value(echarity_amount, charity_amount); + strcat(templ->coinb2, echarity_amount); + char coinb2_part[1024] = { 0 }; + char coinb2_len[3] = { 0 }; + sprintf(coinb2_part, "a9%02x%s87", (unsigned int)(strlen(script_payee) >> 1) & 0xFF, script_payee); + sprintf(coinb2_len, "%02x", (unsigned int)(strlen(coinb2_part) >> 1) & 0xFF); + strcat(templ->coinb2, coinb2_len); + strcat(templ->coinb2, coinb2_part); + debuglog("pack tx %s\n", coinb2_part); + strcat(templ->coinb2, "00000000"); // locktime + + coind->reward = (double)available/100000000*coind->reward_mul; + //debuglog("INFO %s block available %f, charity %f miner %f\n", coind->symbol, + // (double) available/1e8, (double) charity_amount/1e8, coind->reward); + return; + } + } + + else if(strcmp(coind->symbol, "PGN") == 0) { + bool founder_enabled = json_get_bool(json_result, "founder_payments_started"); + json_value* founder = json_get_object(json_result, "founder"); + + if (!coind->hasmasternodes && founder_enabled && founder) { + char founder_payee[256] = { 0 }; + char founder_script[1024] = { 0}; + const char *payee = json_get_string(founder, "payee"); + bool founder_use_p2sh = (strcmp(coind->symbol, "PGN") == 0); + json_int_t amount = json_get_int(founder, "amount"); + if(payee && amount) { + if (payee) snprintf(founder_payee, 255, "%s", payee); + if (strlen(founder_payee) == 0) + stratumlog("ERROR %s has no charity_address set!\n", coind->name); + base58_decode(founder_payee, founder_script); + available -= amount; + + if (templ->has_segwit_txs) { + strcat(templ->coinb2, "03"); // 3 outputs (nulldata + fees + miner) + strcat(templ->coinb2, commitment); + } else { + strcat(templ->coinb2, "02"); + } + job_pack_tx(coind, templ->coinb2, available, NULL); + if(founder_use_p2sh) { + p2sh_pack_tx(coind, templ->coinb2, amount, founder_script); + } else { + job_pack_tx(coind, templ->coinb2, amount, founder_script); + } + strcat(templ->coinb2, "00000000"); // locktime + + coind->reward = (double)available/100000000*coind->reward_mul; + debuglog("%s founder address %s, amount %lld\n", coind->symbol,founder_payee, amount); + debuglog("%s founder script %s\n", coind->symbol,founder_script); + debuglog("%s scripts %s\n", coind->symbol, templ->coinb2); + + return; + } + } +} + + else if(strcmp(coind->symbol, "RITO") == 0) { + bool founder_enabled = json_get_bool(json_result, "founder_payments_started"); + json_value* founder = json_get_object(json_result, "founder"); + + if (!coind->hasmasternodes && founder_enabled && founder) { + char founder_payee[256] = { 0 }; + char founder_script[1024] = { 0}; + const char *payee = json_get_string(founder, "payee"); + bool founder_use_p2sh = (strcmp(coind->symbol, "RITO") == 0); + json_int_t amount = json_get_int(founder, "amount"); + if(payee && amount) { + if (payee) snprintf(founder_payee, 255, "%s", payee); + if (strlen(founder_payee) == 0) + stratumlog("ERROR %s has no charity_address set!\n", coind->name); + base58_decode(founder_payee, founder_script); + available -= amount; + + if (templ->has_segwit_txs) { + strcat(templ->coinb2, "03"); // 3 outputs (nulldata + fees + miner) + strcat(templ->coinb2, commitment); + } else { + strcat(templ->coinb2, "02"); + } + job_pack_tx(coind, templ->coinb2, available, NULL); + if(founder_use_p2sh) { + p2sh_pack_tx(coind, templ->coinb2, amount, founder_script); + } else { + job_pack_tx(coind, templ->coinb2, amount, founder_script); + } + strcat(templ->coinb2, "00000000"); // locktime + + coind->reward = (double)available/100000000*coind->reward_mul; + debuglog("%s founder address %s, amount %lld\n", coind->symbol,founder_payee, amount); + debuglog("%s founder script %s\n", coind->symbol,founder_script); + debuglog("%s scripts %s\n", coind->symbol, templ->coinb2); + + return; + } + } +} // 2 txs are required on these coins, one for foundation (dev fees) if(coind->charity_percent && !coind->hasmasternodes) @@ -329,6 +671,420 @@ void coinbase_create(YAAMP_COIND *coind, YAAMP_JOB_TEMPLATE *templ, json_value * return; } + // add IFX + if (strcmp(coind->symbol, "IFX") == 0) +{ + char payees[4]; + int npayees = 1; + char script_dests[4096] = { 0 }; + // + json_value* founderreward = json_get_array(json_result, "founderreward"); + if (founderreward) + { + const char *payee = json_get_string(founderreward, "founderpayee"); + json_int_t amount = json_get_int(founderreward, "amount"); + if (payee && amount) + { + char script_payee[128] = { 0 }; + npayees++; + available -= amount; + base58_decode(payee, script_payee); + job_pack_tx(coind, script_dests, amount, script_payee); + } + } + json_value* masternode = json_get_object(json_result, "masternode"); + bool masternode_enabled = json_get_bool(json_result, "masternode_payments_enforced"); + if (masternode_enabled && masternode) + { + bool started = json_get_bool(json_result, "masternode_payments_started"); + const char *payee = json_get_string(masternode, "payee"); + json_int_t amount = json_get_int(masternode, "amount"); + if (started && payee && amount) { + char script_payee[128] = { 0 }; + npayees++; + available -= amount; + base58_decode(payee, script_payee); + job_pack_tx(coind, script_dests, amount, script_payee); + } + } + sprintf(payees, "%02x", npayees); + strcat(templ->coinb2, payees); + strcat(templ->coinb2, script_dests); + job_pack_tx(coind, templ->coinb2, available, NULL); + strcat(templ->coinb2, "00000000"); // locktime + coind->reward = (double)available / 100000000 * coind->reward_mul; + return; + } + + // add GTM + if (strcmp(coind->symbol, "GTM") == 0) +{ + char payees[4]; + int npayees = 1; + char script_dests[4096] = { 0 }; + // + json_value* founderreward = json_get_array(json_result, "founderreward"); + if (founderreward) + { + const char *payee = json_get_string(founderreward, "founderpayee"); + json_int_t amount = json_get_int(founderreward, "amount"); + if (payee && amount) + { + char script_payee[128] = { 0 }; + npayees++; + available -= amount; + base58_decode(payee, script_payee); + job_pack_tx(coind, script_dests, amount, script_payee); + } + } + json_value* masternode = json_get_object(json_result, "masternode"); + bool masternode_enabled = json_get_bool(json_result, "masternode_payments_enforced"); + if (masternode_enabled && masternode) + { + bool started = json_get_bool(json_result, "masternode_payments_started"); + const char *payee = json_get_string(masternode, "payee"); + json_int_t amount = json_get_int(masternode, "amount"); + if (started && payee && amount) { + char script_payee[128] = { 0 }; + npayees++; + available -= amount; + base58_decode(payee, script_payee); + job_pack_tx(coind, script_dests, amount, script_payee); + } + } + sprintf(payees, "%02x", npayees); + strcat(templ->coinb2, payees); + strcat(templ->coinb2, script_dests); + job_pack_tx(coind, templ->coinb2, available, NULL); + strcat(templ->coinb2, "00000000"); // locktime + coind->reward = (double)available / 100000000 * coind->reward_mul; + return; + } + + // add GWAY + if (strcmp(coind->symbol, "GWAY") == 0) +{ + char payees[4]; + int npayees = 1; + char script_dests[4096] = { 0 }; + // + json_value* founderreward = json_get_array(json_result, "founderreward"); + if (founderreward) + { + const char *payee = json_get_string(founderreward, "founderpayee"); + json_int_t amount = json_get_int(founderreward, "amount"); + if (payee && amount) + { + char script_payee[128] = { 0 }; + npayees++; + available -= amount; + base58_decode(payee, script_payee); + job_pack_tx(coind, script_dests, amount, script_payee); + } + } + json_value* masternode = json_get_object(json_result, "masternode"); + bool masternode_enabled = json_get_bool(json_result, "masternode_payments_enforced"); + if (masternode_enabled && masternode) + { + bool started = json_get_bool(json_result, "masternode_payments_started"); + const char *payee = json_get_string(masternode, "payee"); + json_int_t amount = json_get_int(masternode, "amount"); + if (started && payee && amount) { + char script_payee[128] = { 0 }; + npayees++; + available -= amount; + base58_decode(payee, script_payee); + job_pack_tx(coind, script_dests, amount, script_payee); + } + } + sprintf(payees, "%02x", npayees); + strcat(templ->coinb2, payees); + strcat(templ->coinb2, script_dests); + job_pack_tx(coind, templ->coinb2, available, NULL); + strcat(templ->coinb2, "00000000"); // locktime + coind->reward = (double)available / 100000000 * coind->reward_mul; + return; + } + + if (strcmp(coind->symbol, "AGM") == 0) +{ + char payees[4]; + int npayees = 1; + char script_dests[4096] = { 0 }; + // + json_value* founderreward = json_get_array(json_result, "founderreward"); + if (founderreward) + { + const char *payee = json_get_string(founderreward, "founderpayee"); + json_int_t amount = json_get_int(founderreward, "amount"); + if (payee && amount) + { + char script_payee[128] = { 0 }; + npayees++; + available -= amount; + base58_decode(payee, script_payee); + job_pack_tx(coind, script_dests, amount, script_payee); + } + } + json_value* masternode = json_get_object(json_result, "masternode"); + bool masternode_enabled = json_get_bool(json_result, "masternode_payments_enforced"); + if (masternode_enabled && masternode) + { + bool started = json_get_bool(json_result, "masternode_payments_started"); + const char *payee = json_get_string(masternode, "payee"); + json_int_t amount = json_get_int(masternode, "amount"); + if (started && payee && amount) { + char script_payee[128] = { 0 }; + npayees++; + available -= amount; + base58_decode(payee, script_payee); + job_pack_tx(coind, script_dests, amount, script_payee); + } + } + sprintf(payees, "%02x", npayees); + strcat(templ->coinb2, payees); + strcat(templ->coinb2, script_dests); + job_pack_tx(coind, templ->coinb2, available, NULL); + strcat(templ->coinb2, "00000000"); // locktime + coind->reward = (double)available / 100000000 * coind->reward_mul; + return; + } + + // add CRDS + if (strcmp(coind->symbol, "CRDS") == 0) +{ + char payees[4]; + int npayees = 1; + char script_dests[4096] = { 0 }; + // + json_value* founderreward = json_get_array(json_result, "founderreward"); + if (founderreward) + { + const char *payee = json_get_string(founderreward, "founderpayee"); + json_int_t amount = json_get_int(founderreward, "amount"); + if (payee && amount) + { + char script_payee[128] = { 0 }; + npayees++; + available -= amount; + base58_decode(payee, script_payee); + job_pack_tx(coind, script_dests, amount, script_payee); + } + } + json_value* masternode = json_get_object(json_result, "masternode"); + bool masternode_enabled = json_get_bool(json_result, "masternode_payments_enforced"); + if (masternode_enabled && masternode) + { + bool started = json_get_bool(json_result, "masternode_payments_started"); + const char *payee = json_get_string(masternode, "payee"); + json_int_t amount = json_get_int(masternode, "amount"); + if (started && payee && amount) { + char script_payee[128] = { 0 }; + npayees++; + available -= amount; + base58_decode(payee, script_payee); + job_pack_tx(coind, script_dests, amount, script_payee); + } + } + sprintf(payees, "%02x", npayees); + strcat(templ->coinb2, payees); + strcat(templ->coinb2, script_dests); + job_pack_tx(coind, templ->coinb2, available, NULL); + strcat(templ->coinb2, "00000000"); // locktime + coind->reward = (double)available / 100000000 * coind->reward_mul; + return; + } + + // add BMN + if (strcmp(coind->symbol, "BMN") == 0) +{ + char payees[4]; + int npayees = 1; + char script_dests[4096] = { 0 }; + // + json_value* founderreward = json_get_array(json_result, "founderreward"); + if (founderreward) + { + const char *payee = json_get_string(founderreward, "founderpayee"); + json_int_t amount = json_get_int(founderreward, "amount"); + if (payee && amount) + { + char script_payee[128] = { 0 }; + npayees++; + available -= amount; + base58_decode(payee, script_payee); + job_pack_tx(coind, script_dests, amount, script_payee); + } + } + json_value* masternode = json_get_object(json_result, "masternode"); + bool masternode_enabled = json_get_bool(json_result, "masternode_payments_enforced"); + if (masternode_enabled && masternode) + { + bool started = json_get_bool(json_result, "masternode_payments_started"); + const char *payee = json_get_string(masternode, "payee"); + json_int_t amount = json_get_int(masternode, "amount"); + if (started && payee && amount) { + char script_payee[128] = { 0 }; + npayees++; + available -= amount; + base58_decode(payee, script_payee); + job_pack_tx(coind, script_dests, amount, script_payee); + } + } + sprintf(payees, "%02x", npayees); + strcat(templ->coinb2, payees); + strcat(templ->coinb2, script_dests); + job_pack_tx(coind, templ->coinb2, available, NULL); + strcat(templ->coinb2, "00000000"); // locktime + coind->reward = (double)available / 100000000 * coind->reward_mul; + return; + } + + //add GLT + else if(strcmp(coind->symbol, "GLT") == 0) + { + char script_dests[2048] = { 0 }; + char script_payee[128] = { 0 }; + char script_treasury[128] = { 0 }; + char payees[4]; + int npayees = 1; + bool masternode_enabled = json_get_bool(json_result, "masternode_payments_enforced"); + json_value* masternode = json_get_object(json_result, "masternode"); + json_value* treasury = json_get_object(json_result, "treasury"); + bool treasury_enabled = true; + if(treasury_enabled && treasury) { + const char *scriptPubKey = json_get_string(treasury, "scriptPubKey"); + json_int_t amount = json_get_int(treasury, "amount"); + if (scriptPubKey && amount) { + npayees++; + available -= amount; + base58_decode(scriptPubKey, script_treasury); + job_pack_tx(coind, script_dests, amount, script_treasury); + //debuglog("%s treasury %u\n", coind->symbol, amount); + } + } + if (masternode_enabled && masternode) { + const char *payee = json_get_string(masternode, "payee"); + json_int_t amount = json_get_int(masternode, "amount"); + if (payee && amount) { + npayees++; + available -= amount; + base58_decode(payee, script_payee); + job_pack_tx(coind, script_dests, amount, script_payee); + } + } + sprintf(payees, "%02x", npayees); + strcat(templ->coinb2, payees); + strcat(templ->coinb2, script_dests); + job_pack_tx(coind, templ->coinb2, available, NULL); + strcat(templ->coinb2, "00000000"); // locktime + coind->reward = (double)available/100000000*coind->reward_mul; + //debuglog("%s %d dests %s\n", coind->symbol, npayees, script_dests); + return; + } + + // Add DigitalNote[XDN] + if(strcmp(coind->symbol, "XDN") == 0) { + + // make sure we pay both mn and devops + bool founder_enabled = json_get_bool(json_result, "founder_reward_enforced"); + bool masternode_enabled = json_get_bool(json_result, "enforce_masternode_payments"); + if (!founder_enabled || !masternode_enabled) + return; + + // founder/masternode vars + char founder_script[1024] = { 0}; + char masternode_script[1024] = { 0}; + char founder_payee[256] = { 0}; + char masternode_payee[256] = { 0}; + json_int_t part_amount = (5000000000); + json_int_t pool_amount = (5000000000*4); + json_value* founder = json_get_object(json_result, "founderreward"); + const char *payee1 = json_get_string(json_result, "payee"); + const char *payee2 = json_get_string(founder, "payee"); + + // mn script + snprintf(masternode_payee, 255, "%s", payee1); + base58_decode(masternode_payee, masternode_script); + available -= part_amount; + + // payee script + snprintf(founder_payee, 255, "%s", payee2); + base58_decode(founder_payee, founder_script); + available -= part_amount; + + // total outputs + strcat(templ->coinb2, "03"); + + // pack the tx + job_pack_tx(coind, templ->coinb2, available, NULL); + job_pack_tx(coind, templ->coinb2, part_amount, founder_script); + job_pack_tx(coind, templ->coinb2, part_amount, masternode_script); + strcat(templ->coinb2, "00000000"); + coind->reward = (double)available/100000000*coind->reward_mul; + return; + } + + if(strcmp(coind->symbol, "SIN") == 0) + { + int npayees = 1; + char payees[2]; + char sinpayee[256] = {0}; + char sinscript[1024] = {0}; + char devpayee[256] = {0}; + char devscript[1024] = {0}; + const char *devpayaddr = json_get_string(json_result, "payee"); + json_int_t devfee_amount = json_get_int(json_result, "payee_amount"); + snprintf(devpayee, 255, "%s", devpayaddr); + base58_decode(devpayee, devscript); + npayees++; + + available -= devfee_amount; + const char* mnpayaddrs[7] = {0}; + json_value* masternodes = json_get_array(json_result, "masternode"); + json_int_t mnamounts[7] = {0}; + for(int i = 0; i < masternodes->u.array.length; i++) { + mnpayaddrs[i] = json_get_string(masternodes->u.array.values[i], "payee"); + mnamounts[i] = json_get_int(masternodes->u.array.values[i], "amount"); + available -= mnamounts[i]; + npayees++; + } + + sprintf(payees, "%02x", npayees); + strcat(templ->coinb2, payees); + job_pack_tx(coind, templ->coinb2, available, NULL); + job_pack_tx(coind, templ->coinb2, devfee_amount, devscript); + for(int i = 0; i < masternodes->u.array.length; i++) { + snprintf(sinpayee, 255, "%s", mnpayaddrs[i]); + base58_decode(sinpayee, sinscript); + job_pack_tx(coind, templ->coinb2, mnamounts[i], sinscript); + } + + strcat(templ->coinb2, "00000000"); + coind->reward = (double)available/100000000; + return; + } + + if(strcmp(coind->symbol, "BITC") == 0) + { + char *params = (char *)malloc(1024); + if (params) { + sprintf(params, "[\"%s\", %i]", coind->wallet, templ->height); + //std::cout << "Params:" << params << std::endl; + json_value *json = rpc_call(&coind->rpc, "createcoinbaseforaddress", params); + free(params); + if (json) { + json_value *json_result = json_get_object(json, "result"); + if (json_result) { + sprintf(templ->coinb1, "%s", json_get_string(json_result, "coinbasepart1")); + templ->coinb1[strlen(templ->coinb1) - 16] = '\0'; + sprintf(templ->coinb2, "%s", json_get_string(json_result, "coinbasepart2")); + } + } + } + return; + } + if(strcmp(coind->symbol, "XVC") == 0) { char charity_payee[256]; @@ -375,19 +1131,19 @@ void coinbase_create(YAAMP_COIND *coind, YAAMP_JOB_TEMPLATE *templ, json_value * return; } if(coind->charity_percent) { - char charity_payee[256] = { 0 }; - const char *payee = json_get_string(json_result, "payee"); - if (payee) snprintf(charity_payee, 255, "%s", payee); - else sprintf(charity_payee, "%s", coind->charity_address); - if (strlen(charity_payee) == 0) - stratumlog("ERROR %s has no charity_address set!\n", coind->name); - json_int_t charity_amount = (available * coind->charity_percent) / 100; - npayees++; - available -= charity_amount; - coind->charity_amount = charity_amount; - base58_decode(charity_payee, script_payee); - job_pack_tx(coind, script_dests, charity_amount, script_payee); - } + char charity_payee[256] = { 0 }; + const char *payee = json_get_string(json_result, "payee"); + if (payee) snprintf(charity_payee, 255, "%s", payee); + else sprintf(charity_payee, "%s", coind->charity_address); + if (strlen(charity_payee) == 0) + stratumlog("ERROR %s has no charity_address set!\n", coind->name); + json_int_t charity_amount = (available * coind->charity_percent) / 100; + npayees++; + available -= charity_amount; + coind->charity_amount = charity_amount; + base58_decode(charity_payee, script_payee); + job_pack_tx(coind, script_dests, charity_amount, script_payee); + } // smart contracts balance refund, same format as DASH superblocks json_value* screfund = json_get_array(json_result, "screfund"); if(screfund && screfund->u.array.length) { @@ -397,8 +1153,14 @@ void coinbase_create(YAAMP_COIND *coind, YAAMP_JOB_TEMPLATE *templ, json_value * if(superblocks_enabled && superblock) { for(int i = 0; i < superblock->u.array.length; i++) { const char *payee = json_get_string(superblock->u.array.values[i], "payee"); + const char *script = json_get_string(superblock->u.array.values[i], "script"); json_int_t amount = json_get_int(superblock->u.array.values[i], "amount"); - if (payee && amount) { + if (!amount) continue; + if (script) { + npayees++; + available -= amount; + script_pack_tx(coind, script_dests, amount, script); + } else if (payee) { npayees++; available -= amount; base58_decode(payee, script_payee); @@ -411,19 +1173,44 @@ void coinbase_create(YAAMP_COIND *coind, YAAMP_JOB_TEMPLATE *templ, json_value * } } } - if (masternode_enabled && masternode) { - bool started = json_get_bool(json_result, "masternode_payments_started"); - const char *payee = json_get_string(masternode, "payee"); - json_int_t amount = json_get_int(masternode, "amount"); - if (payee && amount && started) { - npayees++; - available -= amount; - base58_decode(payee, script_payee); - bool masternode_use_p2sh = (strcmp(coind->symbol, "MAC") == 0); - if(masternode_use_p2sh) - p2sh_pack_tx(coind, script_dests, amount, script_payee); - else - job_pack_tx(coind, script_dests, amount, script_payee); + + bool started = json_get_bool(json_result, "masternode_payments_started"); + if (masternode_enabled && masternode && started) { + if (json_is_array(masternode)) { + for(int i = 0; i < masternode->u.array.length; i++) { + const char *payee = json_get_string(masternode->u.array.values[i], "payee"); + const char *script = json_get_string(masternode->u.array.values[i], "script"); + json_int_t amount = json_get_int(masternode->u.array.values[i], "amount"); + if (!amount) continue; + if (script) { + npayees++; + available -= amount; + script_pack_tx(coind, script_dests, amount, script); + } else if (payee) { + npayees++; + available -= amount; + base58_decode(payee, script_payee); + bool masternode_use_p2sh = (strcmp(coind->symbol, "MAC") == 0); + if(masternode_use_p2sh) + p2sh_pack_tx(coind, script_dests, amount, script_payee); + else + job_pack_tx(coind, script_dests, amount, script_payee); + //debuglog("%s masternode %s %u\n", coind->symbol, payee, amount); + } + } + } else { + const char *payee = json_get_string(masternode, "payee"); + json_int_t amount = json_get_int(masternode, "amount"); + if (payee && amount) { + npayees++; + available -= amount; + base58_decode(payee, script_payee); + bool masternode_use_p2sh = (strcmp(coind->symbol, "MAC") == 0); + if(masternode_use_p2sh) + p2sh_pack_tx(coind, script_dests, amount, script_payee); + else + job_pack_tx(coind, script_dests, amount, script_payee); + } } } sprintf(payees, "%02x", npayees); @@ -432,6 +1219,13 @@ void coinbase_create(YAAMP_COIND *coind, YAAMP_JOB_TEMPLATE *templ, json_value * strcat(templ->coinb2, script_dests); job_pack_tx(coind, templ->coinb2, available, NULL); strcat(templ->coinb2, "00000000"); // locktime + if(coinbase_payload && strlen(coinbase_payload) > 0) { + char coinbase_payload_size[18]; + ser_compactsize((unsigned int)(strlen(coinbase_payload) >> 1), coinbase_payload_size); + strcat(templ->coinb2, coinbase_payload_size); + strcat(templ->coinb2, coinbase_payload); + } + coind->reward = (double)available/100000000*coind->reward_mul; //debuglog("%s total %u available %u\n", coind->symbol, templ->value, available); //debuglog("%s %d dests %s\n", coind->symbol, npayees, script_dests); @@ -607,7 +1401,9 @@ void coinbase_create(YAAMP_COIND *coind, YAAMP_JOB_TEMPLATE *templ, json_value * //if(coind->txmessage) // strcat(templ->coinb2, "00"); - + if(strcmp(coind->symbol, "DEM") == 0){if(coind->txmessage){strcat(templ->coinb2, "00");}} //fixes eMark. + if(strcmp(coind->symbol, "FLO") == 0){if(coind->txmessage){strcat(templ->coinb2, "00");}} //fixes FlorinCoin + if(strcmp(coind->symbol, "GIO") == 0){if(coind->txmessage){strcat(templ->coinb2, "00");}} //fixes GravioCoin strcat(templ->coinb2, "00000000"); // locktime coind->reward = (double)available/100000000*coind->reward_mul; @@ -617,6 +1413,3 @@ void coinbase_create(YAAMP_COIND *coind, YAAMP_JOB_TEMPLATE *templ, json_value * // debuglog("coinb1 %s\n", templ->coinb1); // debuglog("coinb2 %s\n", templ->coinb2); } - - - diff --git a/stratum/coind.cpp b/stratum/coind.cpp index 1eb83a30f..febc4ce42 100644 --- a/stratum/coind.cpp +++ b/stratum/coind.cpp @@ -115,11 +115,8 @@ bool coind_validate_address(YAAMP_COIND *coind) sprintf(params, "[\"%s\"]", coind->wallet); json_value *json; - bool getaddressinfo = ((strcmp(coind->symbol,"DGB") == 0) || (strcmp(coind->symbol2, "DGB") == 0)); - if(getaddressinfo) - json = rpc_call(&coind->rpc, "getaddressinfo", params); - else - json = rpc_call(&coind->rpc, "validateaddress", params); + bool getaddressinfo = false; + json = rpc_call(&coind->rpc, "validateaddress", params); if(!json) return false; json_value *json_result = json_get_object(json, "result"); @@ -129,6 +126,20 @@ bool coind_validate_address(YAAMP_COIND *coind) return false; } + if(!json_get_bool(json_result, "ismine")) + { + stratumlog("%s wallet is using getaddressinfo.\n", coind->name); + getaddressinfo = true; + json = rpc_call(&coind->rpc, "getaddressinfo", params); + + json_result = json_get_object(json, "result"); + if(!json_result) + { + json_value_free(json); + return false; + } + } + bool isvalid = getaddressinfo || json_get_bool(json_result, "isvalid"); if(!isvalid) stratumlog("%s wallet %s is not valid.\n", coind->name, coind->wallet); @@ -179,9 +190,9 @@ void coind_init(YAAMP_COIND *coind) bool valid = coind_validate_address(coind); if(valid) return; - sprintf(params, "[\"%s\"]", account); + sprintf(params, "[\"legacy\"]", account); - json_value *json = rpc_call(&coind->rpc, "getaccountaddress", params); + json_value *json = rpc_call(&coind->rpc, "getrawchangeaddress", params); if(!json) { json = rpc_call(&coind->rpc, "getaddressesbyaccount", params); @@ -260,9 +271,3 @@ void coind_terminate(YAAMP_COIND *coind) // coind_terminate(coind); //} - - - - - - diff --git a/stratum/coind_submit.cpp b/stratum/coind_submit.cpp index f1f8b6f7f..6089494a9 100644 --- a/stratum/coind_submit.cpp +++ b/stratum/coind_submit.cpp @@ -140,6 +140,9 @@ bool coind_submitgetauxblock(YAAMP_COIND *coind, const char *hash, const char *b json_value *json_result = json_get_object(json, "result"); bool b = json_result && json_result->type == json_boolean && json_result->u.boolean; + // some auxpow coins return error:null, result: null on success + if(!b) + b=json_result && json_result->type == json_null; json_value_free(json); return b; diff --git a/stratum/coind_template.cpp b/stratum/coind_template.cpp index 33ecc6259..114f8d10d 100644 --- a/stratum/coind_template.cpp +++ b/stratum/coind_template.cpp @@ -307,6 +307,7 @@ YAAMP_JOB_TEMPLATE *coind_create_template(YAAMP_COIND *coind) strcpy(templ->prevhash_hex, prev ? prev : ""); const char *flags = json_get_string(json_coinbaseaux, "flags"); strcpy(templ->flags, flags ? flags : ""); + strcpy(templ->priceinfo, ""); // LBC Claim Tree (with wallet gbt patch) const char *claim = json_get_string(json_result, "claimtrie"); @@ -332,6 +333,13 @@ YAAMP_JOB_TEMPLATE *coind_create_template(YAAMP_COIND *coind) debuglog("claim_hex: %s\n", templ->claim_hex); } } + else if (strcmp(coind->symbol, "BITC") == 0) { + if (strlen(json_get_string(json_result, "priceinfo")) < 1000) { + templ->needpriceinfo = json_get_bool(json_result, "needpriceinfo"); + if (templ->needpriceinfo) + strcpy(templ->priceinfo, json_get_string(json_result, "priceinfo")); + } + } const char *sc_root = json_get_string(json_result, "stateroot"); const char *sc_utxo = json_get_string(json_result, "utxoroot"); diff --git a/stratum/config.sample/argon2d-crds.conf b/stratum/config.sample/argon2d-crds.conf new file mode 100644 index 000000000..c1d95ed33 --- /dev/null +++ b/stratum/config.sample/argon2d-crds.conf @@ -0,0 +1,15 @@ +[TCP] +server = yaamp.com +port = 4238 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = argon2d-crds +difficulty = 2.0 +max_ttf = 400000000 \ No newline at end of file diff --git a/stratum/config.sample/argon2m.conf b/stratum/config.sample/argon2m.conf new file mode 100644 index 000000000..d7631b0b5 --- /dev/null +++ b/stratum/config.sample/argon2m.conf @@ -0,0 +1,16 @@ +[TCP] +server = yaamp.com +port = 4234 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = argon2m +difficulty = 4 +max_ttf = 40000 + diff --git a/stratum/config.sample/astralhash.conf b/stratum/config.sample/astralhash.conf new file mode 100644 index 000000000..649eecfdc --- /dev/null +++ b/stratum/config.sample/astralhash.conf @@ -0,0 +1,15 @@ +[TCP] +server = yaamp.com +port = 8640 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = astralhash +difficulty = 0.25 +max_ttf = 4000000 diff --git a/stratum/config.sample/balloon.conf b/stratum/config.sample/balloon.conf new file mode 100644 index 000000000..97c507fd0 --- /dev/null +++ b/stratum/config.sample/balloon.conf @@ -0,0 +1,16 @@ +[TCP] +server = yaamp.com +port = 5100 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = balloon +difficulty = 0.5 +max_ttf = 50000 + diff --git a/stratum/config.sample/bcd.conf b/stratum/config.sample/bcd.conf new file mode 100644 index 000000000..046274911 --- /dev/null +++ b/stratum/config.sample/bcd.conf @@ -0,0 +1,15 @@ +[TCP] +server = yaamp.com +port = 3643 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = binarium-v1 +difficulty = 0.01 +max_ttf = 4000000 diff --git a/stratum/config.sample/bitcash.conf b/stratum/config.sample/bitcash.conf new file mode 100644 index 000000000..63255e7bb --- /dev/null +++ b/stratum/config.sample/bitcash.conf @@ -0,0 +1,16 @@ +[TCP] +server = yaamp.com +port = 3636 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = x25x +difficulty = 0.008 +max_ttf = 50000 + diff --git a/stratum/config.sample/bmw512.conf b/stratum/config.sample/bmw512.conf new file mode 100644 index 000000000..c02a8ac31 --- /dev/null +++ b/stratum/config.sample/bmw512.conf @@ -0,0 +1,13 @@ +[TCP] +server = yaamp.com +port = 5787 +password = tu8tu5 + [SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + [STRATUM] +algo = bmw512 +difficulty = 256 +max_ttf = 4000000 \ No newline at end of file diff --git a/stratum/config.sample/dedal.conf b/stratum/config.sample/dedal.conf new file mode 100644 index 000000000..b3e12c674 --- /dev/null +++ b/stratum/config.sample/dedal.conf @@ -0,0 +1,15 @@ +[TCP] +server = yaamp.com +port = 3538 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = dedal +difficulty = 0.25 +max_ttf = 200000000000000 diff --git a/stratum/config.sample/geek.conf b/stratum/config.sample/geek.conf new file mode 100644 index 000000000..ffdbe4bd5 --- /dev/null +++ b/stratum/config.sample/geek.conf @@ -0,0 +1,16 @@ +[TCP] +server = yaamp.com +port = 3691 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = geek +difficulty = 0.001 +max_ttf = 4000000 + diff --git a/stratum/config.sample/hex.conf b/stratum/config.sample/hex.conf new file mode 100644 index 000000000..9fc9e3f88 --- /dev/null +++ b/stratum/config.sample/hex.conf @@ -0,0 +1,15 @@ +[TCP] +server = yaamp.com +port = 5135 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = hex +difficulty = 1 +max_ttf = 40000 diff --git a/stratum/config.sample/jeonghash.conf b/stratum/config.sample/jeonghash.conf new file mode 100644 index 000000000..18f28dc22 --- /dev/null +++ b/stratum/config.sample/jeonghash.conf @@ -0,0 +1,15 @@ +[TCP] +server = yaamp.com +port = 8660 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = jeonghash +difficulty = 0.25 +max_ttf = 4000000 diff --git a/stratum/config.sample/lyra2.conf b/stratum/config.sample/lyra2.conf index d2f73617f..0faa798e0 100644 --- a/stratum/config.sample/lyra2.conf +++ b/stratum/config.sample/lyra2.conf @@ -1,6 +1,6 @@ [TCP] server = yaamp.com -port = 4433 +port = 4432 password = tu8tu5 [SQL] diff --git a/stratum/config.sample/lyra2v3.conf b/stratum/config.sample/lyra2v3.conf new file mode 100644 index 000000000..04c9dadbc --- /dev/null +++ b/stratum/config.sample/lyra2v3.conf @@ -0,0 +1,16 @@ +[TCP] +server = yaamp.com +port = 4433 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = lyra2v3 +difficulty = 1 +max_ttf = 40000 + diff --git a/stratum/config.sample/lyra2vc0ban.conf b/stratum/config.sample/lyra2vc0ban.conf new file mode 100644 index 000000000..d300580ae --- /dev/null +++ b/stratum/config.sample/lyra2vc0ban.conf @@ -0,0 +1,16 @@ +[TCP] +server = yaamp.com +port = 4563 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = lyra2vc0ban +difficulty = 1 +max_ttf = 40000 + diff --git a/stratum/config.sample/lyra2z330.conf b/stratum/config.sample/lyra2z330.conf new file mode 100644 index 000000000..4ad7a391e --- /dev/null +++ b/stratum/config.sample/lyra2z330.conf @@ -0,0 +1,16 @@ +[TCP] +server = yaamp.com +port = 3000 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = lyra2z330 +difficulty = 0.0001 +max_ttf = 40000 + diff --git a/stratum/config.sample/lyra2zz.conf b/stratum/config.sample/lyra2zz.conf new file mode 100644 index 000000000..67d0c34ce --- /dev/null +++ b/stratum/config.sample/lyra2zz.conf @@ -0,0 +1,15 @@ +[TCP] +server = yaamp.com +port = 4556 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = lyra2zz +difficulty = 1 +max_ttf = 40000 diff --git a/stratum/config.sample/minotaur.conf b/stratum/config.sample/minotaur.conf new file mode 100644 index 000000000..85c7615ae --- /dev/null +++ b/stratum/config.sample/minotaur.conf @@ -0,0 +1,13 @@ +[TCP] +server = yaamp.com +port = 7018 +password = tu8tu5 + [SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + [STRATUM] +algo = minotaur +difficulty = 0.001 +max_ttf = 4000000 diff --git a/stratum/config.sample/pawelhash.conf b/stratum/config.sample/pawelhash.conf new file mode 100644 index 000000000..e3b1e4119 --- /dev/null +++ b/stratum/config.sample/pawelhash.conf @@ -0,0 +1,15 @@ +[TCP] +server = yaamp.com +port = 8680 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = pawelhash +difficulty = 0.25 +max_ttf = 4000000 diff --git a/stratum/config.sample/pipe.conf b/stratum/config.sample/pipe.conf new file mode 100644 index 000000000..26e253990 --- /dev/null +++ b/stratum/config.sample/pipe.conf @@ -0,0 +1,15 @@ +[TCP] +server = yaamp.com +port = 9393 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = pipe +difficulty = 0.125 +max_ttf = 50000 diff --git a/stratum/config.sample/renesis.conf b/stratum/config.sample/renesis.conf new file mode 100644 index 000000000..7bac3e586 --- /dev/null +++ b/stratum/config.sample/renesis.conf @@ -0,0 +1,15 @@ +[TCP] +server = yaamp.com +port = 5252 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = renesis +difficulty = 1 +max_ttf = 400000000 diff --git a/stratum/config.sample/sonoa.conf b/stratum/config.sample/sonoa.conf new file mode 100644 index 000000000..10575484f --- /dev/null +++ b/stratum/config.sample/sonoa.conf @@ -0,0 +1,15 @@ +[TCP] +server = yaamp.com +port = 8733 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = sonoa +difficulty = 0.5 +max_ttf = 50000 diff --git a/stratum/config.sample/x16rt.conf b/stratum/config.sample/x16rt.conf new file mode 100644 index 000000000..3088d462d --- /dev/null +++ b/stratum/config.sample/x16rt.conf @@ -0,0 +1,15 @@ +[TCP] +server = yaamp.com +port = 7220 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = x16rt +difficulty = 0.25 +max_ttf = 50000 diff --git a/stratum/config.sample/x16rv2.conf b/stratum/config.sample/x16rv2.conf new file mode 100644 index 000000000..2779358f5 --- /dev/null +++ b/stratum/config.sample/x16rv2.conf @@ -0,0 +1,15 @@ +[TCP] +server = yaamp.com +port = 3637 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = x16rv2 +difficulty = 0.25 +max_ttf = 50000 diff --git a/stratum/config.sample/x18.conf b/stratum/config.sample/x18.conf new file mode 100644 index 000000000..37ce6af02 --- /dev/null +++ b/stratum/config.sample/x18.conf @@ -0,0 +1,15 @@ +[TCP] +server = yaamp.com +port = 3738 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = x18 +difficulty = 0.008 +max_ttf = 50000 diff --git a/stratum/config.sample/x20r.conf b/stratum/config.sample/x20r.conf new file mode 100644 index 000000000..4452b5010 --- /dev/null +++ b/stratum/config.sample/x20r.conf @@ -0,0 +1,15 @@ +[TCP] +server = yaamp.com +port = 4300 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = x20r +difficulty = 0.5 +max_ttf = 50000 diff --git a/stratum/config.sample/x21s.conf b/stratum/config.sample/x21s.conf new file mode 100644 index 000000000..f961a8899 --- /dev/null +++ b/stratum/config.sample/x21s.conf @@ -0,0 +1,15 @@ +[TCP] +server = yaamp.com +port = 3224 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = x21s +difficulty = 1 +max_ttf = 1000000000 diff --git a/stratum/config.sample/x25x.conf b/stratum/config.sample/x25x.conf new file mode 100644 index 000000000..eca7c3eac --- /dev/null +++ b/stratum/config.sample/x25x.conf @@ -0,0 +1,16 @@ +[TCP] +server = yaamp.com +port = 3423 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = x25x +difficulty = 0.0025 +max_ttf = 50000 + diff --git a/stratum/config.sample/yescryptR8.conf b/stratum/config.sample/yescryptR8.conf new file mode 100644 index 000000000..1eb06f324 --- /dev/null +++ b/stratum/config.sample/yescryptR8.conf @@ -0,0 +1,15 @@ +[TCP] +server = yaamp.com +port = 6353 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = yescryptR8 +difficulty = 2 +max_ttf = 400000000 diff --git a/stratum/config.sample/yespower.conf b/stratum/config.sample/yespower.conf new file mode 100644 index 000000000..00d4d86dc --- /dev/null +++ b/stratum/config.sample/yespower.conf @@ -0,0 +1,15 @@ +[TCP] +server = yaamp.com +port = 6234 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = yespower +difficulty = 1 +max_ttf = 400000000 diff --git a/stratum/config.sample/yespowerR16.conf b/stratum/config.sample/yespowerR16.conf new file mode 100644 index 000000000..3729e89dc --- /dev/null +++ b/stratum/config.sample/yespowerR16.conf @@ -0,0 +1,15 @@ +[TCP] +server = yaamp.com +port = 6236 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = yespowerR16 +difficulty = 1 +max_ttf = 400000000 diff --git a/stratum/config.sample/yespowerR24.conf b/stratum/config.sample/yespowerR24.conf new file mode 100644 index 000000000..d82601dcd --- /dev/null +++ b/stratum/config.sample/yespowerR24.conf @@ -0,0 +1,15 @@ +[TCP] +server = yaamp.com +port = 6237 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = yespowerR24 +difficulty = 1 +max_ttf = 400000000 diff --git a/stratum/config.sample/yespowerR32.conf b/stratum/config.sample/yespowerR32.conf new file mode 100644 index 000000000..64efba690 --- /dev/null +++ b/stratum/config.sample/yespowerR32.conf @@ -0,0 +1,15 @@ +[TCP] +server = yaamp.com +port = 6238 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = yespowerR32 +difficulty = 1 +max_ttf = 400000000 diff --git a/stratum/config.sample/yespowerR8.conf b/stratum/config.sample/yespowerR8.conf new file mode 100644 index 000000000..75d133a4d --- /dev/null +++ b/stratum/config.sample/yespowerR8.conf @@ -0,0 +1,15 @@ +[TCP] +server = yaamp.com +port = 6235 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = yespowerR8 +difficulty = 1 +max_ttf = 400000000 diff --git a/stratum/db.cpp b/stratum/db.cpp index f8c513cd8..a2b3b59c7 100644 --- a/stratum/db.cpp +++ b/stratum/db.cpp @@ -207,6 +207,8 @@ void db_update_coinds(YAAMP_DB *db) YAAMP_COIND *coind = (YAAMP_COIND *)object_find(&g_list_coind, atoi(row[0])); if(!coind) { + if (!strlen(g_stratum_coin_include) || (strlen(g_stratum_coin_include) && strstr(g_stratum_coin_include, row[20]))) + { coind = new YAAMP_COIND; memset(coind, 0, sizeof(YAAMP_COIND)); @@ -214,6 +216,9 @@ void db_update_coinds(YAAMP_DB *db) coind->newblock = true; coind->id = atoi(row[0]); coind->aux.coind = coind; + } + else + continue; } else coind->newcoind = false; @@ -322,6 +327,7 @@ void db_update_coinds(YAAMP_DB *db) if (strcmp(coind->symbol, "FLAX") == 0) coind->oldmasternodes = true; if (strcmp(coind->symbol, "ITZ") == 0) coind->oldmasternodes = true; if (strcmp(coind->symbol, "J") == 0 || strcmp(coind->symbol2, "J") == 0) coind->oldmasternodes = true; + if (strcmp(coind->symbol, "LAX") == 0) coind->oldmasternodes = true; if (strcmp(coind->symbol, "MAG") == 0) coind->oldmasternodes = true; if (strcmp(coind->symbol, "PBS") == 0) coind->oldmasternodes = true; if (strcmp(coind->symbol, "URALS") == 0) coind->oldmasternodes = true; diff --git a/stratum/job.h b/stratum/job.h index aef4bdbe1..855a0cd5e 100644 --- a/stratum/job.h +++ b/stratum/job.h @@ -51,6 +51,9 @@ struct YAAMP_JOB_TEMPLATE char coinb1[4*1024]; char coinb2[4*1024]; + char coinforsubmitb1[4*1024]; + char coinforsubmitb2[4*1024]; + bool isbitcash; char header[256]; @@ -61,6 +64,9 @@ struct YAAMP_JOB_TEMPLATE int auxs_size; YAAMP_COIND_AUX *auxs[MAX_AUXS]; + + bool needpriceinfo; + char priceinfo[1024]; }; #define YAAMP_JOB_MAXSUBIDS 200 diff --git a/stratum/sha3/KeccakP-800-SnP.h b/stratum/sha3/KeccakP-800-SnP.h new file mode 100644 index 000000000..4b2556c06 --- /dev/null +++ b/stratum/sha3/KeccakP-800-SnP.h @@ -0,0 +1,41 @@ +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _KeccakP_800_SnP_h_ +#define _KeccakP_800_SnP_h_ + +/** For the documentation, see SnP-documentation.h. + */ + +#define KeccakP800_implementation "32-bit reference implementation" +#define KeccakP800_stateSizeInBytes 100 +#define KeccakP800_stateAlignment 4 + +#ifdef KeccakReference +void KeccakP800_StaticInitialize( void ); +#else +#define KeccakP800_StaticInitialize() +#endif +void KeccakP800_Initialize(void *state); +void KeccakP800_AddByte(void *state, unsigned char data, unsigned int offset); +void KeccakP800_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP800_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP800_OverwriteWithZeroes(void *state, unsigned int byteCount); +void KeccakP800_Permute_12rounds(void *state); +void KeccakP800_Permute_22rounds(void *state); +void KeccakP800_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP800_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length); + +#endif diff --git a/stratum/sha3/KeccakP-800-reference.c b/stratum/sha3/KeccakP-800-reference.c new file mode 100644 index 000000000..b71a4889d --- /dev/null +++ b/stratum/sha3/KeccakP-800-reference.c @@ -0,0 +1,421 @@ +/* +Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, +Michaël Peeters, Gilles Van Assche and Ronny Van Keer, +hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ + +--- + +This file implements Keccak-p[800] in a SnP-compatible way. +Please refer to SnP-documentation.h for more details. + +This implementation comes with KeccakP-800-SnP.h in the same folder. +Please refer to LowLevel.build for the exact list of other files it must be combined with. +*/ + +#include +#include +#include +#include +#include "brg_endian.h" +#ifdef KeccakReference +#include "displayIntermediateValues.h" +#endif + +typedef unsigned char UINT8; +typedef unsigned int UINT32; +typedef UINT32 tKeccakLane; + +#define maxNrRounds 22 +#define nrLanes 25 +#define index(x, y) (((x)%5)+5*((y)%5)) + +#ifdef KeccakReference + +static tKeccakLane KeccakRoundConstants[maxNrRounds]; +static unsigned int KeccakRhoOffsets[nrLanes]; + +/* ---------------------------------------------------------------- */ + +void KeccakP800_InitializeRoundConstants(void); +void KeccakP800_InitializeRhoOffsets(void); +static int LFSR86540(UINT8 *LFSR); + +void KeccakP800_StaticInitialize(void) +{ + if (sizeof(tKeccakLane) != 4) { + printf("tKeccakLane should be 32-bit wide\n"); + abort(); + } + KeccakP800_InitializeRoundConstants(); + KeccakP800_InitializeRhoOffsets(); +} + +void KeccakP800_InitializeRoundConstants(void) +{ + UINT8 LFSRstate = 0x01; + unsigned int i, j, bitPosition; + + for(i=0; i> (8*j)) & 0xFF; +} + +void KeccakP800OnWords(tKeccakLane *state, unsigned int nrRounds) +{ + unsigned int i; + +#ifdef KeccakReference + displayStateAsLanes(3, "Same, with lanes as 32-bit words", state, 800); +#endif + + for(i=(maxNrRounds-nrRounds); i> (sizeof(tKeccakLane)*8-offset))) : a) + +static void theta(tKeccakLane *A) +{ + unsigned int x, y; + tKeccakLane C[5], D[5]; + + for(x=0; x<5; x++) { + C[x] = 0; + for(y=0; y<5; y++) + C[x] ^= A[index(x, y)]; + } + for(x=0; x<5; x++) + D[x] = ROL32(C[(x+1)%5], 1) ^ C[(x+4)%5]; + for(x=0; x<5; x++) + for(y=0; y<5; y++) + A[index(x, y)] ^= D[x]; +} + +static void rho(tKeccakLane *A) +{ + unsigned int x, y; + + for(x=0; x<5; x++) for(y=0; y<5; y++) + A[index(x, y)] = ROL32(A[index(x, y)], KeccakRhoOffsets[index(x, y)]); +} + +static void pi(tKeccakLane *A) +{ + unsigned int x, y; + tKeccakLane tempA[25]; + + for(x=0; x<5; x++) for(y=0; y<5; y++) + tempA[index(x, y)] = A[index(x, y)]; + for(x=0; x<5; x++) for(y=0; y<5; y++) + A[index(0*x+1*y, 2*x+3*y)] = tempA[index(x, y)]; +} + +static void chi(tKeccakLane *A) +{ + unsigned int x, y; + tKeccakLane C[5]; + + for(y=0; y<5; y++) { + for(x=0; x<5; x++) + C[x] = A[index(x, y)] ^ ((~A[index(x+1, y)]) & A[index(x+2, y)]); + for(x=0; x<5; x++) + A[index(x, y)] = C[x]; + } +} + +static void iota(tKeccakLane *A, unsigned int indexRound) +{ + A[index(0, 0)] ^= KeccakRoundConstants[indexRound]; +} + +/* ---------------------------------------------------------------- */ + +void KeccakP800_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length) +{ + assert(offset < 100); + assert(offset+length <= 100); + memcpy(data, (unsigned char*)state+offset, length); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP800_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) +{ + unsigned int i; + + assert(offset < 100); + assert(offset+length <= 100); + for(i=0; i + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Optimised ANSI-C implementation of LANE + */ + +#include "lane.h" + +#define T8(x) ((x) & 0xff) +#define B0(x) (T8((x) )) +#define B1(x) (T8((x) >> 8)) +#define B2(x) (T8((x) >> 16)) +#define B3(x) (T8((x) >> 24)) +#define MSB32(x) ((u32)((((u64)(x))>>32) & 0xffffffff)) +#define LSB32(x) ((u32)((((u64)(x)) ) & 0xffffffff)) +#ifdef LANE_BIG_ENDIAN +#define U8TO32_BIG(c) (((u32*)(c))[0]) +#define U32TO8_BIG(c, v) ((u32*)(c))[0]=v +#else +#define U8TO32_BIG(c) (((u32)T8(*((u8*)(c))) << 24) | \ + ((u32)T8(*(((u8*)(c)) + 1)) << 16) | \ + ((u32)T8(*(((u8*)(c)) + 2)) << 8) | \ + ((u32)T8(*(((u8*)(c)) + 3)))) +#define U32TO8_BIG(c, v) do { \ + u32 tmp_portable_h_x = (v); \ + u8 *tmp_portable_h_d = (c); \ + tmp_portable_h_d[0] = T8(tmp_portable_h_x >> 24); \ + tmp_portable_h_d[1] = T8(tmp_portable_h_x >> 16); \ + tmp_portable_h_d[2] = T8(tmp_portable_h_x >> 8); \ + tmp_portable_h_d[3] = T8(tmp_portable_h_x); \ + } while (0) +#endif /* LANE_BIG_ENDIAN */ + +static const u32 iv224[8] = { + 0xc8245a86U, 0x8d733102U, 0x314ddcb9U, 0xf60a7ef4U, + 0x57b8c917U, 0xeefeaec2U, 0xff4fc3beU, 0x87c4728eU +}; + +static const u32 iv256[8] = { + 0xbe292e17U, 0xbb541ff2U, 0xfe54b6f7U, 0x30b1c96aU, + 0x7b259268U, 0x8539bdf3U, 0x97c4bdd6U, 0x49763fb8U +}; + +static const u32 iv384[16] = { + 0x148922ceU, 0x548c3001U, 0x76978bc8U, 0x266e008cU, + 0x3dc60765U, 0xd85b09d9U, 0x4cb1c8d8U, 0xe2cab952U, + 0xdb72be8eU, 0x685f0783U, 0xfa436c3dU, 0x4b9acb90U, + 0x5088dd47U, 0x932f55a9U, 0xa0c415c6U, 0xdb6dd795U +}; + +static const u32 iv512[16] = { + 0x9b603481U, 0x1d5a931bU, 0x69c4e6e0U, 0x975e2681U, + 0xb863ba53U, 0x8d1be11bU, 0x77340080U, 0xd42c48a5U, + 0x3a3a1d61U, 0x1cf3a1c4U, 0xf0a30347U, 0x7e56a44aU, + 0x9530ee60U, 0xdadb05b6U, 0x3ae3ac7cU, 0xd732ac6aU +}; + +static const u32 T0[256] = { + 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, + 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, + 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, + 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, + 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, + 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, + 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, + 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, + 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, + 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, + 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, + 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, + 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, + 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, + 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, + 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, + 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, + 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, + 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, + 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, + 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, + 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, + 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, + 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, + 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, + 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, + 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, + 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, + 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, + 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, + 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, + 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, + 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, + 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, + 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, + 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, + 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, + 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, + 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, + 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, + 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, + 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, + 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, + 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, + 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, + 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, + 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, + 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, + 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, + 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, + 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, + 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, + 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, + 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, + 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, + 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, + 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, + 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, + 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, + 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, + 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, + 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, + 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, + 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, +}; +static const u32 T1[256] = { + 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, + 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, + 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, + 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, + 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, + 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, + 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, + 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, + 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, + 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, + 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, + 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, + 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, + 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, + 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, + 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, + 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, + 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, + 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, + 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, + 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, + 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, + 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, + 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, + 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, + 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, + 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, + 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, + 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, + 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, + 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, + 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, + 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, + 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, + 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, + 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, + 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, + 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, + 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, + 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, + 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, + 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, + 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, + 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, + 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, + 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, + 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, + 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, + 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, + 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, + 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, + 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, + 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, + 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, + 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, + 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, + 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, + 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, + 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, + 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, + 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, + 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, + 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, + 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, +}; +static const u32 T2[256] = { + 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, + 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, + 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, + 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, + 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, + 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, + 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, + 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, + 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, + 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, + 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, + 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, + 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, + 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, + 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, + 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, + 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, + 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, + 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, + 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, + 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, + 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, + 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, + 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, + 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, + 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, + 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, + 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, + 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, + 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, + 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, + 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, + 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, + 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, + 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, + 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, + 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, + 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, + 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, + 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, + 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, + 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, + 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, + 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, + 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, + 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, + 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, + 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, + 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, + 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, + 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, + 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, + 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, + 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, + 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, + 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, + 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, + 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, + 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, + 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, + 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, + 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, + 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, + 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, +}; +static const u32 T3[256] = { + 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, + 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, + 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, + 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, + 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, + 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, + 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, + 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, + 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, + 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, + 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, + 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, + 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, + 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, + 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, + 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, + 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, + 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, + 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, + 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, + 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, + 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, + 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, + 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, + 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, + 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, + 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, + 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, + 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, + 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, + 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, + 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, + 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, + 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, + 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, + 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, + 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, + 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, + 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, + 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, + 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, + 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, + 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, + 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, + 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, + 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, + 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, + 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, + 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, + 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, + 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, + 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, + 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, + 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, + 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, + 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, + 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, + 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, + 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, + 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, + 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, + 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, + 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, + 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, +}; + +static const u32 C[768] = { + 0x07fc703d, 0xd3fe381f, 0xb9ff1c0e, 0x5cff8e07, 0xfe7fc702, 0x7f3fe381, 0xef9ff1c1, 0xa7cff8e1, + 0x83e7fc71, 0x91f3fe39, 0x98f9ff1d, 0x9c7cff8f, 0x9e3e7fc6, 0x4f1f3fe3, 0xf78f9ff0, 0x7bc7cff8, + 0x3de3e7fc, 0x1ef1f3fe, 0x0f78f9ff, 0xd7bc7cfe, 0x6bde3e7f, 0xe5ef1f3e, 0x72f78f9f, 0xe97bc7ce, + 0x74bde3e7, 0xea5ef1f2, 0x752f78f9, 0xea97bc7d, 0xa54bde3f, 0x82a5ef1e, 0x4152f78f, 0xf0a97bc6, + 0x7854bde3, 0xec2a5ef0, 0x76152f78, 0x3b0a97bc, 0x1d854bde, 0x0ec2a5ef, 0xd76152f6, 0x6bb0a97b, + 0xe5d854bc, 0x72ec2a5e, 0x3976152f, 0xccbb0a96, 0x665d854b, 0xe32ec2a4, 0x71976152, 0x38cbb0a9, + 0xcc65d855, 0xb632ec2b, 0x8b197614, 0x458cbb0a, 0x22c65d85, 0xc1632ec3, 0xb0b19760, 0x5858cbb0, + 0x2c2c65d8, 0x161632ec, 0x0b0b1976, 0x05858cbb, 0xd2c2c65c, 0x6961632e, 0x34b0b197, 0xca5858ca, + 0x652c2c65, 0xe2961633, 0xa14b0b18, 0x50a5858c, 0x2852c2c6, 0x14296163, 0xda14b0b0, 0x6d0a5858, + 0x36852c2c, 0x1b429616, 0x0da14b0b, 0xd6d0a584, 0x6b6852c2, 0x35b42961, 0xcada14b1, 0xb56d0a59, + 0x8ab6852d, 0x955b4297, 0x9aada14a, 0x4d56d0a5, 0xf6ab6853, 0xab55b428, 0x55aada14, 0x2ad56d0a, + 0x156ab685, 0xdab55b43, 0xbd5aada0, 0x5ead56d0, 0x2f56ab68, 0x17ab55b4, 0x0bd5aada, 0x05ead56d, + 0xd2f56ab7, 0xb97ab55a, 0x5cbd5aad, 0xfe5ead57, 0xaf2f56aa, 0x5797ab55, 0xfbcbd5ab, 0xade5ead4, + 0x56f2f56a, 0x2b797ab5, 0xc5bcbd5b, 0xb2de5eac, 0x596f2f56, 0x2cb797ab, 0xc65bcbd4, 0x632de5ea, + 0x3196f2f5, 0xc8cb797b, 0xb465bcbc, 0x5a32de5e, 0x2d196f2f, 0xc68cb796, 0x63465bcb, 0xe1a32de4, + 0x70d196f2, 0x3868cb79, 0xcc3465bd, 0xb61a32df, 0x8b0d196e, 0x45868cb7, 0xf2c3465a, 0x7961a32d, + 0xecb0d197, 0xa65868ca, 0x532c3465, 0xf9961a33, 0xaccb0d18, 0x5665868c, 0x2b32c346, 0x159961a3, + 0xdaccb0d0, 0x6d665868, 0x36b32c34, 0x1b59961a, 0x0daccb0d, 0xd6d66587, 0xbb6b32c2, 0x5db59961, + 0xfedaccb1, 0xaf6d6659, 0x87b6b32d, 0x93db5997, 0x99edacca, 0x4cf6d665, 0xf67b6b33, 0xab3db598, + 0x559edacc, 0x2acf6d66, 0x1567b6b3, 0xdab3db58, 0x6d59edac, 0x36acf6d6, 0x1b567b6b, 0xddab3db4, + 0x6ed59eda, 0x376acf6d, 0xcbb567b7, 0xb5dab3da, 0x5aed59ed, 0xfd76acf7, 0xaebb567a, 0x575dab3d, + 0xfbaed59f, 0xadd76ace, 0x56ebb567, 0xfb75dab2, 0x7dbaed59, 0xeedd76ad, 0xa76ebb57, 0x83b75daa, + 0x41dbaed5, 0xf0edd76b, 0xa876ebb4, 0x543b75da, 0x2a1dbaed, 0xc50edd77, 0xb2876eba, 0x5943b75d, + 0xfca1dbaf, 0xae50edd6, 0x572876eb, 0xfb943b74, 0x7dca1dba, 0x3ee50edd, 0xcf72876f, 0xb7b943b6, + 0x5bdca1db, 0xfdee50ec, 0x7ef72876, 0x3f7b943b, 0xcfbdca1c, 0x67dee50e, 0x33ef7287, 0xc9f7b942, + 0x64fbdca1, 0xe27dee51, 0xa13ef729, 0x809f7b95, 0x904fbdcb, 0x9827dee4, 0x4c13ef72, 0x2609f7b9, + 0xc304fbdd, 0xb1827def, 0x88c13ef6, 0x44609f7b, 0xf2304fbc, 0x791827de, 0x3c8c13ef, 0xce4609f6, + 0x672304fb, 0xe391827c, 0x71c8c13e, 0x38e4609f, 0xcc72304e, 0x66391827, 0xe31c8c12, 0x718e4609, + 0xe8c72305, 0xa4639183, 0x8231c8c0, 0x4118e460, 0x208c7230, 0x10463918, 0x08231c8c, 0x04118e46, + 0x0208c723, 0xd1046390, 0x688231c8, 0x344118e4, 0x1a208c72, 0x0d104639, 0xd688231d, 0xbb44118f, + 0x8da208c6, 0x46d10463, 0xf3688230, 0x79b44118, 0x3cda208c, 0x1e6d1046, 0x0f368823, 0xd79b4410, + 0x6bcda208, 0x35e6d104, 0x1af36882, 0x0d79b441, 0xd6bcda21, 0xbb5e6d11, 0x8daf3689, 0x96d79b45, + 0x9b6bcda3, 0x9db5e6d0, 0x4edaf368, 0x276d79b4, 0x13b6bcda, 0x09db5e6d, 0xd4edaf37, 0xba76d79a, + 0x5d3b6bcd, 0xfe9db5e7, 0xaf4edaf2, 0x57a76d79, 0xfbd3b6bd, 0xade9db5f, 0x86f4edae, 0x437a76d7, + 0xf1bd3b6a, 0x78de9db5, 0xec6f4edb, 0xa637a76c, 0x531bd3b6, 0x298de9db, 0xc4c6f4ec, 0x62637a76, + 0x3131bd3b, 0xc898de9c, 0x644c6f4e, 0x322637a7, 0xc9131bd2, 0x64898de9, 0xe244c6f5, 0xa122637b, + 0x809131bc, 0x404898de, 0x20244c6f, 0xc0122636, 0x6009131b, 0xe004898c, 0x700244c6, 0x38012263, + 0xcc009130, 0x66004898, 0x3300244c, 0x19801226, 0x0cc00913, 0xd6600488, 0x6b300244, 0x35980122, + 0x1acc0091, 0xdd660049, 0xbeb30025, 0x8f598013, 0x97acc008, 0x4bd66004, 0x25eb3002, 0x12f59801, + 0xd97acc01, 0xbcbd6601, 0x8e5eb301, 0x972f5981, 0x9b97acc1, 0x9dcbd661, 0x9ee5eb31, 0x9f72f599, + 0x9fb97acd, 0x9fdcbd67, 0x9fee5eb2, 0x4ff72f59, 0xf7fb97ad, 0xabfdcbd7, 0x85fee5ea, 0x42ff72f5, + 0xf17fb97b, 0xa8bfdcbc, 0x545fee5e, 0x2a2ff72f, 0xc517fb96, 0x628bfdcb, 0xe145fee4, 0x70a2ff72, + 0x38517fb9, 0xcc28bfdd, 0xb6145fef, 0x8b0a2ff6, 0x458517fb, 0xf2c28bfc, 0x796145fe, 0x3cb0a2ff, + 0xce58517e, 0x672c28bf, 0xe396145e, 0x71cb0a2f, 0xe8e58516, 0x7472c28b, 0xea396144, 0x751cb0a2, + 0x3a8e5851, 0xcd472c29, 0xb6a39615, 0x8b51cb0b, 0x95a8e584, 0x4ad472c2, 0x256a3961, 0xc2b51cb1, + 0xb15a8e59, 0x88ad472d, 0x9456a397, 0x9a2b51ca, 0x4d15a8e5, 0xf68ad473, 0xab456a38, 0x55a2b51c, + 0x2ad15a8e, 0x1568ad47, 0xdab456a2, 0x6d5a2b51, 0xe6ad15a9, 0xa3568ad5, 0x81ab456b, 0x90d5a2b4, + 0x486ad15a, 0x243568ad, 0xc21ab457, 0xb10d5a2a, 0x5886ad15, 0xfc43568b, 0xae21ab44, 0x5710d5a2, + 0x2b886ad1, 0xc5c43569, 0xb2e21ab5, 0x89710d5b, 0x94b886ac, 0x4a5c4356, 0x252e21ab, 0xc29710d4, + 0x614b886a, 0x30a5c435, 0xc852e21b, 0xb429710c, 0x5a14b886, 0x2d0a5c43, 0xc6852e20, 0x63429710, + 0x31a14b88, 0x18d0a5c4, 0x0c6852e2, 0x06342971, 0xd31a14b9, 0xb98d0a5d, 0x8cc6852f, 0x96634296, + 0x4b31a14b, 0xf598d0a4, 0x7acc6852, 0x3d663429, 0xceb31a15, 0xb7598d0b, 0x8bacc684, 0x45d66342, + 0x22eb31a1, 0xc17598d1, 0xb0bacc69, 0x885d6635, 0x942eb31b, 0x9a17598c, 0x4d0bacc6, 0x2685d663, + 0xc342eb30, 0x61a17598, 0x30d0bacc, 0x18685d66, 0x0c342eb3, 0xd61a1758, 0x6b0d0bac, 0x358685d6, + 0x1ac342eb, 0xdd61a174, 0x6eb0d0ba, 0x3758685d, 0xcbac342f, 0xb5d61a16, 0x5aeb0d0b, 0xfd758684, + 0x7ebac342, 0x3f5d61a1, 0xcfaeb0d1, 0xb7d75869, 0x8bebac35, 0x95f5d61b, 0x9afaeb0c, 0x4d7d7586, + 0x26bebac3, 0xc35f5d60, 0x61afaeb0, 0x30d7d758, 0x186bebac, 0x0c35f5d6, 0x061afaeb, 0xd30d7d74, + 0x6986beba, 0x34c35f5d, 0xca61afaf, 0xb530d7d6, 0x5a986beb, 0xfd4c35f4, 0x7ea61afa, 0x3f530d7d, + 0xcfa986bf, 0xb7d4c35e, 0x5bea61af, 0xfdf530d6, 0x7efa986b, 0xef7d4c34, 0x77bea61a, 0x3bdf530d, + 0xcdefa987, 0xb6f7d4c2, 0x5b7bea61, 0xfdbdf531, 0xaedefa99, 0x876f7d4d, 0x93b7bea7, 0x99dbdf52, + 0x4cedefa9, 0xf676f7d5, 0xab3b7beb, 0x859dbdf4, 0x42cedefa, 0x21676f7d, 0xc0b3b7bf, 0xb059dbde, + 0x582cedef, 0xfc1676f6, 0x7e0b3b7b, 0xef059dbc, 0x7782cede, 0x3bc1676f, 0xcde0b3b6, 0x66f059db, + 0xe3782cec, 0x71bc1676, 0x38de0b3b, 0xcc6f059c, 0x663782ce, 0x331bc167, 0xc98de0b2, 0x64c6f059, + 0xe263782d, 0xa131bc17, 0x8098de0a, 0x404c6f05, 0xf0263783, 0xa8131bc0, 0x54098de0, 0x2a04c6f0, + 0x15026378, 0x0a8131bc, 0x054098de, 0x02a04c6f, 0xd1502636, 0x68a8131b, 0xe454098c, 0x722a04c6, + 0x39150263, 0xcc8a8130, 0x66454098, 0x3322a04c, 0x19915026, 0x0cc8a813, 0xd6645408, 0x6b322a04, + 0x35991502, 0x1acc8a81, 0xdd664541, 0xbeb322a1, 0x8f599151, 0x97acc8a9, 0x9bd66455, 0x9deb322b, + 0x9ef59914, 0x4f7acc8a, 0x27bd6645, 0xc3deb323, 0xb1ef5990, 0x58f7acc8, 0x2c7bd664, 0x163deb32, + 0x0b1ef599, 0xd58f7acd, 0xbac7bd67, 0x8d63deb2, 0x46b1ef59, 0xf358f7ad, 0xa9ac7bd7, 0x84d63dea, + 0x426b1ef5, 0xf1358f7b, 0xa89ac7bc, 0x544d63de, 0x2a26b1ef, 0xc51358f6, 0x6289ac7b, 0xe144d63c, + 0x70a26b1e, 0x3851358f, 0xcc289ac6, 0x66144d63, 0xe30a26b0, 0x71851358, 0x38c289ac, 0x1c6144d6, + 0x0e30a26b, 0xd7185134, 0x6b8c289a, 0x35c6144d, 0xcae30a27, 0xb5718512, 0x5ab8c289, 0xfd5c6145, + 0xaeae30a3, 0x87571850, 0x43ab8c28, 0x21d5c614, 0x10eae30a, 0x08757185, 0xd43ab8c3, 0xba1d5c60, + 0x5d0eae30, 0x2e875718, 0x1743ab8c, 0x0ba1d5c6, 0x05d0eae3, 0xd2e87570, 0x69743ab8, 0x34ba1d5c, + 0x1a5d0eae, 0x0d2e8757, 0xd69743aa, 0x6b4ba1d5, 0xe5a5d0eb, 0xa2d2e874, 0x5169743a, 0x28b4ba1d, + 0xc45a5d0f, 0xb22d2e86, 0x59169743, 0xfc8b4ba0, 0x7e45a5d0, 0x3f22d2e8, 0x1f916974, 0x0fc8b4ba, + 0x07e45a5d, 0xd3f22d2f, 0xb9f91696, 0x5cfc8b4b, 0xfe7e45a4, 0x7f3f22d2, 0x3f9f9169, 0xcfcfc8b5, + 0xb7e7e45b, 0x8bf3f22c, 0x45f9f916, 0x22fcfc8b, 0xc17e7e44, 0x60bf3f22, 0x305f9f91, 0xc82fcfc9, + 0xb417e7e5, 0x8a0bf3f3, 0x9505f9f8, 0x4a82fcfc, 0x25417e7e, 0x12a0bf3f, 0xd9505f9e, 0x6ca82fcf, + 0xe65417e6, 0x732a0bf3, 0xe99505f8, 0x74ca82fc, 0x3a65417e, 0x1d32a0bf, 0xde99505e, 0x6f4ca82f, + 0xe7a65416, 0x73d32a0b, 0xe9e99504, 0x74f4ca82, 0x3a7a6541, 0xcd3d32a1, 0xb69e9951, 0x8b4f4ca9, + 0x95a7a655, 0x9ad3d32b, 0x9d69e994, 0x4eb4f4ca, 0x275a7a65, 0xc3ad3d33, 0xb1d69e98, 0x58eb4f4c, + 0x2c75a7a6, 0x163ad3d3, 0xdb1d69e8, 0x6d8eb4f4, 0x36c75a7a, 0x1b63ad3d, 0xddb1d69f, 0xbed8eb4e, + 0x5f6c75a7, 0xffb63ad2, 0x7fdb1d69, 0xefed8eb5, 0xa7f6c75b, 0x83fb63ac, 0x41fdb1d6, 0x20fed8eb, + 0xc07f6c74, 0x603fb63a, 0x301fdb1d, 0xc80fed8f, 0xb407f6c6, 0x5a03fb63, 0xfd01fdb0, 0x7e80fed8, + 0x3f407f6c, 0x1fa03fb6, 0x0fd01fdb, 0xd7e80fec, 0x6bf407f6, 0x35fa03fb, 0xcafd01fc, 0x657e80fe, + 0x32bf407f, 0xc95fa03e, 0x64afd01f, 0xe257e80e, 0x712bf407, 0xe895fa02, 0x744afd01, 0xea257e81, + 0xa512bf41, 0x82895fa1, 0x9144afd1, 0x98a257e9, 0x9c512bf5, 0x9e2895fb, 0x9f144afc, 0x4f8a257e, + 0x27c512bf, 0xc3e2895e, 0x61f144af, 0xe0f8a256, 0x707c512b, 0xe83e2894, 0x741f144a, 0x3a0f8a25, + 0xcd07c513, 0xb683e288, 0x5b41f144, 0x2da0f8a2, 0x16d07c51, 0xdb683e29, 0xbdb41f15, 0x8eda0f8b, + 0x976d07c4, 0x4bb683e2, 0x25db41f1, 0xc2eda0f9, 0xb176d07d, 0x88bb683f, 0x945db41e, 0x4a2eda0f, + 0xf5176d06, 0x7a8bb683, 0xed45db40, 0x76a2eda0, 0x3b5176d0, 0x1da8bb68, 0x0ed45db4, 0x076a2eda, + 0x03b5176d, 0xd1da8bb7, 0xb8ed45da, 0x5c76a2ed, 0xfe3b5177, 0xaf1da8ba, 0x578ed45d, 0xfbc76a2f, + 0xade3b516, 0x56f1da8b, 0xfb78ed44, 0x7dbc76a2, 0x3ede3b51, 0xcf6f1da9, 0xb7b78ed5, 0x8bdbc76b, + 0x95ede3b4, 0x4af6f1da, 0x257b78ed, 0xc2bdbc77, 0xb15ede3a, 0x58af6f1d, 0xfc57b78f, 0xae2bdbc6, + 0x5715ede3, 0xfb8af6f0, 0x7dc57b78, 0x3ee2bdbc, 0x1f715ede, 0x0fb8af6f, 0xd7dc57b6, 0x6bee2bdb, +}; + +void lane256_compress(const u8 m[64], u32 h[8], const u32 ctrh, const u32 ctrl) +{ + u32 t0, t1, t2, t3, t4, t5, t6, t7; /* temp */ + u32 s00, s01, s02, s03, s04, s05, s06, s07; /* lane 0 */ + u32 s10, s11, s12, s13, s14, s15, s16, s17; /* lane 1 */ + u32 s20, s21, s22, s23, s24, s25, s26, s27; /* lane 2 */ + u32 s30, s31, s32, s33, s34, s35, s36, s37; /* lane 3 */ + u32 s40, s41, s42, s43, s44, s45, s46, s47; /* lane 4 */ + u32 s50, s51, s52, s53, s54, s55, s56, s57; /* lane 5 */ + u32 s60, s61, s62, s63, s64, s65, s66, s67; /* lane 6 */ + u32 s70, s71, s72, s73, s74, s75, s76, s77; /* lane 7 */ + + /* Message expansion */ + s30 = h[0]; + s31 = h[1]; + s32 = h[2]; + s33 = h[3]; + s34 = h[4]; + s35 = h[5]; + s36 = h[6]; + s37 = h[7]; + s40 = U8TO32_BIG(m + 0); + s41 = U8TO32_BIG(m + 4); + s42 = U8TO32_BIG(m + 8); + s43 = U8TO32_BIG(m + 12); + s44 = U8TO32_BIG(m + 16); + s45 = U8TO32_BIG(m + 20); + s46 = U8TO32_BIG(m + 24); + s47 = U8TO32_BIG(m + 28); + s50 = U8TO32_BIG(m + 32); + s51 = U8TO32_BIG(m + 36); + s52 = U8TO32_BIG(m + 40); + s53 = U8TO32_BIG(m + 44); + s54 = U8TO32_BIG(m + 48); + s55 = U8TO32_BIG(m + 52); + s56 = U8TO32_BIG(m + 56); + s57 = U8TO32_BIG(m + 60); + s00 = s30 ^ s40 ^ s44 ^ s50 ^ s54; + s01 = s31 ^ s41 ^ s45 ^ s51 ^ s55; + s02 = s32 ^ s42 ^ s46 ^ s52 ^ s56; + s03 = s33 ^ s43 ^ s47 ^ s53 ^ s57; + s04 = s34 ^ s40 ^ s50; + s05 = s35 ^ s41 ^ s51; + s06 = s36 ^ s42 ^ s52; + s07 = s37 ^ s43 ^ s53; + s10 = s00 ^ s34 ^ s44; + s11 = s01 ^ s35 ^ s45; + s12 = s02 ^ s36 ^ s46; + s13 = s03 ^ s37 ^ s47; + s14 = s30 ^ s44 ^ s50; + s15 = s31 ^ s45 ^ s51; + s16 = s32 ^ s46 ^ s52; + s17 = s33 ^ s47 ^ s53; + s20 = s00 ^ s34 ^ s54; + s21 = s01 ^ s35 ^ s55; + s22 = s02 ^ s36 ^ s56; + s23 = s03 ^ s37 ^ s57; + s24 = s30 ^ s40 ^ s54; + s25 = s31 ^ s41 ^ s55; + s26 = s32 ^ s42 ^ s56; + s27 = s33 ^ s43 ^ s57; + + /* Lane 0 */ + t0 = T0[B3(s00)] ^ T1[B2(s01)] ^ T2[B1(s02)] ^ T3[B0(s03)] ^ C[ 0]; + t1 = T0[B3(s01)] ^ T1[B2(s02)] ^ T2[B1(s03)] ^ T3[B0(s00)] ^ C[ 1]; + t4 = T0[B3(s02)] ^ T1[B2(s03)] ^ T2[B1(s00)] ^ T3[B0(s01)] ^ C[ 2]; + t5 = T0[B3(s03)] ^ T1[B2(s00)] ^ T2[B1(s01)] ^ T3[B0(s02)] ^ C[ 3] ^ ctrh; + t2 = T0[B3(s04)] ^ T1[B2(s05)] ^ T2[B1(s06)] ^ T3[B0(s07)] ^ C[ 4]; + t3 = T0[B3(s05)] ^ T1[B2(s06)] ^ T2[B1(s07)] ^ T3[B0(s04)] ^ C[ 5]; + t6 = T0[B3(s06)] ^ T1[B2(s07)] ^ T2[B1(s04)] ^ T3[B0(s05)] ^ C[ 6]; + t7 = T0[B3(s07)] ^ T1[B2(s04)] ^ T2[B1(s05)] ^ T3[B0(s06)] ^ C[ 7]; + + s00 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 8]; + s01 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 9]; + s04 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[10]; + s05 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[11] ^ ctrl; + s02 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[12]; + s03 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[13]; + s06 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[14]; + s07 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[15]; + + t0 = T0[B3(s00)] ^ T1[B2(s01)] ^ T2[B1(s02)] ^ T3[B0(s03)] ^ C[16]; + t1 = T0[B3(s01)] ^ T1[B2(s02)] ^ T2[B1(s03)] ^ T3[B0(s00)] ^ C[17]; + t4 = T0[B3(s02)] ^ T1[B2(s03)] ^ T2[B1(s00)] ^ T3[B0(s01)] ^ C[18]; + t5 = T0[B3(s03)] ^ T1[B2(s00)] ^ T2[B1(s01)] ^ T3[B0(s02)] ^ C[19] ^ ctrh; + t2 = T0[B3(s04)] ^ T1[B2(s05)] ^ T2[B1(s06)] ^ T3[B0(s07)] ^ C[20]; + t3 = T0[B3(s05)] ^ T1[B2(s06)] ^ T2[B1(s07)] ^ T3[B0(s04)] ^ C[21]; + t6 = T0[B3(s06)] ^ T1[B2(s07)] ^ T2[B1(s04)] ^ T3[B0(s05)] ^ C[22]; + t7 = T0[B3(s07)] ^ T1[B2(s04)] ^ T2[B1(s05)] ^ T3[B0(s06)] ^ C[23]; + + s00 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[24]; + s01 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[25]; + s04 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[26]; + s05 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[27] ^ ctrl; + s02 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[28]; + s03 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[29]; + s06 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[30]; + s07 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[31]; + + t0 = T0[B3(s00)] ^ T1[B2(s01)] ^ T2[B1(s02)] ^ T3[B0(s03)] ^ C[32]; + t1 = T0[B3(s01)] ^ T1[B2(s02)] ^ T2[B1(s03)] ^ T3[B0(s00)] ^ C[33]; + t4 = T0[B3(s02)] ^ T1[B2(s03)] ^ T2[B1(s00)] ^ T3[B0(s01)] ^ C[34]; + t5 = T0[B3(s03)] ^ T1[B2(s00)] ^ T2[B1(s01)] ^ T3[B0(s02)] ^ C[35] ^ ctrh; + t2 = T0[B3(s04)] ^ T1[B2(s05)] ^ T2[B1(s06)] ^ T3[B0(s07)] ^ C[36]; + t3 = T0[B3(s05)] ^ T1[B2(s06)] ^ T2[B1(s07)] ^ T3[B0(s04)] ^ C[37]; + t6 = T0[B3(s06)] ^ T1[B2(s07)] ^ T2[B1(s04)] ^ T3[B0(s05)] ^ C[38]; + t7 = T0[B3(s07)] ^ T1[B2(s04)] ^ T2[B1(s05)] ^ T3[B0(s06)] ^ C[39]; + + s60 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + s61 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + s64 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + s65 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + s62 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + s63 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + s66 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + s67 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + + /* Lane 1 */ + t0 = T0[B3(s10)] ^ T1[B2(s11)] ^ T2[B1(s12)] ^ T3[B0(s13)] ^ C[ 0+40]; + t1 = T0[B3(s11)] ^ T1[B2(s12)] ^ T2[B1(s13)] ^ T3[B0(s10)] ^ C[ 1+40]; + t4 = T0[B3(s12)] ^ T1[B2(s13)] ^ T2[B1(s10)] ^ T3[B0(s11)] ^ C[ 2+40]; + t5 = T0[B3(s13)] ^ T1[B2(s10)] ^ T2[B1(s11)] ^ T3[B0(s12)] ^ C[ 3+40] ^ ctrl; + t2 = T0[B3(s14)] ^ T1[B2(s15)] ^ T2[B1(s16)] ^ T3[B0(s17)] ^ C[ 4+40]; + t3 = T0[B3(s15)] ^ T1[B2(s16)] ^ T2[B1(s17)] ^ T3[B0(s14)] ^ C[ 5+40]; + t6 = T0[B3(s16)] ^ T1[B2(s17)] ^ T2[B1(s14)] ^ T3[B0(s15)] ^ C[ 6+40]; + t7 = T0[B3(s17)] ^ T1[B2(s14)] ^ T2[B1(s15)] ^ T3[B0(s16)] ^ C[ 7+40]; + + s10 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 8+40]; + s11 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 9+40]; + s14 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[10+40]; + s15 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[11+40] ^ ctrh; + s12 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[12+40]; + s13 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[13+40]; + s16 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[14+40]; + s17 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[15+40]; + + t0 = T0[B3(s10)] ^ T1[B2(s11)] ^ T2[B1(s12)] ^ T3[B0(s13)] ^ C[16+40]; + t1 = T0[B3(s11)] ^ T1[B2(s12)] ^ T2[B1(s13)] ^ T3[B0(s10)] ^ C[17+40]; + t4 = T0[B3(s12)] ^ T1[B2(s13)] ^ T2[B1(s10)] ^ T3[B0(s11)] ^ C[18+40]; + t5 = T0[B3(s13)] ^ T1[B2(s10)] ^ T2[B1(s11)] ^ T3[B0(s12)] ^ C[19+40] ^ ctrl; + t2 = T0[B3(s14)] ^ T1[B2(s15)] ^ T2[B1(s16)] ^ T3[B0(s17)] ^ C[20+40]; + t3 = T0[B3(s15)] ^ T1[B2(s16)] ^ T2[B1(s17)] ^ T3[B0(s14)] ^ C[21+40]; + t6 = T0[B3(s16)] ^ T1[B2(s17)] ^ T2[B1(s14)] ^ T3[B0(s15)] ^ C[22+40]; + t7 = T0[B3(s17)] ^ T1[B2(s14)] ^ T2[B1(s15)] ^ T3[B0(s16)] ^ C[23+40]; + + s10 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[24+40]; + s11 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[25+40]; + s14 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[26+40]; + s15 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[27+40] ^ ctrh; + s12 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[28+40]; + s13 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[29+40]; + s16 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[30+40]; + s17 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[31+40]; + + t0 = T0[B3(s10)] ^ T1[B2(s11)] ^ T2[B1(s12)] ^ T3[B0(s13)] ^ C[32+40]; + t1 = T0[B3(s11)] ^ T1[B2(s12)] ^ T2[B1(s13)] ^ T3[B0(s10)] ^ C[33+40]; + t4 = T0[B3(s12)] ^ T1[B2(s13)] ^ T2[B1(s10)] ^ T3[B0(s11)] ^ C[34+40]; + t5 = T0[B3(s13)] ^ T1[B2(s10)] ^ T2[B1(s11)] ^ T3[B0(s12)] ^ C[35+40] ^ ctrl; + t2 = T0[B3(s14)] ^ T1[B2(s15)] ^ T2[B1(s16)] ^ T3[B0(s17)] ^ C[36+40]; + t3 = T0[B3(s15)] ^ T1[B2(s16)] ^ T2[B1(s17)] ^ T3[B0(s14)] ^ C[37+40]; + t6 = T0[B3(s16)] ^ T1[B2(s17)] ^ T2[B1(s14)] ^ T3[B0(s15)] ^ C[38+40]; + t7 = T0[B3(s17)] ^ T1[B2(s14)] ^ T2[B1(s15)] ^ T3[B0(s16)] ^ C[39+40]; + + s60 ^= T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + s61 ^= T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + s64 ^= T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + s65 ^= T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + s62 ^= T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + s63 ^= T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + s66 ^= T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + s67 ^= T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + + /* Lane 2 */ + t0 = T0[B3(s20)] ^ T1[B2(s21)] ^ T2[B1(s22)] ^ T3[B0(s23)] ^ C[ 0+80]; + t1 = T0[B3(s21)] ^ T1[B2(s22)] ^ T2[B1(s23)] ^ T3[B0(s20)] ^ C[ 1+80]; + t4 = T0[B3(s22)] ^ T1[B2(s23)] ^ T2[B1(s20)] ^ T3[B0(s21)] ^ C[ 2+80]; + t5 = T0[B3(s23)] ^ T1[B2(s20)] ^ T2[B1(s21)] ^ T3[B0(s22)] ^ C[ 3+80] ^ ctrh; + t2 = T0[B3(s24)] ^ T1[B2(s25)] ^ T2[B1(s26)] ^ T3[B0(s27)] ^ C[ 4+80]; + t3 = T0[B3(s25)] ^ T1[B2(s26)] ^ T2[B1(s27)] ^ T3[B0(s24)] ^ C[ 5+80]; + t6 = T0[B3(s26)] ^ T1[B2(s27)] ^ T2[B1(s24)] ^ T3[B0(s25)] ^ C[ 6+80]; + t7 = T0[B3(s27)] ^ T1[B2(s24)] ^ T2[B1(s25)] ^ T3[B0(s26)] ^ C[ 7+80]; + + s20 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 8+80]; + s21 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 9+80]; + s24 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[10+80]; + s25 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[11+80] ^ ctrl; + s22 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[12+80]; + s23 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[13+80]; + s26 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[14+80]; + s27 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[15+80]; + + t0 = T0[B3(s20)] ^ T1[B2(s21)] ^ T2[B1(s22)] ^ T3[B0(s23)] ^ C[16+80]; + t1 = T0[B3(s21)] ^ T1[B2(s22)] ^ T2[B1(s23)] ^ T3[B0(s20)] ^ C[17+80]; + t4 = T0[B3(s22)] ^ T1[B2(s23)] ^ T2[B1(s20)] ^ T3[B0(s21)] ^ C[18+80]; + t5 = T0[B3(s23)] ^ T1[B2(s20)] ^ T2[B1(s21)] ^ T3[B0(s22)] ^ C[19+80] ^ ctrh; + t2 = T0[B3(s24)] ^ T1[B2(s25)] ^ T2[B1(s26)] ^ T3[B0(s27)] ^ C[20+80]; + t3 = T0[B3(s25)] ^ T1[B2(s26)] ^ T2[B1(s27)] ^ T3[B0(s24)] ^ C[21+80]; + t6 = T0[B3(s26)] ^ T1[B2(s27)] ^ T2[B1(s24)] ^ T3[B0(s25)] ^ C[22+80]; + t7 = T0[B3(s27)] ^ T1[B2(s24)] ^ T2[B1(s25)] ^ T3[B0(s26)] ^ C[23+80]; + + s20 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[24+80]; + s21 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[25+80]; + s24 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[26+80]; + s25 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[27+80] ^ ctrl; + s22 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[28+80]; + s23 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[29+80]; + s26 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[30+80]; + s27 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[31+80]; + + t0 = T0[B3(s20)] ^ T1[B2(s21)] ^ T2[B1(s22)] ^ T3[B0(s23)] ^ C[32+80]; + t1 = T0[B3(s21)] ^ T1[B2(s22)] ^ T2[B1(s23)] ^ T3[B0(s20)] ^ C[33+80]; + t4 = T0[B3(s22)] ^ T1[B2(s23)] ^ T2[B1(s20)] ^ T3[B0(s21)] ^ C[34+80]; + t5 = T0[B3(s23)] ^ T1[B2(s20)] ^ T2[B1(s21)] ^ T3[B0(s22)] ^ C[35+80] ^ ctrh; + t2 = T0[B3(s24)] ^ T1[B2(s25)] ^ T2[B1(s26)] ^ T3[B0(s27)] ^ C[36+80]; + t3 = T0[B3(s25)] ^ T1[B2(s26)] ^ T2[B1(s27)] ^ T3[B0(s24)] ^ C[37+80]; + t6 = T0[B3(s26)] ^ T1[B2(s27)] ^ T2[B1(s24)] ^ T3[B0(s25)] ^ C[38+80]; + t7 = T0[B3(s27)] ^ T1[B2(s24)] ^ T2[B1(s25)] ^ T3[B0(s26)] ^ C[39+80]; + + s60 ^= T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + s61 ^= T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + s64 ^= T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + s65 ^= T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + s62 ^= T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + s63 ^= T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + s66 ^= T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + s67 ^= T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + + /* Lane 3 */ + t0 = T0[B3(s30)] ^ T1[B2(s31)] ^ T2[B1(s32)] ^ T3[B0(s33)] ^ C[ 0+120]; + t1 = T0[B3(s31)] ^ T1[B2(s32)] ^ T2[B1(s33)] ^ T3[B0(s30)] ^ C[ 1+120]; + t4 = T0[B3(s32)] ^ T1[B2(s33)] ^ T2[B1(s30)] ^ T3[B0(s31)] ^ C[ 2+120]; + t5 = T0[B3(s33)] ^ T1[B2(s30)] ^ T2[B1(s31)] ^ T3[B0(s32)] ^ C[ 3+120] ^ ctrl; + t2 = T0[B3(s34)] ^ T1[B2(s35)] ^ T2[B1(s36)] ^ T3[B0(s37)] ^ C[ 4+120]; + t3 = T0[B3(s35)] ^ T1[B2(s36)] ^ T2[B1(s37)] ^ T3[B0(s34)] ^ C[ 5+120]; + t6 = T0[B3(s36)] ^ T1[B2(s37)] ^ T2[B1(s34)] ^ T3[B0(s35)] ^ C[ 6+120]; + t7 = T0[B3(s37)] ^ T1[B2(s34)] ^ T2[B1(s35)] ^ T3[B0(s36)] ^ C[ 7+120]; + + s30 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 8+120]; + s31 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 9+120]; + s34 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[10+120]; + s35 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[11+120] ^ ctrh; + s32 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[12+120]; + s33 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[13+120]; + s36 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[14+120]; + s37 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[15+120]; + + t0 = T0[B3(s30)] ^ T1[B2(s31)] ^ T2[B1(s32)] ^ T3[B0(s33)] ^ C[16+120]; + t1 = T0[B3(s31)] ^ T1[B2(s32)] ^ T2[B1(s33)] ^ T3[B0(s30)] ^ C[17+120]; + t4 = T0[B3(s32)] ^ T1[B2(s33)] ^ T2[B1(s30)] ^ T3[B0(s31)] ^ C[18+120]; + t5 = T0[B3(s33)] ^ T1[B2(s30)] ^ T2[B1(s31)] ^ T3[B0(s32)] ^ C[19+120] ^ ctrl; + t2 = T0[B3(s34)] ^ T1[B2(s35)] ^ T2[B1(s36)] ^ T3[B0(s37)] ^ C[20+120]; + t3 = T0[B3(s35)] ^ T1[B2(s36)] ^ T2[B1(s37)] ^ T3[B0(s34)] ^ C[21+120]; + t6 = T0[B3(s36)] ^ T1[B2(s37)] ^ T2[B1(s34)] ^ T3[B0(s35)] ^ C[22+120]; + t7 = T0[B3(s37)] ^ T1[B2(s34)] ^ T2[B1(s35)] ^ T3[B0(s36)] ^ C[23+120]; + + s30 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[24+120]; + s31 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[25+120]; + s34 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[26+120]; + s35 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[27+120] ^ ctrh; + s32 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[28+120]; + s33 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[29+120]; + s36 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[30+120]; + s37 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[31+120]; + + t0 = T0[B3(s30)] ^ T1[B2(s31)] ^ T2[B1(s32)] ^ T3[B0(s33)] ^ C[32+120]; + t1 = T0[B3(s31)] ^ T1[B2(s32)] ^ T2[B1(s33)] ^ T3[B0(s30)] ^ C[33+120]; + t4 = T0[B3(s32)] ^ T1[B2(s33)] ^ T2[B1(s30)] ^ T3[B0(s31)] ^ C[34+120]; + t5 = T0[B3(s33)] ^ T1[B2(s30)] ^ T2[B1(s31)] ^ T3[B0(s32)] ^ C[35+120] ^ ctrl; + t2 = T0[B3(s34)] ^ T1[B2(s35)] ^ T2[B1(s36)] ^ T3[B0(s37)] ^ C[36+120]; + t3 = T0[B3(s35)] ^ T1[B2(s36)] ^ T2[B1(s37)] ^ T3[B0(s34)] ^ C[37+120]; + t6 = T0[B3(s36)] ^ T1[B2(s37)] ^ T2[B1(s34)] ^ T3[B0(s35)] ^ C[38+120]; + t7 = T0[B3(s37)] ^ T1[B2(s34)] ^ T2[B1(s35)] ^ T3[B0(s36)] ^ C[39+120]; + + s70 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + s71 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + s74 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + s75 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + s72 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + s73 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + s76 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + s77 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + + /* Lane 4 */ + t0 = T0[B3(s40)] ^ T1[B2(s41)] ^ T2[B1(s42)] ^ T3[B0(s43)] ^ C[ 0+160]; + t1 = T0[B3(s41)] ^ T1[B2(s42)] ^ T2[B1(s43)] ^ T3[B0(s40)] ^ C[ 1+160]; + t4 = T0[B3(s42)] ^ T1[B2(s43)] ^ T2[B1(s40)] ^ T3[B0(s41)] ^ C[ 2+160]; + t5 = T0[B3(s43)] ^ T1[B2(s40)] ^ T2[B1(s41)] ^ T3[B0(s42)] ^ C[ 3+160] ^ ctrh; + t2 = T0[B3(s44)] ^ T1[B2(s45)] ^ T2[B1(s46)] ^ T3[B0(s47)] ^ C[ 4+160]; + t3 = T0[B3(s45)] ^ T1[B2(s46)] ^ T2[B1(s47)] ^ T3[B0(s44)] ^ C[ 5+160]; + t6 = T0[B3(s46)] ^ T1[B2(s47)] ^ T2[B1(s44)] ^ T3[B0(s45)] ^ C[ 6+160]; + t7 = T0[B3(s47)] ^ T1[B2(s44)] ^ T2[B1(s45)] ^ T3[B0(s46)] ^ C[ 7+160]; + + s40 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 8+160]; + s41 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 9+160]; + s44 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[10+160]; + s45 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[11+160] ^ ctrl; + s42 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[12+160]; + s43 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[13+160]; + s46 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[14+160]; + s47 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[15+160]; + + t0 = T0[B3(s40)] ^ T1[B2(s41)] ^ T2[B1(s42)] ^ T3[B0(s43)] ^ C[16+160]; + t1 = T0[B3(s41)] ^ T1[B2(s42)] ^ T2[B1(s43)] ^ T3[B0(s40)] ^ C[17+160]; + t4 = T0[B3(s42)] ^ T1[B2(s43)] ^ T2[B1(s40)] ^ T3[B0(s41)] ^ C[18+160]; + t5 = T0[B3(s43)] ^ T1[B2(s40)] ^ T2[B1(s41)] ^ T3[B0(s42)] ^ C[19+160] ^ ctrh; + t2 = T0[B3(s44)] ^ T1[B2(s45)] ^ T2[B1(s46)] ^ T3[B0(s47)] ^ C[20+160]; + t3 = T0[B3(s45)] ^ T1[B2(s46)] ^ T2[B1(s47)] ^ T3[B0(s44)] ^ C[21+160]; + t6 = T0[B3(s46)] ^ T1[B2(s47)] ^ T2[B1(s44)] ^ T3[B0(s45)] ^ C[22+160]; + t7 = T0[B3(s47)] ^ T1[B2(s44)] ^ T2[B1(s45)] ^ T3[B0(s46)] ^ C[23+160]; + + s40 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[24+160]; + s41 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[25+160]; + s44 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[26+160]; + s45 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[27+160] ^ ctrl; + s42 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[28+160]; + s43 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[29+160]; + s46 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[30+160]; + s47 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[31+160]; + + t0 = T0[B3(s40)] ^ T1[B2(s41)] ^ T2[B1(s42)] ^ T3[B0(s43)] ^ C[32+160]; + t1 = T0[B3(s41)] ^ T1[B2(s42)] ^ T2[B1(s43)] ^ T3[B0(s40)] ^ C[33+160]; + t4 = T0[B3(s42)] ^ T1[B2(s43)] ^ T2[B1(s40)] ^ T3[B0(s41)] ^ C[34+160]; + t5 = T0[B3(s43)] ^ T1[B2(s40)] ^ T2[B1(s41)] ^ T3[B0(s42)] ^ C[35+160] ^ ctrh; + t2 = T0[B3(s44)] ^ T1[B2(s45)] ^ T2[B1(s46)] ^ T3[B0(s47)] ^ C[36+160]; + t3 = T0[B3(s45)] ^ T1[B2(s46)] ^ T2[B1(s47)] ^ T3[B0(s44)] ^ C[37+160]; + t6 = T0[B3(s46)] ^ T1[B2(s47)] ^ T2[B1(s44)] ^ T3[B0(s45)] ^ C[38+160]; + t7 = T0[B3(s47)] ^ T1[B2(s44)] ^ T2[B1(s45)] ^ T3[B0(s46)] ^ C[39+160]; + + s70 ^= T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + s71 ^= T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + s74 ^= T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + s75 ^= T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + s72 ^= T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + s73 ^= T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + s76 ^= T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + s77 ^= T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + + /* Lane 5 */ + t0 = T0[B3(s50)] ^ T1[B2(s51)] ^ T2[B1(s52)] ^ T3[B0(s53)] ^ C[ 0+200]; + t1 = T0[B3(s51)] ^ T1[B2(s52)] ^ T2[B1(s53)] ^ T3[B0(s50)] ^ C[ 1+200]; + t4 = T0[B3(s52)] ^ T1[B2(s53)] ^ T2[B1(s50)] ^ T3[B0(s51)] ^ C[ 2+200]; + t5 = T0[B3(s53)] ^ T1[B2(s50)] ^ T2[B1(s51)] ^ T3[B0(s52)] ^ C[ 3+200] ^ ctrl; + t2 = T0[B3(s54)] ^ T1[B2(s55)] ^ T2[B1(s56)] ^ T3[B0(s57)] ^ C[ 4+200]; + t3 = T0[B3(s55)] ^ T1[B2(s56)] ^ T2[B1(s57)] ^ T3[B0(s54)] ^ C[ 5+200]; + t6 = T0[B3(s56)] ^ T1[B2(s57)] ^ T2[B1(s54)] ^ T3[B0(s55)] ^ C[ 6+200]; + t7 = T0[B3(s57)] ^ T1[B2(s54)] ^ T2[B1(s55)] ^ T3[B0(s56)] ^ C[ 7+200]; + + s50 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 8+200]; + s51 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 9+200]; + s54 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[10+200]; + s55 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[11+200] ^ ctrh; + s52 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[12+200]; + s53 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[13+200]; + s56 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[14+200]; + s57 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[15+200]; + + t0 = T0[B3(s50)] ^ T1[B2(s51)] ^ T2[B1(s52)] ^ T3[B0(s53)] ^ C[16+200]; + t1 = T0[B3(s51)] ^ T1[B2(s52)] ^ T2[B1(s53)] ^ T3[B0(s50)] ^ C[17+200]; + t4 = T0[B3(s52)] ^ T1[B2(s53)] ^ T2[B1(s50)] ^ T3[B0(s51)] ^ C[18+200]; + t5 = T0[B3(s53)] ^ T1[B2(s50)] ^ T2[B1(s51)] ^ T3[B0(s52)] ^ C[19+200] ^ ctrl; + t2 = T0[B3(s54)] ^ T1[B2(s55)] ^ T2[B1(s56)] ^ T3[B0(s57)] ^ C[20+200]; + t3 = T0[B3(s55)] ^ T1[B2(s56)] ^ T2[B1(s57)] ^ T3[B0(s54)] ^ C[21+200]; + t6 = T0[B3(s56)] ^ T1[B2(s57)] ^ T2[B1(s54)] ^ T3[B0(s55)] ^ C[22+200]; + t7 = T0[B3(s57)] ^ T1[B2(s54)] ^ T2[B1(s55)] ^ T3[B0(s56)] ^ C[23+200]; + + s50 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[24+200]; + s51 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[25+200]; + s54 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[26+200]; + s55 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[27+200] ^ ctrh; + s52 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[28+200]; + s53 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[29+200]; + s56 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[30+200]; + s57 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[31+200]; + + t0 = T0[B3(s50)] ^ T1[B2(s51)] ^ T2[B1(s52)] ^ T3[B0(s53)] ^ C[32+200]; + t1 = T0[B3(s51)] ^ T1[B2(s52)] ^ T2[B1(s53)] ^ T3[B0(s50)] ^ C[33+200]; + t4 = T0[B3(s52)] ^ T1[B2(s53)] ^ T2[B1(s50)] ^ T3[B0(s51)] ^ C[34+200]; + t5 = T0[B3(s53)] ^ T1[B2(s50)] ^ T2[B1(s51)] ^ T3[B0(s52)] ^ C[35+200] ^ ctrl; + t2 = T0[B3(s54)] ^ T1[B2(s55)] ^ T2[B1(s56)] ^ T3[B0(s57)] ^ C[36+200]; + t3 = T0[B3(s55)] ^ T1[B2(s56)] ^ T2[B1(s57)] ^ T3[B0(s54)] ^ C[37+200]; + t6 = T0[B3(s56)] ^ T1[B2(s57)] ^ T2[B1(s54)] ^ T3[B0(s55)] ^ C[38+200]; + t7 = T0[B3(s57)] ^ T1[B2(s54)] ^ T2[B1(s55)] ^ T3[B0(s56)] ^ C[39+200]; + + s70 ^= T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + s71 ^= T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + s74 ^= T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + s75 ^= T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + s72 ^= T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + s73 ^= T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + s76 ^= T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + s77 ^= T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + + /* Lane 6 */ + t0 = T0[B3(s60)] ^ T1[B2(s61)] ^ T2[B1(s62)] ^ T3[B0(s63)] ^ C[ 0+240]; + t1 = T0[B3(s61)] ^ T1[B2(s62)] ^ T2[B1(s63)] ^ T3[B0(s60)] ^ C[ 1+240]; + t4 = T0[B3(s62)] ^ T1[B2(s63)] ^ T2[B1(s60)] ^ T3[B0(s61)] ^ C[ 2+240]; + t5 = T0[B3(s63)] ^ T1[B2(s60)] ^ T2[B1(s61)] ^ T3[B0(s62)] ^ C[ 3+240] ^ ctrh; + t2 = T0[B3(s64)] ^ T1[B2(s65)] ^ T2[B1(s66)] ^ T3[B0(s67)] ^ C[ 4+240]; + t3 = T0[B3(s65)] ^ T1[B2(s66)] ^ T2[B1(s67)] ^ T3[B0(s64)] ^ C[ 5+240]; + t6 = T0[B3(s66)] ^ T1[B2(s67)] ^ T2[B1(s64)] ^ T3[B0(s65)] ^ C[ 6+240]; + t7 = T0[B3(s67)] ^ T1[B2(s64)] ^ T2[B1(s65)] ^ T3[B0(s66)] ^ C[ 7+240]; + + s60 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 8+240]; + s61 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 9+240]; + s64 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[10+240]; + s65 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[11+240] ^ ctrl; + s62 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[12+240]; + s63 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[13+240]; + s66 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[14+240]; + s67 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[15+240]; + + h[0] = T0[B3(s60)] ^ T1[B2(s61)] ^ T2[B1(s62)] ^ T3[B0(s63)]; + h[1] = T0[B3(s61)] ^ T1[B2(s62)] ^ T2[B1(s63)] ^ T3[B0(s60)]; + h[4] = T0[B3(s62)] ^ T1[B2(s63)] ^ T2[B1(s60)] ^ T3[B0(s61)]; + h[5] = T0[B3(s63)] ^ T1[B2(s60)] ^ T2[B1(s61)] ^ T3[B0(s62)]; + h[2] = T0[B3(s64)] ^ T1[B2(s65)] ^ T2[B1(s66)] ^ T3[B0(s67)]; + h[3] = T0[B3(s65)] ^ T1[B2(s66)] ^ T2[B1(s67)] ^ T3[B0(s64)]; + h[6] = T0[B3(s66)] ^ T1[B2(s67)] ^ T2[B1(s64)] ^ T3[B0(s65)]; + h[7] = T0[B3(s67)] ^ T1[B2(s64)] ^ T2[B1(s65)] ^ T3[B0(s66)]; + + /* Lane 7 */ + t0 = T0[B3(s70)] ^ T1[B2(s71)] ^ T2[B1(s72)] ^ T3[B0(s73)] ^ C[ 0+256]; + t1 = T0[B3(s71)] ^ T1[B2(s72)] ^ T2[B1(s73)] ^ T3[B0(s70)] ^ C[ 1+256]; + t4 = T0[B3(s72)] ^ T1[B2(s73)] ^ T2[B1(s70)] ^ T3[B0(s71)] ^ C[ 2+256]; + t5 = T0[B3(s73)] ^ T1[B2(s70)] ^ T2[B1(s71)] ^ T3[B0(s72)] ^ C[ 3+256] ^ ctrh; + t2 = T0[B3(s74)] ^ T1[B2(s75)] ^ T2[B1(s76)] ^ T3[B0(s77)] ^ C[ 4+256]; + t3 = T0[B3(s75)] ^ T1[B2(s76)] ^ T2[B1(s77)] ^ T3[B0(s74)] ^ C[ 5+256]; + t6 = T0[B3(s76)] ^ T1[B2(s77)] ^ T2[B1(s74)] ^ T3[B0(s75)] ^ C[ 6+256]; + t7 = T0[B3(s77)] ^ T1[B2(s74)] ^ T2[B1(s75)] ^ T3[B0(s76)] ^ C[ 7+256]; + + s70 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 8+256]; + s71 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 9+256]; + s74 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[10+256]; + s75 = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[11+256] ^ ctrl; + s72 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[12+256]; + s73 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[13+256]; + s76 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[14+256]; + s77 = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[15+256]; + + h[0] ^= T0[B3(s70)] ^ T1[B2(s71)] ^ T2[B1(s72)] ^ T3[B0(s73)]; + h[1] ^= T0[B3(s71)] ^ T1[B2(s72)] ^ T2[B1(s73)] ^ T3[B0(s70)]; + h[4] ^= T0[B3(s72)] ^ T1[B2(s73)] ^ T2[B1(s70)] ^ T3[B0(s71)]; + h[5] ^= T0[B3(s73)] ^ T1[B2(s70)] ^ T2[B1(s71)] ^ T3[B0(s72)]; + h[2] ^= T0[B3(s74)] ^ T1[B2(s75)] ^ T2[B1(s76)] ^ T3[B0(s77)]; + h[3] ^= T0[B3(s75)] ^ T1[B2(s76)] ^ T2[B1(s77)] ^ T3[B0(s74)]; + h[6] ^= T0[B3(s76)] ^ T1[B2(s77)] ^ T2[B1(s74)] ^ T3[B0(s75)]; + h[7] ^= T0[B3(s77)] ^ T1[B2(s74)] ^ T2[B1(s75)] ^ T3[B0(s76)]; +} + +void lane512_compress(const u8 m[128], u32 h[16], const u32 ctrh, const u32 ctrl) +{ + u32 t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, ta, tb, tc, td, te, tf; /* temp */ + u32 s00, s01, s02, s03, s04, s05, s06, s07, s08, s09, s0a, s0b, s0c, s0d, s0e, s0f; /* lane 0 */ + u32 s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s1a, s1b, s1c, s1d, s1e, s1f; /* lane 1 */ + u32 s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s2a, s2b, s2c, s2d, s2e, s2f; /* lane 2 */ + u32 s30, s31, s32, s33, s34, s35, s36, s37, s38, s39, s3a, s3b, s3c, s3d, s3e, s3f; /* lane 3 */ + u32 s40, s41, s42, s43, s44, s45, s46, s47, s48, s49, s4a, s4b, s4c, s4d, s4e, s4f; /* lane 4 */ + u32 s50, s51, s52, s53, s54, s55, s56, s57, s58, s59, s5a, s5b, s5c, s5d, s5e, s5f; /* lane 5 */ + u32 s60, s61, s62, s63, s64, s65, s66, s67, s68, s69, s6a, s6b, s6c, s6d, s6e, s6f; /* lane 6 */ + u32 s70, s71, s72, s73, s74, s75, s76, s77, s78, s79, s7a, s7b, s7c, s7d, s7e, s7f; /* lane 7 */ + + /* Message expansion */ + s30 = h[0]; + s31 = h[1]; + s32 = h[2]; + s33 = h[3]; + s34 = h[4]; + s35 = h[5]; + s36 = h[6]; + s37 = h[7]; + s38 = h[8]; + s39 = h[9]; + s3a = h[10]; + s3b = h[11]; + s3c = h[12]; + s3d = h[13]; + s3e = h[14]; + s3f = h[15]; + s40 = U8TO32_BIG(m + 0); + s41 = U8TO32_BIG(m + 4); + s42 = U8TO32_BIG(m + 8); + s43 = U8TO32_BIG(m + 12); + s44 = U8TO32_BIG(m + 16); + s45 = U8TO32_BIG(m + 20); + s46 = U8TO32_BIG(m + 24); + s47 = U8TO32_BIG(m + 28); + s48 = U8TO32_BIG(m + 32); + s49 = U8TO32_BIG(m + 36); + s4a = U8TO32_BIG(m + 40); + s4b = U8TO32_BIG(m + 44); + s4c = U8TO32_BIG(m + 48); + s4d = U8TO32_BIG(m + 52); + s4e = U8TO32_BIG(m + 56); + s4f = U8TO32_BIG(m + 60); + s50 = U8TO32_BIG(m + 64); + s51 = U8TO32_BIG(m + 68); + s52 = U8TO32_BIG(m + 72); + s53 = U8TO32_BIG(m + 76); + s54 = U8TO32_BIG(m + 80); + s55 = U8TO32_BIG(m + 84); + s56 = U8TO32_BIG(m + 88); + s57 = U8TO32_BIG(m + 92); + s58 = U8TO32_BIG(m + 96); + s59 = U8TO32_BIG(m + 100); + s5a = U8TO32_BIG(m + 104); + s5b = U8TO32_BIG(m + 108); + s5c = U8TO32_BIG(m + 112); + s5d = U8TO32_BIG(m + 116); + s5e = U8TO32_BIG(m + 120); + s5f = U8TO32_BIG(m + 124); + s00 = s30 ^ s40 ^ s48 ^ s50 ^ s58; + s01 = s31 ^ s41 ^ s49 ^ s51 ^ s59; + s02 = s32 ^ s42 ^ s4a ^ s52 ^ s5a; + s03 = s33 ^ s43 ^ s4b ^ s53 ^ s5b; + s04 = s34 ^ s44 ^ s4c ^ s54 ^ s5c; + s05 = s35 ^ s45 ^ s4d ^ s55 ^ s5d; + s06 = s36 ^ s46 ^ s4e ^ s56 ^ s5e; + s07 = s37 ^ s47 ^ s4f ^ s57 ^ s5f; + s08 = s38 ^ s40 ^ s50; + s09 = s39 ^ s41 ^ s51; + s0a = s3a ^ s42 ^ s52; + s0b = s3b ^ s43 ^ s53; + s0c = s3c ^ s44 ^ s54; + s0d = s3d ^ s45 ^ s55; + s0e = s3e ^ s46 ^ s56; + s0f = s3f ^ s47 ^ s57; + s10 = s00 ^ s38 ^ s48; + s11 = s01 ^ s39 ^ s49; + s12 = s02 ^ s3a ^ s4a; + s13 = s03 ^ s3b ^ s4b; + s14 = s04 ^ s3c ^ s4c; + s15 = s05 ^ s3d ^ s4d; + s16 = s06 ^ s3e ^ s4e; + s17 = s07 ^ s3f ^ s4f; + s18 = s30 ^ s48 ^ s50; + s19 = s31 ^ s49 ^ s51; + s1a = s32 ^ s4a ^ s52; + s1b = s33 ^ s4b ^ s53; + s1c = s34 ^ s4c ^ s54; + s1d = s35 ^ s4d ^ s55; + s1e = s36 ^ s4e ^ s56; + s1f = s37 ^ s4f ^ s57; + s20 = s00 ^ s38 ^ s58; + s21 = s01 ^ s39 ^ s59; + s22 = s02 ^ s3a ^ s5a; + s23 = s03 ^ s3b ^ s5b; + s24 = s04 ^ s3c ^ s5c; + s25 = s05 ^ s3d ^ s5d; + s26 = s06 ^ s3e ^ s5e; + s27 = s07 ^ s3f ^ s5f; + s28 = s30 ^ s40 ^ s58; + s29 = s31 ^ s41 ^ s59; + s2a = s32 ^ s42 ^ s5a; + s2b = s33 ^ s43 ^ s5b; + s2c = s34 ^ s44 ^ s5c; + s2d = s35 ^ s45 ^ s5d; + s2e = s36 ^ s46 ^ s5e; + s2f = s37 ^ s47 ^ s5f; + + /* Lane 0 */ + t0 = T0[B3(s00)] ^ T1[B2(s01)] ^ T2[B1(s02)] ^ T3[B0(s03)] ^ C[ 0]; + t4 = T0[B3(s01)] ^ T1[B2(s02)] ^ T2[B1(s03)] ^ T3[B0(s00)] ^ C[ 1]; + t8 = T0[B3(s02)] ^ T1[B2(s03)] ^ T2[B1(s00)] ^ T3[B0(s01)] ^ C[ 2]; + tc = T0[B3(s03)] ^ T1[B2(s00)] ^ T2[B1(s01)] ^ T3[B0(s02)] ^ C[ 3] ^ ctrh; + t1 = T0[B3(s04)] ^ T1[B2(s05)] ^ T2[B1(s06)] ^ T3[B0(s07)] ^ C[ 4]; + t5 = T0[B3(s05)] ^ T1[B2(s06)] ^ T2[B1(s07)] ^ T3[B0(s04)] ^ C[ 5]; + t9 = T0[B3(s06)] ^ T1[B2(s07)] ^ T2[B1(s04)] ^ T3[B0(s05)] ^ C[ 6]; + td = T0[B3(s07)] ^ T1[B2(s04)] ^ T2[B1(s05)] ^ T3[B0(s06)] ^ C[ 7]; + t2 = T0[B3(s08)] ^ T1[B2(s09)] ^ T2[B1(s0a)] ^ T3[B0(s0b)] ^ C[ 8]; + t6 = T0[B3(s09)] ^ T1[B2(s0a)] ^ T2[B1(s0b)] ^ T3[B0(s08)] ^ C[ 9]; + ta = T0[B3(s0a)] ^ T1[B2(s0b)] ^ T2[B1(s08)] ^ T3[B0(s09)] ^ C[ 10]; + te = T0[B3(s0b)] ^ T1[B2(s08)] ^ T2[B1(s09)] ^ T3[B0(s0a)] ^ C[ 11]; + t3 = T0[B3(s0c)] ^ T1[B2(s0d)] ^ T2[B1(s0e)] ^ T3[B0(s0f)] ^ C[ 12]; + t7 = T0[B3(s0d)] ^ T1[B2(s0e)] ^ T2[B1(s0f)] ^ T3[B0(s0c)] ^ C[ 13]; + tb = T0[B3(s0e)] ^ T1[B2(s0f)] ^ T2[B1(s0c)] ^ T3[B0(s0d)] ^ C[ 14]; + tf = T0[B3(s0f)] ^ T1[B2(s0c)] ^ T2[B1(s0d)] ^ T3[B0(s0e)] ^ C[ 15]; + + s00 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 16]; + s04 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 17]; + s08 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 18]; + s0c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 19] ^ ctrl; + s01 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 20]; + s05 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 21]; + s09 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 22]; + s0d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 23]; + s02 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 24]; + s06 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 25]; + s0a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 26]; + s0e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 27]; + s03 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 28]; + s07 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 29]; + s0b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 30]; + s0f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 31]; + + t0 = T0[B3(s00)] ^ T1[B2(s01)] ^ T2[B1(s02)] ^ T3[B0(s03)] ^ C[ 32]; + t4 = T0[B3(s01)] ^ T1[B2(s02)] ^ T2[B1(s03)] ^ T3[B0(s00)] ^ C[ 33]; + t8 = T0[B3(s02)] ^ T1[B2(s03)] ^ T2[B1(s00)] ^ T3[B0(s01)] ^ C[ 34]; + tc = T0[B3(s03)] ^ T1[B2(s00)] ^ T2[B1(s01)] ^ T3[B0(s02)] ^ C[ 35] ^ ctrh; + t1 = T0[B3(s04)] ^ T1[B2(s05)] ^ T2[B1(s06)] ^ T3[B0(s07)] ^ C[ 36]; + t5 = T0[B3(s05)] ^ T1[B2(s06)] ^ T2[B1(s07)] ^ T3[B0(s04)] ^ C[ 37]; + t9 = T0[B3(s06)] ^ T1[B2(s07)] ^ T2[B1(s04)] ^ T3[B0(s05)] ^ C[ 38]; + td = T0[B3(s07)] ^ T1[B2(s04)] ^ T2[B1(s05)] ^ T3[B0(s06)] ^ C[ 39]; + t2 = T0[B3(s08)] ^ T1[B2(s09)] ^ T2[B1(s0a)] ^ T3[B0(s0b)] ^ C[ 40]; + t6 = T0[B3(s09)] ^ T1[B2(s0a)] ^ T2[B1(s0b)] ^ T3[B0(s08)] ^ C[ 41]; + ta = T0[B3(s0a)] ^ T1[B2(s0b)] ^ T2[B1(s08)] ^ T3[B0(s09)] ^ C[ 42]; + te = T0[B3(s0b)] ^ T1[B2(s08)] ^ T2[B1(s09)] ^ T3[B0(s0a)] ^ C[ 43]; + t3 = T0[B3(s0c)] ^ T1[B2(s0d)] ^ T2[B1(s0e)] ^ T3[B0(s0f)] ^ C[ 44]; + t7 = T0[B3(s0d)] ^ T1[B2(s0e)] ^ T2[B1(s0f)] ^ T3[B0(s0c)] ^ C[ 45]; + tb = T0[B3(s0e)] ^ T1[B2(s0f)] ^ T2[B1(s0c)] ^ T3[B0(s0d)] ^ C[ 46]; + tf = T0[B3(s0f)] ^ T1[B2(s0c)] ^ T2[B1(s0d)] ^ T3[B0(s0e)] ^ C[ 47]; + + s00 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 48]; + s04 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 49]; + s08 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 50]; + s0c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 51] ^ ctrl; + s01 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 52]; + s05 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 53]; + s09 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 54]; + s0d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 55]; + s02 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 56]; + s06 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 57]; + s0a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 58]; + s0e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 59]; + s03 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 60]; + s07 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 61]; + s0b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 62]; + s0f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 63]; + + t0 = T0[B3(s00)] ^ T1[B2(s01)] ^ T2[B1(s02)] ^ T3[B0(s03)] ^ C[ 64]; + t4 = T0[B3(s01)] ^ T1[B2(s02)] ^ T2[B1(s03)] ^ T3[B0(s00)] ^ C[ 65]; + t8 = T0[B3(s02)] ^ T1[B2(s03)] ^ T2[B1(s00)] ^ T3[B0(s01)] ^ C[ 66]; + tc = T0[B3(s03)] ^ T1[B2(s00)] ^ T2[B1(s01)] ^ T3[B0(s02)] ^ C[ 67] ^ ctrh; + t1 = T0[B3(s04)] ^ T1[B2(s05)] ^ T2[B1(s06)] ^ T3[B0(s07)] ^ C[ 68]; + t5 = T0[B3(s05)] ^ T1[B2(s06)] ^ T2[B1(s07)] ^ T3[B0(s04)] ^ C[ 69]; + t9 = T0[B3(s06)] ^ T1[B2(s07)] ^ T2[B1(s04)] ^ T3[B0(s05)] ^ C[ 70]; + td = T0[B3(s07)] ^ T1[B2(s04)] ^ T2[B1(s05)] ^ T3[B0(s06)] ^ C[ 71]; + t2 = T0[B3(s08)] ^ T1[B2(s09)] ^ T2[B1(s0a)] ^ T3[B0(s0b)] ^ C[ 72]; + t6 = T0[B3(s09)] ^ T1[B2(s0a)] ^ T2[B1(s0b)] ^ T3[B0(s08)] ^ C[ 73]; + ta = T0[B3(s0a)] ^ T1[B2(s0b)] ^ T2[B1(s08)] ^ T3[B0(s09)] ^ C[ 74]; + te = T0[B3(s0b)] ^ T1[B2(s08)] ^ T2[B1(s09)] ^ T3[B0(s0a)] ^ C[ 75]; + t3 = T0[B3(s0c)] ^ T1[B2(s0d)] ^ T2[B1(s0e)] ^ T3[B0(s0f)] ^ C[ 76]; + t7 = T0[B3(s0d)] ^ T1[B2(s0e)] ^ T2[B1(s0f)] ^ T3[B0(s0c)] ^ C[ 77]; + tb = T0[B3(s0e)] ^ T1[B2(s0f)] ^ T2[B1(s0c)] ^ T3[B0(s0d)] ^ C[ 78]; + tf = T0[B3(s0f)] ^ T1[B2(s0c)] ^ T2[B1(s0d)] ^ T3[B0(s0e)] ^ C[ 79]; + + s00 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 80]; + s04 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 81]; + s08 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 82]; + s0c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 83] ^ ctrl; + s01 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 84]; + s05 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 85]; + s09 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 86]; + s0d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 87]; + s02 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 88]; + s06 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 89]; + s0a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 90]; + s0e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 91]; + s03 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 92]; + s07 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 93]; + s0b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 94]; + s0f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 95]; + + t0 = T0[B3(s00)] ^ T1[B2(s01)] ^ T2[B1(s02)] ^ T3[B0(s03)] ^ C[ 96]; + t4 = T0[B3(s01)] ^ T1[B2(s02)] ^ T2[B1(s03)] ^ T3[B0(s00)] ^ C[ 97]; + t8 = T0[B3(s02)] ^ T1[B2(s03)] ^ T2[B1(s00)] ^ T3[B0(s01)] ^ C[ 98]; + tc = T0[B3(s03)] ^ T1[B2(s00)] ^ T2[B1(s01)] ^ T3[B0(s02)] ^ C[ 99] ^ ctrh; + t1 = T0[B3(s04)] ^ T1[B2(s05)] ^ T2[B1(s06)] ^ T3[B0(s07)] ^ C[100]; + t5 = T0[B3(s05)] ^ T1[B2(s06)] ^ T2[B1(s07)] ^ T3[B0(s04)] ^ C[101]; + t9 = T0[B3(s06)] ^ T1[B2(s07)] ^ T2[B1(s04)] ^ T3[B0(s05)] ^ C[102]; + td = T0[B3(s07)] ^ T1[B2(s04)] ^ T2[B1(s05)] ^ T3[B0(s06)] ^ C[103]; + t2 = T0[B3(s08)] ^ T1[B2(s09)] ^ T2[B1(s0a)] ^ T3[B0(s0b)] ^ C[104]; + t6 = T0[B3(s09)] ^ T1[B2(s0a)] ^ T2[B1(s0b)] ^ T3[B0(s08)] ^ C[105]; + ta = T0[B3(s0a)] ^ T1[B2(s0b)] ^ T2[B1(s08)] ^ T3[B0(s09)] ^ C[106]; + te = T0[B3(s0b)] ^ T1[B2(s08)] ^ T2[B1(s09)] ^ T3[B0(s0a)] ^ C[107]; + t3 = T0[B3(s0c)] ^ T1[B2(s0d)] ^ T2[B1(s0e)] ^ T3[B0(s0f)] ^ C[108]; + t7 = T0[B3(s0d)] ^ T1[B2(s0e)] ^ T2[B1(s0f)] ^ T3[B0(s0c)] ^ C[109]; + tb = T0[B3(s0e)] ^ T1[B2(s0f)] ^ T2[B1(s0c)] ^ T3[B0(s0d)] ^ C[110]; + tf = T0[B3(s0f)] ^ T1[B2(s0c)] ^ T2[B1(s0d)] ^ T3[B0(s0e)] ^ C[111]; + + s60 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + s64 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + s68 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + s6c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + s61 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + s65 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + s69 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + s6d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + s62 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )]; + s66 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )]; + s6a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )]; + s6e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )]; + s63 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )]; + s67 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )]; + s6b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )]; + s6f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )]; + + /* Lane 1 */ + t0 = T0[B3(s10)] ^ T1[B2(s11)] ^ T2[B1(s12)] ^ T3[B0(s13)] ^ C[ 0+112]; + t4 = T0[B3(s11)] ^ T1[B2(s12)] ^ T2[B1(s13)] ^ T3[B0(s10)] ^ C[ 1+112]; + t8 = T0[B3(s12)] ^ T1[B2(s13)] ^ T2[B1(s10)] ^ T3[B0(s11)] ^ C[ 2+112]; + tc = T0[B3(s13)] ^ T1[B2(s10)] ^ T2[B1(s11)] ^ T3[B0(s12)] ^ C[ 3+112] ^ ctrl; + t1 = T0[B3(s14)] ^ T1[B2(s15)] ^ T2[B1(s16)] ^ T3[B0(s17)] ^ C[ 4+112]; + t5 = T0[B3(s15)] ^ T1[B2(s16)] ^ T2[B1(s17)] ^ T3[B0(s14)] ^ C[ 5+112]; + t9 = T0[B3(s16)] ^ T1[B2(s17)] ^ T2[B1(s14)] ^ T3[B0(s15)] ^ C[ 6+112]; + td = T0[B3(s17)] ^ T1[B2(s14)] ^ T2[B1(s15)] ^ T3[B0(s16)] ^ C[ 7+112]; + t2 = T0[B3(s18)] ^ T1[B2(s19)] ^ T2[B1(s1a)] ^ T3[B0(s1b)] ^ C[ 8+112]; + t6 = T0[B3(s19)] ^ T1[B2(s1a)] ^ T2[B1(s1b)] ^ T3[B0(s18)] ^ C[ 9+112]; + ta = T0[B3(s1a)] ^ T1[B2(s1b)] ^ T2[B1(s18)] ^ T3[B0(s19)] ^ C[ 10+112]; + te = T0[B3(s1b)] ^ T1[B2(s18)] ^ T2[B1(s19)] ^ T3[B0(s1a)] ^ C[ 11+112]; + t3 = T0[B3(s1c)] ^ T1[B2(s1d)] ^ T2[B1(s1e)] ^ T3[B0(s1f)] ^ C[ 12+112]; + t7 = T0[B3(s1d)] ^ T1[B2(s1e)] ^ T2[B1(s1f)] ^ T3[B0(s1c)] ^ C[ 13+112]; + tb = T0[B3(s1e)] ^ T1[B2(s1f)] ^ T2[B1(s1c)] ^ T3[B0(s1d)] ^ C[ 14+112]; + tf = T0[B3(s1f)] ^ T1[B2(s1c)] ^ T2[B1(s1d)] ^ T3[B0(s1e)] ^ C[ 15+112]; + + s10 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 16+112]; + s14 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 17+112]; + s18 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 18+112]; + s1c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 19+112] ^ ctrh; + s11 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 20+112]; + s15 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 21+112]; + s19 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 22+112]; + s1d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 23+112]; + s12 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 24+112]; + s16 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 25+112]; + s1a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 26+112]; + s1e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 27+112]; + s13 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 28+112]; + s17 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 29+112]; + s1b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 30+112]; + s1f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 31+112]; + + t0 = T0[B3(s10)] ^ T1[B2(s11)] ^ T2[B1(s12)] ^ T3[B0(s13)] ^ C[ 32+112]; + t4 = T0[B3(s11)] ^ T1[B2(s12)] ^ T2[B1(s13)] ^ T3[B0(s10)] ^ C[ 33+112]; + t8 = T0[B3(s12)] ^ T1[B2(s13)] ^ T2[B1(s10)] ^ T3[B0(s11)] ^ C[ 34+112]; + tc = T0[B3(s13)] ^ T1[B2(s10)] ^ T2[B1(s11)] ^ T3[B0(s12)] ^ C[ 35+112] ^ ctrl; + t1 = T0[B3(s14)] ^ T1[B2(s15)] ^ T2[B1(s16)] ^ T3[B0(s17)] ^ C[ 36+112]; + t5 = T0[B3(s15)] ^ T1[B2(s16)] ^ T2[B1(s17)] ^ T3[B0(s14)] ^ C[ 37+112]; + t9 = T0[B3(s16)] ^ T1[B2(s17)] ^ T2[B1(s14)] ^ T3[B0(s15)] ^ C[ 38+112]; + td = T0[B3(s17)] ^ T1[B2(s14)] ^ T2[B1(s15)] ^ T3[B0(s16)] ^ C[ 39+112]; + t2 = T0[B3(s18)] ^ T1[B2(s19)] ^ T2[B1(s1a)] ^ T3[B0(s1b)] ^ C[ 40+112]; + t6 = T0[B3(s19)] ^ T1[B2(s1a)] ^ T2[B1(s1b)] ^ T3[B0(s18)] ^ C[ 41+112]; + ta = T0[B3(s1a)] ^ T1[B2(s1b)] ^ T2[B1(s18)] ^ T3[B0(s19)] ^ C[ 42+112]; + te = T0[B3(s1b)] ^ T1[B2(s18)] ^ T2[B1(s19)] ^ T3[B0(s1a)] ^ C[ 43+112]; + t3 = T0[B3(s1c)] ^ T1[B2(s1d)] ^ T2[B1(s1e)] ^ T3[B0(s1f)] ^ C[ 44+112]; + t7 = T0[B3(s1d)] ^ T1[B2(s1e)] ^ T2[B1(s1f)] ^ T3[B0(s1c)] ^ C[ 45+112]; + tb = T0[B3(s1e)] ^ T1[B2(s1f)] ^ T2[B1(s1c)] ^ T3[B0(s1d)] ^ C[ 46+112]; + tf = T0[B3(s1f)] ^ T1[B2(s1c)] ^ T2[B1(s1d)] ^ T3[B0(s1e)] ^ C[ 47+112]; + + s10 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 48+112]; + s14 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 49+112]; + s18 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 50+112]; + s1c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 51+112] ^ ctrh; + s11 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 52+112]; + s15 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 53+112]; + s19 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 54+112]; + s1d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 55+112]; + s12 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 56+112]; + s16 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 57+112]; + s1a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 58+112]; + s1e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 59+112]; + s13 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 60+112]; + s17 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 61+112]; + s1b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 62+112]; + s1f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 63+112]; + + t0 = T0[B3(s10)] ^ T1[B2(s11)] ^ T2[B1(s12)] ^ T3[B0(s13)] ^ C[ 64+112]; + t4 = T0[B3(s11)] ^ T1[B2(s12)] ^ T2[B1(s13)] ^ T3[B0(s10)] ^ C[ 65+112]; + t8 = T0[B3(s12)] ^ T1[B2(s13)] ^ T2[B1(s10)] ^ T3[B0(s11)] ^ C[ 66+112]; + tc = T0[B3(s13)] ^ T1[B2(s10)] ^ T2[B1(s11)] ^ T3[B0(s12)] ^ C[ 67+112] ^ ctrl; + t1 = T0[B3(s14)] ^ T1[B2(s15)] ^ T2[B1(s16)] ^ T3[B0(s17)] ^ C[ 68+112]; + t5 = T0[B3(s15)] ^ T1[B2(s16)] ^ T2[B1(s17)] ^ T3[B0(s14)] ^ C[ 69+112]; + t9 = T0[B3(s16)] ^ T1[B2(s17)] ^ T2[B1(s14)] ^ T3[B0(s15)] ^ C[ 70+112]; + td = T0[B3(s17)] ^ T1[B2(s14)] ^ T2[B1(s15)] ^ T3[B0(s16)] ^ C[ 71+112]; + t2 = T0[B3(s18)] ^ T1[B2(s19)] ^ T2[B1(s1a)] ^ T3[B0(s1b)] ^ C[ 72+112]; + t6 = T0[B3(s19)] ^ T1[B2(s1a)] ^ T2[B1(s1b)] ^ T3[B0(s18)] ^ C[ 73+112]; + ta = T0[B3(s1a)] ^ T1[B2(s1b)] ^ T2[B1(s18)] ^ T3[B0(s19)] ^ C[ 74+112]; + te = T0[B3(s1b)] ^ T1[B2(s18)] ^ T2[B1(s19)] ^ T3[B0(s1a)] ^ C[ 75+112]; + t3 = T0[B3(s1c)] ^ T1[B2(s1d)] ^ T2[B1(s1e)] ^ T3[B0(s1f)] ^ C[ 76+112]; + t7 = T0[B3(s1d)] ^ T1[B2(s1e)] ^ T2[B1(s1f)] ^ T3[B0(s1c)] ^ C[ 77+112]; + tb = T0[B3(s1e)] ^ T1[B2(s1f)] ^ T2[B1(s1c)] ^ T3[B0(s1d)] ^ C[ 78+112]; + tf = T0[B3(s1f)] ^ T1[B2(s1c)] ^ T2[B1(s1d)] ^ T3[B0(s1e)] ^ C[ 79+112]; + + s10 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 80+112]; + s14 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 81+112]; + s18 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 82+112]; + s1c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 83+112] ^ ctrh; + s11 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 84+112]; + s15 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 85+112]; + s19 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 86+112]; + s1d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 87+112]; + s12 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 88+112]; + s16 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 89+112]; + s1a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 90+112]; + s1e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 91+112]; + s13 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 92+112]; + s17 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 93+112]; + s1b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 94+112]; + s1f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 95+112]; + + t0 = T0[B3(s10)] ^ T1[B2(s11)] ^ T2[B1(s12)] ^ T3[B0(s13)] ^ C[ 96+112]; + t4 = T0[B3(s11)] ^ T1[B2(s12)] ^ T2[B1(s13)] ^ T3[B0(s10)] ^ C[ 97+112]; + t8 = T0[B3(s12)] ^ T1[B2(s13)] ^ T2[B1(s10)] ^ T3[B0(s11)] ^ C[ 98+112]; + tc = T0[B3(s13)] ^ T1[B2(s10)] ^ T2[B1(s11)] ^ T3[B0(s12)] ^ C[ 99+112] ^ ctrl; + t1 = T0[B3(s14)] ^ T1[B2(s15)] ^ T2[B1(s16)] ^ T3[B0(s17)] ^ C[100+112]; + t5 = T0[B3(s15)] ^ T1[B2(s16)] ^ T2[B1(s17)] ^ T3[B0(s14)] ^ C[101+112]; + t9 = T0[B3(s16)] ^ T1[B2(s17)] ^ T2[B1(s14)] ^ T3[B0(s15)] ^ C[102+112]; + td = T0[B3(s17)] ^ T1[B2(s14)] ^ T2[B1(s15)] ^ T3[B0(s16)] ^ C[103+112]; + t2 = T0[B3(s18)] ^ T1[B2(s19)] ^ T2[B1(s1a)] ^ T3[B0(s1b)] ^ C[104+112]; + t6 = T0[B3(s19)] ^ T1[B2(s1a)] ^ T2[B1(s1b)] ^ T3[B0(s18)] ^ C[105+112]; + ta = T0[B3(s1a)] ^ T1[B2(s1b)] ^ T2[B1(s18)] ^ T3[B0(s19)] ^ C[106+112]; + te = T0[B3(s1b)] ^ T1[B2(s18)] ^ T2[B1(s19)] ^ T3[B0(s1a)] ^ C[107+112]; + t3 = T0[B3(s1c)] ^ T1[B2(s1d)] ^ T2[B1(s1e)] ^ T3[B0(s1f)] ^ C[108+112]; + t7 = T0[B3(s1d)] ^ T1[B2(s1e)] ^ T2[B1(s1f)] ^ T3[B0(s1c)] ^ C[109+112]; + tb = T0[B3(s1e)] ^ T1[B2(s1f)] ^ T2[B1(s1c)] ^ T3[B0(s1d)] ^ C[110+112]; + tf = T0[B3(s1f)] ^ T1[B2(s1c)] ^ T2[B1(s1d)] ^ T3[B0(s1e)] ^ C[111+112]; + + s60 ^= T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + s64 ^= T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + s68 ^= T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + s6c ^= T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + s61 ^= T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + s65 ^= T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + s69 ^= T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + s6d ^= T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + s62 ^= T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )]; + s66 ^= T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )]; + s6a ^= T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )]; + s6e ^= T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )]; + s63 ^= T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )]; + s67 ^= T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )]; + s6b ^= T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )]; + s6f ^= T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )]; + + /* Lane 2 */ + t0 = T0[B3(s20)] ^ T1[B2(s21)] ^ T2[B1(s22)] ^ T3[B0(s23)] ^ C[ 0+224]; + t4 = T0[B3(s21)] ^ T1[B2(s22)] ^ T2[B1(s23)] ^ T3[B0(s20)] ^ C[ 1+224]; + t8 = T0[B3(s22)] ^ T1[B2(s23)] ^ T2[B1(s20)] ^ T3[B0(s21)] ^ C[ 2+224]; + tc = T0[B3(s23)] ^ T1[B2(s20)] ^ T2[B1(s21)] ^ T3[B0(s22)] ^ C[ 3+224] ^ ctrh; + t1 = T0[B3(s24)] ^ T1[B2(s25)] ^ T2[B1(s26)] ^ T3[B0(s27)] ^ C[ 4+224]; + t5 = T0[B3(s25)] ^ T1[B2(s26)] ^ T2[B1(s27)] ^ T3[B0(s24)] ^ C[ 5+224]; + t9 = T0[B3(s26)] ^ T1[B2(s27)] ^ T2[B1(s24)] ^ T3[B0(s25)] ^ C[ 6+224]; + td = T0[B3(s27)] ^ T1[B2(s24)] ^ T2[B1(s25)] ^ T3[B0(s26)] ^ C[ 7+224]; + t2 = T0[B3(s28)] ^ T1[B2(s29)] ^ T2[B1(s2a)] ^ T3[B0(s2b)] ^ C[ 8+224]; + t6 = T0[B3(s29)] ^ T1[B2(s2a)] ^ T2[B1(s2b)] ^ T3[B0(s28)] ^ C[ 9+224]; + ta = T0[B3(s2a)] ^ T1[B2(s2b)] ^ T2[B1(s28)] ^ T3[B0(s29)] ^ C[ 10+224]; + te = T0[B3(s2b)] ^ T1[B2(s28)] ^ T2[B1(s29)] ^ T3[B0(s2a)] ^ C[ 11+224]; + t3 = T0[B3(s2c)] ^ T1[B2(s2d)] ^ T2[B1(s2e)] ^ T3[B0(s2f)] ^ C[ 12+224]; + t7 = T0[B3(s2d)] ^ T1[B2(s2e)] ^ T2[B1(s2f)] ^ T3[B0(s2c)] ^ C[ 13+224]; + tb = T0[B3(s2e)] ^ T1[B2(s2f)] ^ T2[B1(s2c)] ^ T3[B0(s2d)] ^ C[ 14+224]; + tf = T0[B3(s2f)] ^ T1[B2(s2c)] ^ T2[B1(s2d)] ^ T3[B0(s2e)] ^ C[ 15+224]; + + s20 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 16+224]; + s24 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 17+224]; + s28 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 18+224]; + s2c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 19+224] ^ ctrl; + s21 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 20+224]; + s25 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 21+224]; + s29 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 22+224]; + s2d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 23+224]; + s22 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 24+224]; + s26 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 25+224]; + s2a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 26+224]; + s2e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 27+224]; + s23 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 28+224]; + s27 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 29+224]; + s2b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 30+224]; + s2f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 31+224]; + + t0 = T0[B3(s20)] ^ T1[B2(s21)] ^ T2[B1(s22)] ^ T3[B0(s23)] ^ C[ 32+224]; + t4 = T0[B3(s21)] ^ T1[B2(s22)] ^ T2[B1(s23)] ^ T3[B0(s20)] ^ C[ 33+224]; + t8 = T0[B3(s22)] ^ T1[B2(s23)] ^ T2[B1(s20)] ^ T3[B0(s21)] ^ C[ 34+224]; + tc = T0[B3(s23)] ^ T1[B2(s20)] ^ T2[B1(s21)] ^ T3[B0(s22)] ^ C[ 35+224] ^ ctrh; + t1 = T0[B3(s24)] ^ T1[B2(s25)] ^ T2[B1(s26)] ^ T3[B0(s27)] ^ C[ 36+224]; + t5 = T0[B3(s25)] ^ T1[B2(s26)] ^ T2[B1(s27)] ^ T3[B0(s24)] ^ C[ 37+224]; + t9 = T0[B3(s26)] ^ T1[B2(s27)] ^ T2[B1(s24)] ^ T3[B0(s25)] ^ C[ 38+224]; + td = T0[B3(s27)] ^ T1[B2(s24)] ^ T2[B1(s25)] ^ T3[B0(s26)] ^ C[ 39+224]; + t2 = T0[B3(s28)] ^ T1[B2(s29)] ^ T2[B1(s2a)] ^ T3[B0(s2b)] ^ C[ 40+224]; + t6 = T0[B3(s29)] ^ T1[B2(s2a)] ^ T2[B1(s2b)] ^ T3[B0(s28)] ^ C[ 41+224]; + ta = T0[B3(s2a)] ^ T1[B2(s2b)] ^ T2[B1(s28)] ^ T3[B0(s29)] ^ C[ 42+224]; + te = T0[B3(s2b)] ^ T1[B2(s28)] ^ T2[B1(s29)] ^ T3[B0(s2a)] ^ C[ 43+224]; + t3 = T0[B3(s2c)] ^ T1[B2(s2d)] ^ T2[B1(s2e)] ^ T3[B0(s2f)] ^ C[ 44+224]; + t7 = T0[B3(s2d)] ^ T1[B2(s2e)] ^ T2[B1(s2f)] ^ T3[B0(s2c)] ^ C[ 45+224]; + tb = T0[B3(s2e)] ^ T1[B2(s2f)] ^ T2[B1(s2c)] ^ T3[B0(s2d)] ^ C[ 46+224]; + tf = T0[B3(s2f)] ^ T1[B2(s2c)] ^ T2[B1(s2d)] ^ T3[B0(s2e)] ^ C[ 47+224]; + + s20 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 48+224]; + s24 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 49+224]; + s28 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 50+224]; + s2c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 51+224] ^ ctrl; + s21 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 52+224]; + s25 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 53+224]; + s29 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 54+224]; + s2d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 55+224]; + s22 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 56+224]; + s26 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 57+224]; + s2a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 58+224]; + s2e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 59+224]; + s23 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 60+224]; + s27 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 61+224]; + s2b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 62+224]; + s2f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 63+224]; + + t0 = T0[B3(s20)] ^ T1[B2(s21)] ^ T2[B1(s22)] ^ T3[B0(s23)] ^ C[ 64+224]; + t4 = T0[B3(s21)] ^ T1[B2(s22)] ^ T2[B1(s23)] ^ T3[B0(s20)] ^ C[ 65+224]; + t8 = T0[B3(s22)] ^ T1[B2(s23)] ^ T2[B1(s20)] ^ T3[B0(s21)] ^ C[ 66+224]; + tc = T0[B3(s23)] ^ T1[B2(s20)] ^ T2[B1(s21)] ^ T3[B0(s22)] ^ C[ 67+224] ^ ctrh; + t1 = T0[B3(s24)] ^ T1[B2(s25)] ^ T2[B1(s26)] ^ T3[B0(s27)] ^ C[ 68+224]; + t5 = T0[B3(s25)] ^ T1[B2(s26)] ^ T2[B1(s27)] ^ T3[B0(s24)] ^ C[ 69+224]; + t9 = T0[B3(s26)] ^ T1[B2(s27)] ^ T2[B1(s24)] ^ T3[B0(s25)] ^ C[ 70+224]; + td = T0[B3(s27)] ^ T1[B2(s24)] ^ T2[B1(s25)] ^ T3[B0(s26)] ^ C[ 71+224]; + t2 = T0[B3(s28)] ^ T1[B2(s29)] ^ T2[B1(s2a)] ^ T3[B0(s2b)] ^ C[ 72+224]; + t6 = T0[B3(s29)] ^ T1[B2(s2a)] ^ T2[B1(s2b)] ^ T3[B0(s28)] ^ C[ 73+224]; + ta = T0[B3(s2a)] ^ T1[B2(s2b)] ^ T2[B1(s28)] ^ T3[B0(s29)] ^ C[ 74+224]; + te = T0[B3(s2b)] ^ T1[B2(s28)] ^ T2[B1(s29)] ^ T3[B0(s2a)] ^ C[ 75+224]; + t3 = T0[B3(s2c)] ^ T1[B2(s2d)] ^ T2[B1(s2e)] ^ T3[B0(s2f)] ^ C[ 76+224]; + t7 = T0[B3(s2d)] ^ T1[B2(s2e)] ^ T2[B1(s2f)] ^ T3[B0(s2c)] ^ C[ 77+224]; + tb = T0[B3(s2e)] ^ T1[B2(s2f)] ^ T2[B1(s2c)] ^ T3[B0(s2d)] ^ C[ 78+224]; + tf = T0[B3(s2f)] ^ T1[B2(s2c)] ^ T2[B1(s2d)] ^ T3[B0(s2e)] ^ C[ 79+224]; + + s20 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 80+224]; + s24 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 81+224]; + s28 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 82+224]; + s2c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 83+224] ^ ctrl; + s21 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 84+224]; + s25 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 85+224]; + s29 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 86+224]; + s2d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 87+224]; + s22 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 88+224]; + s26 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 89+224]; + s2a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 90+224]; + s2e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 91+224]; + s23 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 92+224]; + s27 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 93+224]; + s2b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 94+224]; + s2f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 95+224]; + + t0 = T0[B3(s20)] ^ T1[B2(s21)] ^ T2[B1(s22)] ^ T3[B0(s23)] ^ C[ 96+224]; + t4 = T0[B3(s21)] ^ T1[B2(s22)] ^ T2[B1(s23)] ^ T3[B0(s20)] ^ C[ 97+224]; + t8 = T0[B3(s22)] ^ T1[B2(s23)] ^ T2[B1(s20)] ^ T3[B0(s21)] ^ C[ 98+224]; + tc = T0[B3(s23)] ^ T1[B2(s20)] ^ T2[B1(s21)] ^ T3[B0(s22)] ^ C[ 99+224] ^ ctrh; + t1 = T0[B3(s24)] ^ T1[B2(s25)] ^ T2[B1(s26)] ^ T3[B0(s27)] ^ C[100+224]; + t5 = T0[B3(s25)] ^ T1[B2(s26)] ^ T2[B1(s27)] ^ T3[B0(s24)] ^ C[101+224]; + t9 = T0[B3(s26)] ^ T1[B2(s27)] ^ T2[B1(s24)] ^ T3[B0(s25)] ^ C[102+224]; + td = T0[B3(s27)] ^ T1[B2(s24)] ^ T2[B1(s25)] ^ T3[B0(s26)] ^ C[103+224]; + t2 = T0[B3(s28)] ^ T1[B2(s29)] ^ T2[B1(s2a)] ^ T3[B0(s2b)] ^ C[104+224]; + t6 = T0[B3(s29)] ^ T1[B2(s2a)] ^ T2[B1(s2b)] ^ T3[B0(s28)] ^ C[105+224]; + ta = T0[B3(s2a)] ^ T1[B2(s2b)] ^ T2[B1(s28)] ^ T3[B0(s29)] ^ C[106+224]; + te = T0[B3(s2b)] ^ T1[B2(s28)] ^ T2[B1(s29)] ^ T3[B0(s2a)] ^ C[107+224]; + t3 = T0[B3(s2c)] ^ T1[B2(s2d)] ^ T2[B1(s2e)] ^ T3[B0(s2f)] ^ C[108+224]; + t7 = T0[B3(s2d)] ^ T1[B2(s2e)] ^ T2[B1(s2f)] ^ T3[B0(s2c)] ^ C[109+224]; + tb = T0[B3(s2e)] ^ T1[B2(s2f)] ^ T2[B1(s2c)] ^ T3[B0(s2d)] ^ C[110+224]; + tf = T0[B3(s2f)] ^ T1[B2(s2c)] ^ T2[B1(s2d)] ^ T3[B0(s2e)] ^ C[111+224]; + + s60 ^= T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + s64 ^= T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + s68 ^= T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + s6c ^= T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + s61 ^= T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + s65 ^= T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + s69 ^= T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + s6d ^= T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + s62 ^= T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )]; + s66 ^= T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )]; + s6a ^= T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )]; + s6e ^= T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )]; + s63 ^= T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )]; + s67 ^= T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )]; + s6b ^= T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )]; + s6f ^= T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )]; + + /* Lane 3 */ + t0 = T0[B3(s30)] ^ T1[B2(s31)] ^ T2[B1(s32)] ^ T3[B0(s33)] ^ C[ 0+336]; + t4 = T0[B3(s31)] ^ T1[B2(s32)] ^ T2[B1(s33)] ^ T3[B0(s30)] ^ C[ 1+336]; + t8 = T0[B3(s32)] ^ T1[B2(s33)] ^ T2[B1(s30)] ^ T3[B0(s31)] ^ C[ 2+336]; + tc = T0[B3(s33)] ^ T1[B2(s30)] ^ T2[B1(s31)] ^ T3[B0(s32)] ^ C[ 3+336] ^ ctrl; + t1 = T0[B3(s34)] ^ T1[B2(s35)] ^ T2[B1(s36)] ^ T3[B0(s37)] ^ C[ 4+336]; + t5 = T0[B3(s35)] ^ T1[B2(s36)] ^ T2[B1(s37)] ^ T3[B0(s34)] ^ C[ 5+336]; + t9 = T0[B3(s36)] ^ T1[B2(s37)] ^ T2[B1(s34)] ^ T3[B0(s35)] ^ C[ 6+336]; + td = T0[B3(s37)] ^ T1[B2(s34)] ^ T2[B1(s35)] ^ T3[B0(s36)] ^ C[ 7+336]; + t2 = T0[B3(s38)] ^ T1[B2(s39)] ^ T2[B1(s3a)] ^ T3[B0(s3b)] ^ C[ 8+336]; + t6 = T0[B3(s39)] ^ T1[B2(s3a)] ^ T2[B1(s3b)] ^ T3[B0(s38)] ^ C[ 9+336]; + ta = T0[B3(s3a)] ^ T1[B2(s3b)] ^ T2[B1(s38)] ^ T3[B0(s39)] ^ C[ 10+336]; + te = T0[B3(s3b)] ^ T1[B2(s38)] ^ T2[B1(s39)] ^ T3[B0(s3a)] ^ C[ 11+336]; + t3 = T0[B3(s3c)] ^ T1[B2(s3d)] ^ T2[B1(s3e)] ^ T3[B0(s3f)] ^ C[ 12+336]; + t7 = T0[B3(s3d)] ^ T1[B2(s3e)] ^ T2[B1(s3f)] ^ T3[B0(s3c)] ^ C[ 13+336]; + tb = T0[B3(s3e)] ^ T1[B2(s3f)] ^ T2[B1(s3c)] ^ T3[B0(s3d)] ^ C[ 14+336]; + tf = T0[B3(s3f)] ^ T1[B2(s3c)] ^ T2[B1(s3d)] ^ T3[B0(s3e)] ^ C[ 15+336]; + + s30 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 16+336]; + s34 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 17+336]; + s38 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 18+336]; + s3c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 19+336] ^ ctrh; + s31 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 20+336]; + s35 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 21+336]; + s39 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 22+336]; + s3d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 23+336]; + s32 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 24+336]; + s36 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 25+336]; + s3a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 26+336]; + s3e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 27+336]; + s33 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 28+336]; + s37 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 29+336]; + s3b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 30+336]; + s3f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 31+336]; + + t0 = T0[B3(s30)] ^ T1[B2(s31)] ^ T2[B1(s32)] ^ T3[B0(s33)] ^ C[ 32+336]; + t4 = T0[B3(s31)] ^ T1[B2(s32)] ^ T2[B1(s33)] ^ T3[B0(s30)] ^ C[ 33+336]; + t8 = T0[B3(s32)] ^ T1[B2(s33)] ^ T2[B1(s30)] ^ T3[B0(s31)] ^ C[ 34+336]; + tc = T0[B3(s33)] ^ T1[B2(s30)] ^ T2[B1(s31)] ^ T3[B0(s32)] ^ C[ 35+336] ^ ctrl; + t1 = T0[B3(s34)] ^ T1[B2(s35)] ^ T2[B1(s36)] ^ T3[B0(s37)] ^ C[ 36+336]; + t5 = T0[B3(s35)] ^ T1[B2(s36)] ^ T2[B1(s37)] ^ T3[B0(s34)] ^ C[ 37+336]; + t9 = T0[B3(s36)] ^ T1[B2(s37)] ^ T2[B1(s34)] ^ T3[B0(s35)] ^ C[ 38+336]; + td = T0[B3(s37)] ^ T1[B2(s34)] ^ T2[B1(s35)] ^ T3[B0(s36)] ^ C[ 39+336]; + t2 = T0[B3(s38)] ^ T1[B2(s39)] ^ T2[B1(s3a)] ^ T3[B0(s3b)] ^ C[ 40+336]; + t6 = T0[B3(s39)] ^ T1[B2(s3a)] ^ T2[B1(s3b)] ^ T3[B0(s38)] ^ C[ 41+336]; + ta = T0[B3(s3a)] ^ T1[B2(s3b)] ^ T2[B1(s38)] ^ T3[B0(s39)] ^ C[ 42+336]; + te = T0[B3(s3b)] ^ T1[B2(s38)] ^ T2[B1(s39)] ^ T3[B0(s3a)] ^ C[ 43+336]; + t3 = T0[B3(s3c)] ^ T1[B2(s3d)] ^ T2[B1(s3e)] ^ T3[B0(s3f)] ^ C[ 44+336]; + t7 = T0[B3(s3d)] ^ T1[B2(s3e)] ^ T2[B1(s3f)] ^ T3[B0(s3c)] ^ C[ 45+336]; + tb = T0[B3(s3e)] ^ T1[B2(s3f)] ^ T2[B1(s3c)] ^ T3[B0(s3d)] ^ C[ 46+336]; + tf = T0[B3(s3f)] ^ T1[B2(s3c)] ^ T2[B1(s3d)] ^ T3[B0(s3e)] ^ C[ 47+336]; + + s30 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 48+336]; + s34 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 49+336]; + s38 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 50+336]; + s3c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 51+336] ^ ctrh; + s31 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 52+336]; + s35 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 53+336]; + s39 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 54+336]; + s3d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 55+336]; + s32 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 56+336]; + s36 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 57+336]; + s3a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 58+336]; + s3e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 59+336]; + s33 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 60+336]; + s37 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 61+336]; + s3b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 62+336]; + s3f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 63+336]; + + t0 = T0[B3(s30)] ^ T1[B2(s31)] ^ T2[B1(s32)] ^ T3[B0(s33)] ^ C[ 64+336]; + t4 = T0[B3(s31)] ^ T1[B2(s32)] ^ T2[B1(s33)] ^ T3[B0(s30)] ^ C[ 65+336]; + t8 = T0[B3(s32)] ^ T1[B2(s33)] ^ T2[B1(s30)] ^ T3[B0(s31)] ^ C[ 66+336]; + tc = T0[B3(s33)] ^ T1[B2(s30)] ^ T2[B1(s31)] ^ T3[B0(s32)] ^ C[ 67+336] ^ ctrl; + t1 = T0[B3(s34)] ^ T1[B2(s35)] ^ T2[B1(s36)] ^ T3[B0(s37)] ^ C[ 68+336]; + t5 = T0[B3(s35)] ^ T1[B2(s36)] ^ T2[B1(s37)] ^ T3[B0(s34)] ^ C[ 69+336]; + t9 = T0[B3(s36)] ^ T1[B2(s37)] ^ T2[B1(s34)] ^ T3[B0(s35)] ^ C[ 70+336]; + td = T0[B3(s37)] ^ T1[B2(s34)] ^ T2[B1(s35)] ^ T3[B0(s36)] ^ C[ 71+336]; + t2 = T0[B3(s38)] ^ T1[B2(s39)] ^ T2[B1(s3a)] ^ T3[B0(s3b)] ^ C[ 72+336]; + t6 = T0[B3(s39)] ^ T1[B2(s3a)] ^ T2[B1(s3b)] ^ T3[B0(s38)] ^ C[ 73+336]; + ta = T0[B3(s3a)] ^ T1[B2(s3b)] ^ T2[B1(s38)] ^ T3[B0(s39)] ^ C[ 74+336]; + te = T0[B3(s3b)] ^ T1[B2(s38)] ^ T2[B1(s39)] ^ T3[B0(s3a)] ^ C[ 75+336]; + t3 = T0[B3(s3c)] ^ T1[B2(s3d)] ^ T2[B1(s3e)] ^ T3[B0(s3f)] ^ C[ 76+336]; + t7 = T0[B3(s3d)] ^ T1[B2(s3e)] ^ T2[B1(s3f)] ^ T3[B0(s3c)] ^ C[ 77+336]; + tb = T0[B3(s3e)] ^ T1[B2(s3f)] ^ T2[B1(s3c)] ^ T3[B0(s3d)] ^ C[ 78+336]; + tf = T0[B3(s3f)] ^ T1[B2(s3c)] ^ T2[B1(s3d)] ^ T3[B0(s3e)] ^ C[ 79+336]; + + s30 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 80+336]; + s34 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 81+336]; + s38 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 82+336]; + s3c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 83+336] ^ ctrh; + s31 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 84+336]; + s35 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 85+336]; + s39 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 86+336]; + s3d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 87+336]; + s32 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 88+336]; + s36 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 89+336]; + s3a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 90+336]; + s3e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 91+336]; + s33 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 92+336]; + s37 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 93+336]; + s3b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 94+336]; + s3f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 95+336]; + + t0 = T0[B3(s30)] ^ T1[B2(s31)] ^ T2[B1(s32)] ^ T3[B0(s33)] ^ C[ 96+336]; + t4 = T0[B3(s31)] ^ T1[B2(s32)] ^ T2[B1(s33)] ^ T3[B0(s30)] ^ C[ 97+336]; + t8 = T0[B3(s32)] ^ T1[B2(s33)] ^ T2[B1(s30)] ^ T3[B0(s31)] ^ C[ 98+336]; + tc = T0[B3(s33)] ^ T1[B2(s30)] ^ T2[B1(s31)] ^ T3[B0(s32)] ^ C[ 99+336] ^ ctrl; + t1 = T0[B3(s34)] ^ T1[B2(s35)] ^ T2[B1(s36)] ^ T3[B0(s37)] ^ C[100+336]; + t5 = T0[B3(s35)] ^ T1[B2(s36)] ^ T2[B1(s37)] ^ T3[B0(s34)] ^ C[101+336]; + t9 = T0[B3(s36)] ^ T1[B2(s37)] ^ T2[B1(s34)] ^ T3[B0(s35)] ^ C[102+336]; + td = T0[B3(s37)] ^ T1[B2(s34)] ^ T2[B1(s35)] ^ T3[B0(s36)] ^ C[103+336]; + t2 = T0[B3(s38)] ^ T1[B2(s39)] ^ T2[B1(s3a)] ^ T3[B0(s3b)] ^ C[104+336]; + t6 = T0[B3(s39)] ^ T1[B2(s3a)] ^ T2[B1(s3b)] ^ T3[B0(s38)] ^ C[105+336]; + ta = T0[B3(s3a)] ^ T1[B2(s3b)] ^ T2[B1(s38)] ^ T3[B0(s39)] ^ C[106+336]; + te = T0[B3(s3b)] ^ T1[B2(s38)] ^ T2[B1(s39)] ^ T3[B0(s3a)] ^ C[107+336]; + t3 = T0[B3(s3c)] ^ T1[B2(s3d)] ^ T2[B1(s3e)] ^ T3[B0(s3f)] ^ C[108+336]; + t7 = T0[B3(s3d)] ^ T1[B2(s3e)] ^ T2[B1(s3f)] ^ T3[B0(s3c)] ^ C[109+336]; + tb = T0[B3(s3e)] ^ T1[B2(s3f)] ^ T2[B1(s3c)] ^ T3[B0(s3d)] ^ C[110+336]; + tf = T0[B3(s3f)] ^ T1[B2(s3c)] ^ T2[B1(s3d)] ^ T3[B0(s3e)] ^ C[111+336]; + + s70 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + s74 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + s78 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + s7c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + s71 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + s75 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + s79 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + s7d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + s72 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )]; + s76 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )]; + s7a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )]; + s7e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )]; + s73 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )]; + s77 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )]; + s7b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )]; + s7f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )]; + + /* Lane 4 */ + t0 = T0[B3(s40)] ^ T1[B2(s41)] ^ T2[B1(s42)] ^ T3[B0(s43)] ^ C[ 0+448]; + t4 = T0[B3(s41)] ^ T1[B2(s42)] ^ T2[B1(s43)] ^ T3[B0(s40)] ^ C[ 1+448]; + t8 = T0[B3(s42)] ^ T1[B2(s43)] ^ T2[B1(s40)] ^ T3[B0(s41)] ^ C[ 2+448]; + tc = T0[B3(s43)] ^ T1[B2(s40)] ^ T2[B1(s41)] ^ T3[B0(s42)] ^ C[ 3+448] ^ ctrh; + t1 = T0[B3(s44)] ^ T1[B2(s45)] ^ T2[B1(s46)] ^ T3[B0(s47)] ^ C[ 4+448]; + t5 = T0[B3(s45)] ^ T1[B2(s46)] ^ T2[B1(s47)] ^ T3[B0(s44)] ^ C[ 5+448]; + t9 = T0[B3(s46)] ^ T1[B2(s47)] ^ T2[B1(s44)] ^ T3[B0(s45)] ^ C[ 6+448]; + td = T0[B3(s47)] ^ T1[B2(s44)] ^ T2[B1(s45)] ^ T3[B0(s46)] ^ C[ 7+448]; + t2 = T0[B3(s48)] ^ T1[B2(s49)] ^ T2[B1(s4a)] ^ T3[B0(s4b)] ^ C[ 8+448]; + t6 = T0[B3(s49)] ^ T1[B2(s4a)] ^ T2[B1(s4b)] ^ T3[B0(s48)] ^ C[ 9+448]; + ta = T0[B3(s4a)] ^ T1[B2(s4b)] ^ T2[B1(s48)] ^ T3[B0(s49)] ^ C[ 10+448]; + te = T0[B3(s4b)] ^ T1[B2(s48)] ^ T2[B1(s49)] ^ T3[B0(s4a)] ^ C[ 11+448]; + t3 = T0[B3(s4c)] ^ T1[B2(s4d)] ^ T2[B1(s4e)] ^ T3[B0(s4f)] ^ C[ 12+448]; + t7 = T0[B3(s4d)] ^ T1[B2(s4e)] ^ T2[B1(s4f)] ^ T3[B0(s4c)] ^ C[ 13+448]; + tb = T0[B3(s4e)] ^ T1[B2(s4f)] ^ T2[B1(s4c)] ^ T3[B0(s4d)] ^ C[ 14+448]; + tf = T0[B3(s4f)] ^ T1[B2(s4c)] ^ T2[B1(s4d)] ^ T3[B0(s4e)] ^ C[ 15+448]; + + s40 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 16+448]; + s44 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 17+448]; + s48 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 18+448]; + s4c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 19+448] ^ ctrl; + s41 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 20+448]; + s45 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 21+448]; + s49 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 22+448]; + s4d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 23+448]; + s42 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 24+448]; + s46 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 25+448]; + s4a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 26+448]; + s4e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 27+448]; + s43 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 28+448]; + s47 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 29+448]; + s4b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 30+448]; + s4f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 31+448]; + + t0 = T0[B3(s40)] ^ T1[B2(s41)] ^ T2[B1(s42)] ^ T3[B0(s43)] ^ C[ 32+448]; + t4 = T0[B3(s41)] ^ T1[B2(s42)] ^ T2[B1(s43)] ^ T3[B0(s40)] ^ C[ 33+448]; + t8 = T0[B3(s42)] ^ T1[B2(s43)] ^ T2[B1(s40)] ^ T3[B0(s41)] ^ C[ 34+448]; + tc = T0[B3(s43)] ^ T1[B2(s40)] ^ T2[B1(s41)] ^ T3[B0(s42)] ^ C[ 35+448] ^ ctrh; + t1 = T0[B3(s44)] ^ T1[B2(s45)] ^ T2[B1(s46)] ^ T3[B0(s47)] ^ C[ 36+448]; + t5 = T0[B3(s45)] ^ T1[B2(s46)] ^ T2[B1(s47)] ^ T3[B0(s44)] ^ C[ 37+448]; + t9 = T0[B3(s46)] ^ T1[B2(s47)] ^ T2[B1(s44)] ^ T3[B0(s45)] ^ C[ 38+448]; + td = T0[B3(s47)] ^ T1[B2(s44)] ^ T2[B1(s45)] ^ T3[B0(s46)] ^ C[ 39+448]; + t2 = T0[B3(s48)] ^ T1[B2(s49)] ^ T2[B1(s4a)] ^ T3[B0(s4b)] ^ C[ 40+448]; + t6 = T0[B3(s49)] ^ T1[B2(s4a)] ^ T2[B1(s4b)] ^ T3[B0(s48)] ^ C[ 41+448]; + ta = T0[B3(s4a)] ^ T1[B2(s4b)] ^ T2[B1(s48)] ^ T3[B0(s49)] ^ C[ 42+448]; + te = T0[B3(s4b)] ^ T1[B2(s48)] ^ T2[B1(s49)] ^ T3[B0(s4a)] ^ C[ 43+448]; + t3 = T0[B3(s4c)] ^ T1[B2(s4d)] ^ T2[B1(s4e)] ^ T3[B0(s4f)] ^ C[ 44+448]; + t7 = T0[B3(s4d)] ^ T1[B2(s4e)] ^ T2[B1(s4f)] ^ T3[B0(s4c)] ^ C[ 45+448]; + tb = T0[B3(s4e)] ^ T1[B2(s4f)] ^ T2[B1(s4c)] ^ T3[B0(s4d)] ^ C[ 46+448]; + tf = T0[B3(s4f)] ^ T1[B2(s4c)] ^ T2[B1(s4d)] ^ T3[B0(s4e)] ^ C[ 47+448]; + + s40 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 48+448]; + s44 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 49+448]; + s48 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 50+448]; + s4c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 51+448] ^ ctrl; + s41 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 52+448]; + s45 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 53+448]; + s49 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 54+448]; + s4d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 55+448]; + s42 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 56+448]; + s46 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 57+448]; + s4a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 58+448]; + s4e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 59+448]; + s43 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 60+448]; + s47 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 61+448]; + s4b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 62+448]; + s4f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 63+448]; + + t0 = T0[B3(s40)] ^ T1[B2(s41)] ^ T2[B1(s42)] ^ T3[B0(s43)] ^ C[ 64+448]; + t4 = T0[B3(s41)] ^ T1[B2(s42)] ^ T2[B1(s43)] ^ T3[B0(s40)] ^ C[ 65+448]; + t8 = T0[B3(s42)] ^ T1[B2(s43)] ^ T2[B1(s40)] ^ T3[B0(s41)] ^ C[ 66+448]; + tc = T0[B3(s43)] ^ T1[B2(s40)] ^ T2[B1(s41)] ^ T3[B0(s42)] ^ C[ 67+448] ^ ctrh; + t1 = T0[B3(s44)] ^ T1[B2(s45)] ^ T2[B1(s46)] ^ T3[B0(s47)] ^ C[ 68+448]; + t5 = T0[B3(s45)] ^ T1[B2(s46)] ^ T2[B1(s47)] ^ T3[B0(s44)] ^ C[ 69+448]; + t9 = T0[B3(s46)] ^ T1[B2(s47)] ^ T2[B1(s44)] ^ T3[B0(s45)] ^ C[ 70+448]; + td = T0[B3(s47)] ^ T1[B2(s44)] ^ T2[B1(s45)] ^ T3[B0(s46)] ^ C[ 71+448]; + t2 = T0[B3(s48)] ^ T1[B2(s49)] ^ T2[B1(s4a)] ^ T3[B0(s4b)] ^ C[ 72+448]; + t6 = T0[B3(s49)] ^ T1[B2(s4a)] ^ T2[B1(s4b)] ^ T3[B0(s48)] ^ C[ 73+448]; + ta = T0[B3(s4a)] ^ T1[B2(s4b)] ^ T2[B1(s48)] ^ T3[B0(s49)] ^ C[ 74+448]; + te = T0[B3(s4b)] ^ T1[B2(s48)] ^ T2[B1(s49)] ^ T3[B0(s4a)] ^ C[ 75+448]; + t3 = T0[B3(s4c)] ^ T1[B2(s4d)] ^ T2[B1(s4e)] ^ T3[B0(s4f)] ^ C[ 76+448]; + t7 = T0[B3(s4d)] ^ T1[B2(s4e)] ^ T2[B1(s4f)] ^ T3[B0(s4c)] ^ C[ 77+448]; + tb = T0[B3(s4e)] ^ T1[B2(s4f)] ^ T2[B1(s4c)] ^ T3[B0(s4d)] ^ C[ 78+448]; + tf = T0[B3(s4f)] ^ T1[B2(s4c)] ^ T2[B1(s4d)] ^ T3[B0(s4e)] ^ C[ 79+448]; + + s40 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 80+448]; + s44 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 81+448]; + s48 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 82+448]; + s4c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 83+448] ^ ctrl; + s41 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 84+448]; + s45 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 85+448]; + s49 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 86+448]; + s4d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 87+448]; + s42 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 88+448]; + s46 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 89+448]; + s4a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 90+448]; + s4e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 91+448]; + s43 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 92+448]; + s47 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 93+448]; + s4b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 94+448]; + s4f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 95+448]; + + t0 = T0[B3(s40)] ^ T1[B2(s41)] ^ T2[B1(s42)] ^ T3[B0(s43)] ^ C[ 96+448]; + t4 = T0[B3(s41)] ^ T1[B2(s42)] ^ T2[B1(s43)] ^ T3[B0(s40)] ^ C[ 97+448]; + t8 = T0[B3(s42)] ^ T1[B2(s43)] ^ T2[B1(s40)] ^ T3[B0(s41)] ^ C[ 98+448]; + tc = T0[B3(s43)] ^ T1[B2(s40)] ^ T2[B1(s41)] ^ T3[B0(s42)] ^ C[ 99+448] ^ ctrh; + t1 = T0[B3(s44)] ^ T1[B2(s45)] ^ T2[B1(s46)] ^ T3[B0(s47)] ^ C[100+448]; + t5 = T0[B3(s45)] ^ T1[B2(s46)] ^ T2[B1(s47)] ^ T3[B0(s44)] ^ C[101+448]; + t9 = T0[B3(s46)] ^ T1[B2(s47)] ^ T2[B1(s44)] ^ T3[B0(s45)] ^ C[102+448]; + td = T0[B3(s47)] ^ T1[B2(s44)] ^ T2[B1(s45)] ^ T3[B0(s46)] ^ C[103+448]; + t2 = T0[B3(s48)] ^ T1[B2(s49)] ^ T2[B1(s4a)] ^ T3[B0(s4b)] ^ C[104+448]; + t6 = T0[B3(s49)] ^ T1[B2(s4a)] ^ T2[B1(s4b)] ^ T3[B0(s48)] ^ C[105+448]; + ta = T0[B3(s4a)] ^ T1[B2(s4b)] ^ T2[B1(s48)] ^ T3[B0(s49)] ^ C[106+448]; + te = T0[B3(s4b)] ^ T1[B2(s48)] ^ T2[B1(s49)] ^ T3[B0(s4a)] ^ C[107+448]; + t3 = T0[B3(s4c)] ^ T1[B2(s4d)] ^ T2[B1(s4e)] ^ T3[B0(s4f)] ^ C[108+448]; + t7 = T0[B3(s4d)] ^ T1[B2(s4e)] ^ T2[B1(s4f)] ^ T3[B0(s4c)] ^ C[109+448]; + tb = T0[B3(s4e)] ^ T1[B2(s4f)] ^ T2[B1(s4c)] ^ T3[B0(s4d)] ^ C[110+448]; + tf = T0[B3(s4f)] ^ T1[B2(s4c)] ^ T2[B1(s4d)] ^ T3[B0(s4e)] ^ C[111+448]; + + s70 ^= T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + s74 ^= T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + s78 ^= T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + s7c ^= T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + s71 ^= T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + s75 ^= T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + s79 ^= T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + s7d ^= T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + s72 ^= T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )]; + s76 ^= T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )]; + s7a ^= T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )]; + s7e ^= T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )]; + s73 ^= T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )]; + s77 ^= T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )]; + s7b ^= T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )]; + s7f ^= T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )]; + + /* Lane 5 */ + t0 = T0[B3(s50)] ^ T1[B2(s51)] ^ T2[B1(s52)] ^ T3[B0(s53)] ^ C[ 0+560]; + t4 = T0[B3(s51)] ^ T1[B2(s52)] ^ T2[B1(s53)] ^ T3[B0(s50)] ^ C[ 1+560]; + t8 = T0[B3(s52)] ^ T1[B2(s53)] ^ T2[B1(s50)] ^ T3[B0(s51)] ^ C[ 2+560]; + tc = T0[B3(s53)] ^ T1[B2(s50)] ^ T2[B1(s51)] ^ T3[B0(s52)] ^ C[ 3+560] ^ ctrl; + t1 = T0[B3(s54)] ^ T1[B2(s55)] ^ T2[B1(s56)] ^ T3[B0(s57)] ^ C[ 4+560]; + t5 = T0[B3(s55)] ^ T1[B2(s56)] ^ T2[B1(s57)] ^ T3[B0(s54)] ^ C[ 5+560]; + t9 = T0[B3(s56)] ^ T1[B2(s57)] ^ T2[B1(s54)] ^ T3[B0(s55)] ^ C[ 6+560]; + td = T0[B3(s57)] ^ T1[B2(s54)] ^ T2[B1(s55)] ^ T3[B0(s56)] ^ C[ 7+560]; + t2 = T0[B3(s58)] ^ T1[B2(s59)] ^ T2[B1(s5a)] ^ T3[B0(s5b)] ^ C[ 8+560]; + t6 = T0[B3(s59)] ^ T1[B2(s5a)] ^ T2[B1(s5b)] ^ T3[B0(s58)] ^ C[ 9+560]; + ta = T0[B3(s5a)] ^ T1[B2(s5b)] ^ T2[B1(s58)] ^ T3[B0(s59)] ^ C[ 10+560]; + te = T0[B3(s5b)] ^ T1[B2(s58)] ^ T2[B1(s59)] ^ T3[B0(s5a)] ^ C[ 11+560]; + t3 = T0[B3(s5c)] ^ T1[B2(s5d)] ^ T2[B1(s5e)] ^ T3[B0(s5f)] ^ C[ 12+560]; + t7 = T0[B3(s5d)] ^ T1[B2(s5e)] ^ T2[B1(s5f)] ^ T3[B0(s5c)] ^ C[ 13+560]; + tb = T0[B3(s5e)] ^ T1[B2(s5f)] ^ T2[B1(s5c)] ^ T3[B0(s5d)] ^ C[ 14+560]; + tf = T0[B3(s5f)] ^ T1[B2(s5c)] ^ T2[B1(s5d)] ^ T3[B0(s5e)] ^ C[ 15+560]; + + s50 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 16+560]; + s54 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 17+560]; + s58 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 18+560]; + s5c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 19+560] ^ ctrh; + s51 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 20+560]; + s55 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 21+560]; + s59 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 22+560]; + s5d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 23+560]; + s52 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 24+560]; + s56 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 25+560]; + s5a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 26+560]; + s5e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 27+560]; + s53 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 28+560]; + s57 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 29+560]; + s5b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 30+560]; + s5f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 31+560]; + + t0 = T0[B3(s50)] ^ T1[B2(s51)] ^ T2[B1(s52)] ^ T3[B0(s53)] ^ C[ 32+560]; + t4 = T0[B3(s51)] ^ T1[B2(s52)] ^ T2[B1(s53)] ^ T3[B0(s50)] ^ C[ 33+560]; + t8 = T0[B3(s52)] ^ T1[B2(s53)] ^ T2[B1(s50)] ^ T3[B0(s51)] ^ C[ 34+560]; + tc = T0[B3(s53)] ^ T1[B2(s50)] ^ T2[B1(s51)] ^ T3[B0(s52)] ^ C[ 35+560] ^ ctrl; + t1 = T0[B3(s54)] ^ T1[B2(s55)] ^ T2[B1(s56)] ^ T3[B0(s57)] ^ C[ 36+560]; + t5 = T0[B3(s55)] ^ T1[B2(s56)] ^ T2[B1(s57)] ^ T3[B0(s54)] ^ C[ 37+560]; + t9 = T0[B3(s56)] ^ T1[B2(s57)] ^ T2[B1(s54)] ^ T3[B0(s55)] ^ C[ 38+560]; + td = T0[B3(s57)] ^ T1[B2(s54)] ^ T2[B1(s55)] ^ T3[B0(s56)] ^ C[ 39+560]; + t2 = T0[B3(s58)] ^ T1[B2(s59)] ^ T2[B1(s5a)] ^ T3[B0(s5b)] ^ C[ 40+560]; + t6 = T0[B3(s59)] ^ T1[B2(s5a)] ^ T2[B1(s5b)] ^ T3[B0(s58)] ^ C[ 41+560]; + ta = T0[B3(s5a)] ^ T1[B2(s5b)] ^ T2[B1(s58)] ^ T3[B0(s59)] ^ C[ 42+560]; + te = T0[B3(s5b)] ^ T1[B2(s58)] ^ T2[B1(s59)] ^ T3[B0(s5a)] ^ C[ 43+560]; + t3 = T0[B3(s5c)] ^ T1[B2(s5d)] ^ T2[B1(s5e)] ^ T3[B0(s5f)] ^ C[ 44+560]; + t7 = T0[B3(s5d)] ^ T1[B2(s5e)] ^ T2[B1(s5f)] ^ T3[B0(s5c)] ^ C[ 45+560]; + tb = T0[B3(s5e)] ^ T1[B2(s5f)] ^ T2[B1(s5c)] ^ T3[B0(s5d)] ^ C[ 46+560]; + tf = T0[B3(s5f)] ^ T1[B2(s5c)] ^ T2[B1(s5d)] ^ T3[B0(s5e)] ^ C[ 47+560]; + + s50 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 48+560]; + s54 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 49+560]; + s58 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 50+560]; + s5c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 51+560] ^ ctrh; + s51 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 52+560]; + s55 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 53+560]; + s59 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 54+560]; + s5d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 55+560]; + s52 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 56+560]; + s56 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 57+560]; + s5a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 58+560]; + s5e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 59+560]; + s53 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 60+560]; + s57 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 61+560]; + s5b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 62+560]; + s5f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 63+560]; + + t0 = T0[B3(s50)] ^ T1[B2(s51)] ^ T2[B1(s52)] ^ T3[B0(s53)] ^ C[ 64+560]; + t4 = T0[B3(s51)] ^ T1[B2(s52)] ^ T2[B1(s53)] ^ T3[B0(s50)] ^ C[ 65+560]; + t8 = T0[B3(s52)] ^ T1[B2(s53)] ^ T2[B1(s50)] ^ T3[B0(s51)] ^ C[ 66+560]; + tc = T0[B3(s53)] ^ T1[B2(s50)] ^ T2[B1(s51)] ^ T3[B0(s52)] ^ C[ 67+560] ^ ctrl; + t1 = T0[B3(s54)] ^ T1[B2(s55)] ^ T2[B1(s56)] ^ T3[B0(s57)] ^ C[ 68+560]; + t5 = T0[B3(s55)] ^ T1[B2(s56)] ^ T2[B1(s57)] ^ T3[B0(s54)] ^ C[ 69+560]; + t9 = T0[B3(s56)] ^ T1[B2(s57)] ^ T2[B1(s54)] ^ T3[B0(s55)] ^ C[ 70+560]; + td = T0[B3(s57)] ^ T1[B2(s54)] ^ T2[B1(s55)] ^ T3[B0(s56)] ^ C[ 71+560]; + t2 = T0[B3(s58)] ^ T1[B2(s59)] ^ T2[B1(s5a)] ^ T3[B0(s5b)] ^ C[ 72+560]; + t6 = T0[B3(s59)] ^ T1[B2(s5a)] ^ T2[B1(s5b)] ^ T3[B0(s58)] ^ C[ 73+560]; + ta = T0[B3(s5a)] ^ T1[B2(s5b)] ^ T2[B1(s58)] ^ T3[B0(s59)] ^ C[ 74+560]; + te = T0[B3(s5b)] ^ T1[B2(s58)] ^ T2[B1(s59)] ^ T3[B0(s5a)] ^ C[ 75+560]; + t3 = T0[B3(s5c)] ^ T1[B2(s5d)] ^ T2[B1(s5e)] ^ T3[B0(s5f)] ^ C[ 76+560]; + t7 = T0[B3(s5d)] ^ T1[B2(s5e)] ^ T2[B1(s5f)] ^ T3[B0(s5c)] ^ C[ 77+560]; + tb = T0[B3(s5e)] ^ T1[B2(s5f)] ^ T2[B1(s5c)] ^ T3[B0(s5d)] ^ C[ 78+560]; + tf = T0[B3(s5f)] ^ T1[B2(s5c)] ^ T2[B1(s5d)] ^ T3[B0(s5e)] ^ C[ 79+560]; + + s50 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 80+560]; + s54 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 81+560]; + s58 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 82+560]; + s5c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 83+560] ^ ctrh; + s51 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 84+560]; + s55 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 85+560]; + s59 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 86+560]; + s5d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 87+560]; + s52 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 88+560]; + s56 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 89+560]; + s5a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 90+560]; + s5e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 91+560]; + s53 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 92+560]; + s57 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 93+560]; + s5b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 94+560]; + s5f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 95+560]; + + t0 = T0[B3(s50)] ^ T1[B2(s51)] ^ T2[B1(s52)] ^ T3[B0(s53)] ^ C[ 96+560]; + t4 = T0[B3(s51)] ^ T1[B2(s52)] ^ T2[B1(s53)] ^ T3[B0(s50)] ^ C[ 97+560]; + t8 = T0[B3(s52)] ^ T1[B2(s53)] ^ T2[B1(s50)] ^ T3[B0(s51)] ^ C[ 98+560]; + tc = T0[B3(s53)] ^ T1[B2(s50)] ^ T2[B1(s51)] ^ T3[B0(s52)] ^ C[ 99+560] ^ ctrl; + t1 = T0[B3(s54)] ^ T1[B2(s55)] ^ T2[B1(s56)] ^ T3[B0(s57)] ^ C[100+560]; + t5 = T0[B3(s55)] ^ T1[B2(s56)] ^ T2[B1(s57)] ^ T3[B0(s54)] ^ C[101+560]; + t9 = T0[B3(s56)] ^ T1[B2(s57)] ^ T2[B1(s54)] ^ T3[B0(s55)] ^ C[102+560]; + td = T0[B3(s57)] ^ T1[B2(s54)] ^ T2[B1(s55)] ^ T3[B0(s56)] ^ C[103+560]; + t2 = T0[B3(s58)] ^ T1[B2(s59)] ^ T2[B1(s5a)] ^ T3[B0(s5b)] ^ C[104+560]; + t6 = T0[B3(s59)] ^ T1[B2(s5a)] ^ T2[B1(s5b)] ^ T3[B0(s58)] ^ C[105+560]; + ta = T0[B3(s5a)] ^ T1[B2(s5b)] ^ T2[B1(s58)] ^ T3[B0(s59)] ^ C[106+560]; + te = T0[B3(s5b)] ^ T1[B2(s58)] ^ T2[B1(s59)] ^ T3[B0(s5a)] ^ C[107+560]; + t3 = T0[B3(s5c)] ^ T1[B2(s5d)] ^ T2[B1(s5e)] ^ T3[B0(s5f)] ^ C[108+560]; + t7 = T0[B3(s5d)] ^ T1[B2(s5e)] ^ T2[B1(s5f)] ^ T3[B0(s5c)] ^ C[109+560]; + tb = T0[B3(s5e)] ^ T1[B2(s5f)] ^ T2[B1(s5c)] ^ T3[B0(s5d)] ^ C[110+560]; + tf = T0[B3(s5f)] ^ T1[B2(s5c)] ^ T2[B1(s5d)] ^ T3[B0(s5e)] ^ C[111+560]; + + s70 ^= T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + s74 ^= T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + s78 ^= T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + s7c ^= T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + s71 ^= T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + s75 ^= T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + s79 ^= T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + s7d ^= T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + s72 ^= T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )]; + s76 ^= T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )]; + s7a ^= T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )]; + s7e ^= T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )]; + s73 ^= T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )]; + s77 ^= T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )]; + s7b ^= T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )]; + s7f ^= T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )]; + + /* Lane 6 */ + t0 = T0[B3(s60)] ^ T1[B2(s61)] ^ T2[B1(s62)] ^ T3[B0(s63)] ^ C[ 0+672]; + t4 = T0[B3(s61)] ^ T1[B2(s62)] ^ T2[B1(s63)] ^ T3[B0(s60)] ^ C[ 1+672]; + t8 = T0[B3(s62)] ^ T1[B2(s63)] ^ T2[B1(s60)] ^ T3[B0(s61)] ^ C[ 2+672]; + tc = T0[B3(s63)] ^ T1[B2(s60)] ^ T2[B1(s61)] ^ T3[B0(s62)] ^ C[ 3+672] ^ ctrh; + t1 = T0[B3(s64)] ^ T1[B2(s65)] ^ T2[B1(s66)] ^ T3[B0(s67)] ^ C[ 4+672]; + t5 = T0[B3(s65)] ^ T1[B2(s66)] ^ T2[B1(s67)] ^ T3[B0(s64)] ^ C[ 5+672]; + t9 = T0[B3(s66)] ^ T1[B2(s67)] ^ T2[B1(s64)] ^ T3[B0(s65)] ^ C[ 6+672]; + td = T0[B3(s67)] ^ T1[B2(s64)] ^ T2[B1(s65)] ^ T3[B0(s66)] ^ C[ 7+672]; + t2 = T0[B3(s68)] ^ T1[B2(s69)] ^ T2[B1(s6a)] ^ T3[B0(s6b)] ^ C[ 8+672]; + t6 = T0[B3(s69)] ^ T1[B2(s6a)] ^ T2[B1(s6b)] ^ T3[B0(s68)] ^ C[ 9+672]; + ta = T0[B3(s6a)] ^ T1[B2(s6b)] ^ T2[B1(s68)] ^ T3[B0(s69)] ^ C[ 10+672]; + te = T0[B3(s6b)] ^ T1[B2(s68)] ^ T2[B1(s69)] ^ T3[B0(s6a)] ^ C[ 11+672]; + t3 = T0[B3(s6c)] ^ T1[B2(s6d)] ^ T2[B1(s6e)] ^ T3[B0(s6f)] ^ C[ 12+672]; + t7 = T0[B3(s6d)] ^ T1[B2(s6e)] ^ T2[B1(s6f)] ^ T3[B0(s6c)] ^ C[ 13+672]; + tb = T0[B3(s6e)] ^ T1[B2(s6f)] ^ T2[B1(s6c)] ^ T3[B0(s6d)] ^ C[ 14+672]; + tf = T0[B3(s6f)] ^ T1[B2(s6c)] ^ T2[B1(s6d)] ^ T3[B0(s6e)] ^ C[ 15+672]; + + s60 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 16+672]; + s64 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 17+672]; + s68 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 18+672]; + s6c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 19+672] ^ ctrl; + s61 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 20+672]; + s65 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 21+672]; + s69 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 22+672]; + s6d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 23+672]; + s62 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 24+672]; + s66 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 25+672]; + s6a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 26+672]; + s6e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 27+672]; + s63 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 28+672]; + s67 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 29+672]; + s6b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 30+672]; + s6f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 31+672]; + + t0 = T0[B3(s60)] ^ T1[B2(s61)] ^ T2[B1(s62)] ^ T3[B0(s63)] ^ C[ 32+672]; + t4 = T0[B3(s61)] ^ T1[B2(s62)] ^ T2[B1(s63)] ^ T3[B0(s60)] ^ C[ 33+672]; + t8 = T0[B3(s62)] ^ T1[B2(s63)] ^ T2[B1(s60)] ^ T3[B0(s61)] ^ C[ 34+672]; + tc = T0[B3(s63)] ^ T1[B2(s60)] ^ T2[B1(s61)] ^ T3[B0(s62)] ^ C[ 35+672] ^ ctrh; + t1 = T0[B3(s64)] ^ T1[B2(s65)] ^ T2[B1(s66)] ^ T3[B0(s67)] ^ C[ 36+672]; + t5 = T0[B3(s65)] ^ T1[B2(s66)] ^ T2[B1(s67)] ^ T3[B0(s64)] ^ C[ 37+672]; + t9 = T0[B3(s66)] ^ T1[B2(s67)] ^ T2[B1(s64)] ^ T3[B0(s65)] ^ C[ 38+672]; + td = T0[B3(s67)] ^ T1[B2(s64)] ^ T2[B1(s65)] ^ T3[B0(s66)] ^ C[ 39+672]; + t2 = T0[B3(s68)] ^ T1[B2(s69)] ^ T2[B1(s6a)] ^ T3[B0(s6b)] ^ C[ 40+672]; + t6 = T0[B3(s69)] ^ T1[B2(s6a)] ^ T2[B1(s6b)] ^ T3[B0(s68)] ^ C[ 41+672]; + ta = T0[B3(s6a)] ^ T1[B2(s6b)] ^ T2[B1(s68)] ^ T3[B0(s69)] ^ C[ 42+672]; + te = T0[B3(s6b)] ^ T1[B2(s68)] ^ T2[B1(s69)] ^ T3[B0(s6a)] ^ C[ 43+672]; + t3 = T0[B3(s6c)] ^ T1[B2(s6d)] ^ T2[B1(s6e)] ^ T3[B0(s6f)] ^ C[ 44+672]; + t7 = T0[B3(s6d)] ^ T1[B2(s6e)] ^ T2[B1(s6f)] ^ T3[B0(s6c)] ^ C[ 45+672]; + tb = T0[B3(s6e)] ^ T1[B2(s6f)] ^ T2[B1(s6c)] ^ T3[B0(s6d)] ^ C[ 46+672]; + tf = T0[B3(s6f)] ^ T1[B2(s6c)] ^ T2[B1(s6d)] ^ T3[B0(s6e)] ^ C[ 47+672]; + + h[ 0] = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + h[ 4] = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + h[ 8] = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + h[12] = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + h[ 1] = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + h[ 5] = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + h[ 9] = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + h[13] = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + h[ 2] = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )]; + h[ 6] = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )]; + h[10] = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )]; + h[14] = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )]; + h[ 3] = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )]; + h[ 7] = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )]; + h[11] = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )]; + h[15] = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )]; + + /* Lane 7 */ + t0 = T0[B3(s70)] ^ T1[B2(s71)] ^ T2[B1(s72)] ^ T3[B0(s73)] ^ C[ 0+720]; + t4 = T0[B3(s71)] ^ T1[B2(s72)] ^ T2[B1(s73)] ^ T3[B0(s70)] ^ C[ 1+720]; + t8 = T0[B3(s72)] ^ T1[B2(s73)] ^ T2[B1(s70)] ^ T3[B0(s71)] ^ C[ 2+720]; + tc = T0[B3(s73)] ^ T1[B2(s70)] ^ T2[B1(s71)] ^ T3[B0(s72)] ^ C[ 3+720] ^ ctrl; + t1 = T0[B3(s74)] ^ T1[B2(s75)] ^ T2[B1(s76)] ^ T3[B0(s77)] ^ C[ 4+720]; + t5 = T0[B3(s75)] ^ T1[B2(s76)] ^ T2[B1(s77)] ^ T3[B0(s74)] ^ C[ 5+720]; + t9 = T0[B3(s76)] ^ T1[B2(s77)] ^ T2[B1(s74)] ^ T3[B0(s75)] ^ C[ 6+720]; + td = T0[B3(s77)] ^ T1[B2(s74)] ^ T2[B1(s75)] ^ T3[B0(s76)] ^ C[ 7+720]; + t2 = T0[B3(s78)] ^ T1[B2(s79)] ^ T2[B1(s7a)] ^ T3[B0(s7b)] ^ C[ 8+720]; + t6 = T0[B3(s79)] ^ T1[B2(s7a)] ^ T2[B1(s7b)] ^ T3[B0(s78)] ^ C[ 9+720]; + ta = T0[B3(s7a)] ^ T1[B2(s7b)] ^ T2[B1(s78)] ^ T3[B0(s79)] ^ C[ 10+720]; + te = T0[B3(s7b)] ^ T1[B2(s78)] ^ T2[B1(s79)] ^ T3[B0(s7a)] ^ C[ 11+720]; + t3 = T0[B3(s7c)] ^ T1[B2(s7d)] ^ T2[B1(s7e)] ^ T3[B0(s7f)] ^ C[ 12+720]; + t7 = T0[B3(s7d)] ^ T1[B2(s7e)] ^ T2[B1(s7f)] ^ T3[B0(s7c)] ^ C[ 13+720]; + tb = T0[B3(s7e)] ^ T1[B2(s7f)] ^ T2[B1(s7c)] ^ T3[B0(s7d)] ^ C[ 14+720]; + tf = T0[B3(s7f)] ^ T1[B2(s7c)] ^ T2[B1(s7d)] ^ T3[B0(s7e)] ^ C[ 15+720]; + + s70 = T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )] ^ C[ 16+720]; + s74 = T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )] ^ C[ 17+720]; + s78 = T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )] ^ C[ 18+720]; + s7c = T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )] ^ C[ 19+720] ^ ctrh; + s71 = T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )] ^ C[ 20+720]; + s75 = T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )] ^ C[ 21+720]; + s79 = T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )] ^ C[ 22+720]; + s7d = T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )] ^ C[ 23+720]; + s72 = T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )] ^ C[ 24+720]; + s76 = T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )] ^ C[ 25+720]; + s7a = T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )] ^ C[ 26+720]; + s7e = T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )] ^ C[ 27+720]; + s73 = T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )] ^ C[ 28+720]; + s77 = T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )] ^ C[ 29+720]; + s7b = T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )] ^ C[ 30+720]; + s7f = T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )] ^ C[ 31+720]; + + t0 = T0[B3(s70)] ^ T1[B2(s71)] ^ T2[B1(s72)] ^ T3[B0(s73)] ^ C[ 32+720]; + t4 = T0[B3(s71)] ^ T1[B2(s72)] ^ T2[B1(s73)] ^ T3[B0(s70)] ^ C[ 33+720]; + t8 = T0[B3(s72)] ^ T1[B2(s73)] ^ T2[B1(s70)] ^ T3[B0(s71)] ^ C[ 34+720]; + tc = T0[B3(s73)] ^ T1[B2(s70)] ^ T2[B1(s71)] ^ T3[B0(s72)] ^ C[ 35+720] ^ ctrl; + t1 = T0[B3(s74)] ^ T1[B2(s75)] ^ T2[B1(s76)] ^ T3[B0(s77)] ^ C[ 36+720]; + t5 = T0[B3(s75)] ^ T1[B2(s76)] ^ T2[B1(s77)] ^ T3[B0(s74)] ^ C[ 37+720]; + t9 = T0[B3(s76)] ^ T1[B2(s77)] ^ T2[B1(s74)] ^ T3[B0(s75)] ^ C[ 38+720]; + td = T0[B3(s77)] ^ T1[B2(s74)] ^ T2[B1(s75)] ^ T3[B0(s76)] ^ C[ 39+720]; + t2 = T0[B3(s78)] ^ T1[B2(s79)] ^ T2[B1(s7a)] ^ T3[B0(s7b)] ^ C[ 40+720]; + t6 = T0[B3(s79)] ^ T1[B2(s7a)] ^ T2[B1(s7b)] ^ T3[B0(s78)] ^ C[ 41+720]; + ta = T0[B3(s7a)] ^ T1[B2(s7b)] ^ T2[B1(s78)] ^ T3[B0(s79)] ^ C[ 42+720]; + te = T0[B3(s7b)] ^ T1[B2(s78)] ^ T2[B1(s79)] ^ T3[B0(s7a)] ^ C[ 43+720]; + t3 = T0[B3(s7c)] ^ T1[B2(s7d)] ^ T2[B1(s7e)] ^ T3[B0(s7f)] ^ C[ 44+720]; + t7 = T0[B3(s7d)] ^ T1[B2(s7e)] ^ T2[B1(s7f)] ^ T3[B0(s7c)] ^ C[ 45+720]; + tb = T0[B3(s7e)] ^ T1[B2(s7f)] ^ T2[B1(s7c)] ^ T3[B0(s7d)] ^ C[ 46+720]; + tf = T0[B3(s7f)] ^ T1[B2(s7c)] ^ T2[B1(s7d)] ^ T3[B0(s7e)] ^ C[ 47+720]; + + h[ 0] ^= T0[B3(t0 )] ^ T1[B2(t1 )] ^ T2[B1(t2 )] ^ T3[B0(t3 )]; + h[ 4] ^= T0[B3(t1 )] ^ T1[B2(t2 )] ^ T2[B1(t3 )] ^ T3[B0(t0 )]; + h[ 8] ^= T0[B3(t2 )] ^ T1[B2(t3 )] ^ T2[B1(t0 )] ^ T3[B0(t1 )]; + h[12] ^= T0[B3(t3 )] ^ T1[B2(t0 )] ^ T2[B1(t1 )] ^ T3[B0(t2 )]; + h[ 1] ^= T0[B3(t4 )] ^ T1[B2(t5 )] ^ T2[B1(t6 )] ^ T3[B0(t7 )]; + h[ 5] ^= T0[B3(t5 )] ^ T1[B2(t6 )] ^ T2[B1(t7 )] ^ T3[B0(t4 )]; + h[ 9] ^= T0[B3(t6 )] ^ T1[B2(t7 )] ^ T2[B1(t4 )] ^ T3[B0(t5 )]; + h[13] ^= T0[B3(t7 )] ^ T1[B2(t4 )] ^ T2[B1(t5 )] ^ T3[B0(t6 )]; + h[ 2] ^= T0[B3(t8 )] ^ T1[B2(t9 )] ^ T2[B1(ta )] ^ T3[B0(tb )]; + h[ 6] ^= T0[B3(t9 )] ^ T1[B2(ta )] ^ T2[B1(tb )] ^ T3[B0(t8 )]; + h[10] ^= T0[B3(ta )] ^ T1[B2(tb )] ^ T2[B1(t8 )] ^ T3[B0(t9 )]; + h[14] ^= T0[B3(tb )] ^ T1[B2(t8 )] ^ T2[B1(t9 )] ^ T3[B0(ta )]; + h[ 3] ^= T0[B3(tc )] ^ T1[B2(td )] ^ T2[B1(te )] ^ T3[B0(tf )]; + h[ 7] ^= T0[B3(td )] ^ T1[B2(te )] ^ T2[B1(tf )] ^ T3[B0(tc )]; + h[11] ^= T0[B3(te )] ^ T1[B2(tf )] ^ T2[B1(tc )] ^ T3[B0(td )]; + h[15] ^= T0[B3(tf )] ^ T1[B2(tc )] ^ T2[B1(td )] ^ T3[B0(te )]; +} + +HashReturn laneInit (hashState *state, int hashbitlen) +{ + if (hashbitlen != 224 && hashbitlen != 256 && hashbitlen != 384 && hashbitlen != 512) + return BAD_HASHBITLEN; + + state->hashbitlen = hashbitlen; + state->ctr = 0; + + switch (state->hashbitlen) { + case 224: + memcpy(state->h, iv224, 8*sizeof(u32)); + break; + case 256: default: + memcpy(state->h, iv256, 8*sizeof(u32)); + break; + case 384: + memcpy(state->h, iv384, 16*sizeof(u32)); + break; + case 512: + memcpy(state->h, iv512, 16*sizeof(u32)); + break; + } + + return SUCCESS; +} + +HashReturn laneUpdate (hashState *state, const BitSequence *data, DataLength databitlen) +{ + u64 buffill; + u64 bytes; + + switch (state->hashbitlen) { + case 224: case 256: default: + buffill = (state->ctr >> 3) & 0x3f; + bytes = databitlen >> 3; + + if (state->ctr & 0x7) + return BAD_DATABITLEN; /* Only the last call to Update() may contain a fractional byte */ + + /* Check if we have some stuff left in the buffer. If so, fill it, and process it */ + if (buffill) { + const u64 n = buffill + bytes > 64 ? 64-buffill : bytes; /* number of bytes to copy */ + memcpy(state->buffer + buffill, data, n); + state->ctr += n << 3; + if (buffill + n == 64) /* full buffer now */ + lane256_compress(state->buffer, state->h, MSB32(state->ctr), LSB32(state->ctr)); + data += n; + bytes -= n; + } + + /* Now process as many full blocks as we can directly from the input message */ + while (bytes >= 64) { + state->ctr += 64 << 3; + lane256_compress(data, state->h, MSB32(state->ctr), LSB32(state->ctr)); + data += 64; + bytes -= 64; + } + break; + + case 384: case 512: + buffill = (state->ctr >> 3) & 0x7f; + bytes = databitlen >> 3; + + if (state->ctr & 0x7) + return BAD_DATABITLEN; /* Only the last call to Update() may contain a fractional byte */ + + /* Check if we have some stuff left in the buffer. If so, fill it, and process it */ + if (buffill) { + const u64 n = buffill + bytes > 128 ? 128-buffill : bytes; /* number of bytes to copy */ + memcpy(state->buffer + buffill, data, n); + state->ctr += n << 3; + if (buffill + n == 128) /* full buffer now */ + lane512_compress(state->buffer, state->h, MSB32(state->ctr), LSB32(state->ctr)); + data += n; + bytes -= n; + } + + /* Now process as many full blocks as we can directly from the input message */ + while (bytes >= 128) { + state->ctr += 128 << 3; + lane512_compress(data, state->h, MSB32(state->ctr), LSB32(state->ctr)); + data += 128; + bytes -= 128; + } + break; + } + + /* And finally, save the last, incomplete message block */ + if (bytes || (databitlen & 0x7)) { + memcpy(state->buffer, data, databitlen & 0x7 ? bytes+1 : bytes); /* also copy partial byte */ + state->ctr += (bytes << 3) + (databitlen & 0x7); + } + + return SUCCESS; +} + +HashReturn laneFinal (hashState *state, BitSequence *hashval) +{ + + switch (state->hashbitlen) { + case 224: case 256: default: + /* do zero padding and compress last block, if there is some data in the buffer */ + if (state->ctr & 0x1ff) { + const u64 n = (((state->ctr & 0x1ff) - 1) >> 3) + 1; /* number of bytes in buffer that are (partially) filled */ + if (n < 64) + memset(state->buffer + n, 0, 64-n); + state->buffer[(state->ctr >> 3)&0x3f] &= ~(0xff >> (state->ctr & 0x7)); /* zero-pad partial byte */ + lane256_compress(state->buffer, state->h, MSB32(state->ctr), LSB32(state->ctr)); + } + + /* output transformation */ + memset(state->buffer, 0, 64); + state->buffer[0] = 0x00; /* flag byte 0x00: output transformation without seed */ + state->buffer[1] = T8(state->ctr >> 56); /* message length in big-endian */ + state->buffer[2] = T8(state->ctr >> 48); + state->buffer[3] = T8(state->ctr >> 40); + state->buffer[4] = T8(state->ctr >> 32); + state->buffer[5] = T8(state->ctr >> 24); + state->buffer[6] = T8(state->ctr >> 16); + state->buffer[7] = T8(state->ctr >> 8); + state->buffer[8] = T8(state->ctr >> 0); + lane256_compress(state->buffer, state->h, 0, 0); + + /* write back result */ + U32TO8_BIG(hashval, state->h[0]); + U32TO8_BIG(hashval+4, state->h[1]); + U32TO8_BIG(hashval+8, state->h[2]); + U32TO8_BIG(hashval+12, state->h[3]); + U32TO8_BIG(hashval+16, state->h[4]); + U32TO8_BIG(hashval+20, state->h[5]); + U32TO8_BIG(hashval+24, state->h[6]); + U32TO8_BIG(hashval+28, state->h[7]); + + break; + + case 384: case 512: + /* do zero padding and compress last block, if there is some data in the buffer */ + if (state->ctr & 0x3ff) { + const u64 n = (((state->ctr & 0x3ff) - 1) >> 3) + 1; /* number of bytes in buffer that are (partially) filled */ + if (n < 128) + memset(state->buffer + n, 0, 128-n); + state->buffer[(state->ctr >> 3)&0x7f] &= ~(0xff >> (state->ctr & 0x7)); /* zero-pad partial byte */ + lane512_compress(state->buffer, state->h, MSB32(state->ctr), LSB32(state->ctr)); + } + + /* output transformation */ + memset(state->buffer, 0, 128); + state->buffer[0] = 0x00; /* flag byte 0x00: output transformation without seed */ + state->buffer[1] = T8(state->ctr >> 56); /* message length in big-endian */ + state->buffer[2] = T8(state->ctr >> 48); + state->buffer[3] = T8(state->ctr >> 40); + state->buffer[4] = T8(state->ctr >> 32); + state->buffer[5] = T8(state->ctr >> 24); + state->buffer[6] = T8(state->ctr >> 16); + state->buffer[7] = T8(state->ctr >> 8); + state->buffer[8] = T8(state->ctr >> 0); + lane512_compress(state->buffer, state->h, 0, 0); + + /* write back result */ + U32TO8_BIG(hashval, state->h[0]); + U32TO8_BIG(hashval+4, state->h[1]); + U32TO8_BIG(hashval+8, state->h[2]); + U32TO8_BIG(hashval+12, state->h[3]); + U32TO8_BIG(hashval+16, state->h[4]); + U32TO8_BIG(hashval+20, state->h[5]); + U32TO8_BIG(hashval+24, state->h[6]); + U32TO8_BIG(hashval+28, state->h[7]); + U32TO8_BIG(hashval+32, state->h[8]); + U32TO8_BIG(hashval+36, state->h[9]); + U32TO8_BIG(hashval+40, state->h[10]); + U32TO8_BIG(hashval+44, state->h[11]); + U32TO8_BIG(hashval+48, state->h[12]); + U32TO8_BIG(hashval+52, state->h[13]); + U32TO8_BIG(hashval+56, state->h[14]); + U32TO8_BIG(hashval+60, state->h[15]); + + break; + } + + return SUCCESS; +} + +HashReturn laneHash (int hashbitlen, const BitSequence *data, DataLength databitlen, BitSequence *hashval) +{ + hashState state; + HashReturn hashReturn; + + if ((hashReturn = laneInit(&state, hashbitlen)) != SUCCESS) + return hashReturn; + if ((hashReturn = laneUpdate(&state, data, databitlen)) != SUCCESS) + return hashReturn; + if ((hashReturn = laneFinal(&state, hashval)) != SUCCESS) + return hashReturn; + return SUCCESS; +} diff --git a/stratum/sha3/lane.h b/stratum/sha3/lane.h new file mode 100644 index 000000000..1d935a171 --- /dev/null +++ b/stratum/sha3/lane.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2008 Sebastiaan Indesteege + * + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Optimised ANSI-C implementation of LANE + */ + +#ifndef LANE_H +#define LANE_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include + +typedef unsigned char BitSequence; +typedef unsigned long long DataLength; + +typedef enum { SUCCESS = 0, FAIL = 1, BAD_HASHBITLEN = 2, BAD_DATABITLEN = 3 } HashReturn; + +typedef unsigned char u8; +typedef unsigned int u32; +typedef unsigned long long u64; + +typedef struct { + int hashbitlen; + u64 ctr; + u32 h[16]; + u8 buffer[128]; +} hashState; + +HashReturn laneInit (hashState *state, int hashbitlen); +HashReturn laneUpdate (hashState *state, const BitSequence *data, DataLength databitlen); +HashReturn laneFinal (hashState *state, BitSequence *hashval); +HashReturn laneHash (int hashbitlen, const BitSequence *data, DataLength databitlen, BitSequence *hashval); + +#if defined(__cplusplus) +} +#endif + +#endif /* LANE_H */ diff --git a/stratum/sha3/makefile b/stratum/sha3/makefile index 6c917993b..7232f7257 100644 --- a/stratum/sha3/makefile +++ b/stratum/sha3/makefile @@ -5,8 +5,8 @@ CFLAGS= -O3 -march=native LDFLAGS=-O2 SOURCES=sph_jh.c sph_blake.c sph_bmw.c sph_groestl.c sph_skein.c sph_keccak.c sph_luffa.c sph_cubehash.c sph_shavite.c \ - sph_simd.c sph_echo.c sph_fugue.c sph_hamsi.c sph_shabal.c sph_whirlpool.c \ - sph_haval.c sph_hefty1.c sph_ripemd.c sph_sha2.c sph_sha2big.c sph_tiger.c \ + sph_simd.c sph_echo.c sph_fugue.c sph_hamsi.c sph_shabal.c sph_whirlpool.c sph_sm3.c sph_streebog.c \ + sph_haval.c sph_hefty1.c sph_ripemd.c sph_sha2.c sph_sha2big.c sph_tiger.c sph_panama.c sph_radiogatun.c \ blake2s.c blake2b.c OBJECTS=$(SOURCES:.c=.o) diff --git a/stratum/sha3/panama.c b/stratum/sha3/panama.c new file mode 100644 index 000000000..2c864bff8 --- /dev/null +++ b/stratum/sha3/panama.c @@ -0,0 +1,334 @@ +/* $Id: panama.c 216 2010-06-08 09:46:57Z tp $ */ +/* + * PANAMA implementation. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @author Thomas Pornin + */ + +#include +#include + +#include "sph_panama.h" + +#define LVAR17(b) sph_u32 \ + b ## 0, b ## 1, b ## 2, b ## 3, b ## 4, b ## 5, \ + b ## 6, b ## 7, b ## 8, b ## 9, b ## 10, b ## 11, \ + b ## 12, b ## 13, b ## 14, b ## 15, b ## 16; + +#define LVARS \ + LVAR17(a) \ + LVAR17(g) \ + LVAR17(p) \ + LVAR17(t) + +#define M17(macro) do { \ + macro( 0, 1, 2, 4); \ + macro( 1, 2, 3, 5); \ + macro( 2, 3, 4, 6); \ + macro( 3, 4, 5, 7); \ + macro( 4, 5, 6, 8); \ + macro( 5, 6, 7, 9); \ + macro( 6, 7, 8, 10); \ + macro( 7, 8, 9, 11); \ + macro( 8, 9, 10, 12); \ + macro( 9, 10, 11, 13); \ + macro(10, 11, 12, 14); \ + macro(11, 12, 13, 15); \ + macro(12, 13, 14, 16); \ + macro(13, 14, 15, 0); \ + macro(14, 15, 16, 1); \ + macro(15, 16, 0, 2); \ + macro(16, 0, 1, 3); \ + } while (0) + +#define BUPDATE1(n0, n2) do { \ + sc->buffer[ptr24][n0] ^= sc->buffer[ptr31][n2]; \ + sc->buffer[ptr31][n2] ^= INW1(n2); \ + } while (0) + +#define BUPDATE do { \ + BUPDATE1(0, 2); \ + BUPDATE1(1, 3); \ + BUPDATE1(2, 4); \ + BUPDATE1(3, 5); \ + BUPDATE1(4, 6); \ + BUPDATE1(5, 7); \ + BUPDATE1(6, 0); \ + BUPDATE1(7, 1); \ + } while (0) + +#define RSTATE(n0, n1, n2, n4) (a ## n0 = sc->state[n0]) + +#define WSTATE(n0, n1, n2, n4) (sc->state[n0] = a ## n0) + +#define GAMMA(n0, n1, n2, n4) \ + (g ## n0 = a ## n0 ^ (a ## n1 | SPH_T32(~a ## n2))) + +#define PI_ALL do { \ + p0 = g0; \ + p1 = SPH_ROTL32( g7, 1); \ + p2 = SPH_ROTL32(g14, 3); \ + p3 = SPH_ROTL32( g4, 6); \ + p4 = SPH_ROTL32(g11, 10); \ + p5 = SPH_ROTL32( g1, 15); \ + p6 = SPH_ROTL32( g8, 21); \ + p7 = SPH_ROTL32(g15, 28); \ + p8 = SPH_ROTL32( g5, 4); \ + p9 = SPH_ROTL32(g12, 13); \ + p10 = SPH_ROTL32( g2, 23); \ + p11 = SPH_ROTL32( g9, 2); \ + p12 = SPH_ROTL32(g16, 14); \ + p13 = SPH_ROTL32( g6, 27); \ + p14 = SPH_ROTL32(g13, 9); \ + p15 = SPH_ROTL32( g3, 24); \ + p16 = SPH_ROTL32(g10, 8); \ + } while (0) + +#define THETA(n0, n1, n2, n4) \ + (t ## n0 = p ## n0 ^ p ## n1 ^ p ## n4) + +#define SIGMA_ALL do { \ + a0 = t0 ^ 1; \ + a1 = t1 ^ INW2(0); \ + a2 = t2 ^ INW2(1); \ + a3 = t3 ^ INW2(2); \ + a4 = t4 ^ INW2(3); \ + a5 = t5 ^ INW2(4); \ + a6 = t6 ^ INW2(5); \ + a7 = t7 ^ INW2(6); \ + a8 = t8 ^ INW2(7); \ + a9 = t9 ^ sc->buffer[ptr16][0]; \ + a10 = t10 ^ sc->buffer[ptr16][1]; \ + a11 = t11 ^ sc->buffer[ptr16][2]; \ + a12 = t12 ^ sc->buffer[ptr16][3]; \ + a13 = t13 ^ sc->buffer[ptr16][4]; \ + a14 = t14 ^ sc->buffer[ptr16][5]; \ + a15 = t15 ^ sc->buffer[ptr16][6]; \ + a16 = t16 ^ sc->buffer[ptr16][7]; \ + } while (0) + +#define PANAMA_STEP do { \ + unsigned ptr16, ptr24, ptr31; \ + \ + ptr24 = (ptr0 - 8) & 31; \ + ptr31 = (ptr0 - 1) & 31; \ + BUPDATE; \ + M17(GAMMA); \ + PI_ALL; \ + M17(THETA); \ + ptr16 = ptr0 ^ 16; \ + SIGMA_ALL; \ + ptr0 = ptr31; \ + } while (0) + +/* + * These macros are used to compute + */ +#define INC0 1 +#define INC1 2 +#define INC2 3 +#define INC3 4 +#define INC4 5 +#define INC5 6 +#define INC6 7 +#define INC7 8 + +/* + * Push data by blocks of 32 bytes. "pbuf" must be 32-bit aligned. Each + * iteration processes 32 data bytes; "num" contains the number of + * iterations. + */ +static void +panama_push(sph_panama_context *sc, const unsigned char *pbuf, size_t num) +{ + LVARS + unsigned ptr0; +#if SPH_LITTLE_FAST +#define INW1(i) sph_dec32le_aligned(pbuf + 4 * (i)) +#else + sph_u32 X_var[8]; +#define INW1(i) X_var[i] +#endif +#define INW2(i) INW1(i) + + M17(RSTATE); + ptr0 = sc->buffer_ptr; + while (num -- > 0) { +#if !SPH_LITTLE_FAST + int i; + + for (i = 0; i < 8; i ++) + X_var[i] = sph_dec32le_aligned(pbuf + 4 * (i)); +#endif + PANAMA_STEP; + pbuf = (const unsigned char *)pbuf + 32; + } + M17(WSTATE); + sc->buffer_ptr = ptr0; + +#undef INW1 +#undef INW2 +} + +/* + * Perform the "pull" operation repeatedly ("num" times). The hash output + * will be extracted from the state afterwards. + */ +static void +panama_pull(sph_panama_context *sc, unsigned num) +{ + LVARS + unsigned ptr0; +#define INW1(i) INW_H1(INC ## i) +#define INW_H1(i) INW_H2(i) +#define INW_H2(i) a ## i +#define INW2(i) sc->buffer[ptr4][i] + + M17(RSTATE); + ptr0 = sc->buffer_ptr; + while (num -- > 0) { + unsigned ptr4; + + ptr4 = (ptr0 + 4) & 31; + PANAMA_STEP; + } + M17(WSTATE); + +#undef INW1 +#undef INW_H1 +#undef INW_H2 +#undef INW2 +} + +/* see sph_panama.h */ +void +sph_panama_init(void *cc) +{ + sph_panama_context *sc; + + sc = cc; + /* + * This is not completely conformant, but "it will work + * everywhere". Initial state consists of zeroes everywhere. + * Conceptually, the sph_u32 type may have padding bits which + * must not be set to 0; but such an architecture remains to + * be seen. + */ + sc->data_ptr = 0; + memset(sc->buffer, 0, sizeof sc->buffer); + sc->buffer_ptr = 0; + memset(sc->state, 0, sizeof sc->state); +} + +#ifdef SPH_UPTR +static void +panama_short(void *cc, const void *data, size_t len) +#else +void +sph_panama(void *cc, const void *data, size_t len) +#endif +{ + sph_panama_context *sc; + unsigned current; + + sc = cc; + current = sc->data_ptr; + while (len > 0) { + unsigned clen; + + clen = (sizeof sc->data) - current; + if (clen > len) + clen = len; + memcpy(sc->data + current, data, clen); + data = (const unsigned char *)data + clen; + len -= clen; + current += clen; + if (current == sizeof sc->data) { + current = 0; + panama_push(sc, sc->data, 1); + } + } + sc->data_ptr = current; +} + +#ifdef SPH_UPTR +/* see sph_panama.h */ +void +sph_panama(void *cc, const void *data, size_t len) +{ + sph_panama_context *sc; + unsigned current; + size_t rlen; + + if (len < (2 * sizeof sc->data)) { + panama_short(cc, data, len); + return; + } + sc = cc; + current = sc->data_ptr; + if (current > 0) { + unsigned t; + + t = (sizeof sc->data) - current; + panama_short(sc, data, t); + data = (const unsigned char *)data + t; + len -= t; + } +#if !SPH_UNALIGNED + if (((SPH_UPTR)data & 3) != 0) { + panama_short(sc, data, len); + return; + } +#endif + panama_push(sc, data, len >> 5); + rlen = len & 31; + if (rlen > 0) + memcpy(sc->data, + (const unsigned char *)data + len - rlen, rlen); + sc->data_ptr = rlen; +} +#endif + +/* see sph_panama.h */ +void +sph_panama_close(void *cc, void *dst) +{ + sph_panama_context *sc; + unsigned current; + int i; + + sc = cc; + current = sc->data_ptr; + sc->data[current ++] = 0x01; + memset(sc->data + current, 0, (sizeof sc->data) - current); + panama_push(sc, sc->data, 1); + panama_pull(sc, 32); + for (i = 0; i < 8; i ++) + sph_enc32le((unsigned char *)dst + 4 * i, sc->state[i + 9]); + sph_panama_init(sc); +} diff --git a/stratum/sha3/sha2.c b/stratum/sha3/sha2.c new file mode 100644 index 000000000..1989dd1bb --- /dev/null +++ b/stratum/sha3/sha2.c @@ -0,0 +1,475 @@ +/* + * Copyright 2011 ArtForz + * Copyright 2011-2013 pooler + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. See COPYING for more details. + */ + +#include +#include + +#if defined(__arm__) && defined(__APCS_32__) +#define EXTERN_SHA256 +#endif + +#define bswap_32(x) ((((x) << 24) & 0xff000000u) | (((x) << 8) & 0x00ff0000u) \ + | (((x) >> 8) & 0x0000ff00u) | (((x) >> 24) & 0x000000ffu)) + +static inline uint32_t swab32(uint32_t v) +{ + return bswap_32(v); +} + +#if !HAVE_DECL_BE32ENC +static inline void be32enc(void *pp, uint32_t x) +{ + uint8_t *p = (uint8_t *)pp; + p[3] = x & 0xff; + p[2] = (x >> 8) & 0xff; + p[1] = (x >> 16) & 0xff; + p[0] = (x >> 24) & 0xff; +} +#endif + +#if !HAVE_DECL_BE32DEC +static inline uint32_t be32dec(const void *pp) +{ + const uint8_t *p = (uint8_t const *)pp; + return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) + + ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24)); +} +#endif + +static const uint32_t sha256_h[8] = { + 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, + 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 +}; + +static const uint32_t sha256_k[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +void sha256_init(uint32_t *state) +{ + memcpy(state, sha256_h, 32); +} + +/* Elementary functions used by SHA256 */ +#define Ch(x, y, z) ((x & (y ^ z)) ^ z) +#define Maj(x, y, z) ((x & (y | z)) | (y & z)) +#define ROTR(x, n) ((x >> n) | (x << (32 - n))) +#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) +#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) +#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ (x >> 3)) +#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ (x >> 10)) + +/* SHA256 round function */ +#define RND(a, b, c, d, e, f, g, h, k) \ + do { \ + t0 = h + S1(e) + Ch(e, f, g) + k; \ + t1 = S0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; \ + } while (0) + +/* Adjusted round function for rotating state */ +#define RNDr(S, W, i) \ + RND(S[(64 - i) % 8], S[(65 - i) % 8], \ + S[(66 - i) % 8], S[(67 - i) % 8], \ + S[(68 - i) % 8], S[(69 - i) % 8], \ + S[(70 - i) % 8], S[(71 - i) % 8], \ + W[i] + sha256_k[i]) + +#ifndef EXTERN_SHA256 + +/* + * SHA256 block compression function. The 256-bit state is transformed via + * the 512-bit input block to produce a new state. + */ +void sha256_transform(uint32_t *state, const uint32_t *block, int swap) +{ + uint32_t W[64]; + uint32_t S[8]; + uint32_t t0, t1; + int i; + + /* 1. Prepare message schedule W. */ + if (swap) { + for (i = 0; i < 16; i++) + W[i] = swab32(block[i]); + } else + memcpy(W, block, 64); + for (i = 16; i < 64; i += 2) { + W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; + W[i+1] = s1(W[i - 1]) + W[i - 6] + s0(W[i - 14]) + W[i - 15]; + } + + /* 2. Initialize working variables. */ + memcpy(S, state, 32); + + /* 3. Mix. */ + RNDr(S, W, 0); + RNDr(S, W, 1); + RNDr(S, W, 2); + RNDr(S, W, 3); + RNDr(S, W, 4); + RNDr(S, W, 5); + RNDr(S, W, 6); + RNDr(S, W, 7); + RNDr(S, W, 8); + RNDr(S, W, 9); + RNDr(S, W, 10); + RNDr(S, W, 11); + RNDr(S, W, 12); + RNDr(S, W, 13); + RNDr(S, W, 14); + RNDr(S, W, 15); + RNDr(S, W, 16); + RNDr(S, W, 17); + RNDr(S, W, 18); + RNDr(S, W, 19); + RNDr(S, W, 20); + RNDr(S, W, 21); + RNDr(S, W, 22); + RNDr(S, W, 23); + RNDr(S, W, 24); + RNDr(S, W, 25); + RNDr(S, W, 26); + RNDr(S, W, 27); + RNDr(S, W, 28); + RNDr(S, W, 29); + RNDr(S, W, 30); + RNDr(S, W, 31); + RNDr(S, W, 32); + RNDr(S, W, 33); + RNDr(S, W, 34); + RNDr(S, W, 35); + RNDr(S, W, 36); + RNDr(S, W, 37); + RNDr(S, W, 38); + RNDr(S, W, 39); + RNDr(S, W, 40); + RNDr(S, W, 41); + RNDr(S, W, 42); + RNDr(S, W, 43); + RNDr(S, W, 44); + RNDr(S, W, 45); + RNDr(S, W, 46); + RNDr(S, W, 47); + RNDr(S, W, 48); + RNDr(S, W, 49); + RNDr(S, W, 50); + RNDr(S, W, 51); + RNDr(S, W, 52); + RNDr(S, W, 53); + RNDr(S, W, 54); + RNDr(S, W, 55); + RNDr(S, W, 56); + RNDr(S, W, 57); + RNDr(S, W, 58); + RNDr(S, W, 59); + RNDr(S, W, 60); + RNDr(S, W, 61); + RNDr(S, W, 62); + RNDr(S, W, 63); + + /* 4. Mix local working variables into global state */ + for (i = 0; i < 8; i++) + state[i] += S[i]; +} + +#endif /* EXTERN_SHA256 */ + + +static const uint32_t sha256d_hash1[16] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x80000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000100 +}; + + +void sha256d(unsigned char *hash, const unsigned char *data, int len) +{ + uint32_t S[16], T[16]; + int i, r; + + sha256_init(S); + for (r = len; r > -9; r -= 64) { + if (r < 64) + memset(T, 0, 64); + memcpy(T, data + len - r, r > 64 ? 64 : (r < 0 ? 0 : r)); + if (r >= 0 && r < 64) + ((unsigned char *)T)[r] = 0x80; + for (i = 0; i < 16; i++) + T[i] = be32dec(T + i); + if (r < 56) + T[15] = 8 * len; + sha256_transform(S, T, 0); + } + memcpy(S + 8, sha256d_hash1 + 8, 32); + sha256_init(T); + sha256_transform(T, S, 0); + for (i = 0; i < 8; i++) + be32enc((uint32_t *)hash + i, T[i]); +} + +static inline void sha256d_preextend(uint32_t *W) +{ + W[16] = s1(W[14]) + W[ 9] + s0(W[ 1]) + W[ 0]; + W[17] = s1(W[15]) + W[10] + s0(W[ 2]) + W[ 1]; + W[18] = s1(W[16]) + W[11] + W[ 2]; + W[19] = s1(W[17]) + W[12] + s0(W[ 4]); + W[20] = W[13] + s0(W[ 5]) + W[ 4]; + W[21] = W[14] + s0(W[ 6]) + W[ 5]; + W[22] = W[15] + s0(W[ 7]) + W[ 6]; + W[23] = W[16] + s0(W[ 8]) + W[ 7]; + W[24] = W[17] + s0(W[ 9]) + W[ 8]; + W[25] = s0(W[10]) + W[ 9]; + W[26] = s0(W[11]) + W[10]; + W[27] = s0(W[12]) + W[11]; + W[28] = s0(W[13]) + W[12]; + W[29] = s0(W[14]) + W[13]; + W[30] = s0(W[15]) + W[14]; + W[31] = s0(W[16]) + W[15]; +} + +static inline void sha256d_prehash(uint32_t *S, const uint32_t *W) +{ + uint32_t t0, t1; + RNDr(S, W, 0); + RNDr(S, W, 1); + RNDr(S, W, 2); +} + +#ifdef EXTERN_SHA256 + +void sha256d_ms(uint32_t *hash, uint32_t *W, + const uint32_t *midstate, const uint32_t *prehash); + +#else + +static inline void sha256d_ms(uint32_t *hash, uint32_t *W, + const uint32_t *midstate, const uint32_t *prehash) +{ + uint32_t S[64]; + uint32_t t0, t1; + int i; + + S[18] = W[18]; + S[19] = W[19]; + S[20] = W[20]; + S[22] = W[22]; + S[23] = W[23]; + S[24] = W[24]; + S[30] = W[30]; + S[31] = W[31]; + + W[18] += s0(W[3]); + W[19] += W[3]; + W[20] += s1(W[18]); + W[21] = s1(W[19]); + W[22] += s1(W[20]); + W[23] += s1(W[21]); + W[24] += s1(W[22]); + W[25] = s1(W[23]) + W[18]; + W[26] = s1(W[24]) + W[19]; + W[27] = s1(W[25]) + W[20]; + W[28] = s1(W[26]) + W[21]; + W[29] = s1(W[27]) + W[22]; + W[30] += s1(W[28]) + W[23]; + W[31] += s1(W[29]) + W[24]; + for (i = 32; i < 64; i += 2) { + W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; + W[i+1] = s1(W[i - 1]) + W[i - 6] + s0(W[i - 14]) + W[i - 15]; + } + + memcpy(S, prehash, 32); + + RNDr(S, W, 3); + RNDr(S, W, 4); + RNDr(S, W, 5); + RNDr(S, W, 6); + RNDr(S, W, 7); + RNDr(S, W, 8); + RNDr(S, W, 9); + RNDr(S, W, 10); + RNDr(S, W, 11); + RNDr(S, W, 12); + RNDr(S, W, 13); + RNDr(S, W, 14); + RNDr(S, W, 15); + RNDr(S, W, 16); + RNDr(S, W, 17); + RNDr(S, W, 18); + RNDr(S, W, 19); + RNDr(S, W, 20); + RNDr(S, W, 21); + RNDr(S, W, 22); + RNDr(S, W, 23); + RNDr(S, W, 24); + RNDr(S, W, 25); + RNDr(S, W, 26); + RNDr(S, W, 27); + RNDr(S, W, 28); + RNDr(S, W, 29); + RNDr(S, W, 30); + RNDr(S, W, 31); + RNDr(S, W, 32); + RNDr(S, W, 33); + RNDr(S, W, 34); + RNDr(S, W, 35); + RNDr(S, W, 36); + RNDr(S, W, 37); + RNDr(S, W, 38); + RNDr(S, W, 39); + RNDr(S, W, 40); + RNDr(S, W, 41); + RNDr(S, W, 42); + RNDr(S, W, 43); + RNDr(S, W, 44); + RNDr(S, W, 45); + RNDr(S, W, 46); + RNDr(S, W, 47); + RNDr(S, W, 48); + RNDr(S, W, 49); + RNDr(S, W, 50); + RNDr(S, W, 51); + RNDr(S, W, 52); + RNDr(S, W, 53); + RNDr(S, W, 54); + RNDr(S, W, 55); + RNDr(S, W, 56); + RNDr(S, W, 57); + RNDr(S, W, 58); + RNDr(S, W, 59); + RNDr(S, W, 60); + RNDr(S, W, 61); + RNDr(S, W, 62); + RNDr(S, W, 63); + + for (i = 0; i < 8; i++) + S[i] += midstate[i]; + + W[18] = S[18]; + W[19] = S[19]; + W[20] = S[20]; + W[22] = S[22]; + W[23] = S[23]; + W[24] = S[24]; + W[30] = S[30]; + W[31] = S[31]; + + memcpy(S + 8, sha256d_hash1 + 8, 32); + S[16] = s1(sha256d_hash1[14]) + sha256d_hash1[ 9] + s0(S[ 1]) + S[ 0]; + S[17] = s1(sha256d_hash1[15]) + sha256d_hash1[10] + s0(S[ 2]) + S[ 1]; + S[18] = s1(S[16]) + sha256d_hash1[11] + s0(S[ 3]) + S[ 2]; + S[19] = s1(S[17]) + sha256d_hash1[12] + s0(S[ 4]) + S[ 3]; + S[20] = s1(S[18]) + sha256d_hash1[13] + s0(S[ 5]) + S[ 4]; + S[21] = s1(S[19]) + sha256d_hash1[14] + s0(S[ 6]) + S[ 5]; + S[22] = s1(S[20]) + sha256d_hash1[15] + s0(S[ 7]) + S[ 6]; + S[23] = s1(S[21]) + S[16] + s0(sha256d_hash1[ 8]) + S[ 7]; + S[24] = s1(S[22]) + S[17] + s0(sha256d_hash1[ 9]) + sha256d_hash1[ 8]; + S[25] = s1(S[23]) + S[18] + s0(sha256d_hash1[10]) + sha256d_hash1[ 9]; + S[26] = s1(S[24]) + S[19] + s0(sha256d_hash1[11]) + sha256d_hash1[10]; + S[27] = s1(S[25]) + S[20] + s0(sha256d_hash1[12]) + sha256d_hash1[11]; + S[28] = s1(S[26]) + S[21] + s0(sha256d_hash1[13]) + sha256d_hash1[12]; + S[29] = s1(S[27]) + S[22] + s0(sha256d_hash1[14]) + sha256d_hash1[13]; + S[30] = s1(S[28]) + S[23] + s0(sha256d_hash1[15]) + sha256d_hash1[14]; + S[31] = s1(S[29]) + S[24] + s0(S[16]) + sha256d_hash1[15]; + for (i = 32; i < 60; i += 2) { + S[i] = s1(S[i - 2]) + S[i - 7] + s0(S[i - 15]) + S[i - 16]; + S[i+1] = s1(S[i - 1]) + S[i - 6] + s0(S[i - 14]) + S[i - 15]; + } + S[60] = s1(S[58]) + S[53] + s0(S[45]) + S[44]; + + sha256_init(hash); + + RNDr(hash, S, 0); + RNDr(hash, S, 1); + RNDr(hash, S, 2); + RNDr(hash, S, 3); + RNDr(hash, S, 4); + RNDr(hash, S, 5); + RNDr(hash, S, 6); + RNDr(hash, S, 7); + RNDr(hash, S, 8); + RNDr(hash, S, 9); + RNDr(hash, S, 10); + RNDr(hash, S, 11); + RNDr(hash, S, 12); + RNDr(hash, S, 13); + RNDr(hash, S, 14); + RNDr(hash, S, 15); + RNDr(hash, S, 16); + RNDr(hash, S, 17); + RNDr(hash, S, 18); + RNDr(hash, S, 19); + RNDr(hash, S, 20); + RNDr(hash, S, 21); + RNDr(hash, S, 22); + RNDr(hash, S, 23); + RNDr(hash, S, 24); + RNDr(hash, S, 25); + RNDr(hash, S, 26); + RNDr(hash, S, 27); + RNDr(hash, S, 28); + RNDr(hash, S, 29); + RNDr(hash, S, 30); + RNDr(hash, S, 31); + RNDr(hash, S, 32); + RNDr(hash, S, 33); + RNDr(hash, S, 34); + RNDr(hash, S, 35); + RNDr(hash, S, 36); + RNDr(hash, S, 37); + RNDr(hash, S, 38); + RNDr(hash, S, 39); + RNDr(hash, S, 40); + RNDr(hash, S, 41); + RNDr(hash, S, 42); + RNDr(hash, S, 43); + RNDr(hash, S, 44); + RNDr(hash, S, 45); + RNDr(hash, S, 46); + RNDr(hash, S, 47); + RNDr(hash, S, 48); + RNDr(hash, S, 49); + RNDr(hash, S, 50); + RNDr(hash, S, 51); + RNDr(hash, S, 52); + RNDr(hash, S, 53); + RNDr(hash, S, 54); + RNDr(hash, S, 55); + RNDr(hash, S, 56); + + hash[2] += hash[6] + S1(hash[3]) + Ch(hash[3], hash[4], hash[5]) + + S[57] + sha256_k[57]; + hash[1] += hash[5] + S1(hash[2]) + Ch(hash[2], hash[3], hash[4]) + + S[58] + sha256_k[58]; + hash[0] += hash[4] + S1(hash[1]) + Ch(hash[1], hash[2], hash[3]) + + S[59] + sha256_k[59]; + hash[7] += hash[3] + S1(hash[0]) + Ch(hash[0], hash[1], hash[2]) + + S[60] + sha256_k[60] + + sha256_h[7]; +} + +#endif /* EXTERN_SHA256 */ diff --git a/stratum/sha3/sph_gost.c b/stratum/sha3/sph_gost.c new file mode 100644 index 000000000..389ef0034 --- /dev/null +++ b/stratum/sha3/sph_gost.c @@ -0,0 +1,1101 @@ +/* $Id: gost.c 259 2011-07-19 22:11:27Z tp $ */ +/* + * GOST R 34.11-2012 implementation. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @author Thomas Pornin + */ + +//#include +//#include + +#include +#include +#include +#include + +#include "sph_gost.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +#ifdef _MSC_VER +#pragma warning (disable: 4146) +#endif + +//-------------------------------------------------------------------------------------------- +// +// stribog implementation +// +//-------------------------------------------------------------------------------------------- + + +// Tables for function F +const unsigned long long T[8][256] = { + { + 0xE6F87E5C5B711FD0,0x258377800924FA16,0xC849E07E852EA4A8,0x5B4686A18F06C16A, + 0x0B32E9A2D77B416E,0xABDA37A467815C66,0xF61796A81A686676,0xF5DC0B706391954B, + 0x4862F38DB7E64BF1,0xFF5C629A68BD85C5,0xCB827DA6FCD75795,0x66D36DAF69B9F089, + 0x356C9F74483D83B0,0x7CBCECB1238C99A1,0x36A702AC31C4708D,0x9EB6A8D02FBCDFD6, + 0x8B19FA51E5B3AE37,0x9CCFB5408A127D0B,0xBC0C78B508208F5A,0xE533E3842288ECED, + 0xCEC2C7D377C15FD2,0xEC7817B6505D0F5E,0xB94CC2C08336871D,0x8C205DB4CB0B04AD, + 0x763C855B28A0892F,0x588D1B79F6FF3257,0x3FECF69E4311933E,0x0FC0D39F803A18C9, + 0xEE010A26F5F3AD83,0x10EFE8F4411979A6,0x5DCDA10C7DE93A10,0x4A1BEE1D1248E92C, + 0x53BFF2DB21847339,0xB4F50CCFA6A23D09,0x5FB4BC9CD84798CD,0xE88A2D8B071C56F9, + 0x7F7771695A756A9C,0xC5F02E71A0BA1EBC,0xA663F9AB4215E672,0x2EB19E22DE5FBB78, + 0x0DB9CE0F2594BA14,0x82520E6397664D84,0x2F031E6A0208EA98,0x5C7F2144A1BE6BF0, + 0x7A37CB1CD16362DB,0x83E08E2B4B311C64,0xCF70479BAB960E32,0x856BA986B9DEE71E, + 0xB5478C877AF56CE9,0xB8FE42885F61D6FD,0x1BDD0156966238C8,0x622157923EF8A92E, + 0xFC97FF42114476F8,0x9D7D350856452CEB,0x4C90C9B0E0A71256,0x2308502DFBCB016C, + 0x2D7A03FAA7A64845,0xF46E8B38BFC6C4AB,0xBDBEF8FDD477DEBA,0x3AAC4CEBC8079B79, + 0xF09CB105E8879D0C,0x27FA6A10AC8A58CB,0x8960E7C1401D0CEA,0x1A6F811E4A356928, + 0x90C4FB0773D196FF,0x43501A2F609D0A9F,0xF7A516E0C63F3796,0x1CE4A6B3B8DA9252, + 0x1324752C38E08A9B,0xA5A864733BEC154F,0x2BF124575549B33F,0xD766DB15440DC5C7, + 0xA7D179E39E42B792,0xDADF151A61997FD3,0x86A0345EC0271423,0x38D5517B6DA939A4, + 0x6518F077104003B4,0x02791D90A5AEA2DD,0x88D267899C4A5D0A,0x930F66DF0A2865C2, + 0x4EE9D4204509B08B,0x325538916685292A,0x412907BFC533A842,0xB27E2B62544DC673, + 0x6C5304456295E007,0x5AF406E95351908A,0x1F2F3B6BC123616F,0xC37B09DC5255E5C6, + 0x3967D133B1FE6844,0x298839C7F0E711E2,0x409B87F71964F9A2,0xE938ADC3DB4B0719, + 0x0C0B4E47F9C3EBF4,0x5534D576D36B8843,0x4610A05AEB8B02D8,0x20C3CDF58232F251, + 0x6DE1840DBEC2B1E7,0xA0E8DE06B0FA1D08,0x7B854B540D34333B,0x42E29A67BCCA5B7F, + 0xD8A6088AC437DD0E,0xC63BB3A9D943ED81,0x21714DBD5E65A3B1,0x6761EDE7B5EEA169, + 0x2431F7C8D573ABF6,0xD51FC685E1A3671A,0x5E063CD40410C92D,0x283AB98F2CB04002, + 0x8FEBC06CB2F2F790,0x17D64F116FA1D33C,0xE07359F1A99EE4AA,0x784ED68C74CDC006, + 0x6E2A19D5C73B42DA,0x8712B4161C7045C3,0x371582E4ED93216D,0xACE390414939F6FC, + 0x7EC5F12186223B7C,0xC0B094042BAC16FB,0xF9D745379A527EBF,0x737C3F2EA3B68168, + 0x33E7B8D9BAD278CA,0xA9A32A34C22FFEBB,0xE48163CCFEDFBD0D,0x8E5940246EA5A670, + 0x51C6EF4B842AD1E4,0x22BAD065279C508C,0xD91488C218608CEE,0x319EA5491F7CDA17, + 0xD394E128134C9C60,0x094BF43272D5E3B3,0x9BF612A5A4AAD791,0xCCBBDA43D26FFD0F, + 0x34DE1F3C946AD250,0x4F5B5468995EE16B,0xDF9FAF6FEA8F7794,0x2648EA5870DD092B, + 0xBFC7E56D71D97C67,0xDDE6B2FF4F21D549,0x3C276B463AE86003,0x91767B4FAF86C71F, + 0x68A13E7835D4B9A0,0xB68C115F030C9FD4,0x141DD2C916582001,0x983D8F7DDD5324AC, + 0x64AA703FCC175254,0xC2C989948E02B426,0x3E5E76D69F46C2DE,0x50746F03587D8004, + 0x45DB3D829272F1E5,0x60584A029B560BF3,0xFBAE58A73FFCDC62,0xA15A5E4E6CAD4CE8, + 0x4BA96E55CE1FB8CC,0x08F9747AAE82B253,0xC102144CF7FB471B,0x9F042898F3EB8E36, + 0x068B27ADF2EFFB7A,0xEDCA97FE8C0A5EBE,0x778E0513F4F7D8CF,0x302C2501C32B8BF7, + 0x8D92DDFC175C554D,0xF865C57F46052F5F,0xEAF3301BA2B2F424,0xAA68B7ECBBD60D86, + 0x998F0F350104754C,0x0000000000000000,0xF12E314D34D0CCEC,0x710522BE061823B5, + 0xAF280D9930C005C1,0x97FD5CE25D693C65,0x19A41CC633CC9A15,0x95844172F8C79EB8, + 0xDC5432B7937684A9,0x9436C13A2490CF58,0x802B13F332C8EF59,0xC442AE397CED4F5C, + 0xFA1CD8EFE3AB8D82,0xF2E5AC954D293FD1,0x6AD823E8907A1B7D,0x4D2249F83CF043B6, + 0x03CB9DD879F9F33D,0xDE2D2F2736D82674,0x2A43A41F891EE2DF,0x6F98999D1B6C133A, + 0xD4AD46CD3DF436FA,0xBB35DF50269825C0,0x964FDCAA813E6D85,0xEB41B0537EE5A5C4, + 0x0540BA758B160847,0xA41AE43BE7BB44AF,0xE3B8C429D0671797,0x819993BBEE9FBEB9, + 0xAE9A8DD1EC975421,0xF3572CDD917E6E31,0x6393D7DAE2AFF8CE,0x47A2201237DC5338, + 0xA32343DEC903EE35,0x79FC56C4A89A91E6,0x01B28048DC5751E0,0x1296F564E4B7DB7B, + 0x75F7188351597A12,0xDB6D9552BDCE2E33,0x1E9DBB231D74308F,0x520D7293FDD322D9, + 0xE20A44610C304677,0xFEEEE2D2B4EAD425,0xCA30FDEE20800675,0x61EACA4A47015A13, + 0xE74AFE1487264E30,0x2CC883B27BF119A5,0x1664CF59B3F682DC,0xA811AA7C1E78AF5B, + 0x1D5626FB648DC3B2,0xB73E9117DF5BCE34,0xD05F7CF06AB56F5D,0xFD257F0ACD132718, + 0x574DC8E676C52A9E,0x0739A7E52EB8AA9A,0x5486553E0F3CD9A3,0x56FF48AEAA927B7E, + 0xBE756525AD8E2D87,0x7D0E6CF9FFDBC841,0x3B1ECCA31450CA99,0x6913BE30E983E840, + 0xAD511009956EA71C,0xB1B5B6BA2DB4354E,0x4469BDCA4E25A005,0x15AF5281CA0F71E1, + 0x744598CB8D0E2BF2,0x593F9B312AA863B7,0xEFB38A6E29A4FC63,0x6B6AA3A04C2D4A9D, + 0x3D95EB0EE6BF31E3,0xA291C3961554BFD5,0x18169C8EEF9BCBF5,0x115D68BC9D4E2846, + 0xBA875F18FACF7420,0xD1EDFCB8B6E23EBD,0xB00736F2F1E364AE,0x84D929CE6589B6FE, + 0x70B7A2F6DA4F7255,0x0E7253D75C6D4929,0x04F23A3D574159A7,0x0A8069EA0B2C108E, + 0x49D073C56BB11A11,0x8AAB7A1939E4FFD7,0xCD095A0B0E38ACEF,0xC9FB60365979F548, + 0x92BDE697D67F3422,0xC78933E10514BC61,0xE1C1D9B975C9B54A,0xD2266160CF1BCD80, + 0x9A4492ED78FD8671,0xB3CCAB2A881A9793,0x72CEBF667FE1D088,0xD6D45B5D985A9427 + }, + { + 0xC811A8058C3F55DE,0x65F5B43196B50619,0xF74F96B1D6706E43,0x859D1E8BCB43D336, + 0x5AAB8A85CCFA3D84,0xF9C7BF99C295FCFD,0xA21FD5A1DE4B630F,0xCDB3EF763B8B456D, + 0x803F59F87CF7C385,0xB27C73BE5F31913C,0x98E3AC6633B04821,0xBF61674C26B8F818, + 0x0FFBC995C4C130C8,0xAAA0862010761A98,0x6057F342210116AA,0xF63C760C0654CC35, + 0x2DDB45CC667D9042,0xBCF45A964BD40382,0x68E8A0C3EF3C6F3D,0xA7BD92D269FF73BC, + 0x290AE20201ED2287,0xB7DE34CDE885818F,0xD901EEA7DD61059B,0xD6FA273219A03553, + 0xD56F1AE874CCCEC9,0xEA31245C2E83F554,0x7034555DA07BE499,0xCE26D2AC56E7BEF7, + 0xFD161857A5054E38,0x6A0E7DA4527436D1,0x5BD86A381CDE9FF2,0xCAF7756231770C32, + 0xB09AAED9E279C8D0,0x5DEF1091C60674DB,0x111046A2515E5045,0x23536CE4729802FC, + 0xC50CBCF7F5B63CFA,0x73A16887CD171F03,0x7D2941AFD9F28DBD,0x3F5E3EB45A4F3B9D, + 0x84EEFE361B677140,0x3DB8E3D3E7076271,0x1A3A28F9F20FD248,0x7EBC7C75B49E7627, + 0x74E5F293C7EB565C,0x18DCF59E4F478BA4,0x0C6EF44FA9ADCB52,0xC699812D98DAC760, + 0x788B06DC6E469D0E,0xFC65F8EA7521EC4E,0x30A5F7219E8E0B55,0x2BEC3F65BCA57B6B, + 0xDDD04969BAF1B75E,0x99904CDBE394EA57,0x14B201D1E6EA40F6,0xBBB0C08241284ADD, + 0x50F20463BF8F1DFF,0xE8D7F93B93CBACB8,0x4D8CB68E477C86E8,0xC1DD1B3992268E3F, + 0x7C5AA11209D62FCB,0x2F3D98ABDB35C9AE,0x671369562BFD5FF5,0x15C1E16C36CEE280, + 0x1D7EB2EDF8F39B17,0xDA94D37DB00DFE01,0x877BC3EC760B8ADA,0xCB8495DFE153AE44, + 0x05A24773B7B410B3,0x12857B783C32ABDF,0x8EB770D06812513B,0x536739B9D2E3E665, + 0x584D57E271B26468,0xD789C78FC9849725,0xA935BBFA7D1AE102,0x8B1537A3DFA64188, + 0xD0CD5D9BC378DE7A,0x4AC82C9A4D80CFB7,0x42777F1B83BDB620,0x72D2883A1D33BD75, + 0x5E7A2D4BAB6A8F41,0xF4DAAB6BBB1C95D9,0x905CFFE7FD8D31B6,0x83AA6422119B381F, + 0xC0AEFB8442022C49,0xA0F908C663033AE3,0xA428AF0804938826,0xADE41C341A8A53C7, + 0xAE7121EE77E6A85D,0xC47F5C4A25929E8C,0xB538E9AA55CDD863,0x06377AA9DAD8EB29, + 0xA18AE87BB3279895,0x6EDFDA6A35E48414,0x6B7D9D19825094A7,0xD41CFA55A4E86CBF, + 0xE5CAEDC9EA42C59C,0xA36C351C0E6FC179,0x5181E4DE6FABBF89,0xFFF0C530184D17D4, + 0x9D41EB1584045892,0x1C0D525028D73961,0xF178EC180CA8856A,0x9A0571018EF811CD, + 0x4091A27C3EF5EFCC,0x19AF15239F6329D2,0x347450EFF91EB990,0xE11B4A078DD27759, + 0xB9561DE5FC601331,0x912F1F5A2DA993C0,0x1654DCB65BA2191A,0x3E2DDE098A6B99EB, + 0x8A66D71E0F82E3FE,0x8C51ADB7D55A08D7,0x4533E50F8941FF7F,0x02E6DD67BD4859EC, + 0xE068AABA5DF6D52F,0xC24826E3FF4A75A5,0x6C39070D88ACDDF8,0x6486548C4691A46F, + 0xD1BEBD26135C7C0C,0xB30F93038F15334A,0x82D9849FC1BF9A69,0x9C320BA85420FAE4, + 0xFA528243AFF90767,0x9ED4D6CFE968A308,0xB825FD582C44B147,0x9B7691BC5EDCB3BB, + 0xC7EA619048FE6516,0x1063A61F817AF233,0x47D538683409A693,0x63C2CE984C6DED30, + 0x2A9FDFD86C81D91D,0x7B1E3B06032A6694,0x666089EBFBD9FD83,0x0A598EE67375207B, + 0x07449A140AFC495F,0x2CA8A571B6593234,0x1F986F8A45BBC2FB,0x381AA4A050B372C2, + 0x5423A3ADD81FAF3A,0x17273C0B8B86BB6C,0xFE83258DC869B5A2,0x287902BFD1C980F1, + 0xF5A94BD66B3837AF,0x88800A79B2CABA12,0x55504310083B0D4C,0xDF36940E07B9EEB2, + 0x04D1A7CE6790B2C5,0x612413FFF125B4DC,0x26F12B97C52C124F,0x86082351A62F28AC, + 0xEF93632F9937E5E7,0x3507B052293A1BE6,0xE72C30AE570A9C70,0xD3586041AE1425E0, + 0xDE4574B3D79D4CC4,0x92BA228040C5685A,0xF00B0CA5DC8C271C,0xBE1287F1F69C5A6E, + 0xF39E317FB1E0DC86,0x495D114020EC342D,0x699B407E3F18CD4B,0xDCA3A9D46AD51528, + 0x0D1D14F279896924,0x0000000000000000,0x593EB75FA196C61E,0x2E4E78160B116BD8, + 0x6D4AE7B058887F8E,0xE65FD013872E3E06,0x7A6DDBBBD30EC4E2,0xAC97FC89CAAEF1B1, + 0x09CCB33C1E19DBE1,0x89F3EAC462EE1864,0x7770CF49AA87ADC6,0x56C57ECA6557F6D6, + 0x03953DDA6D6CFB9A,0x36928D884456E07C,0x1EEB8F37959F608D,0x31D6179C4EAAA923, + 0x6FAC3AD7E5C02662,0x43049FA653991456,0xABD3669DC052B8EE,0xAF02C153A7C20A2B, + 0x3CCB036E3723C007,0x93C9C23D90E1CA2C,0xC33BC65E2F6ED7D3,0x4CFF56339758249E, + 0xB1E94E64325D6AA6,0x37E16D359472420A,0x79F8E661BE623F78,0x5214D90402C74413, + 0x482EF1FDF0C8965B,0x13F69BC5EC1609A9,0x0E88292814E592BE,0x4E198B542A107D72, + 0xCCC00FCBEBAFE71B,0x1B49C844222B703E,0x2564164DA840E9D5,0x20C6513E1FF4F966, + 0xBAC3203F910CE8AB,0xF2EDD1C261C47EF0,0x814CB945ACD361F3,0x95FEB8944A392105, + 0x5C9CF02C1622D6AD,0x971865F3F77178E9,0xBD87BA2B9BF0A1F4,0x444005B259655D09, + 0xED75BE48247FBC0B,0x7596122E17CFF42A,0xB44B091785E97A15,0x966B854E2755DA9F, + 0xEEE0839249134791,0x32432A4623C652B9,0xA8465B47AD3E4374,0xF8B45F2412B15E8B, + 0x2417F6F078644BA3,0xFB2162FE7FDDA511,0x4BBBCC279DA46DC1,0x0173E0BDD024A276, + 0x22208C59A2BCA08A,0x8FC4906DB836F34D,0xE4B90D743A6667EA,0x7147B5E0705F46EF, + 0x2782CB2A1508B039,0xEC065EF5F45B1E7D,0x21B5B183CFD05B10,0xDBE733C060295C77, + 0x9FA73672394C017E,0xCF55321186C31C81,0xD8720E1A0D45A7ED,0x3B8F997A3DDF8958, + 0x3AFC79C7EDFB2B2E,0xE9A4198643EF0ECE,0x5F09CDF67B4E2D37,0x4F6A6BE9FA34DF04, + 0xB6ADD47038A123F9,0x8D224D0A057EAAA1,0xC96248B85C1BF7A8,0xE3FD9760309A2EB5, + 0x0B2A6E5BA351820D,0xEB42C4E1FEA75722,0x948D58299A1D8373,0x7FCF9CC864BAD451, + 0xA55B4FB5D4B72A50,0x08BF5381CE3D7997,0x46A6D8D5E42D04E5,0xD22B80FC7E308796, + 0x57B69E77B57354A0,0x3969441D8097D0B4,0x3330CAFBF3E2F0CF,0xE28E77DDE0BE8CC3, + 0x62B12E259C494F46,0xA6CE726FB9DBD1CA,0x41E242C1EED14DBA,0x76032FF47AA30FB0 + }, + { + 0x45B268A93ACDE4CC,0xAF7F0BE884549D08,0x048354B3C1468263,0x925435C2C80EFED2, + 0xEE4E37F27FDFFBA7,0x167A33920C60F14D,0xFB123B52EA03E584,0x4A0CAB53FDBB9007, + 0x9DEAF6380F788A19,0xCB48EC558F0CB32A,0xB59DC4B2D6FEF7E0,0xDCDBCA22F4F3ECB6, + 0x11DF5813549A9C40,0xE33FDEDF568ACED3,0xA0C1C8124322E9C3,0x07A56B8158FA6D0D, + 0x77279579B1E1F3DD,0xD9B18B74422AC004,0xB8EC2D9FFFABC294,0xF4ACF8A82D75914F, + 0x7BBF69B1EF2B6878,0xC4F62FAF487AC7E1,0x76CE809CC67E5D0C,0x6711D88F92E4C14C, + 0x627B99D9243DEDFE,0x234AA5C3DFB68B51,0x909B1F15262DBF6D,0x4F66EA054B62BCB5, + 0x1AE2CF5A52AA6AE8,0xBEA053FBD0CE0148,0xED6808C0E66314C9,0x43FE16CD15A82710, + 0xCD049231A06970F6,0xE7BC8A6C97CC4CB0,0x337CE835FCB3B9C0,0x65DEF2587CC780F3, + 0x52214EDE4132BB50,0x95F15E4390F493DF,0x870839625DD2E0F1,0x41313C1AFB8B66AF, + 0x91720AF051B211BC,0x477D427ED4EEA573,0x2E3B4CEEF6E3BE25,0x82627834EB0BCC43, + 0x9C03E3DD78E724C8,0x2877328AD9867DF9,0x14B51945E243B0F2,0x574B0F88F7EB97E2, + 0x88B6FA989AA4943A,0x19C4F068CB168586,0x50EE6409AF11FAEF,0x7DF317D5C04EABA4, + 0x7A567C5498B4C6A9,0xB6BBFB804F42188E,0x3CC22BCF3BC5CD0B,0xD04336EAAA397713, + 0xF02FAC1BEC33132C,0x2506DBA7F0D3488D,0xD7E65D6BF2C31A1E,0x5EB9B2161FF820F5, + 0x842E0650C46E0F9F,0x716BEB1D9E843001,0xA933758CAB315ED4,0x3FE414FDA2792265, + 0x27C9F1701EF00932,0x73A4C1CA70A771BE,0x94184BA6E76B3D0E,0x40D829FF8C14C87E, + 0x0FBEC3FAC77674CB,0x3616A9634A6A9572,0x8F139119C25EF937,0xF545ED4D5AEA3F9E, + 0xE802499650BA387B,0x6437E7BD0B582E22,0xE6559F89E053E261,0x80AD52E305288DFC, + 0x6DC55A23E34B9935,0xDE14E0F51AD0AD09,0xC6390578A659865E,0x96D7617109487CB1, + 0xE2D6CB3A21156002,0x01E915E5779FAED1,0xADB0213F6A77DCB7,0x9880B76EB9A1A6AB, + 0x5D9F8D248644CF9B,0xFD5E4536C5662658,0xF1C6B9FE9BACBDFD,0xEACD6341BE9979C4, + 0xEFA7221708405576,0x510771ECD88E543E,0xC2BA51CB671F043D,0x0AD482AC71AF5879, + 0xFE787A045CDAC936,0xB238AF338E049AED,0xBD866CC94972EE26,0x615DA6EBBD810290, + 0x3295FDD08B2C1711,0xF834046073BF0AEA,0xF3099329758FFC42,0x1CAEB13E7DCFA934, + 0xBA2307481188832B,0x24EFCE42874CE65C,0x0E57D61FB0E9DA1A,0xB3D1BAD6F99B343C, + 0xC0757B1C893C4582,0x2B510DB8403A9297,0x5C7698C1F1DB614A,0x3E0D0118D5E68CB4, + 0xD60F488E855CB4CF,0xAE961E0DF3CB33D9,0x3A8E55AB14A00ED7,0x42170328623789C1, + 0x838B6DD19C946292,0x895FEF7DED3B3AEB,0xCFCBB8E64E4A3149,0x064C7E642F65C3DC, + 0x3D2B3E2A4C5A63DA,0x5BD3F340A9210C47,0xB474D157A1615931,0xAC5934DA1DE87266, + 0x6EE365117AF7765B,0xC86ED36716B05C44,0x9BA6885C201D49C5,0xB905387A88346C45, + 0x131072C4BAB9DDFF,0xBF49461EA751AF99,0xD52977BC1CE05BA1,0xB0F785E46027DB52, + 0x546D30BA6E57788C,0x305AD707650F56AE,0xC987C682612FF295,0xA5AB8944F5FBC571, + 0x7ED528E759F244CA,0x8DDCBBCE2C7DB888,0xAA154ABE328DB1BA,0x1E619BE993ECE88B, + 0x09F2BD9EE813B717,0x7401AA4B285D1CB3,0x21858F143195CAEE,0x48C381841398D1B8, + 0xFCB750D3B2F98889,0x39A86A998D1CE1B9,0x1F888E0CE473465A,0x7899568376978716, + 0x02CF2AD7EE2341BF,0x85C713B5B3F1A14E,0xFF916FE12B4567E7,0x7C1A0230B7D10575, + 0x0C98FCC85ECA9BA5,0xA3E7F720DA9E06AD,0x6A6031A2BBB1F438,0x973E74947ED7D260, + 0x2CF4663918C0FF9A,0x5F50A7F368678E24,0x34D983B4A449D4CD,0x68AF1B755592B587, + 0x7F3C3D022E6DEA1B,0xABFC5F5B45121F6B,0x0D71E92D29553574,0xDFFDF5106D4F03D8, + 0x081BA87B9F8C19C6,0xDB7EA1A3AC0981BB,0xBBCA12AD66172DFA,0x79704366010829C7, + 0x179326777BFF5F9C,0x0000000000000000,0xEB2476A4C906D715,0x724DD42F0738DF6F, + 0xB752EE6538DDB65F,0x37FFBC863DF53BA3,0x8EFA84FCB5C157E6,0xE9EB5C73272596AA, + 0x1B0BDABF2535C439,0x86E12C872A4D4E20,0x9969A28BCE3E087A,0xFAFB2EB79D9C4B55, + 0x056A4156B6D92CB2,0x5A3AE6A5DEBEA296,0x22A3B026A8292580,0x53C85B3B36AD1581, + 0xB11E900117B87583,0xC51F3A4A3FE56930,0xE019E1EDCF3621BD,0xEC811D2591FCBA18, + 0x445B7D4C4D524A1D,0xA8DA6069DCAEF005,0x58F5CC72309DE329,0xD4C062596B7FF570, + 0xCE22AD0339D59F98,0x591CD99747024DF8,0x8B90C5AA03187B54,0xF663D27FC356D0F0, + 0xD8589E9135B56ED5,0x35309651D3D67A1C,0x12F96721CD26732E,0xD28C1C3D441A36AC, + 0x492A946164077F69,0x2D1D73DC6F5F514B,0x6F0A70F40D68D88A,0x60B4B30ECA1EAC41, + 0xD36509D83385987D,0x0B3D97490630F6A8,0x9ECCC90A96C46577,0xA20EE2C5AD01A87C, + 0xE49AB55E0E70A3DE,0xA4429CA182646BA0,0xDA97B446DB962F6A,0xCCED87D4D7F6DE27, + 0x2AB8185D37A53C46,0x9F25DCEFE15BCBA6,0xC19C6EF9FEA3EB53,0xA764A3931BD884CE, + 0x2FD2590B817C10F4,0x56A21A6D80743933,0xE573A0BB79EF0D0F,0x155C0CA095DC1E23, + 0x6C2C4FC694D437E4,0x10364DF623053291,0xDD32DFC7836C4267,0x03263F3299BCEF6E, + 0x66F8CD6AE57B6F9D,0x8C35AE2B5BE21659,0x31B3C2E21290F87F,0x93BD2027BF915003, + 0x69460E90220D1B56,0x299E276FAE19D328,0x63928C3C53A2432F,0x7082FEF8E91B9ED0, + 0xBC6F792C3EED40F7,0x4C40D537D2DE53DB,0x75E8BFAE5FC2B262,0x4DA9C0D2A541FD0A, + 0x4E8FFFE03CFD1264,0x2620E495696FA7E3,0xE1F0F408B8A98F6C,0xD1AA230FDDA6D9C2, + 0xC7D0109DD1C6288F,0x8A79D04F7487D585,0x4694579BA3710BA2,0x38417F7CFA834F68, + 0x1D47A4DB0A5007E5,0x206C9AF1460A643F,0xA128DDF734BD4712,0x8144470672B7232D, + 0xF2E086CC02105293,0x182DE58DBC892B57,0xCAA1F9B0F8931DFB,0x6B892447CC2E5AE9, + 0xF9DD11850420A43B,0x4BE5BEB68A243ED6,0x5584255F19C8D65D,0x3B67404E633FA006, + 0xA68DB6766C472A1F,0xF78AC79AB4C97E21,0xC353442E1080AAEC,0x9A4F9DB95782E714 + }, + { + 0x05BA7BC82C9B3220,0x31A54665F8B65E4F,0xB1B651F77547F4D4,0x8BFA0D857BA46682, + 0x85A96C5AA16A98BB,0x990FAEF908EB79C9,0xA15E37A247F4A62D,0x76857DCD5D27741E, + 0xF8C50B800A1820BC,0xBE65DCB201F7A2B4,0x666D1B986F9426E7,0x4CC921BF53C4E648, + 0x95410A0F93D9CA42,0x20CDCCAA647BA4EF,0x429A4060890A1871,0x0C4EA4F69B32B38B, + 0xCCDA362DDE354CD3,0x96DC23BC7C5B2FA9,0xC309BB68AA851AB3,0xD26131A73648E013, + 0x021DC52941FC4DB2,0xCD5ADAB7704BE48A,0xA77965D984ED71E6,0x32386FD61734BBA4, + 0xE82D6DD538AB7245,0x5C2147EA6177B4B1,0x5DA1AB70CF091CE8,0xAC907FCE72B8BDFF, + 0x57C85DFD972278A8,0xA4E44C6A6B6F940D,0x3851995B4F1FDFE4,0x62578CCAED71BC9E, + 0xD9882BB0C01D2C0A,0x917B9D5D113C503B,0xA2C31E11A87643C6,0xE463C923A399C1CE, + 0xF71686C57EA876DC,0x87B4A973E096D509,0xAF0D567D9D3A5814,0xB40C2A3F59DCC6F4, + 0x3602F88495D121DD,0xD3E1DD3D9836484A,0xF945E71AA46688E5,0x7518547EB2A591F5, + 0x9366587450C01D89,0x9EA81018658C065B,0x4F54080CBC4603A3,0x2D0384C65137BF3D, + 0xDC325078EC861E2A,0xEA30A8FC79573FF7,0x214D2030CA050CB6,0x65F0322B8016C30C, + 0x69BE96DD1B247087,0xDB95EE9981E161B8,0xD1FC1814D9CA05F8,0x820ED2BBCC0DE729, + 0x63D76050430F14C7,0x3BCCB0E8A09D3A0F,0x8E40764D573F54A2,0x39D175C1E16177BD, + 0x12F5A37C734F1F4B,0xAB37C12F1FDFC26D,0x5648B167395CD0F1,0x6C04ED1537BF42A7, + 0xED97161D14304065,0x7D6C67DAAB72B807,0xEC17FA87BA4EE83C,0xDFAF79CB0304FBC1, + 0x733F060571BC463E,0x78D61C1287E98A27,0xD07CF48E77B4ADA1,0xB9C262536C90DD26, + 0xE2449B5860801605,0x8FC09AD7F941FCFB,0xFAD8CEA94BE46D0E,0xA343F28B0608EB9F, + 0x9B126BD04917347B,0x9A92874AE7699C22,0x1B017C42C4E69EE0,0x3A4C5C720EE39256, + 0x4B6E9F5E3EA399DA,0x6BA353F45AD83D35,0xE7FEE0904C1B2425,0x22D009832587E95D, + 0x842980C00F1430E2,0xC6B3C0A0861E2893,0x087433A419D729F2,0x341F3DADD42D6C6F, + 0xEE0A3FAEFBB2A58E,0x4AEE73C490DD3183,0xAAB72DB5B1A16A34,0xA92A04065E238FDF, + 0x7B4B35A1686B6FCC,0x6A23BF6EF4A6956C,0x191CB96B851AD352,0x55D598D4D6DE351A, + 0xC9604DE5F2AE7EF3,0x1CA6C2A3A981E172,0xDE2F9551AD7A5398,0x3025AAFF56C8F616, + 0x15521D9D1E2860D9,0x506FE31CFA45073A,0x189C55F12B647B0B,0x0180EC9AAE7EA859, + 0x7CEC8B40050C105E,0x2350E5198BF94104,0xEF8AD33455CC0DD7,0x07A7BEE16D677F92, + 0xE5E325B90DE76997,0x5A061591A26E637A,0xB611EF1618208B46,0x09F4DF3EB7A981AB, + 0x1EBB078AE87DACC0,0xB791038CB65E231F,0x0FD38D4574B05660,0x67EDF702C1EA8EBE, + 0xBA5F4BE0831238CD,0xE3C477C2CEFEBE5C,0x0DCE486C354C1BD2,0x8C5DB36416C31910, + 0x26EA9ED1A7627324,0x039D29B3EF82E5EB,0x9F28FC82CBF2AE02,0xA8AAE89CF05D2786, + 0x431AACFA2774B028,0xCF471F9E31B7A938,0x581BD0B8E3922EC8,0xBC78199B400BEF06, + 0x90FB71C7BF42F862,0x1F3BEB1046030499,0x683E7A47B55AD8DE,0x988F4263A695D190, + 0xD808C72A6E638453,0x0627527BC319D7CB,0xEBB04466D72997AE,0xE67E0C0AE2658C7C, + 0x14D2F107B056C880,0x7122C32C30400B8C,0x8A7AE11FD5DACEDB,0xA0DEDB38E98A0E74, + 0xAD109354DCC615A6,0x0BE91A17F655CC19,0x8DDD5FFEB8BDB149,0xBFE53028AF890AED, + 0xD65BA6F5B4AD7A6A,0x7956F0882997227E,0x10E8665532B352F9,0x0E5361DFDACEFE39, + 0xCEC7F3049FC90161,0xFF62B561677F5F2E,0x975CCF26D22587F0,0x51EF0F86543BAF63, + 0x2F1E41EF10CBF28F,0x52722635BBB94A88,0xAE8DBAE73344F04D,0x410769D36688FD9A, + 0xB3AB94DE34BBB966,0x801317928DF1AA9B,0xA564A0F0C5113C54,0xF131D4BEBDB1A117, + 0x7F71A2F3EA8EF5B5,0x40878549C8F655C3,0x7EF14E6944F05DEC,0xD44663DCF55137D8, + 0xF2ACFD0D523344FC,0x0000000000000000,0x5FBC6E598EF5515A,0x16CF342EF1AA8532, + 0xB036BD6DDB395C8D,0x13754FE6DD31B712,0xBBDFA77A2D6C9094,0x89E7C8AC3A582B30, + 0x3C6B0E09CDFA459D,0xC4AE0589C7E26521,0x49735A777F5FD468,0xCAFD64561D2C9B18, + 0xDA1502032F9FC9E1,0x8867243694268369,0x3782141E3BAF8984,0x9CB5D53124704BE9, + 0xD7DB4A6F1AD3D233,0xA6F989432A93D9BF,0x9D3539AB8A0EE3B0,0x53F2CAAF15C7E2D1, + 0x6E19283C76430F15,0x3DEBE2936384EDC4,0x5E3C82C3208BF903,0x33B8834CB94A13FD, + 0x6470DEB12E686B55,0x359FD1377A53C436,0x61CAA57902F35975,0x043A975282E59A79, + 0xFD7F70482683129C,0xC52EE913699CCD78,0x28B9FF0E7DAC8D1D,0x5455744E78A09D43, + 0xCB7D88CCB3523341,0x44BD121B4A13CFBA,0x4D49CD25FDBA4E11,0x3E76CB208C06082F, + 0x3FF627BA2278A076,0xC28957F204FBB2EA,0x453DFE81E46D67E3,0x94C1E6953DA7621B, + 0x2C83685CFF491764,0xF32C1197FC4DECA5,0x2B24D6BD922E68F6,0xB22B78449AC5113F, + 0x48F3B6EDD1217C31,0x2E9EAD75BEB55AD6,0x174FD8B45FD42D6B,0x4ED4E4961238ABFA, + 0x92E6B4EEFEBEB5D0,0x46A0D7320BEF8208,0x47203BA8A5912A51,0x24F75BF8E69E3E96, + 0xF0B1382413CF094E,0xFEE259FBC901F777,0x276A724B091CDB7D,0xBDF8F501EE75475F, + 0x599B3C224DEC8691,0x6D84018F99C1EAFE,0x7498B8E41CDB39AC,0xE0595E71217C5BB7, + 0x2AA43A273C50C0AF,0xF50B43EC3F543B6E,0x838E3E2162734F70,0xC09492DB4507FF58, + 0x72BFEA9FDFC2EE67,0x11688ACF9CCDFAA0,0x1A8190D86A9836B9,0x7ACBD93BC615C795, + 0xC7332C3A286080CA,0x863445E94EE87D50,0xF6966A5FD0D6DE85,0xE9AD814F96D5DA1C, + 0x70A22FB69E3EA3D5,0x0A69F68D582B6440,0xB8428EC9C2EE757F,0x604A49E3AC8DF12C, + 0x5B86F90B0C10CB23,0xE1D9B2EB8F02F3EE,0x29391394D3D22544,0xC8E0A17F5CD0D6AA, + 0xB58CC6A5F7A26EAD,0x8193FB08238F02C2,0xD5C68F465B2F9F81,0xFCFF9CD288FDBAC5, + 0x77059157F359DC47,0x1D262E3907FF492B,0xFB582233E59AC557,0xDDB2BCE242F8B673, + 0x2577B76248E096CF,0x6F99C4A6D83DA74C,0xC1147E41EB795701,0xF48BAF76912A9337 + }, + { + 0x3EF29D249B2C0A19,0xE9E16322B6F8622F,0x5536994047757F7A,0x9F4D56D5A47B0B33, + 0x822567466AA1174C,0xB8F5057DEB082FB2,0xCC48C10BF4475F53,0x373088D4275DEC3A, + 0x968F4325180AED10,0x173D232CF7016151,0xAE4ED09F946FCC13,0xFD4B4741C4539873, + 0x1B5B3F0DD9933765,0x2FFCB0967B644052,0xE02376D20A89840C,0xA3AE3A70329B18D7, + 0x419CBD2335DE8526,0xFAFEBF115B7C3199,0x0397074F85AA9B0D,0xC58AD4FB4836B970, + 0xBEC60BE3FC4104A8,0x1EFF36DC4B708772,0x131FDC33ED8453B6,0x0844E33E341764D3, + 0x0FF11B6EAB38CD39,0x64351F0A7761B85A,0x3B5694F509CFBA0E,0x30857084B87245D0, + 0x47AFB3BD2297AE3C,0xF2BA5C2F6F6B554A,0x74BDC4761F4F70E1,0xCFDFC64471EDC45E, + 0xE610784C1DC0AF16,0x7ACA29D63C113F28,0x2DED411776A859AF,0xAC5F211E99A3D5EE, + 0xD484F949A87EF33B,0x3CE36CA596E013E4,0xD120F0983A9D432C,0x6BC40464DC597563, + 0x69D5F5E5D1956C9E,0x9AE95F043698BB24,0xC9ECC8DA66A4EF44,0xD69508C8A5B2EAC6, + 0xC40C2235C0503B80,0x38C193BA8C652103,0x1CEEC75D46BC9E8F,0xD331011937515AD1, + 0xD8E2E56886ECA50F,0xB137108D5779C991,0x709F3B6905CA4206,0x4FEB50831680CAEF, + 0xEC456AF3241BD238,0x58D673AFE181ABBE,0x242F54E7CAD9BF8C,0x0211F1810DCC19FD, + 0x90BC4DBB0F43C60A,0x9518446A9DA0761D,0xA1BFCBF13F57012A,0x2BDE4F8961E172B5, + 0x27B853A84F732481,0xB0B1E643DF1F4B61,0x18CC38425C39AC68,0xD2B7F7D7BF37D821, + 0x3103864A3014C720,0x14AA246372ABFA5C,0x6E600DB54EBAC574,0x394765740403A3F3, + 0x09C215F0BC71E623,0x2A58B947E987F045,0x7B4CDF18B477BDD8,0x9709B5EB906C6FE0, + 0x73083C268060D90B,0xFEDC400E41F9037E,0x284948C6E44BE9B8,0x728ECAE808065BFB, + 0x06330E9E17492B1A,0x5950856169E7294E,0xBAE4F4FCE6C4364F,0xCA7BCF95E30E7449, + 0x7D7FD186A33E96C2,0x52836110D85AD690,0x4DFAA1021B4CD312,0x913ABB75872544FA, + 0xDD46ECB9140F1518,0x3D659A6B1E869114,0xC23F2CABD719109A,0xD713FE062DD46836, + 0xD0A60656B2FBC1DC,0x221C5A79DD909496,0xEFD26DBCA1B14935,0x0E77EDA0235E4FC9, + 0xCBFD395B6B68F6B9,0x0DE0EAEFA6F4D4C4,0x0422FF1F1A8532E7,0xF969B85EDED6AA94, + 0x7F6E2007AEF28F3F,0x3AD0623B81A938FE,0x6624EE8B7AADA1A7,0xB682E8DDC856607B, + 0xA78CC56F281E2A30,0xC79B257A45FAA08D,0x5B4174E0642B30B3,0x5F638BFF7EAE0254, + 0x4BC9AF9C0C05F808,0xCE59308AF98B46AE,0x8FC58DA9CC55C388,0x803496C7676D0EB1, + 0xF33CAAE1E70DD7BA,0xBB6202326EA2B4BF,0xD5020F87201871CB,0x9D5CA754A9B712CE, + 0x841669D87DE83C56,0x8A6184785EB6739F,0x420BBA6CB0741E2B,0xF12D5B60EAC1CE47, + 0x76AC35F71283691C,0x2C6BB7D9FECEDB5F,0xFCCDB18F4C351A83,0x1F79C012C3160582, + 0xF0ABADAE62A74CB7,0xE1A5801C82EF06FC,0x67A21845F2CB2357,0x5114665F5DF04D9D, + 0xBF40FD2D74278658,0xA0393D3FB73183DA,0x05A409D192E3B017,0xA9FB28CF0B4065F9, + 0x25A9A22942BF3D7C,0xDB75E22703463E02,0xB326E10C5AB5D06C,0xE7968E8295A62DE6, + 0xB973F3B3636EAD42,0xDF571D3819C30CE5,0xEE549B7229D7CBC5,0x12992AFD65E2D146, + 0xF8EF4E9056B02864,0xB7041E134030E28B,0xC02EDD2ADAD50967,0x932B4AF48AE95D07, + 0x6FE6FB7BC6DC4784,0x239AACB755F61666,0x401A4BEDBDB807D6,0x485EA8D389AF6305, + 0xA41BC220ADB4B13D,0x753B32B89729F211,0x997E584BB3322029,0x1D683193CEDA1C7F, + 0xFF5AB6C0C99F818E,0x16BBD5E27F67E3A1,0xA59D34EE25D233CD,0x98F8AE853B54A2D9, + 0x6DF70AFACB105E79,0x795D2E99B9BBA425,0x8E437B6744334178,0x0186F6CE886682F0, + 0xEBF092A3BB347BD2,0xBCD7FA62F18D1D55,0xADD9D7D011C5571E,0x0BD3E471B1BDFFDE, + 0xAA6C2F808EEAFEF4,0x5EE57D31F6C880A4,0xF50FA47FF044FCA0,0x1ADDC9C351F5B595, + 0xEA76646D3352F922,0x0000000000000000,0x85909F16F58EBEA6,0x46294573AAF12CCC, + 0x0A5512BF39DB7D2E,0x78DBD85731DD26D5,0x29CFBE086C2D6B48,0x218B5D36583A0F9B, + 0x152CD2ADFACD78AC,0x83A39188E2C795BC,0xC3B9DA655F7F926A,0x9ECBA01B2C1D89C3, + 0x07B5F8509F2FA9EA,0x7EE8D6C926940DCF,0x36B67E1AAF3B6ECA,0x86079859702425AB, + 0xFB7849DFD31AB369,0x4C7C57CC932A51E2,0xD96413A60E8A27FF,0x263EA566C715A671, + 0x6C71FC344376DC89,0x4A4F595284637AF8,0xDAF314E98B20BCF2,0x572768C14AB96687, + 0x1088DB7C682EC8BB,0x887075F9537A6A62,0x2E7A4658F302C2A2,0x619116DBE582084D, + 0xA87DDE018326E709,0xDCC01A779C6997E8,0xEDC39C3DAC7D50C8,0xA60A33A1A078A8C0, + 0xC1A82BE452B38B97,0x3F746BEA134A88E9,0xA228CCBEBAFD9A27,0xABEAD94E068C7C04, + 0xF48952B178227E50,0x5CF48CB0FB049959,0x6017E0156DE48ABD,0x4438B4F2A73D3531, + 0x8C528AE649FF5885,0xB515EF924DFCFB76,0x0C661C212E925634,0xB493195CC59A7986, + 0x9CDA519A21D1903E,0x32948105B5BE5C2D,0x194ACE8CD45F2E98,0x438D4CA238129CDB, + 0x9B6FA9CABEFE39D4,0x81B26009EF0B8C41,0xDED1EBF691A58E15,0x4E6DA64D9EE6481F, + 0x54B06F8ECF13FD8A,0x49D85E1D01C9E1F5,0xAFC826511C094EE3,0xF698A33075EE67AD, + 0x5AC7822EEC4DB243,0x8DD47C28C199DA75,0x89F68337DB1CE892,0xCDCE37C57C21DDA3, + 0x530597DE503C5460,0x6A42F2AA543FF793,0x5D727A7E73621BA9,0xE232875307459DF1, + 0x56A19E0FC2DFE477,0xC61DD3B4CD9C227D,0xE5877F03986A341B,0x949EB2A415C6F4ED, + 0x6206119460289340,0x6380E75AE84E11B0,0x8BE772B6D6D0F16F,0x50929091D596CF6D, + 0xE86795EC3E9EE0DF,0x7CF927482B581432,0xC86A3E14EEC26DB4,0x7119CDA78DACC0F6, + 0xE40189CD100CB6EB,0x92ADBC3A028FDFF7,0xB2A017C2D2D3529C,0x200DABF8D05C8D6B, + 0x34A78F9BA2F77737,0xE3B4719D8F231F01,0x45BE423C2F5BB7C1,0xF71E55FEFD88E55D, + 0x6853032B59F3EE6E,0x65B3E9C4FF073AAA,0x772AC3399AE5EBEC,0x87816E97F842A75B, + 0x110E2DB2E0484A4B,0x331277CB3DD8DEDD,0xBD510CAC79EB9FA5,0x352179552A91F5C7 + }, + { + 0x8AB0A96846E06A6D,0x43C7E80B4BF0B33A,0x08C9B3546B161EE5,0x39F1C235EBA990BE, + 0xC1BEF2376606C7B2,0x2C209233614569AA,0xEB01523B6FC3289A,0x946953AB935ACEDD, + 0x272838F63E13340E,0x8B0455ECA12BA052,0x77A1B2C4978FF8A2,0xA55122CA13E54086, + 0x2276135862D3F1CD,0xDB8DDFDE08B76CFE,0x5D1E12C89E4A178A,0x0E56816B03969867, + 0xEE5F79953303ED59,0xAFED748BAB78D71D,0x6D929F2DF93E53EE,0xF5D8A8F8BA798C2A, + 0xF619B1698E39CF6B,0x95DDAF2F749104E2,0xEC2A9C80E0886427,0xCE5C8FD8825B95EA, + 0xC4E0D9993AC60271,0x4699C3A5173076F9,0x3D1B151F50A29F42,0x9ED505EA2BC75946, + 0x34665ACFDC7F4B98,0x61B1FB53292342F7,0xC721C0080E864130,0x8693CD1696FD7B74, + 0x872731927136B14B,0xD3446C8A63A1721B,0x669A35E8A6680E4A,0xCAB658F239509A16, + 0xA4E5DE4EF42E8AB9,0x37A7435EE83F08D9,0x134E6239E26C7F96,0x82791A3C2DF67488, + 0x3F6EF00A8329163C,0x8E5A7E42FDEB6591,0x5CAAEE4C7981DDB5,0x19F234785AF1E80D, + 0x255DDDE3ED98BD70,0x50898A32A99CCCAC,0x28CA4519DA4E6656,0xAE59880F4CB31D22, + 0x0D9798FA37D6DB26,0x32F968F0B4FFCD1A,0xA00F09644F258545,0xFA3AD5175E24DE72, + 0xF46C547C5DB24615,0x713E80FBFF0F7E20,0x7843CF2B73D2AAFA,0xBD17EA36AEDF62B4, + 0xFD111BACD16F92CF,0x4ABAA7DBC72D67E0,0xB3416B5DAD49FAD3,0xBCA316B24914A88B, + 0x15D150068AECF914,0xE27C1DEBE31EFC40,0x4FE48C759BEDA223,0x7EDCFD141B522C78, + 0x4E5070F17C26681C,0xE696CAC15815F3BC,0x35D2A64B3BB481A7,0x800CFF29FE7DFDF6, + 0x1ED9FAC3D5BAA4B0,0x6C2663A91EF599D1,0x03C1199134404341,0xF7AD4DED69F20554, + 0xCD9D9649B61BD6AB,0xC8C3BDE7EADB1368,0xD131899FB02AFB65,0x1D18E352E1FAE7F1, + 0xDA39235AEF7CA6C1,0xA1BBF5E0A8EE4F7A,0x91377805CF9A0B1E,0x3138716180BF8E5B, + 0xD9F83ACBDB3CE580,0x0275E515D38B897E,0x472D3F21F0FBBCC6,0x2D946EB7868EA395, + 0xBA3C248D21942E09,0xE7223645BFDE3983,0xFF64FEB902E41BB1,0xC97741630D10D957, + 0xC3CB1722B58D4ECC,0xA27AEC719CAE0C3B,0x99FECB51A48C15FB,0x1465AC826D27332B, + 0xE1BD047AD75EBF01,0x79F733AF941960C5,0x672EC96C41A3C475,0xC27FEBA6524684F3, + 0x64EFD0FD75E38734,0xED9E60040743AE18,0xFB8E2993B9EF144D,0x38453EB10C625A81, + 0x6978480742355C12,0x48CF42CE14A6EE9E,0x1CAC1FD606312DCE,0x7B82D6BA4792E9BB, + 0x9D141C7B1F871A07,0x5616B80DC11C4A2E,0xB849C198F21FA777,0x7CA91801C8D9A506, + 0xB1348E487EC273AD,0x41B20D1E987B3A44,0x7460AB55A3CFBBE3,0x84E628034576F20A, + 0x1B87D16D897A6173,0x0FE27DEFE45D5258,0x83CDE6B8CA3DBEB7,0x0C23647ED01D1119, + 0x7A362A3EA0592384,0xB61F40F3F1893F10,0x75D457D1440471DC,0x4558DA34237035B8, + 0xDCA6116587FC2043,0x8D9B67D3C9AB26D0,0x2B0B5C88EE0E2517,0x6FE77A382AB5DA90, + 0x269CC472D9D8FE31,0x63C41E46FAA8CB89,0xB7ABBC771642F52F,0x7D1DE4852F126F39, + 0xA8C6BA3024339BA0,0x600507D7CEE888C8,0x8FEE82C61A20AFAE,0x57A2448926D78011, + 0xFCA5E72836A458F0,0x072BCEBB8F4B4CBD,0x497BBE4AF36D24A1,0x3CAFE99BB769557D, + 0x12FA9EBD05A7B5A9,0xE8C04BAA5B836BDB,0x4273148FAC3B7905,0x908384812851C121, + 0xE557D3506C55B0FD,0x72FF996ACB4F3D61,0x3EDA0C8E64E2DC03,0xF0868356E6B949E9, + 0x04EAD72ABB0B0FFC,0x17A4B5135967706A,0xE3C8E16F04D5367F,0xF84F30028DAF570C, + 0x1846C8FCBD3A2232,0x5B8120F7F6CA9108,0xD46FA231ECEA3EA6,0x334D947453340725, + 0x58403966C28AD249,0xBED6F3A79A9F21F5,0x68CCB483A5FE962D,0xD085751B57E1315A, + 0xFED0023DE52FD18E,0x4B0E5B5F20E6ADDF,0x1A332DE96EB1AB4C,0xA3CE10F57B65C604, + 0x108F7BA8D62C3CD7,0xAB07A3A11073D8E1,0x6B0DAD1291BED56C,0xF2F366433532C097, + 0x2E557726B2CEE0D4,0x0000000000000000,0xCB02A476DE9B5029,0xE4E32FD48B9E7AC2, + 0x734B65EE2C84F75E,0x6E5386BCCD7E10AF,0x01B4FC84E7CBCA3F,0xCFE8735C65905FD5, + 0x3613BFDA0FF4C2E6,0x113B872C31E7F6E8,0x2FE18BA255052AEB,0xE974B72EBC48A1E4, + 0x0ABC5641B89D979B,0xB46AA5E62202B66E,0x44EC26B0C4BBFF87,0xA6903B5B27A503C7, + 0x7F680190FC99E647,0x97A84A3AA71A8D9C,0xDD12EDE16037EA7C,0xC554251DDD0DC84E, + 0x88C54C7D956BE313,0x4D91696048662B5D,0xB08072CC9909B992,0xB5DE5962C5C97C51, + 0x81B803AD19B637C9,0xB2F597D94A8230EC,0x0B08AAC55F565DA4,0xF1327FD2017283D6, + 0xAD98919E78F35E63,0x6AB9519676751F53,0x24E921670A53774F,0xB9FD3D1C15D46D48, + 0x92F66194FBDA485F,0x5A35DC7311015B37,0xDED3F4705477A93D,0xC00A0EB381CD0D8D, + 0xBB88D809C65FE436,0x16104997BEACBA55,0x21B70AC95693B28C,0x59F4C5E225411876, + 0xD5DB5EB50B21F499,0x55D7A19CF55C096F,0xA97246B4C3F8519F,0x8552D487A2BD3835, + 0x54635D181297C350,0x23C2EFDC85183BF2,0x9F61F96ECC0C9379,0x534893A39DDC8FED, + 0x5EDF0B59AA0A54CB,0xAC2C6D1A9F38945C,0xD7AEBBA0D8AA7DE7,0x2ABFA00C09C5EF28, + 0xD84CC64F3CF72FBF,0x2003F64DB15878B3,0xA724C7DFC06EC9F8,0x069F323F68808682, + 0xCC296ACD51D01C94,0x055E2BAE5CC0C5C3,0x6270E2C21D6301B6,0x3B842720382219C0, + 0xD2F0900E846AB824,0x52FC6F277A1745D2,0xC6953C8CE94D8B0F,0xE009F8FE3095753E, + 0x655B2C7992284D0B,0x984A37D54347DFC4,0xEAB5AEBF8808E2A5,0x9A3FD2C090CC56BA, + 0x9CA0E0FFF84CD038,0x4C2595E4AFADE162,0xDF6708F4B3BC6302,0xBF620F237D54EBCA, + 0x93429D101C118260,0x097D4FD08CDDD4DA,0x8C2F9B572E60ECEF,0x708A7C7F18C4B41F, + 0x3A30DBA4DFE9D3FF,0x4006F19A7FB0F07B,0x5F6BF7DD4DC19EF4,0x1F6D064732716E8F, + 0xF9FBCC866A649D33,0x308C8DE567744464,0x8971B0F972A0292C,0xD61A47243F61B7D8, + 0xEFEB8511D4C82766,0x961CB6BE40D147A3,0xAAB35F25F7B812DE,0x76154E407044329D, + 0x513D76B64E570693,0xF3479AC7D2F90AA8,0x9B8B2E4477079C85,0x297EB99D3D85AC69 + }, + { + 0x7E37E62DFC7D40C3,0x776F25A4EE939E5B,0xE045C850DD8FB5AD,0x86ED5BA711FF1952, + 0xE91D0BD9CF616B35,0x37E0AB256E408FFB,0x9607F6C031025A7A,0x0B02F5E116D23C9D, + 0xF3D8486BFB50650C,0x621CFF27C40875F5,0x7D40CB71FA5FD34A,0x6DAA6616DAA29062, + 0x9F5F354923EC84E2,0xEC847C3DC507C3B3,0x025A3668043CE205,0xA8BF9E6C4DAC0B19, + 0xFA808BE2E9BEBB94,0xB5B99C5277C74FA3,0x78D9BC95F0397BCC,0xE332E50CDBAD2624, + 0xC74FCE129332797E,0x1729ECEB2EA709AB,0xC2D6B9F69954D1F8,0x5D898CBFBAB8551A, + 0x859A76FB17DD8ADB,0x1BE85886362F7FB5,0xF6413F8FF136CD8A,0xD3110FA5BBB7E35C, + 0x0A2FEED514CC4D11,0xE83010EDCD7F1AB9,0xA1E75DE55F42D581,0xEEDE4A55C13B21B6, + 0xF2F5535FF94E1480,0x0CC1B46D1888761E,0xBCE15FDB6529913B,0x2D25E8975A7181C2, + 0x71817F1CE2D7A554,0x2E52C5CB5C53124B,0xF9F7A6BEEF9C281D,0x9E722E7D21F2F56E, + 0xCE170D9B81DCA7E6,0x0E9B82051CB4941B,0x1E712F623C49D733,0x21E45CFA42F9F7DC, + 0xCB8E7A7F8BBA0F60,0x8E98831A010FB646,0x474CCF0D8E895B23,0xA99285584FB27A95, + 0x8CC2B57205335443,0x42D5B8E984EFF3A5,0x012D1B34021E718C,0x57A6626AAE74180B, + 0xFF19FC06E3D81312,0x35BA9D4D6A7C6DFE,0xC9D44C178F86ED65,0x506523E6A02E5288, + 0x03772D5C06229389,0x8B01F4FE0B691EC0,0xF8DABD8AED825991,0x4C4E3AEC985B67BE, + 0xB10DF0827FBF96A9,0x6A69279AD4F8DAE1,0xE78689DCD3D5FF2E,0x812E1A2B1FA553D1, + 0xFBAD90D6EBA0CA18,0x1AC543B234310E39,0x1604F7DF2CB97827,0xA6241C6951189F02, + 0x753513CCEAAF7C5E,0x64F2A59FC84C4EFA,0x247D2B1E489F5F5A,0xDB64D718AB474C48, + 0x79F4A7A1F2270A40,0x1573DA832A9BEBAE,0x3497867968621C72,0x514838D2A2302304, + 0xF0AF6537FD72F685,0x1D06023E3A6B44BA,0x678588C3CE6EDD73,0x66A893F7CC70ACFF, + 0xD4D24E29B5EDA9DF,0x3856321470EA6A6C,0x07C3418C0E5A4A83,0x2BCBB22F5635BACD, + 0x04B46CD00878D90A,0x06EE5AB80C443B0F,0x3B211F4876C8F9E5,0x0958C38912EEDE98, + 0xD14B39CDBF8B0159,0x397B292072F41BE0,0x87C0409313E168DE,0xAD26E98847CAA39F, + 0x4E140C849C6785BB,0xD5FF551DB7F3D853,0xA0CA46D15D5CA40D,0xCD6020C787FE346F, + 0x84B76DCF15C3FB57,0xDEFDA0FCA121E4CE,0x4B8D7B6096012D3D,0x9AC642AD298A2C64, + 0x0875D8BD10F0AF14,0xB357C6EA7B8374AC,0x4D6321D89A451632,0xEDA96709C719B23F, + 0xF76C24BBF328BC06,0xC662D526912C08F2,0x3CE25EC47892B366,0xB978283F6F4F39BD, + 0xC08C8F9E9D6833FD,0x4F3917B09E79F437,0x593DE06FB2C08C10,0xD6887841B1D14BDA, + 0x19B26EEE32139DB0,0xB494876675D93E2F,0x825937771987C058,0x90E9AC783D466175, + 0xF1827E03FF6C8709,0x945DC0A8353EB87F,0x4516F9658AB5B926,0x3F9573987EB020EF, + 0xB855330B6D514831,0x2AE6A91B542BCB41,0x6331E413C6160479,0x408F8E8180D311A0, + 0xEFF35161C325503A,0xD06622F9BD9570D5,0x8876D9A20D4B8D49,0xA5533135573A0C8B, + 0xE168D364DF91C421,0xF41B09E7F50A2F8F,0x12B09B0F24C1A12D,0xDA49CC2CA9593DC4, + 0x1F5C34563E57A6BF,0x54D14F36A8568B82,0xAF7CDFE043F6419A,0xEA6A2685C943F8BC, + 0xE5DCBFB4D7E91D2B,0xB27ADDDE799D0520,0x6B443CAED6E6AB6D,0x7BAE91C9F61BE845, + 0x3EB868AC7CAE5163,0x11C7B65322E332A4,0xD23C1491B9A992D0,0x8FB5982E0311C7CA, + 0x70AC6428E0C9D4D8,0x895BC2960F55FCC5,0x76423E90EC8DEFD7,0x6FF0507EDE9E7267, + 0x3DCF45F07A8CC2EA,0x4AA06054941F5CB1,0x5810FB5BB0DEFD9C,0x5EFEA1E3BC9AC693, + 0x6EDD4B4ADC8003EB,0x741808F8E8B10DD2,0x145EC1B728859A22,0x28BC9F7350172944, + 0x270A06424EBDCCD3,0x972AEDF4331C2BF6,0x059977E40A66A886,0x2550302A4A812ED6, + 0xDD8A8DA0A7037747,0xC515F87A970E9B7B,0x3023EAA9601AC578,0xB7E3AA3A73FBADA6, + 0x0FB699311EAAE597,0x0000000000000000,0x310EF19D6204B4F4,0x229371A644DB6455, + 0x0DECAF591A960792,0x5CA4978BB8A62496,0x1C2B190A38753536,0x41A295B582CD602C, + 0x3279DCC16426277D,0xC1A194AA9F764271,0x139D803B26DFD0A1,0xAE51C4D441E83016, + 0xD813FA44AD65DFC1,0xAC0BF2BC45D4D213,0x23BE6A9246C515D9,0x49D74D08923DCF38, + 0x9D05032127D066E7,0x2F7FDEFF5E4D63C7,0xA47E2A0155247D07,0x99B16FF12FA8BFED, + 0x4661D4398C972AAF,0xDFD0BBC8A33F9542,0xDCA79694A51D06CB,0xB020EBB67DA1E725, + 0xBA0F0563696DAA34,0xE4F1A480D5F76CA7,0xC438E34E9510EAF7,0x939E81243B64F2FC, + 0x8DEFAE46072D25CF,0x2C08F3A3586FF04E,0xD7A56375B3CF3A56,0x20C947CE40E78650, + 0x43F8A3DD86F18229,0x568B795EAC6A6987,0x8003011F1DBB225D,0xF53612D3F7145E03, + 0x189F75DA300DEC3C,0x9570DB9C3720C9F3,0xBB221E576B73DBB8,0x72F65240E4F536DD, + 0x443BE25188ABC8AA,0xE21FFE38D9B357A8,0xFD43CA6EE7E4F117,0xCAA3614B89A47EEC, + 0xFE34E732E1C6629E,0x83742C431B99B1D4,0xCF3A16AF83C2D66A,0xAAE5A8044990E91C, + 0x26271D764CA3BD5F,0x91C4B74C3F5810F9,0x7C6DD045F841A2C6,0x7F1AFD19FE63314F, + 0xC8F957238D989CE9,0xA709075D5306EE8E,0x55FC5402AA48FA0E,0x48FA563C9023BEB4, + 0x65DFBEABCA523F76,0x6C877D22D8BCE1EE,0xCC4D3BF385E045E3,0xBEBB69B36115733E, + 0x10EAAD6720FD4328,0xB6CEB10E71E5DC2A,0xBDCC44EF6737E0B7,0x523F158EA412B08D, + 0x989C74C52DB6CE61,0x9BEB59992B945DE8,0x8A2CEFCA09776F4C,0xA3BD6B8D5B7E3784, + 0xEB473DB1CB5D8930,0xC3FBA2C29B4AA074,0x9C28181525CE176B,0x683311F2D0C438E4, + 0x5FD3BAD7BE84B71F,0xFC6ED15AE5FA809B,0x36CDB0116C5EFE77,0x29918447520958C8, + 0xA29070B959604608,0x53120EBAA60CC101,0x3A0C047C74D68869,0x691E0AC6D2DA4968, + 0x73DB4974E6EB4751,0x7A838AFDF40599C9,0x5A4ACD33B4E21F99,0x6046C94FC03497F0, + 0xE6AB92E8D1CB8EA2,0x3354C7F5663856F1,0xD93EE170AF7BAE4D,0x616BD27BC22AE67C, + 0x92B39A10397A8370,0xABC8B3304B8E9890,0xBF967287630B02B2,0x5B67D607B6FC6E15 + }, + { + 0xD031C397CE553FE6,0x16BA5B01B006B525,0xA89BADE6296E70C8,0x6A1F525D77D3435B, + 0x6E103570573DFA0B,0x660EFB2A17FC95AB,0x76327A9E97634BF6,0x4BAD9D6462458BF5, + 0xF1830CAEDBC3F748,0xC5C8F542669131FF,0x95044A1CDC48B0CB,0x892962DF3CF8B866, + 0xB0B9E208E930C135,0xA14FB3F0611A767C,0x8D2605F21C160136,0xD6B71922FECC549E, + 0x37089438A5907D8B,0x0B5DA38E5803D49C,0x5A5BCC9CEA6F3CBC,0xEDAE246D3B73FFE5, + 0xD2B87E0FDE22EDCE,0x5E54ABB1CA8185EC,0x1DE7F88FE80561B9,0xAD5E1A870135A08C, + 0x2F2ADBD665CECC76,0x5780B5A782F58358,0x3EDC8A2EEDE47B3F,0xC9D95C3506BEE70F, + 0x83BE111D6C4E05EE,0xA603B90959367410,0x103C81B4809FDE5D,0x2C69B6027D0C774A, + 0x399080D7D5C87953,0x09D41E16487406B4,0xCDD63B1826505E5F,0xF99DC2F49B0298E8, + 0x9CD0540A943CB67F,0xBCA84B7F891F17C5,0x723D1DB3B78DF2A6,0x78AA6E71E73B4F2E, + 0x1433E699A071670D,0x84F21BE454620782,0x98DF3327B4D20F2F,0xF049DCE2D3769E5C, + 0xDB6C60199656EB7A,0x648746B2078B4783,0x32CD23598DCBADCF,0x1EA4955BF0C7DA85, + 0xE9A143401B9D46B5,0xFD92A5D9BBEC21B8,0xC8138C790E0B8E1B,0x2EE00B9A6D7BA562, + 0xF85712B893B7F1FC,0xEB28FED80BEA949D,0x564A65EB8A40EA4C,0x6C9988E8474A2823, + 0x4535898B121D8F2D,0xABD8C03231ACCBF4,0xBA2E91CAB9867CBD,0x7960BE3DEF8E263A, + 0x0C11A977602FD6F0,0xCB50E1AD16C93527,0xEAE22E94035FFD89,0x2866D12F5DE2CE1A, + 0xFF1B1841AB9BF390,0x9F9339DE8CFE0D43,0x964727C8C48A0BF7,0x524502C6AAAE531C, + 0x9B9C5EF3AC10B413,0x4FA2FA4942AB32A5,0x3F165A62E551122B,0xC74148DA76E6E3D7, + 0x924840E5E464B2A7,0xD372AE43D69784DA,0x233B72A105E11A86,0xA48A04914941A638, + 0xB4B68525C9DE7865,0xDDEABAACA6CF8002,0x0A9773C250B6BD88,0xC284FFBB5EBD3393, + 0x8BA0DF472C8F6A4E,0x2AEF6CB74D951C32,0x427983722A318D41,0x73F7CDFFBF389BB2, + 0x074C0AF9382C026C,0x8A6A0F0B243A035A,0x6FDAE53C5F88931F,0xC68B98967E538AC3, + 0x44FF59C71AA8E639,0xE2FCE0CE439E9229,0xA20CDE2479D8CD40,0x19E89FA2C8EBD8E9, + 0xF446BBCFF398270C,0x43B3533E2284E455,0xD82F0DCD8E945046,0x51066F12B26CE820, + 0xE73957AF6BC5426D,0x081ECE5A40C16FA0,0x3B193D4FC5BFAB7B,0x7FE66488DF174D42, + 0x0E9814EF705804D8,0x8137AC857C39D7C6,0xB1733244E185A821,0x695C3F896F11F867, + 0xF6CF0657E3EFF524,0x1AABF276D02963D5,0x2DA3664E75B91E5E,0x0289BD981077D228, + 0x90C1FD7DF413608F,0x3C5537B6FD93A917,0xAA12107E3919A2E0,0x0686DAB530996B78, + 0xDAA6B0559EE3826E,0xC34E2FF756085A87,0x6D5358A44FFF4137,0xFC587595B35948AC, + 0x7CA5095CC7D5F67E,0xFB147F6C8B754AC0,0xBFEB26AB91DDACF9,0x6896EFC567A49173, + 0xCA9A31E11E7C5C33,0xBBE44186B13315A9,0x0DDB793B689ABFE4,0x70B4A02BA7FA208E, + 0xE47A3A7B7307F951,0x8CECD5BE14A36822,0xEEED49B923B144D9,0x17708B4DB8B3DC31, + 0x6088219F2765FED3,0xB3FA8FDCF1F27A09,0x910B2D31FCA6099B,0x0F52C4A378ED6DCC, + 0x50CCBF5EBAD98134,0x6BD582117F662A4F,0x94CE9A50D4FDD9DF,0x2B25BCFB45207526, + 0x67C42B661F49FCBF,0x492420FC723259DD,0x03436DD418C2BB3C,0x1F6E4517F872B391, + 0xA08563BC69AF1F68,0xD43EA4BAEEBB86B6,0x01CAD04C08B56914,0xAC94CACB0980C998, + 0x54C3D8739A373864,0x26FEC5C02DBACAC2,0xDEA9D778BE0D3B3E,0x040F672D20EEB950, + 0xE5B0EA377BB29045,0xF30AB136CBB42560,0x62019C0737122CFB,0xE86B930C13282FA1, + 0xCC1CEB542EE5374B,0x538FD28AA21B3A08,0x1B61223AD89C0AC1,0x36C24474AD25149F, + 0x7A23D3E9F74C9D06,0xBE21F6E79968C5ED,0xCF5F868036278C77,0xF705D61BEB5A9C30, + 0x4D2B47D152DCE08D,0x5F9E7BFDC234ECF8,0x247778583DCD18EA,0x867BA67C4415D5AA, + 0x4CE1979D5A698999,0x0000000000000000,0xEC64F42133C696F1,0xB57C5569C16B1171, + 0xC1C7926F467F88AF,0x654D96FE0F3E2E97,0x15F936D5A8C40E19,0xB8A72C52A9F1AE95, + 0xA9517DAA21DB19DC,0x58D27104FA18EE94,0x5918A148F2AD8780,0x5CDD1629DAF657C4, + 0x8274C15164FB6CFA,0xD1FB13DBC6E056F2,0x7D6FD910CF609F6A,0xB63F38BDD9A9AA4D, + 0x3D9FE7FAF526C003,0x74BBC706871499DE,0xDF630734B6B8522A,0x3AD3ED03CD0AC26F, + 0xFADEAF2083C023D4,0xC00D42234ECAE1BB,0x8538CBA85CD76E96,0xC402250E6E2458EB, + 0x47BC3413026A5D05,0xAFD7A71F114272A4,0x978DF784CC3F62E3,0xB96DFC1EA144C781, + 0x21B2CF391596C8AE,0x318E4E8D950916F3,0xCE9556CC3E92E563,0x385A509BDD7D1047, + 0x358129A0B5E7AFA3,0xE6F387E363702B79,0xE0755D5653E94001,0x7BE903A5FFF9F412, + 0x12B53C2C90E80C75,0x3307F315857EC4DB,0x8FAFB86A0C61D31E,0xD9E5DD8186213952, + 0x77F8AAD29FD622E2,0x25BDA814357871FE,0x7571174A8FA1F0CA,0x137FEC60985D6561, + 0x30449EC19DBC7FE7,0xA540D4DD41F4CF2C,0xDC206AE0AE7AE916,0x5B911CD0E2DA55A8, + 0xB2305F90F947131D,0x344BF9ECBD52C6B7,0x5D17C665D2433ED0,0x18224FEEC05EB1FD, + 0x9E59E992844B6457,0x9A568EBFA4A5DD07,0xA3C60E68716DA454,0x7E2CB4C4D7A22456, + 0x87B176304CA0BCBE,0x413AEEA632F3367D,0x9915E36BBC67663B,0x40F03EEA3A465F69, + 0x1C2D28C3E0B008AD,0x4E682A054A1E5BB1,0x05C5B761285BD044,0xE1BF8D1A5B5C2915, + 0xF2C0617AC3014C74,0xB7F5E8F1D11CC359,0x63CB4C4B3FA745EF,0x9D1A84469C89DF6B, + 0xE33630824B2BFB3D,0xD5F474F6E60EEFA2,0xF58C6B83FB2D4E18,0x4676E45F0ADF3411, + 0x20781F751D23A1BA,0xBD629B3381AA7ED1,0xAE1D775319F71BB0,0xFED1C80DA32E9A84, + 0x5509083F92825170,0x29AC01635557A70E,0xA7C9694551831D04,0x8E65682604D4BA0A, + 0x11F651F8882AB749,0xD77DC96EF6793D8A,0xEF2799F52B042DCD,0x48EEF0B07A8730C9, + 0x22F1A2ED0D547392,0x6142F1D32FD097C7,0x4A674D286AF0E2E1,0x80FD7CC9748CBED2, + 0x717E7067AF4F499A,0x938290A9ECD1DBB3,0x88E3B293344DD172,0x2734158C250FA3D6 + } +}; + +// Constant values for KeySchedule function +const unsigned char C[12][64] = { + { + 0xB1,0x08,0x5B,0xDA,0x1E,0xCA,0xDA,0xE9,0xEB,0xCB,0x2F,0x81,0xC0,0x65,0x7C,0x1F, + 0x2F,0x6A,0x76,0x43,0x2E,0x45,0xD0,0x16,0x71,0x4E,0xB8,0x8D,0x75,0x85,0xC4,0xFC, + 0x4B,0x7C,0xE0,0x91,0x92,0x67,0x69,0x01,0xA2,0x42,0x2A,0x08,0xA4,0x60,0xD3,0x15, + 0x05,0x76,0x74,0x36,0xCC,0x74,0x4D,0x23,0xDD,0x80,0x65,0x59,0xF2,0xA6,0x45,0x07 + }, + { + 0x6F,0xA3,0xB5,0x8A,0xA9,0x9D,0x2F,0x1A,0x4F,0xE3,0x9D,0x46,0x0F,0x70,0xB5,0xD7, + 0xF3,0xFE,0xEA,0x72,0x0A,0x23,0x2B,0x98,0x61,0xD5,0x5E,0x0F,0x16,0xB5,0x01,0x31, + 0x9A,0xB5,0x17,0x6B,0x12,0xD6,0x99,0x58,0x5C,0xB5,0x61,0xC2,0xDB,0x0A,0xA7,0xCA, + 0x55,0xDD,0xA2,0x1B,0xD7,0xCB,0xCD,0x56,0xE6,0x79,0x04,0x70,0x21,0xB1,0x9B,0xB7 + }, + { + 0xF5,0x74,0xDC,0xAC,0x2B,0xCE,0x2F,0xC7,0x0A,0x39,0xFC,0x28,0x6A,0x3D,0x84,0x35, + 0x06,0xF1,0x5E,0x5F,0x52,0x9C,0x1F,0x8B,0xF2,0xEA,0x75,0x14,0xB1,0x29,0x7B,0x7B, + 0xD3,0xE2,0x0F,0xE4,0x90,0x35,0x9E,0xB1,0xC1,0xC9,0x3A,0x37,0x60,0x62,0xDB,0x09, + 0xC2,0xB6,0xF4,0x43,0x86,0x7A,0xDB,0x31,0x99,0x1E,0x96,0xF5,0x0A,0xBA,0x0A,0xB2 + }, + { + 0xEF,0x1F,0xDF,0xB3,0xE8,0x15,0x66,0xD2,0xF9,0x48,0xE1,0xA0,0x5D,0x71,0xE4,0xDD, + 0x48,0x8E,0x85,0x7E,0x33,0x5C,0x3C,0x7D,0x9D,0x72,0x1C,0xAD,0x68,0x5E,0x35,0x3F, + 0xA9,0xD7,0x2C,0x82,0xED,0x03,0xD6,0x75,0xD8,0xB7,0x13,0x33,0x93,0x52,0x03,0xBE, + 0x34,0x53,0xEA,0xA1,0x93,0xE8,0x37,0xF1,0x22,0x0C,0xBE,0xBC,0x84,0xE3,0xD1,0x2E + }, + { + 0x4B,0xEA,0x6B,0xAC,0xAD,0x47,0x47,0x99,0x9A,0x3F,0x41,0x0C,0x6C,0xA9,0x23,0x63, + 0x7F,0x15,0x1C,0x1F,0x16,0x86,0x10,0x4A,0x35,0x9E,0x35,0xD7,0x80,0x0F,0xFF,0xBD, + 0xBF,0xCD,0x17,0x47,0x25,0x3A,0xF5,0xA3,0xDF,0xFF,0x00,0xB7,0x23,0x27,0x1A,0x16, + 0x7A,0x56,0xA2,0x7E,0xA9,0xEA,0x63,0xF5,0x60,0x17,0x58,0xFD,0x7C,0x6C,0xFE,0x57 + }, + { + 0xAE,0x4F,0xAE,0xAE,0x1D,0x3A,0xD3,0xD9,0x6F,0xA4,0xC3,0x3B,0x7A,0x30,0x39,0xC0, + 0x2D,0x66,0xC4,0xF9,0x51,0x42,0xA4,0x6C,0x18,0x7F,0x9A,0xB4,0x9A,0xF0,0x8E,0xC6, + 0xCF,0xFA,0xA6,0xB7,0x1C,0x9A,0xB7,0xB4,0x0A,0xF2,0x1F,0x66,0xC2,0xBE,0xC6,0xB6, + 0xBF,0x71,0xC5,0x72,0x36,0x90,0x4F,0x35,0xFA,0x68,0x40,0x7A,0x46,0x64,0x7D,0x6E + }, + { + 0xF4,0xC7,0x0E,0x16,0xEE,0xAA,0xC5,0xEC,0x51,0xAC,0x86,0xFE,0xBF,0x24,0x09,0x54, + 0x39,0x9E,0xC6,0xC7,0xE6,0xBF,0x87,0xC9,0xD3,0x47,0x3E,0x33,0x19,0x7A,0x93,0xC9, + 0x09,0x92,0xAB,0xC5,0x2D,0x82,0x2C,0x37,0x06,0x47,0x69,0x83,0x28,0x4A,0x05,0x04, + 0x35,0x17,0x45,0x4C,0xA2,0x3C,0x4A,0xF3,0x88,0x86,0x56,0x4D,0x3A,0x14,0xD4,0x93 + }, + { + 0x9B,0x1F,0x5B,0x42,0x4D,0x93,0xC9,0xA7,0x03,0xE7,0xAA,0x02,0x0C,0x6E,0x41,0x41, + 0x4E,0xB7,0xF8,0x71,0x9C,0x36,0xDE,0x1E,0x89,0xB4,0x44,0x3B,0x4D,0xDB,0xC4,0x9A, + 0xF4,0x89,0x2B,0xCB,0x92,0x9B,0x06,0x90,0x69,0xD1,0x8D,0x2B,0xD1,0xA5,0xC4,0x2F, + 0x36,0xAC,0xC2,0x35,0x59,0x51,0xA8,0xD9,0xA4,0x7F,0x0D,0xD4,0xBF,0x02,0xE7,0x1E + }, + { + 0x37,0x8F,0x5A,0x54,0x16,0x31,0x22,0x9B,0x94,0x4C,0x9A,0xD8,0xEC,0x16,0x5F,0xDE, + 0x3A,0x7D,0x3A,0x1B,0x25,0x89,0x42,0x24,0x3C,0xD9,0x55,0xB7,0xE0,0x0D,0x09,0x84, + 0x80,0x0A,0x44,0x0B,0xDB,0xB2,0xCE,0xB1,0x7B,0x2B,0x8A,0x9A,0xA6,0x07,0x9C,0x54, + 0x0E,0x38,0xDC,0x92,0xCB,0x1F,0x2A,0x60,0x72,0x61,0x44,0x51,0x83,0x23,0x5A,0xDB + }, + { + 0xAB,0xBE,0xDE,0xA6,0x80,0x05,0x6F,0x52,0x38,0x2A,0xE5,0x48,0xB2,0xE4,0xF3,0xF3, + 0x89,0x41,0xE7,0x1C,0xFF,0x8A,0x78,0xDB,0x1F,0xFF,0xE1,0x8A,0x1B,0x33,0x61,0x03, + 0x9F,0xE7,0x67,0x02,0xAF,0x69,0x33,0x4B,0x7A,0x1E,0x6C,0x30,0x3B,0x76,0x52,0xF4, + 0x36,0x98,0xFA,0xD1,0x15,0x3B,0xB6,0xC3,0x74,0xB4,0xC7,0xFB,0x98,0x45,0x9C,0xED + }, + { + 0x7B,0xCD,0x9E,0xD0,0xEF,0xC8,0x89,0xFB,0x30,0x02,0xC6,0xCD,0x63,0x5A,0xFE,0x94, + 0xD8,0xFA,0x6B,0xBB,0xEB,0xAB,0x07,0x61,0x20,0x01,0x80,0x21,0x14,0x84,0x66,0x79, + 0x8A,0x1D,0x71,0xEF,0xEA,0x48,0xB9,0xCA,0xEF,0xBA,0xCD,0x1D,0x7D,0x47,0x6E,0x98, + 0xDE,0xA2,0x59,0x4A,0xC0,0x6F,0xD8,0x5D,0x6B,0xCA,0xA4,0xCD,0x81,0xF3,0x2D,0x1B + }, + { + 0x37,0x8E,0xE7,0x67,0xF1,0x16,0x31,0xBA,0xD2,0x13,0x80,0xB0,0x04,0x49,0xB1,0x7A, + 0xCD,0xA4,0x3C,0x32,0xBC,0xDF,0x1D,0x77,0xF8,0x20,0x12,0xD4,0x30,0x21,0x9F,0x9B, + 0x5D,0x80,0xEF,0x9D,0x18,0x91,0xCC,0x86,0xE7,0x1D,0xA4,0xAA,0x88,0xE1,0x28,0x52, + 0xFA,0xF4,0x17,0xD5,0xD9,0xB2,0x1B,0x99,0x48,0xBC,0x92,0x4A,0xF1,0x1B,0xD7,0x20 + } +}; + + +void AddModulo512(const void *a,const void *b,void *c) +{ + const unsigned char *A=a, *B=b; + unsigned char *C=c; + int t = 0; +#ifdef FULL_UNROLL +#define ADDBYTE_8(i) t = A[i] + B[i] + (t >> 8); C[i] = t & 0xFF; + + ADDBYTE_8(63) + ADDBYTE_8(62) + ADDBYTE_8(61) + ADDBYTE_8(60) + ADDBYTE_8(59) + ADDBYTE_8(58) + ADDBYTE_8(57) + ADDBYTE_8(56) + ADDBYTE_8(55) + ADDBYTE_8(54) + ADDBYTE_8(53) + ADDBYTE_8(52) + ADDBYTE_8(51) + ADDBYTE_8(50) + ADDBYTE_8(49) + ADDBYTE_8(48) + ADDBYTE_8(47) + ADDBYTE_8(46) + ADDBYTE_8(45) + ADDBYTE_8(44) + ADDBYTE_8(43) + ADDBYTE_8(42) + ADDBYTE_8(41) + ADDBYTE_8(40) + ADDBYTE_8(39) + ADDBYTE_8(38) + ADDBYTE_8(37) + ADDBYTE_8(36) + ADDBYTE_8(35) + ADDBYTE_8(34) + ADDBYTE_8(33) + ADDBYTE_8(32) + ADDBYTE_8(31) + ADDBYTE_8(30) + ADDBYTE_8(29) + ADDBYTE_8(28) + ADDBYTE_8(27) + ADDBYTE_8(26) + ADDBYTE_8(25) + ADDBYTE_8(24) + ADDBYTE_8(23) + ADDBYTE_8(22) + ADDBYTE_8(21) + ADDBYTE_8(20) + ADDBYTE_8(19) + ADDBYTE_8(18) + ADDBYTE_8(17) + ADDBYTE_8(16) + ADDBYTE_8(15) + ADDBYTE_8(14) + ADDBYTE_8(13) + ADDBYTE_8(12) + ADDBYTE_8(11) + ADDBYTE_8(10) + ADDBYTE_8(9) + ADDBYTE_8(8) + ADDBYTE_8(7) + ADDBYTE_8(6) + ADDBYTE_8(5) + ADDBYTE_8(4) + ADDBYTE_8(3) + ADDBYTE_8(2) + ADDBYTE_8(1) + ADDBYTE_8(0) + +#else + int i = 0; + + for(i=63;i>=0;i--) + { + t = A[i] + B[i] + (t >> 8); + C[i] = t & 0xFF; + } +#endif +} + +void AddXor512(const void *a,const void *b,void *c) +{ + const unsigned long long *A=a, *B=b; + unsigned long long *C=c; +#ifdef FULL_UNROLL + C[0] = A[0] ^ B[0]; + C[1] = A[1] ^ B[1]; + C[2] = A[2] ^ B[2]; + C[3] = A[3] ^ B[3]; + C[4] = A[4] ^ B[4]; + C[5] = A[5] ^ B[5]; + C[6] = A[6] ^ B[6]; + C[7] = A[7] ^ B[7]; +#else + int i = 0; + + for(i=0;i<8;i++) + { + C[i] = A[i] ^ B[i]; + } +#endif +} + +void F(unsigned char *state) +{ + unsigned long long return_state[8]; + register unsigned long long r = 0; + r ^= T[0][state[56]]; + r ^= T[1][state[48]]; + r ^= T[2][state[40]]; + r ^= T[3][state[32]]; + r ^= T[4][state[24]]; + r ^= T[5][state[16]]; + r ^= T[6][state[8]]; + r ^= T[7][state[0]]; + return_state[0] = r; + r = 0; + + r ^= T[0][state[57]]; + r ^= T[1][state[49]]; + r ^= T[2][state[41]]; + r ^= T[3][state[33]]; + r ^= T[4][state[25]]; + r ^= T[5][state[17]]; + r ^= T[6][state[9]]; + r ^= T[7][state[1]]; + return_state[1] = r; + r = 0; + + r ^= T[0][state[58]]; + r ^= T[1][state[50]]; + r ^= T[2][state[42]]; + r ^= T[3][state[34]]; + r ^= T[4][state[26]]; + r ^= T[5][state[18]]; + r ^= T[6][state[10]]; + r ^= T[7][state[2]]; + return_state[2] = r; + r = 0; + + r ^= T[0][state[59]]; + r ^= T[1][state[51]]; + r ^= T[2][state[43]]; + r ^= T[3][state[35]]; + r ^= T[4][state[27]]; + r ^= T[5][state[19]]; + r ^= T[6][state[11]]; + r ^= T[7][state[3]]; + return_state[3] = r; + r = 0; + + r ^= T[0][state[60]]; + r ^= T[1][state[52]]; + r ^= T[2][state[44]]; + r ^= T[3][state[36]]; + r ^= T[4][state[28]]; + r ^= T[5][state[20]]; + r ^= T[6][state[12]]; + r ^= T[7][state[4]]; + return_state[4] = r; + r = 0; + + r ^= T[0][state[61]]; + r ^= T[1][state[53]]; + r ^= T[2][state[45]]; + r ^= T[3][state[37]]; + r ^= T[4][state[29]]; + r ^= T[5][state[21]]; + r ^= T[6][state[13]]; + r ^= T[7][state[5]]; + return_state[5] = r; + r = 0; + + r ^= T[0][state[62]]; + r ^= T[1][state[54]]; + r ^= T[2][state[46]]; + r ^= T[3][state[38]]; + r ^= T[4][state[30]]; + r ^= T[5][state[22]]; + r ^= T[6][state[14]]; + r ^= T[7][state[6]]; + return_state[6] = r; + r = 0; + + r ^= T[0][state[63]]; + r ^= T[1][state[55]]; + r ^= T[2][state[47]]; + r ^= T[3][state[39]]; + r ^= T[4][state[31]]; + r ^= T[5][state[23]]; + r ^= T[6][state[15]]; + r ^= T[7][state[7]]; + return_state[7] = r; + + memcpy(state,(unsigned char*)return_state,64); +} + +#define KeySchedule(K,i) AddXor512(K,C[i],K); F(K); + +void E(unsigned char *K,const unsigned char *m, unsigned char *state) +{ +#ifdef FULL_UNROLL + AddXor512(m,K,state); + + F(state); + KeySchedule(K,0); + AddXor512(state,K,state); + + F(state); + KeySchedule(K,1); + AddXor512(state,K,state); + + F(state); + KeySchedule(K,2); + AddXor512(state,K,state); + + F(state); + KeySchedule(K,3); + AddXor512(state,K,state); + + F(state); + KeySchedule(K,4); + AddXor512(state,K,state); + + F(state); + KeySchedule(K,5); + AddXor512(state,K,state); + + F(state); + KeySchedule(K,6); + AddXor512(state,K,state); + + F(state); + KeySchedule(K,7); + AddXor512(state,K,state); + + F(state); + KeySchedule(K,8); + AddXor512(state,K,state); + + F(state); + KeySchedule(K,9); + AddXor512(state,K,state); + + F(state); + KeySchedule(K,10); + AddXor512(state,K,state); + + F(state); + KeySchedule(K,11); + AddXor512(state,K,state); +#else + int i = 0; + + AddXor512(m,K,state); + + for(i=0;i<12;i++) + { + F(state); + KeySchedule(K,i); + AddXor512(state,K,state); + } +#endif +} + +static void g_N(const unsigned char *N,unsigned char *h,const unsigned char *m) +{ + unsigned char t[64], K[64]; + + AddXor512(N,h,K); + + F(K); + + E(K,m,t); + + AddXor512(t,h,t); + AddXor512(t,m,h); +} + +static void hash_X(unsigned char *IV,const unsigned char *message,unsigned long long length,unsigned char *out) +{ + unsigned char v512[64] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00 + }; + unsigned char v0[64] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; + unsigned char Sigma[64] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; + unsigned char N[64] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; + unsigned char m[64], *hash = IV; + unsigned long long len = length; + + // Stage 2 + while (len >= 512) + { + memcpy(m, message + len/8 - 63 - ( (len & 0x7) == 0 ), 64); + + g_N(N,hash,m); + AddModulo512(N,v512,N); + AddModulo512(Sigma,m,Sigma); + len -= 512; + } + + memset(m,0,64); + memcpy(m + 63 - len/8 + ( (len & 0x7) == 0 ), message, len/8 + 1 - ( (len & 0x7) == 0 )); + + // Stage 3 + m[ 63 - len/8 ] |= (1 << (len & 0x7)); + + g_N(N,hash,m); + v512[63] = len & 0xFF; + v512[62] = len >> 8; + AddModulo512(N,v512,N); + + AddModulo512(Sigma,m,Sigma); + + g_N(v0,hash,N); + g_N(v0,hash,Sigma); + + memcpy(out, hash, 64); +} + +static void hash_512(const unsigned char *message,unsigned long long length,unsigned char *out) +{ + unsigned char IV[64] = + { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; + + hash_X(IV,message,length,out); +} + +static void hash_256(const unsigned char *message,unsigned long long length,unsigned char *out) +{ + unsigned char IV[64] = + { + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 + }; + unsigned char hash[64]; + + hash_X(IV,message,length,hash); + + memcpy(out,hash,32); +} + + + + + +/* see sph_gost.h */ +void +sph_gost256_init(void *cc) +{ + //gost_init(cc, 256); +} + +/* see sph_gost.h */ +void +sph_gost256(void *cc, const void *data, size_t len) +{ + hash_256(data, len * 8, cc); +} + +/* see sph_gost.h */ +void +sph_gost256_close(void *cc, void *dst) +{ + //sph_gost256_addbits_and_close(cc, 0, 0, dst); + memcpy(dst, cc, 32); +} + +/* see sph_gost.h */ +void +sph_gost256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + //gost_close32(cc, ub, n, dst); +} + +/* see sph_gost.h */ +void sph_gost512_init(void *cc) +{ + //gost_init(cc, 512); +} + +/* see sph_gost.h */ +void sph_gost512(void *cc, const void *data, size_t len) +{ + hash_512(data, len * 8, cc); +} + +/* see sph_gost.h */ +void sph_gost512_close(void *cc, void *dst) +{ + //sph_gost512_addbits_and_close(cc, 0, 0, dst); + memcpy(dst, cc, 64); +} + +/* see sph_gost.h */ +void +sph_gost512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + //gost_close64(cc, ub, n, dst); +} + + +#ifdef __cplusplus +} +#endif diff --git a/stratum/sha3/sph_gost.h b/stratum/sha3/sph_gost.h new file mode 100644 index 000000000..c0a4ab750 --- /dev/null +++ b/stratum/sha3/sph_gost.h @@ -0,0 +1,185 @@ +/* $Id: sph_gost.h 216 2010-06-08 09:46:57Z tp $ */ +/** + * GOST interface. This is the interface for GOST R 12 with the + * recommended parameters for SHA-3, with output lengths 256 + * and 512 bits. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @file sph_gost.h + * @author ivan + */ + +#ifndef SPH_GOST_H__ +#define SPH_GOST_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include +#include "sph_types.h" + +/** + * Output size (in bits) for GOST-256. + */ +#define SPH_SIZE_gost256 256 + +/** + * Output size (in bits) for GOST-512. + */ +#define SPH_SIZE_gost512 512 + +/** + * This structure is a context for Keccak computations: it contains the + * intermediate values and some data from the last entered block. Once a + * GOST computation has been performed, the context can be reused for + * another computation. + * + * The contents of this structure are private. A running GOST computation + * can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ + +/** + * This structure is a context for Gost-256 computations. + */ + +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[32]; /* first field, for alignment */ + size_t ptr; + sph_u32 V[3][8]; +#endif +} sph_gost256_context; + +/** + * This structure is a context for Gost-512 computations. + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[64]; /* first field, for alignment */ + size_t ptr; + sph_u32 V[5][8]; +#endif +} sph_gost512_context; + + +/** + * Initialize a GOST-256 context. This process performs no memory allocation. + * + * @param cc the GOST-256 context (pointer to a + * sph_gost256_context) + */ +void sph_gost256_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Gost-256 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_gost256(void *cc, const void *data, size_t len); + +/** + * Terminate the current GOST-256 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (32 bytes). The context is automatically + * reinitialized. + * + * @param cc the GOST-256 context + * @param dst the destination buffer + */ +void sph_gost256_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (32 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the GOST-256 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_gost256_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a Gost-512 context. This process performs no memory allocation. + * + * @param cc the GOST-512 context (pointer to a + * sph_gost512_context) + */ +void sph_gost512_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the GOST-512 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_gost512(void *cc, const void *data, size_t len); + +/** + * Terminate the current GOST-512 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (64 bytes). The context is automatically + * reinitialized. + * + * @param cc the GOST-512 context + * @param dst the destination buffer + */ +void sph_gost512_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (64 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the GOST-512 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_gost512_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/stratum/sha3/sph_panama.c b/stratum/sha3/sph_panama.c new file mode 100644 index 000000000..5dcab208c --- /dev/null +++ b/stratum/sha3/sph_panama.c @@ -0,0 +1,301 @@ +/* $Id: panama.c 216 2010-06-08 09:46:57Z tp $ */ +/* + * PANAMA implementation. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @author Thomas Pornin + */ + #include +#include + #include "sph_panama.h" + #define LVAR17(b) sph_u32 \ + b ## 0, b ## 1, b ## 2, b ## 3, b ## 4, b ## 5, \ + b ## 6, b ## 7, b ## 8, b ## 9, b ## 10, b ## 11, \ + b ## 12, b ## 13, b ## 14, b ## 15, b ## 16; + #define LVARS \ + LVAR17(a) \ + LVAR17(g) \ + LVAR17(p) \ + LVAR17(t) + #define M17(macro) do { \ + macro( 0, 1, 2, 4); \ + macro( 1, 2, 3, 5); \ + macro( 2, 3, 4, 6); \ + macro( 3, 4, 5, 7); \ + macro( 4, 5, 6, 8); \ + macro( 5, 6, 7, 9); \ + macro( 6, 7, 8, 10); \ + macro( 7, 8, 9, 11); \ + macro( 8, 9, 10, 12); \ + macro( 9, 10, 11, 13); \ + macro(10, 11, 12, 14); \ + macro(11, 12, 13, 15); \ + macro(12, 13, 14, 16); \ + macro(13, 14, 15, 0); \ + macro(14, 15, 16, 1); \ + macro(15, 16, 0, 2); \ + macro(16, 0, 1, 3); \ + } while (0) + #define BUPDATE1(n0, n2) do { \ + sc->buffer[ptr24][n0] ^= sc->buffer[ptr31][n2]; \ + sc->buffer[ptr31][n2] ^= INW1(n2); \ + } while (0) + #define BUPDATE do { \ + BUPDATE1(0, 2); \ + BUPDATE1(1, 3); \ + BUPDATE1(2, 4); \ + BUPDATE1(3, 5); \ + BUPDATE1(4, 6); \ + BUPDATE1(5, 7); \ + BUPDATE1(6, 0); \ + BUPDATE1(7, 1); \ + } while (0) + #define RSTATE(n0, n1, n2, n4) (a ## n0 = sc->state[n0]) + #define WSTATE(n0, n1, n2, n4) (sc->state[n0] = a ## n0) + #define GAMMA(n0, n1, n2, n4) \ + (g ## n0 = a ## n0 ^ (a ## n1 | SPH_T32(~a ## n2))) + #define PI_ALL do { \ + p0 = g0; \ + p1 = SPH_ROTL32( g7, 1); \ + p2 = SPH_ROTL32(g14, 3); \ + p3 = SPH_ROTL32( g4, 6); \ + p4 = SPH_ROTL32(g11, 10); \ + p5 = SPH_ROTL32( g1, 15); \ + p6 = SPH_ROTL32( g8, 21); \ + p7 = SPH_ROTL32(g15, 28); \ + p8 = SPH_ROTL32( g5, 4); \ + p9 = SPH_ROTL32(g12, 13); \ + p10 = SPH_ROTL32( g2, 23); \ + p11 = SPH_ROTL32( g9, 2); \ + p12 = SPH_ROTL32(g16, 14); \ + p13 = SPH_ROTL32( g6, 27); \ + p14 = SPH_ROTL32(g13, 9); \ + p15 = SPH_ROTL32( g3, 24); \ + p16 = SPH_ROTL32(g10, 8); \ + } while (0) + #define THETA(n0, n1, n2, n4) \ + (t ## n0 = p ## n0 ^ p ## n1 ^ p ## n4) + #define SIGMA_ALL do { \ + a0 = t0 ^ 1; \ + a1 = t1 ^ INW2(0); \ + a2 = t2 ^ INW2(1); \ + a3 = t3 ^ INW2(2); \ + a4 = t4 ^ INW2(3); \ + a5 = t5 ^ INW2(4); \ + a6 = t6 ^ INW2(5); \ + a7 = t7 ^ INW2(6); \ + a8 = t8 ^ INW2(7); \ + a9 = t9 ^ sc->buffer[ptr16][0]; \ + a10 = t10 ^ sc->buffer[ptr16][1]; \ + a11 = t11 ^ sc->buffer[ptr16][2]; \ + a12 = t12 ^ sc->buffer[ptr16][3]; \ + a13 = t13 ^ sc->buffer[ptr16][4]; \ + a14 = t14 ^ sc->buffer[ptr16][5]; \ + a15 = t15 ^ sc->buffer[ptr16][6]; \ + a16 = t16 ^ sc->buffer[ptr16][7]; \ + } while (0) + #define PANAMA_STEP do { \ + unsigned ptr16, ptr24, ptr31; \ + \ + ptr24 = (ptr0 - 8) & 31; \ + ptr31 = (ptr0 - 1) & 31; \ + BUPDATE; \ + M17(GAMMA); \ + PI_ALL; \ + M17(THETA); \ + ptr16 = ptr0 ^ 16; \ + SIGMA_ALL; \ + ptr0 = ptr31; \ + } while (0) + /* + * These macros are used to compute + */ +#define INC0 1 +#define INC1 2 +#define INC2 3 +#define INC3 4 +#define INC4 5 +#define INC5 6 +#define INC6 7 +#define INC7 8 + /* + * Push data by blocks of 32 bytes. "pbuf" must be 32-bit aligned. Each + * iteration processes 32 data bytes; "num" contains the number of + * iterations. + */ +static void +panama_push(sph_panama_context *sc, const unsigned char *pbuf, size_t num) +{ + LVARS + unsigned ptr0; +#if SPH_LITTLE_FAST +#define INW1(i) sph_dec32le_aligned(pbuf + 4 * (i)) +#else + sph_u32 X_var[8]; +#define INW1(i) X_var[i] +#endif +#define INW2(i) INW1(i) + M17(RSTATE); + ptr0 = sc->buffer_ptr; + while (num -- > 0) { +#if !SPH_LITTLE_FAST + int i; + for (i = 0; i < 8; i ++) + X_var[i] = sph_dec32le_aligned(pbuf + 4 * (i)); +#endif + PANAMA_STEP; + pbuf = (const unsigned char *)pbuf + 32; + } + M17(WSTATE); + sc->buffer_ptr = ptr0; + #undef INW1 +#undef INW2 +} + /* + * Perform the "pull" operation repeatedly ("num" times). The hash output + * will be extracted from the state afterwards. + */ +static void +panama_pull(sph_panama_context *sc, unsigned num) +{ + LVARS + unsigned ptr0; +#define INW1(i) INW_H1(INC ## i) +#define INW_H1(i) INW_H2(i) +#define INW_H2(i) a ## i +#define INW2(i) sc->buffer[ptr4][i] + M17(RSTATE); + ptr0 = sc->buffer_ptr; + while (num -- > 0) { + unsigned ptr4; + ptr4 = (ptr0 + 4) & 31; + PANAMA_STEP; + } + M17(WSTATE); + #undef INW1 +#undef INW_H1 +#undef INW_H2 +#undef INW2 +} + /* see sph_panama.h */ +void +sph_panama_init(void *cc) +{ + sph_panama_context *sc; + sc = cc; + /* + * This is not completely conformant, but "it will work + * everywhere". Initial state consists of zeroes everywhere. + * Conceptually, the sph_u32 type may have padding bits which + * must not be set to 0; but such an architecture remains to + * be seen. + */ + sc->data_ptr = 0; + memset(sc->buffer, 0, sizeof sc->buffer); + sc->buffer_ptr = 0; + memset(sc->state, 0, sizeof sc->state); +} + #ifdef SPH_UPTR +static void +panama_short(void *cc, const void *data, size_t len) +#else +void +sph_panama(void *cc, const void *data, size_t len) +#endif +{ + sph_panama_context *sc; + unsigned current; + sc = cc; + current = sc->data_ptr; + while (len > 0) { + unsigned clen; + clen = (sizeof sc->data) - current; + if (clen > len) + clen = len; + memcpy(sc->data + current, data, clen); + data = (const unsigned char *)data + clen; + len -= clen; + current += clen; + if (current == sizeof sc->data) { + current = 0; + panama_push(sc, sc->data, 1); + } + } + sc->data_ptr = current; +} + #ifdef SPH_UPTR +/* see sph_panama.h */ +void +sph_panama(void *cc, const void *data, size_t len) +{ + sph_panama_context *sc; + unsigned current; + size_t rlen; + if (len < (2 * sizeof sc->data)) { + panama_short(cc, data, len); + return; + } + sc = cc; + current = sc->data_ptr; + if (current > 0) { + unsigned t; + t = (sizeof sc->data) - current; + panama_short(sc, data, t); + data = (const unsigned char *)data + t; + len -= t; + } +#if !SPH_UNALIGNED + if (((SPH_UPTR)data & 3) != 0) { + panama_short(sc, data, len); + return; + } +#endif + panama_push(sc, data, len >> 5); + rlen = len & 31; + if (rlen > 0) + memcpy(sc->data, + (const unsigned char *)data + len - rlen, rlen); + sc->data_ptr = rlen; +} +#endif + /* see sph_panama.h */ +void +sph_panama_close(void *cc, void *dst) +{ + sph_panama_context *sc; + unsigned current; + int i; + sc = cc; + current = sc->data_ptr; + sc->data[current ++] = 0x01; + memset(sc->data + current, 0, (sizeof sc->data) - current); + panama_push(sc, sc->data, 1); + panama_pull(sc, 32); + for (i = 0; i < 8; i ++) + sph_enc32le((unsigned char *)dst + 4 * i, sc->state[i + 9]); + sph_panama_init(sc); +} diff --git a/stratum/sha3/sph_panama.h b/stratum/sha3/sph_panama.h new file mode 100644 index 000000000..fdf3b89cd --- /dev/null +++ b/stratum/sha3/sph_panama.h @@ -0,0 +1,126 @@ +/* $Id: sph_panama.h 154 2010-04-26 17:00:24Z tp $ */ +/** + * PANAMA interface. + * + * PANAMA has been published in: J. Daemen and C. Clapp, "Fast Hashing + * and Stream Encryption with PANAMA", Fast Software Encryption - + * FSE'98, LNCS 1372, Springer (1998), pp. 60--74. + * + * PANAMA is not fully defined with regards to endianness and related + * topics. This implementation follows strict little-endian conventions: + *
    + *
  • Each 32-byte input block is split into eight 32-bit words, the + * first (leftmost) word being numbered 0.
  • + *
  • Each such 32-bit word is decoded from memory in little-endian + * convention.
  • + *
  • The additional padding bit equal to "1" is added by considering + * the least significant bit in a byte to come first; practically, this + * means that a single byte of value 0x01 is appended to the (byte-oriented) + * message, and then 0 to 31 bytes of value 0x00.
  • + *
  • The output consists of eight 32-bit words; the word numbered 0 is + * written first (in leftmost position) and it is encoded in little-endian + * convention. + *
+ * With these conventions, PANAMA is sometimes known as "PANAMA-LE". The + * PANAMA reference implementation uses our conventions for input, but + * prescribes no convention for output. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @file sph_panama.h + * @author Thomas Pornin + */ + +#ifndef SPH_PANAMA_H__ +#define SPH_PANAMA_H__ + +#if defined(__cplusplus) +extern "C" { +#endif + +#include +#include "../sha3/sph_types.h" + +/** + * Output size (in bits) for PANAMA. + */ +#define SPH_SIZE_panama 256 + +/** + * This structure is a context for PANAMA computations: it contains the + * intermediate values and some data from the last entered block. Once + * a PANAMA computation has been performed, the context can be reused for + * another computation. + * + * The contents of this structure are private. A running PANAMA computation + * can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char data[32]; /* first field, for alignment */ + unsigned data_ptr; + + sph_u32 buffer[32][8]; + unsigned buffer_ptr; + + sph_u32 state[17]; +#endif +} sph_panama_context; + +/** + * Initialize a PANAMA context. This process performs no memory allocation. + * + * @param cc the PANAMA context (pointer to a sph_panama_context) + */ +void sph_panama_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the PANAMA context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_panama(void *cc, const void *data, size_t len); + +/** + * Terminate the current PANAMA computation and output the result into the + * provided buffer. The destination buffer must be wide enough to + * accomodate the result (32 bytes). The context is automatically + * reinitialized. + * + * @param cc the PANAMA context + * @param dst the destination buffer + */ +void sph_panama_close(void *cc, void *dst); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/stratum/sha3/sph_radiogatun.c b/stratum/sha3/sph_radiogatun.c new file mode 100644 index 000000000..b5f2771e7 --- /dev/null +++ b/stratum/sha3/sph_radiogatun.c @@ -0,0 +1,907 @@ +/* $Id: radiogatun.c 226 2010-06-16 17:28:08Z tp $ */ +/* + * RadioGatun implementation. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @author Thomas Pornin + */ + #include +#include + #include "sph_radiogatun.h" + #if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_RADIOGATUN +#define SPH_SMALL_FOOTPRINT_RADIOGATUN 1 +#endif + /* ======================================================================= */ +/* + * The core macros. We want to unroll 13 successive rounds so that the + * belt rotation becomes pure routing, solved at compilation time, with + * no unnecessary copying. We also wish all state variables to be + * independant local variables, so that the C compiler becomes free to + * map these on registers at it sees fit. This requires some heavy + * preprocessor trickeries, including a full addition macro modulo 13. + * + * These macros are size-independent. Some macros must be defined before + * use: + * WT evaluates to the type for a word (32-bit or 64-bit) + * T truncates a value to the proper word size + * ROR(x, n) right rotation of a word x, with explicit modular + * reduction of the rotation count n by the word size + * INW(i, j) input word j (0, 1, or 2) of block i (0 to 12) + * + * For INW, the input buffer is pointed to by "buf" which has type + * "const unsigned char *". + */ + #define MUL19(action) do { \ + action(0); \ + action(1); \ + action(2); \ + action(3); \ + action(4); \ + action(5); \ + action(6); \ + action(7); \ + action(8); \ + action(9); \ + action(10); \ + action(11); \ + action(12); \ + action(13); \ + action(14); \ + action(15); \ + action(16); \ + action(17); \ + action(18); \ + } while (0) + #define DECL19(b) b ## 0, b ## 1, b ## 2, b ## 3, b ## 4, b ## 5, \ + b ## 6, b ## 7, b ## 8, b ## 9, b ## 10, b ## 11, \ + b ## 12, b ## 13, b ## 14, b ## 15, b ## 16, \ + b ## 17, b ## 18 + #define M19_T7(i) M19_T7_(i) +#define M19_T7_(i) M19_T7_ ## i +#define M19_T7_0 0 +#define M19_T7_1 7 +#define M19_T7_2 14 +#define M19_T7_3 2 +#define M19_T7_4 9 +#define M19_T7_5 16 +#define M19_T7_6 4 +#define M19_T7_7 11 +#define M19_T7_8 18 +#define M19_T7_9 6 +#define M19_T7_10 13 +#define M19_T7_11 1 +#define M19_T7_12 8 +#define M19_T7_13 15 +#define M19_T7_14 3 +#define M19_T7_15 10 +#define M19_T7_16 17 +#define M19_T7_17 5 +#define M19_T7_18 12 + #define M19_A1(i) M19_A1_(i) +#define M19_A1_(i) M19_A1_ ## i +#define M19_A1_0 1 +#define M19_A1_1 2 +#define M19_A1_2 3 +#define M19_A1_3 4 +#define M19_A1_4 5 +#define M19_A1_5 6 +#define M19_A1_6 7 +#define M19_A1_7 8 +#define M19_A1_8 9 +#define M19_A1_9 10 +#define M19_A1_10 11 +#define M19_A1_11 12 +#define M19_A1_12 13 +#define M19_A1_13 14 +#define M19_A1_14 15 +#define M19_A1_15 16 +#define M19_A1_16 17 +#define M19_A1_17 18 +#define M19_A1_18 0 + #define M19_A2(i) M19_A2_(i) +#define M19_A2_(i) M19_A2_ ## i +#define M19_A2_0 2 +#define M19_A2_1 3 +#define M19_A2_2 4 +#define M19_A2_3 5 +#define M19_A2_4 6 +#define M19_A2_5 7 +#define M19_A2_6 8 +#define M19_A2_7 9 +#define M19_A2_8 10 +#define M19_A2_9 11 +#define M19_A2_10 12 +#define M19_A2_11 13 +#define M19_A2_12 14 +#define M19_A2_13 15 +#define M19_A2_14 16 +#define M19_A2_15 17 +#define M19_A2_16 18 +#define M19_A2_17 0 +#define M19_A2_18 1 + #define M19_A4(i) M19_A4_(i) +#define M19_A4_(i) M19_A4_ ## i +#define M19_A4_0 4 +#define M19_A4_1 5 +#define M19_A4_2 6 +#define M19_A4_3 7 +#define M19_A4_4 8 +#define M19_A4_5 9 +#define M19_A4_6 10 +#define M19_A4_7 11 +#define M19_A4_8 12 +#define M19_A4_9 13 +#define M19_A4_10 14 +#define M19_A4_11 15 +#define M19_A4_12 16 +#define M19_A4_13 17 +#define M19_A4_14 18 +#define M19_A4_15 0 +#define M19_A4_16 1 +#define M19_A4_17 2 +#define M19_A4_18 3 + #define ACC_a(i) ACC_a_(i) +#define ACC_a_(i) a ## i +#define ACC_atmp(i) ACC_atmp_(i) +#define ACC_atmp_(i) atmp ## i + #define MILL1(i) (atmp ## i = a ## i ^ T(ACC_a(M19_A1(i)) \ + | ~ACC_a(M19_A2(i)))) +#define MILL2(i) (a ## i = ROR(ACC_atmp(M19_T7(i)), ((i * (i + 1)) >> 1))) +#define MILL3(i) (atmp ## i = a ## i ^ ACC_a(M19_A1(i)) ^ ACC_a(M19_A4(i))) +#define MILL4(i) (a ## i = atmp ## i ^ (i == 0)) + #define MILL do { \ + WT DECL19(atmp); \ + MUL19(MILL1); \ + MUL19(MILL2); \ + MUL19(MILL3); \ + MUL19(MILL4); \ + } while (0) + #define DECL13(b) b ## 0 ## _0, b ## 0 ## _1, b ## 0 ## _2, \ + b ## 1 ## _0, b ## 1 ## _1, b ## 1 ## _2, \ + b ## 2 ## _0, b ## 2 ## _1, b ## 2 ## _2, \ + b ## 3 ## _0, b ## 3 ## _1, b ## 3 ## _2, \ + b ## 4 ## _0, b ## 4 ## _1, b ## 4 ## _2, \ + b ## 5 ## _0, b ## 5 ## _1, b ## 5 ## _2, \ + b ## 6 ## _0, b ## 6 ## _1, b ## 6 ## _2, \ + b ## 7 ## _0, b ## 7 ## _1, b ## 7 ## _2, \ + b ## 8 ## _0, b ## 8 ## _1, b ## 8 ## _2, \ + b ## 9 ## _0, b ## 9 ## _1, b ## 9 ## _2, \ + b ## 10 ## _0, b ## 10 ## _1, b ## 10 ## _2, \ + b ## 11 ## _0, b ## 11 ## _1, b ## 11 ## _2, \ + b ## 12 ## _0, b ## 12 ## _1, b ## 12 ## _2 + #define M13_A(i, j) M13_A_(i, j) +#define M13_A_(i, j) M13_A_ ## i ## _ ## j +#define M13_A_0_0 0 +#define M13_A_0_1 1 +#define M13_A_0_2 2 +#define M13_A_0_3 3 +#define M13_A_0_4 4 +#define M13_A_0_5 5 +#define M13_A_0_6 6 +#define M13_A_0_7 7 +#define M13_A_0_8 8 +#define M13_A_0_9 9 +#define M13_A_0_10 10 +#define M13_A_0_11 11 +#define M13_A_0_12 12 +#define M13_A_1_0 1 +#define M13_A_1_1 2 +#define M13_A_1_2 3 +#define M13_A_1_3 4 +#define M13_A_1_4 5 +#define M13_A_1_5 6 +#define M13_A_1_6 7 +#define M13_A_1_7 8 +#define M13_A_1_8 9 +#define M13_A_1_9 10 +#define M13_A_1_10 11 +#define M13_A_1_11 12 +#define M13_A_1_12 0 +#define M13_A_2_0 2 +#define M13_A_2_1 3 +#define M13_A_2_2 4 +#define M13_A_2_3 5 +#define M13_A_2_4 6 +#define M13_A_2_5 7 +#define M13_A_2_6 8 +#define M13_A_2_7 9 +#define M13_A_2_8 10 +#define M13_A_2_9 11 +#define M13_A_2_10 12 +#define M13_A_2_11 0 +#define M13_A_2_12 1 +#define M13_A_3_0 3 +#define M13_A_3_1 4 +#define M13_A_3_2 5 +#define M13_A_3_3 6 +#define M13_A_3_4 7 +#define M13_A_3_5 8 +#define M13_A_3_6 9 +#define M13_A_3_7 10 +#define M13_A_3_8 11 +#define M13_A_3_9 12 +#define M13_A_3_10 0 +#define M13_A_3_11 1 +#define M13_A_3_12 2 +#define M13_A_4_0 4 +#define M13_A_4_1 5 +#define M13_A_4_2 6 +#define M13_A_4_3 7 +#define M13_A_4_4 8 +#define M13_A_4_5 9 +#define M13_A_4_6 10 +#define M13_A_4_7 11 +#define M13_A_4_8 12 +#define M13_A_4_9 0 +#define M13_A_4_10 1 +#define M13_A_4_11 2 +#define M13_A_4_12 3 +#define M13_A_5_0 5 +#define M13_A_5_1 6 +#define M13_A_5_2 7 +#define M13_A_5_3 8 +#define M13_A_5_4 9 +#define M13_A_5_5 10 +#define M13_A_5_6 11 +#define M13_A_5_7 12 +#define M13_A_5_8 0 +#define M13_A_5_9 1 +#define M13_A_5_10 2 +#define M13_A_5_11 3 +#define M13_A_5_12 4 +#define M13_A_6_0 6 +#define M13_A_6_1 7 +#define M13_A_6_2 8 +#define M13_A_6_3 9 +#define M13_A_6_4 10 +#define M13_A_6_5 11 +#define M13_A_6_6 12 +#define M13_A_6_7 0 +#define M13_A_6_8 1 +#define M13_A_6_9 2 +#define M13_A_6_10 3 +#define M13_A_6_11 4 +#define M13_A_6_12 5 +#define M13_A_7_0 7 +#define M13_A_7_1 8 +#define M13_A_7_2 9 +#define M13_A_7_3 10 +#define M13_A_7_4 11 +#define M13_A_7_5 12 +#define M13_A_7_6 0 +#define M13_A_7_7 1 +#define M13_A_7_8 2 +#define M13_A_7_9 3 +#define M13_A_7_10 4 +#define M13_A_7_11 5 +#define M13_A_7_12 6 +#define M13_A_8_0 8 +#define M13_A_8_1 9 +#define M13_A_8_2 10 +#define M13_A_8_3 11 +#define M13_A_8_4 12 +#define M13_A_8_5 0 +#define M13_A_8_6 1 +#define M13_A_8_7 2 +#define M13_A_8_8 3 +#define M13_A_8_9 4 +#define M13_A_8_10 5 +#define M13_A_8_11 6 +#define M13_A_8_12 7 +#define M13_A_9_0 9 +#define M13_A_9_1 10 +#define M13_A_9_2 11 +#define M13_A_9_3 12 +#define M13_A_9_4 0 +#define M13_A_9_5 1 +#define M13_A_9_6 2 +#define M13_A_9_7 3 +#define M13_A_9_8 4 +#define M13_A_9_9 5 +#define M13_A_9_10 6 +#define M13_A_9_11 7 +#define M13_A_9_12 8 +#define M13_A_10_0 10 +#define M13_A_10_1 11 +#define M13_A_10_2 12 +#define M13_A_10_3 0 +#define M13_A_10_4 1 +#define M13_A_10_5 2 +#define M13_A_10_6 3 +#define M13_A_10_7 4 +#define M13_A_10_8 5 +#define M13_A_10_9 6 +#define M13_A_10_10 7 +#define M13_A_10_11 8 +#define M13_A_10_12 9 +#define M13_A_11_0 11 +#define M13_A_11_1 12 +#define M13_A_11_2 0 +#define M13_A_11_3 1 +#define M13_A_11_4 2 +#define M13_A_11_5 3 +#define M13_A_11_6 4 +#define M13_A_11_7 5 +#define M13_A_11_8 6 +#define M13_A_11_9 7 +#define M13_A_11_10 8 +#define M13_A_11_11 9 +#define M13_A_11_12 10 +#define M13_A_12_0 12 +#define M13_A_12_1 0 +#define M13_A_12_2 1 +#define M13_A_12_3 2 +#define M13_A_12_4 3 +#define M13_A_12_5 4 +#define M13_A_12_6 5 +#define M13_A_12_7 6 +#define M13_A_12_8 7 +#define M13_A_12_9 8 +#define M13_A_12_10 9 +#define M13_A_12_11 10 +#define M13_A_12_12 11 + #define M13_N(i) M13_N_(i) +#define M13_N_(i) M13_N_ ## i +#define M13_N_0 12 +#define M13_N_1 11 +#define M13_N_2 10 +#define M13_N_3 9 +#define M13_N_4 8 +#define M13_N_5 7 +#define M13_N_6 6 +#define M13_N_7 5 +#define M13_N_8 4 +#define M13_N_9 3 +#define M13_N_10 2 +#define M13_N_11 1 +#define M13_N_12 0 + #define ACC_b(i, k) ACC_b_(i, k) +#define ACC_b_(i, k) b ## i ## _ ## k + #define ROUND_ELT(k, s) do { \ + if ((bj += 3) == 39) \ + bj = 0; \ + sc->b[bj + s] ^= a ## k; \ + } while (0) + #define ROUND_SF(j) do { \ + size_t bj = (j) * 3; \ + ROUND_ELT(1, 0); \ + ROUND_ELT(2, 1); \ + ROUND_ELT(3, 2); \ + ROUND_ELT(4, 0); \ + ROUND_ELT(5, 1); \ + ROUND_ELT(6, 2); \ + ROUND_ELT(7, 0); \ + ROUND_ELT(8, 1); \ + ROUND_ELT(9, 2); \ + ROUND_ELT(10, 0); \ + ROUND_ELT(11, 1); \ + ROUND_ELT(12, 2); \ + MILL; \ + bj = (j) * 3; \ + a ## 13 ^= sc->b[bj + 0]; \ + a ## 14 ^= sc->b[bj + 1]; \ + a ## 15 ^= sc->b[bj + 2]; \ + } while (0) + #define INPUT_SF(j, p0, p1, p2) do { \ + size_t bj = ((j) + 1) * 3; \ + if (bj == 39) \ + bj = 0; \ + sc->b[bj + 0] ^= (p0); \ + sc->b[bj + 1] ^= (p1); \ + sc->b[bj + 2] ^= (p2); \ + a16 ^= (p0); \ + a17 ^= (p1); \ + a18 ^= (p2); \ + } while (0) + #if SPH_SMALL_FOOTPRINT_RADIOGATUN + #define ROUND ROUND_SF +#define INPUT INPUT_SF + #else + /* + * Round function R, on base j. The value j is such that B[0] is actually + * b[j] after the initial rotation. On the 13-round macro, j has the + * successive values 12, 11, 10... 1, 0. + */ +#define ROUND(j) do { \ + ACC_b(M13_A(1, j), 0) ^= a ## 1; \ + ACC_b(M13_A(2, j), 1) ^= a ## 2; \ + ACC_b(M13_A(3, j), 2) ^= a ## 3; \ + ACC_b(M13_A(4, j), 0) ^= a ## 4; \ + ACC_b(M13_A(5, j), 1) ^= a ## 5; \ + ACC_b(M13_A(6, j), 2) ^= a ## 6; \ + ACC_b(M13_A(7, j), 0) ^= a ## 7; \ + ACC_b(M13_A(8, j), 1) ^= a ## 8; \ + ACC_b(M13_A(9, j), 2) ^= a ## 9; \ + ACC_b(M13_A(10, j), 0) ^= a ## 10; \ + ACC_b(M13_A(11, j), 1) ^= a ## 11; \ + ACC_b(M13_A(12, j), 2) ^= a ## 12; \ + MILL; \ + a ## 13 ^= ACC_b(j, 0); \ + a ## 14 ^= ACC_b(j, 1); \ + a ## 15 ^= ACC_b(j, 2); \ + } while (0) + #define INPUT(j, p0, p1, p2) do { \ + ACC_b(M13_A(1, j), 0) ^= (p0); \ + ACC_b(M13_A(1, j), 1) ^= (p1); \ + ACC_b(M13_A(1, j), 2) ^= (p2); \ + a16 ^= (p0); \ + a17 ^= (p1); \ + a18 ^= (p2); \ + } while (0) + #endif + #define MUL13(action) do { \ + action(0); \ + action(1); \ + action(2); \ + action(3); \ + action(4); \ + action(5); \ + action(6); \ + action(7); \ + action(8); \ + action(9); \ + action(10); \ + action(11); \ + action(12); \ + } while (0) + #define MILL_READ_ELT(i) do { \ + a ## i = sc->a[i]; \ + } while (0) + #define MILL_WRITE_ELT(i) do { \ + sc->a[i] = a ## i; \ + } while (0) + #define STATE_READ_SF do { \ + MUL19(MILL_READ_ELT); \ + } while (0) + #define STATE_WRITE_SF do { \ + MUL19(MILL_WRITE_ELT); \ + } while (0) + #define PUSH13_SF do { \ + WT DECL19(a); \ + const unsigned char *buf; \ + \ + buf = data; \ + STATE_READ_SF; \ + while (len >= sizeof sc->data) { \ + size_t mk; \ + for (mk = 13; mk > 0; mk --) { \ + WT p0 = INW(0, 0); \ + WT p1 = INW(0, 1); \ + WT p2 = INW(0, 2); \ + INPUT_SF(mk - 1, p0, p1, p2); \ + ROUND_SF(mk - 1); \ + buf += (sizeof sc->data) / 13; \ + len -= (sizeof sc->data) / 13; \ + } \ + } \ + STATE_WRITE_SF; \ + return len; \ + } while (0) + #if SPH_SMALL_FOOTPRINT_RADIOGATUN + #define STATE_READ STATE_READ_SF +#define STATE_WRITE STATE_WRITE_SF +#define PUSH13 PUSH13_SF + #else + #define BELT_READ_ELT(i) do { \ + b ## i ## _0 = sc->b[3 * i + 0]; \ + b ## i ## _1 = sc->b[3 * i + 1]; \ + b ## i ## _2 = sc->b[3 * i + 2]; \ + } while (0) + #define BELT_WRITE_ELT(i) do { \ + sc->b[3 * i + 0] = b ## i ## _0; \ + sc->b[3 * i + 1] = b ## i ## _1; \ + sc->b[3 * i + 2] = b ## i ## _2; \ + } while (0) + #define STATE_READ do { \ + MUL13(BELT_READ_ELT); \ + MUL19(MILL_READ_ELT); \ + } while (0) + #define STATE_WRITE do { \ + MUL13(BELT_WRITE_ELT); \ + MUL19(MILL_WRITE_ELT); \ + } while (0) + /* + * Input data by chunks of 13*3 blocks. This is the body of the + * radiogatun32_push13() and radiogatun64_push13() functions. + */ +#define PUSH13 do { \ + WT DECL19(a), DECL13(b); \ + const unsigned char *buf; \ + \ + buf = data; \ + STATE_READ; \ + while (len >= sizeof sc->data) { \ + WT p0, p1, p2; \ + MUL13(PUSH13_ELT); \ + buf += sizeof sc->data; \ + len -= sizeof sc->data; \ + } \ + STATE_WRITE; \ + return len; \ + } while (0) + #define PUSH13_ELT(k) do { \ + p0 = INW(k, 0); \ + p1 = INW(k, 1); \ + p2 = INW(k, 2); \ + INPUT(M13_N(k), p0, p1, p2); \ + ROUND(M13_N(k)); \ + } while (0) + #endif + #define BLANK13_SF do { \ + size_t mk = 13; \ + while (mk -- > 0) \ + ROUND_SF(mk); \ + } while (0) + #define BLANK1_SF do { \ + WT tmp0, tmp1, tmp2; \ + ROUND_SF(12); \ + tmp0 = sc->b[36]; \ + tmp1 = sc->b[37]; \ + tmp2 = sc->b[38]; \ + memmove(sc->b + 3, sc->b, 36 * sizeof sc->b[0]); \ + sc->b[0] = tmp0; \ + sc->b[1] = tmp1; \ + sc->b[2] = tmp2; \ + } while (0) + #if SPH_SMALL_FOOTPRINT_RADIOGATUN + #define BLANK13 BLANK13_SF +#define BLANK1 BLANK1_SF + #else + /* + * Run 13 blank rounds. This macro expects the "a" and "b" state variables + * to be alread declared. + */ +#define BLANK13 MUL13(BLANK13_ELT) + #define BLANK13_ELT(k) ROUND(M13_N(k)) + #define MUL12(action) do { \ + action(0); \ + action(1); \ + action(2); \ + action(3); \ + action(4); \ + action(5); \ + action(6); \ + action(7); \ + action(8); \ + action(9); \ + action(10); \ + action(11); \ + } while (0) + /* + * Run a single blank round, and physically rotate the belt. This is used + * for the last blank rounds, and the output rounds. This macro expects the + * "a" abd "b" state variables to be already declared. + */ +#define BLANK1 do { \ + WT tmp0, tmp1, tmp2; \ + ROUND(12); \ + tmp0 = b0_0; \ + tmp1 = b0_1; \ + tmp2 = b0_2; \ + MUL12(BLANK1_ELT); \ + b1_0 = tmp0; \ + b1_1 = tmp1; \ + b1_2 = tmp2; \ + } while (0) + #define BLANK1_ELT(i) do { \ + ACC_b(M13_A(M13_N(i), 1), 0) = ACC_b(M13_N(i), 0); \ + ACC_b(M13_A(M13_N(i), 1), 1) = ACC_b(M13_N(i), 1); \ + ACC_b(M13_A(M13_N(i), 1), 2) = ACC_b(M13_N(i), 2); \ + } while (0) + #endif + #define NO_TOKEN + /* + * Perform padding, then blank rounds, then output some words. This is + * the body of sph_radiogatun32_close() and sph_radiogatun64_close(). + */ +#define CLOSE_SF(width) CLOSE_GEN(width, \ + NO_TOKEN, STATE_READ_SF, BLANK1_SF, BLANK13_SF) + #if SPH_SMALL_FOOTPRINT_RADIOGATUN +#define CLOSE CLOSE_SF +#else +#define CLOSE(width) CLOSE_GEN(width, \ + WT DECL13(b);, STATE_READ, BLANK1, BLANK13) +#endif + #define CLOSE_GEN(width, WTb13, state_read, blank1, blank13) do { \ + unsigned ptr, num; \ + unsigned char *out; \ + WT DECL19(a); \ + WTb13 \ + \ + ptr = sc->data_ptr; \ + sc->data[ptr ++] = 0x01; \ + memset(sc->data + ptr, 0, (sizeof sc->data) - ptr); \ + radiogatun ## width ## _push13(sc, sc->data, sizeof sc->data); \ + \ + num = 17; \ + for (;;) { \ + ptr += 3 * (width >> 3); \ + if (ptr > sizeof sc->data) \ + break; \ + num --; \ + } \ + \ + state_read; \ + if (num >= 13) { \ + blank13; \ + num -= 13; \ + } \ + while (num -- > 0) \ + blank1; \ + \ + num = 0; \ + out = dst; \ + for (;;) { \ + OUTW(out, a1); \ + out += width >> 3; \ + OUTW(out, a2); \ + out += width >> 3; \ + num += 2 * (width >> 3); \ + if (num >= 32) \ + break; \ + blank1; \ + } \ + INIT; \ + } while (0) + /* + * Initialize context structure. + */ +#if SPH_LITTLE_ENDIAN || SPH_BIG_ENDIAN + #define INIT do { \ + memset(sc->a, 0, sizeof sc->a); \ + memset(sc->b, 0, sizeof sc->b); \ + sc->data_ptr = 0; \ + } while (0) + #else + #define INIT do { \ + size_t u; \ + for (u = 0; u < 19; u ++) \ + sc->a[u] = 0; \ + for (u = 0; u < 39; u ++) \ + sc->b[u] = 0; \ + sc->data_ptr = 0; \ + } while (0) + #endif + /* ======================================================================= */ +/* + * RadioGatun[32]. + */ + #if !SPH_NO_RG32 + #undef WT +#define WT sph_u32 +#undef T +#define T SPH_T32 +#undef ROR +#define ROR(x, n) SPH_T32(((x) << ((32 - (n)) & 31)) | ((x) >> ((n) & 31))) +#undef INW +#define INW(i, j) sph_dec32le_aligned(buf + (4 * (3 * (i) + (j)))) +#undef OUTW +#define OUTW(b, v) sph_enc32le(b, v) + /* + * Insert data by big chunks of 13*12 = 156 bytes. Returned value is the + * number of remaining bytes (between 0 and 155). This method assumes that + * the input data is suitably aligned. + */ +static size_t +radiogatun32_push13(sph_radiogatun32_context *sc, const void *data, size_t len) +{ + PUSH13; +} + /* see sph_radiogatun.h */ +void +sph_radiogatun32_init(void *cc) +{ + sph_radiogatun32_context *sc; + sc = cc; + INIT; +} + #ifdef SPH_UPTR +static void +radiogatun32_short(void *cc, const void *data, size_t len) +#else +/* see sph_radiogatun.h */ +void +sph_radiogatun32(void *cc, const void *data, size_t len) +#endif +{ + sph_radiogatun32_context *sc; + unsigned ptr; + sc = cc; + ptr = sc->data_ptr; + while (len > 0) { + size_t clen; + clen = (sizeof sc->data) - ptr; + if (clen > len) + clen = len; + memcpy(sc->data + ptr, data, clen); + data = (const unsigned char *)data + clen; + len -= clen; + ptr += clen; + if (ptr == sizeof sc->data) { + radiogatun32_push13(sc, sc->data, sizeof sc->data); + ptr = 0; + } + } + sc->data_ptr = ptr; +} + #ifdef SPH_UPTR +/* see sph_radiogatun.h */ +void +sph_radiogatun32(void *cc, const void *data, size_t len) +{ + sph_radiogatun32_context *sc; + unsigned ptr; + size_t rlen; + if (len < (2 * sizeof sc->data)) { + radiogatun32_short(cc, data, len); + return; + } + sc = cc; + ptr = sc->data_ptr; + if (ptr > 0) { + unsigned t; + t = (sizeof sc->data) - ptr; + radiogatun32_short(sc, data, t); + data = (const unsigned char *)data + t; + len -= t; + } +#if !SPH_UNALIGNED + if (((SPH_UPTR)data & 3) != 0) { + radiogatun32_short(sc, data, len); + return; + } +#endif + rlen = radiogatun32_push13(sc, data, len); + memcpy(sc->data, (const unsigned char *)data + len - rlen, rlen); + sc->data_ptr = rlen; +} +#endif + /* see sph_radiogatun.h */ +void +sph_radiogatun32_close(void *cc, void *dst) +{ + sph_radiogatun32_context *sc; + sc = cc; + CLOSE(32); +} + #endif + /* ======================================================================= */ +/* + * RadioGatun[64]. Compiled only if a 64-bit or more type is available. + */ + #if SPH_64 + #if !SPH_NO_RG64 + #undef WT +#define WT sph_u64 +#undef T +#define T SPH_T64 +#undef ROR +#define ROR(x, n) SPH_T64(((x) << ((64 - (n)) & 63)) | ((x) >> ((n) & 63))) +#undef INW +#define INW(i, j) sph_dec64le_aligned(buf + (8 * (3 * (i) + (j)))) +#undef OUTW +#define OUTW(b, v) sph_enc64le(b, v) + /* + * On 32-bit x86, register pressure is such that using the small + * footprint version is a net gain (x2 speed), because that variant + * uses fewer local variables. + */ +#if SPH_I386_MSVC || SPH_I386_GCC || defined __i386__ +#undef PUSH13 +#define PUSH13 PUSH13_SF +#undef CLOSE +#define CLOSE CLOSE_SF +#endif + /* + * Insert data by big chunks of 13*24 = 312 bytes. Returned value is the + * number of remaining bytes (between 0 and 311). This method assumes that + * the input data is suitably aligned. + */ +static size_t +radiogatun64_push13(sph_radiogatun64_context *sc, const void *data, size_t len) +{ + PUSH13; +} + /* see sph_radiogatun.h */ +void +sph_radiogatun64_init(void *cc) +{ + sph_radiogatun64_context *sc; + sc = cc; + INIT; +} + #ifdef SPH_UPTR +static void +radiogatun64_short(void *cc, const void *data, size_t len) +#else +/* see sph_radiogatun.h */ +void +sph_radiogatun64(void *cc, const void *data, size_t len) +#endif +{ + sph_radiogatun64_context *sc; + unsigned ptr; + sc = cc; + ptr = sc->data_ptr; + while (len > 0) { + size_t clen; + clen = (sizeof sc->data) - ptr; + if (clen > len) + clen = len; + memcpy(sc->data + ptr, data, clen); + data = (const unsigned char *)data + clen; + len -= clen; + ptr += clen; + if (ptr == sizeof sc->data) { + radiogatun64_push13(sc, sc->data, sizeof sc->data); + ptr = 0; + } + } + sc->data_ptr = ptr; +} + #ifdef SPH_UPTR +/* see sph_radiogatun.h */ +void +sph_radiogatun64(void *cc, const void *data, size_t len) +{ + sph_radiogatun64_context *sc; + unsigned ptr; + size_t rlen; + if (len < (2 * sizeof sc->data)) { + radiogatun64_short(cc, data, len); + return; + } + sc = cc; + ptr = sc->data_ptr; + if (ptr > 0) { + unsigned t; + t = (sizeof sc->data) - ptr; + radiogatun64_short(sc, data, t); + data = (const unsigned char *)data + t; + len -= t; + } +#if !SPH_UNALIGNED + if (((SPH_UPTR)data & 7) != 0) { + radiogatun64_short(sc, data, len); + return; + } +#endif + rlen = radiogatun64_push13(sc, data, len); + memcpy(sc->data, (const unsigned char *)data + len - rlen, rlen); + sc->data_ptr = rlen; +} +#endif + /* see sph_radiogatun.h */ +void +sph_radiogatun64_close(void *cc, void *dst) +{ + sph_radiogatun64_context *sc; + sc = cc; + CLOSE(64); +} + #endif + #endif diff --git a/stratum/sha3/sph_radiogatun.h b/stratum/sha3/sph_radiogatun.h new file mode 100644 index 000000000..b4e53494a --- /dev/null +++ b/stratum/sha3/sph_radiogatun.h @@ -0,0 +1,171 @@ +/* $Id: sph_radiogatun.h 226 2010-06-16 17:28:08Z tp $ */ +/** + * RadioGatun interface. + * + * RadioGatun has been published in: G. Bertoni, J. Daemen, M. Peeters + * and G. Van Assche, "RadioGatun, a belt-and-mill hash function", + * presented at the Second Cryptographic Hash Workshop, Santa Barbara, + * August 24-25, 2006. The main Web site, containing that article, the + * reference code and some test vectors, appears to be currently located + * at the following URL: http://radiogatun.noekeon.org/ + * + * The presentation article does not specify endianness or padding. The + * reference code uses the following conventions, which we also apply + * here: + *
    + *
  • The input message is an integral number of sequences of three + * words. Each word is either a 32-bit of 64-bit word (depending on + * the version of RadioGatun).
  • + *
  • Input bytes are decoded into words using little-endian + * convention.
  • + *
  • Padding consists of a single bit of value 1, using little-endian + * convention within bytes (i.e. for a byte-oriented input, a single + * byte of value 0x01 is appended), then enough bits of value 0 to finish + * the current block.
  • + *
  • Output consists of 256 bits. Successive output words are encoded + * with little-endian convention.
  • + *
+ * These conventions are very close to those we use for PANAMA, which is + * a close ancestor or RadioGatun. + * + * RadioGatun is actually a family of functions, depending on some + * internal parameters. We implement here two functions, with a "belt + * length" of 13, a "belt width" of 3, and a "mill length" of 19. The + * RadioGatun[32] version uses 32-bit words, while the RadioGatun[64] + * variant uses 64-bit words. + * + * Strictly speaking, the name "RadioGatun" should use an acute accent + * on the "u", which we omitted here to keep strict ASCII-compatibility + * of this file. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @file sph_radiogatun.h + * @author Thomas Pornin + */ + #ifndef SPH_RADIOGATUN_H__ +#define SPH_RADIOGATUN_H__ + #include +#include "sph_types.h" + /** + * Output size (in bits) for RadioGatun[32]. + */ +#define SPH_SIZE_radiogatun32 256 + /** + * This structure is a context for RadioGatun[32] computations: it + * contains intermediate values and some data from the last entered + * block. Once a RadioGatun[32] computation has been performed, the + * context can be reused for another computation. + * + * The contents of this structure are private. A running RadioGatun[32] + * computation can be cloned by copying the context (e.g. with a + * simple memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char data[156]; /* first field, for alignment */ + unsigned data_ptr; + sph_u32 a[19], b[39]; +#endif +} sph_radiogatun32_context; + /** + * Initialize a RadioGatun[32] context. This process performs no + * memory allocation. + * + * @param cc the RadioGatun[32] context (pointer to a + * sph_radiogatun32_context) + */ +void sph_radiogatun32_init(void *cc); + /** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the RadioGatun[32] context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_radiogatun32(void *cc, const void *data, size_t len); + /** + * Terminate the current RadioGatun[32] computation and output the + * result into the provided buffer. The destination buffer must be wide + * enough to accomodate the result (32 bytes). The context is + * automatically reinitialized. + * + * @param cc the RadioGatun[32] context + * @param dst the destination buffer + */ +void sph_radiogatun32_close(void *cc, void *dst); + #if SPH_64 + /** + * Output size (in bits) for RadioGatun[64]. + */ +#define SPH_SIZE_radiogatun64 256 + /** + * This structure is a context for RadioGatun[64] computations: it + * contains intermediate values and some data from the last entered + * block. Once a RadioGatun[64] computation has been performed, the + * context can be reused for another computation. + * + * The contents of this structure are private. A running RadioGatun[64] + * computation can be cloned by copying the context (e.g. with a + * simple memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char data[312]; /* first field, for alignment */ + unsigned data_ptr; + sph_u64 a[19], b[39]; +#endif +} sph_radiogatun64_context; + /** + * Initialize a RadioGatun[64] context. This process performs no + * memory allocation. + * + * @param cc the RadioGatun[64] context (pointer to a + * sph_radiogatun64_context) + */ +void sph_radiogatun64_init(void *cc); + /** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the RadioGatun[64] context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_radiogatun64(void *cc, const void *data, size_t len); + /** + * Terminate the current RadioGatun[64] computation and output the + * result into the provided buffer. The destination buffer must be wide + * enough to accomodate the result (32 bytes). The context is + * automatically reinitialized. + * + * @param cc the RadioGatun[64] context + * @param dst the destination buffer + */ +void sph_radiogatun64_close(void *cc, void *dst); + #endif + #endif diff --git a/stratum/sha3/sph_sm3.c b/stratum/sha3/sph_sm3.c new file mode 100644 index 000000000..e5c580568 --- /dev/null +++ b/stratum/sha3/sph_sm3.c @@ -0,0 +1,226 @@ +/* ==================================================================== + * Copyright (c) 2014 - 2017 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include "sph_sm3.h" + +void sm3_init(sm3_ctx_t *ctx) +{ + ctx->digest[0] = 0x7380166F; + ctx->digest[1] = 0x4914B2B9; + ctx->digest[2] = 0x172442D7; + ctx->digest[3] = 0xDA8A0600; + ctx->digest[4] = 0xA96F30BC; + ctx->digest[5] = 0x163138AA; + ctx->digest[6] = 0xE38DEE4D; + ctx->digest[7] = 0xB0FB0E4E; + + ctx->nblocks = 0; + ctx->num = 0; +} + +void +sph_sm3(void *cc, const void *data, size_t len) +{ + sm3_update(cc, data, len); +} + +void sm3_update(sm3_ctx_t *ctx, const unsigned char* data, size_t data_len) +{ + if (ctx->num) { + unsigned int left = SM3_BLOCK_SIZE - ctx->num; + if (data_len < left) { + memcpy(ctx->block + ctx->num, data, data_len); + ctx->num += data_len; + return; + } else { + memcpy(ctx->block + ctx->num, data, left); + sm3_compress(ctx->digest, ctx->block); + ctx->nblocks++; + data += left; + data_len -= left; + } + } + while (data_len >= SM3_BLOCK_SIZE) { + sm3_compress(ctx->digest, data); + ctx->nblocks++; + data += SM3_BLOCK_SIZE; + data_len -= SM3_BLOCK_SIZE; + } + ctx->num = data_len; + if (data_len) { + memcpy(ctx->block, data, data_len); + } +} + +void +sph_sm3_close(void *cc, void *dst) +{ + sm3_final(cc, dst); + memset(cc, 0, sizeof(sm3_ctx_t)); +} + +void sm3_final(sm3_ctx_t *ctx, unsigned char *digest) +{ + int i; + uint32_t *pdigest = (uint32_t *)digest; + uint32_t *count = (uint32_t *)(ctx->block + SM3_BLOCK_SIZE - 8); + + ctx->block[ctx->num] = 0x80; + + if (ctx->num + 9 <= SM3_BLOCK_SIZE) { + memset(ctx->block + ctx->num + 1, 0, SM3_BLOCK_SIZE - ctx->num - 9); + } else { + memset(ctx->block + ctx->num + 1, 0, SM3_BLOCK_SIZE - ctx->num - 1); + sm3_compress(ctx->digest, ctx->block); + memset(ctx->block, 0, SM3_BLOCK_SIZE - 8); + } + + count[0] = cpu_to_be32((ctx->nblocks) >> 23); + count[1] = cpu_to_be32((ctx->nblocks << 9) + (ctx->num << 3)); + + sm3_compress(ctx->digest, ctx->block); + for (i = 0; i < sizeof(ctx->digest)/sizeof(ctx->digest[0]); i++) { + pdigest[i] = cpu_to_be32(ctx->digest[i]); + } +} + +#define ROTATELEFT(X,n) (((X)<<(n)) | ((X)>>(32-(n)))) + +#define P0(x) ((x) ^ ROTATELEFT((x),9) ^ ROTATELEFT((x),17)) +#define P1(x) ((x) ^ ROTATELEFT((x),15) ^ ROTATELEFT((x),23)) + +#define FF0(x,y,z) ( (x) ^ (y) ^ (z)) +#define FF1(x,y,z) (((x) & (y)) | ( (x) & (z)) | ( (y) & (z))) + +#define GG0(x,y,z) ( (x) ^ (y) ^ (z)) +#define GG1(x,y,z) (((x) & (y)) | ( (~(x)) & (z)) ) + + +void sm3_compress(uint32_t digest[8], const unsigned char block[64]) +{ + int j; + uint32_t W[68], W1[64]; + const uint32_t *pblock = (const uint32_t *)block; + + uint32_t A = digest[0]; + uint32_t B = digest[1]; + uint32_t C = digest[2]; + uint32_t D = digest[3]; + uint32_t E = digest[4]; + uint32_t F = digest[5]; + uint32_t G = digest[6]; + uint32_t H = digest[7]; + uint32_t SS1,SS2,TT1,TT2,T[64]; + + for (j = 0; j < 16; j++) { + W[j] = cpu_to_be32(pblock[j]); + } + for (j = 16; j < 68; j++) { + W[j] = P1( W[j-16] ^ W[j-9] ^ ROTATELEFT(W[j-3],15)) ^ ROTATELEFT(W[j - 13],7 ) ^ W[j-6];; + } + for( j = 0; j < 64; j++) { + W1[j] = W[j] ^ W[j+4]; + } + + for(j =0; j < 16; j++) { + + T[j] = 0x79CC4519; + SS1 = ROTATELEFT((ROTATELEFT(A,12) + E + ROTATELEFT(T[j],j)), 7); + SS2 = SS1 ^ ROTATELEFT(A,12); + TT1 = FF0(A,B,C) + D + SS2 + W1[j]; + TT2 = GG0(E,F,G) + H + SS1 + W[j]; + D = C; + C = ROTATELEFT(B,9); + B = A; + A = TT1; + H = G; + G = ROTATELEFT(F,19); + F = E; + E = P0(TT2); + } + + for(j =16; j < 64; j++) { + + T[j] = 0x7A879D8A; + SS1 = ROTATELEFT((ROTATELEFT(A,12) + E + ROTATELEFT(T[j],j)), 7); + SS2 = SS1 ^ ROTATELEFT(A,12); + TT1 = FF1(A,B,C) + D + SS2 + W1[j]; + TT2 = GG1(E,F,G) + H + SS1 + W[j]; + D = C; + C = ROTATELEFT(B,9); + B = A; + A = TT1; + H = G; + G = ROTATELEFT(F,19); + F = E; + E = P0(TT2); + } + + digest[0] ^= A; + digest[1] ^= B; + digest[2] ^= C; + digest[3] ^= D; + digest[4] ^= E; + digest[5] ^= F; + digest[6] ^= G; + digest[7] ^= H; +} + +void sm3(const unsigned char *msg, size_t msglen, + unsigned char dgst[SM3_DIGEST_LENGTH]) +{ + sm3_ctx_t ctx; + + sm3_init(&ctx); + sm3_update(&ctx, msg, msglen); + sm3_final(&ctx, dgst); + + memset(&ctx, 0, sizeof(sm3_ctx_t)); +} diff --git a/stratum/sha3/sph_sm3.h b/stratum/sha3/sph_sm3.h new file mode 100644 index 000000000..eab61d363 --- /dev/null +++ b/stratum/sha3/sph_sm3.h @@ -0,0 +1,120 @@ +/* ==================================================================== + * Copyright (c) 2014 - 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef SPH_SM3_H +#define SPH_SM3_H + +#define SM3_DIGEST_LENGTH 32 +#define SM3_BLOCK_SIZE 64 +#define SM3_CBLOCK (SM3_BLOCK_SIZE) +#define SM3_HMAC_SIZE (SM3_DIGEST_LENGTH) + + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct { + uint32_t digest[8]; + int nblocks; + unsigned char block[64]; + int num; +} sm3_ctx_t; + +void sm3_init(sm3_ctx_t *ctx); +void sm3_update(sm3_ctx_t *ctx, const unsigned char* data, size_t data_len); +void sm3_final(sm3_ctx_t *ctx, unsigned char digest[SM3_DIGEST_LENGTH]); +void sm3_compress(uint32_t digest[8], const unsigned char block[SM3_BLOCK_SIZE]); +void sm3(const unsigned char *data, size_t datalen, + unsigned char digest[SM3_DIGEST_LENGTH]); + +void sph_sm3(void *cc, const void *data, size_t len); +void sph_sm3_close(void *cc, void *dst); + +typedef struct { + sm3_ctx_t sm3_ctx; + unsigned char key[SM3_BLOCK_SIZE]; +} sm3_hmac_ctx_t; + +void sm3_hmac_init(sm3_hmac_ctx_t *ctx, const unsigned char *key, size_t key_len); +void sm3_hmac_update(sm3_hmac_ctx_t *ctx, const unsigned char *data, size_t data_len); +void sm3_hmac_final(sm3_hmac_ctx_t *ctx, unsigned char mac[SM3_HMAC_SIZE]); +void sm3_hmac(const unsigned char *data, size_t data_len, + const unsigned char *key, size_t key_len, unsigned char mac[SM3_HMAC_SIZE]); + +#ifdef CPU_BIGENDIAN + +#define cpu_to_be16(v) (v) +#define cpu_to_be32(v) (v) +#define be16_to_cpu(v) (v) +#define be32_to_cpu(v) (v) + +#else + +#define cpu_to_le16(v) (v) +#define cpu_to_le32(v) (v) +#define le16_to_cpu(v) (v) +#define le32_to_cpu(v) (v) + +#define cpu_to_be16(v) (((v)<< 8) | ((v)>>8)) +#define cpu_to_be32(v) (((v)>>24) | (((v)>>8)&0xff00) | (((v)<<8)&0xff0000) | ((v)<<24)) +#define be16_to_cpu(v) cpu_to_be16(v) +#define be32_to_cpu(v) cpu_to_be32(v) + +#endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/stratum/sha3/sph_streebog.c b/stratum/sha3/sph_streebog.c new file mode 100644 index 000000000..dbae4e54b --- /dev/null +++ b/stratum/sha3/sph_streebog.c @@ -0,0 +1,1045 @@ +/* Streebog GOST hash function for sib algo SibCoin */ + +#include +#include +#include +#include + +#include "sph_streebog.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +#ifdef _MSC_VER +#pragma warning (disable: 4146) +#endif + +//-------------------------------------------------------------------------------------------- +// +// Streebog 512 implementation +// +//-------------------------------------------------------------------------------------------- + + +// Tables for function F +static const sph_u64 TG[8][256] = {{ + 0xE6F87E5C5B711FD0,0x258377800924FA16,0xC849E07E852EA4A8,0x5B4686A18F06C16A, + 0x0B32E9A2D77B416E,0xABDA37A467815C66,0xF61796A81A686676,0xF5DC0B706391954B, + 0x4862F38DB7E64BF1,0xFF5C629A68BD85C5,0xCB827DA6FCD75795,0x66D36DAF69B9F089, + 0x356C9F74483D83B0,0x7CBCECB1238C99A1,0x36A702AC31C4708D,0x9EB6A8D02FBCDFD6, + 0x8B19FA51E5B3AE37,0x9CCFB5408A127D0B,0xBC0C78B508208F5A,0xE533E3842288ECED, + 0xCEC2C7D377C15FD2,0xEC7817B6505D0F5E,0xB94CC2C08336871D,0x8C205DB4CB0B04AD, + 0x763C855B28A0892F,0x588D1B79F6FF3257,0x3FECF69E4311933E,0x0FC0D39F803A18C9, + 0xEE010A26F5F3AD83,0x10EFE8F4411979A6,0x5DCDA10C7DE93A10,0x4A1BEE1D1248E92C, + 0x53BFF2DB21847339,0xB4F50CCFA6A23D09,0x5FB4BC9CD84798CD,0xE88A2D8B071C56F9, + 0x7F7771695A756A9C,0xC5F02E71A0BA1EBC,0xA663F9AB4215E672,0x2EB19E22DE5FBB78, + 0x0DB9CE0F2594BA14,0x82520E6397664D84,0x2F031E6A0208EA98,0x5C7F2144A1BE6BF0, + 0x7A37CB1CD16362DB,0x83E08E2B4B311C64,0xCF70479BAB960E32,0x856BA986B9DEE71E, + 0xB5478C877AF56CE9,0xB8FE42885F61D6FD,0x1BDD0156966238C8,0x622157923EF8A92E, + 0xFC97FF42114476F8,0x9D7D350856452CEB,0x4C90C9B0E0A71256,0x2308502DFBCB016C, + 0x2D7A03FAA7A64845,0xF46E8B38BFC6C4AB,0xBDBEF8FDD477DEBA,0x3AAC4CEBC8079B79, + 0xF09CB105E8879D0C,0x27FA6A10AC8A58CB,0x8960E7C1401D0CEA,0x1A6F811E4A356928, + 0x90C4FB0773D196FF,0x43501A2F609D0A9F,0xF7A516E0C63F3796,0x1CE4A6B3B8DA9252, + 0x1324752C38E08A9B,0xA5A864733BEC154F,0x2BF124575549B33F,0xD766DB15440DC5C7, + 0xA7D179E39E42B792,0xDADF151A61997FD3,0x86A0345EC0271423,0x38D5517B6DA939A4, + 0x6518F077104003B4,0x02791D90A5AEA2DD,0x88D267899C4A5D0A,0x930F66DF0A2865C2, + 0x4EE9D4204509B08B,0x325538916685292A,0x412907BFC533A842,0xB27E2B62544DC673, + 0x6C5304456295E007,0x5AF406E95351908A,0x1F2F3B6BC123616F,0xC37B09DC5255E5C6, + 0x3967D133B1FE6844,0x298839C7F0E711E2,0x409B87F71964F9A2,0xE938ADC3DB4B0719, + 0x0C0B4E47F9C3EBF4,0x5534D576D36B8843,0x4610A05AEB8B02D8,0x20C3CDF58232F251, + 0x6DE1840DBEC2B1E7,0xA0E8DE06B0FA1D08,0x7B854B540D34333B,0x42E29A67BCCA5B7F, + 0xD8A6088AC437DD0E,0xC63BB3A9D943ED81,0x21714DBD5E65A3B1,0x6761EDE7B5EEA169, + 0x2431F7C8D573ABF6,0xD51FC685E1A3671A,0x5E063CD40410C92D,0x283AB98F2CB04002, + 0x8FEBC06CB2F2F790,0x17D64F116FA1D33C,0xE07359F1A99EE4AA,0x784ED68C74CDC006, + 0x6E2A19D5C73B42DA,0x8712B4161C7045C3,0x371582E4ED93216D,0xACE390414939F6FC, + 0x7EC5F12186223B7C,0xC0B094042BAC16FB,0xF9D745379A527EBF,0x737C3F2EA3B68168, + 0x33E7B8D9BAD278CA,0xA9A32A34C22FFEBB,0xE48163CCFEDFBD0D,0x8E5940246EA5A670, + 0x51C6EF4B842AD1E4,0x22BAD065279C508C,0xD91488C218608CEE,0x319EA5491F7CDA17, + 0xD394E128134C9C60,0x094BF43272D5E3B3,0x9BF612A5A4AAD791,0xCCBBDA43D26FFD0F, + 0x34DE1F3C946AD250,0x4F5B5468995EE16B,0xDF9FAF6FEA8F7794,0x2648EA5870DD092B, + 0xBFC7E56D71D97C67,0xDDE6B2FF4F21D549,0x3C276B463AE86003,0x91767B4FAF86C71F, + 0x68A13E7835D4B9A0,0xB68C115F030C9FD4,0x141DD2C916582001,0x983D8F7DDD5324AC, + 0x64AA703FCC175254,0xC2C989948E02B426,0x3E5E76D69F46C2DE,0x50746F03587D8004, + 0x45DB3D829272F1E5,0x60584A029B560BF3,0xFBAE58A73FFCDC62,0xA15A5E4E6CAD4CE8, + 0x4BA96E55CE1FB8CC,0x08F9747AAE82B253,0xC102144CF7FB471B,0x9F042898F3EB8E36, + 0x068B27ADF2EFFB7A,0xEDCA97FE8C0A5EBE,0x778E0513F4F7D8CF,0x302C2501C32B8BF7, + 0x8D92DDFC175C554D,0xF865C57F46052F5F,0xEAF3301BA2B2F424,0xAA68B7ECBBD60D86, + 0x998F0F350104754C,0x0000000000000000,0xF12E314D34D0CCEC,0x710522BE061823B5, + 0xAF280D9930C005C1,0x97FD5CE25D693C65,0x19A41CC633CC9A15,0x95844172F8C79EB8, + 0xDC5432B7937684A9,0x9436C13A2490CF58,0x802B13F332C8EF59,0xC442AE397CED4F5C, + 0xFA1CD8EFE3AB8D82,0xF2E5AC954D293FD1,0x6AD823E8907A1B7D,0x4D2249F83CF043B6, + 0x03CB9DD879F9F33D,0xDE2D2F2736D82674,0x2A43A41F891EE2DF,0x6F98999D1B6C133A, + 0xD4AD46CD3DF436FA,0xBB35DF50269825C0,0x964FDCAA813E6D85,0xEB41B0537EE5A5C4, + 0x0540BA758B160847,0xA41AE43BE7BB44AF,0xE3B8C429D0671797,0x819993BBEE9FBEB9, + 0xAE9A8DD1EC975421,0xF3572CDD917E6E31,0x6393D7DAE2AFF8CE,0x47A2201237DC5338, + 0xA32343DEC903EE35,0x79FC56C4A89A91E6,0x01B28048DC5751E0,0x1296F564E4B7DB7B, + 0x75F7188351597A12,0xDB6D9552BDCE2E33,0x1E9DBB231D74308F,0x520D7293FDD322D9, + 0xE20A44610C304677,0xFEEEE2D2B4EAD425,0xCA30FDEE20800675,0x61EACA4A47015A13, + 0xE74AFE1487264E30,0x2CC883B27BF119A5,0x1664CF59B3F682DC,0xA811AA7C1E78AF5B, + 0x1D5626FB648DC3B2,0xB73E9117DF5BCE34,0xD05F7CF06AB56F5D,0xFD257F0ACD132718, + 0x574DC8E676C52A9E,0x0739A7E52EB8AA9A,0x5486553E0F3CD9A3,0x56FF48AEAA927B7E, + 0xBE756525AD8E2D87,0x7D0E6CF9FFDBC841,0x3B1ECCA31450CA99,0x6913BE30E983E840, + 0xAD511009956EA71C,0xB1B5B6BA2DB4354E,0x4469BDCA4E25A005,0x15AF5281CA0F71E1, + 0x744598CB8D0E2BF2,0x593F9B312AA863B7,0xEFB38A6E29A4FC63,0x6B6AA3A04C2D4A9D, + 0x3D95EB0EE6BF31E3,0xA291C3961554BFD5,0x18169C8EEF9BCBF5,0x115D68BC9D4E2846, + 0xBA875F18FACF7420,0xD1EDFCB8B6E23EBD,0xB00736F2F1E364AE,0x84D929CE6589B6FE, + 0x70B7A2F6DA4F7255,0x0E7253D75C6D4929,0x04F23A3D574159A7,0x0A8069EA0B2C108E, + 0x49D073C56BB11A11,0x8AAB7A1939E4FFD7,0xCD095A0B0E38ACEF,0xC9FB60365979F548, + 0x92BDE697D67F3422,0xC78933E10514BC61,0xE1C1D9B975C9B54A,0xD2266160CF1BCD80, + 0x9A4492ED78FD8671,0xB3CCAB2A881A9793,0x72CEBF667FE1D088,0xD6D45B5D985A9427 +},{ + 0xC811A8058C3F55DE,0x65F5B43196B50619,0xF74F96B1D6706E43,0x859D1E8BCB43D336, + 0x5AAB8A85CCFA3D84,0xF9C7BF99C295FCFD,0xA21FD5A1DE4B630F,0xCDB3EF763B8B456D, + 0x803F59F87CF7C385,0xB27C73BE5F31913C,0x98E3AC6633B04821,0xBF61674C26B8F818, + 0x0FFBC995C4C130C8,0xAAA0862010761A98,0x6057F342210116AA,0xF63C760C0654CC35, + 0x2DDB45CC667D9042,0xBCF45A964BD40382,0x68E8A0C3EF3C6F3D,0xA7BD92D269FF73BC, + 0x290AE20201ED2287,0xB7DE34CDE885818F,0xD901EEA7DD61059B,0xD6FA273219A03553, + 0xD56F1AE874CCCEC9,0xEA31245C2E83F554,0x7034555DA07BE499,0xCE26D2AC56E7BEF7, + 0xFD161857A5054E38,0x6A0E7DA4527436D1,0x5BD86A381CDE9FF2,0xCAF7756231770C32, + 0xB09AAED9E279C8D0,0x5DEF1091C60674DB,0x111046A2515E5045,0x23536CE4729802FC, + 0xC50CBCF7F5B63CFA,0x73A16887CD171F03,0x7D2941AFD9F28DBD,0x3F5E3EB45A4F3B9D, + 0x84EEFE361B677140,0x3DB8E3D3E7076271,0x1A3A28F9F20FD248,0x7EBC7C75B49E7627, + 0x74E5F293C7EB565C,0x18DCF59E4F478BA4,0x0C6EF44FA9ADCB52,0xC699812D98DAC760, + 0x788B06DC6E469D0E,0xFC65F8EA7521EC4E,0x30A5F7219E8E0B55,0x2BEC3F65BCA57B6B, + 0xDDD04969BAF1B75E,0x99904CDBE394EA57,0x14B201D1E6EA40F6,0xBBB0C08241284ADD, + 0x50F20463BF8F1DFF,0xE8D7F93B93CBACB8,0x4D8CB68E477C86E8,0xC1DD1B3992268E3F, + 0x7C5AA11209D62FCB,0x2F3D98ABDB35C9AE,0x671369562BFD5FF5,0x15C1E16C36CEE280, + 0x1D7EB2EDF8F39B17,0xDA94D37DB00DFE01,0x877BC3EC760B8ADA,0xCB8495DFE153AE44, + 0x05A24773B7B410B3,0x12857B783C32ABDF,0x8EB770D06812513B,0x536739B9D2E3E665, + 0x584D57E271B26468,0xD789C78FC9849725,0xA935BBFA7D1AE102,0x8B1537A3DFA64188, + 0xD0CD5D9BC378DE7A,0x4AC82C9A4D80CFB7,0x42777F1B83BDB620,0x72D2883A1D33BD75, + 0x5E7A2D4BAB6A8F41,0xF4DAAB6BBB1C95D9,0x905CFFE7FD8D31B6,0x83AA6422119B381F, + 0xC0AEFB8442022C49,0xA0F908C663033AE3,0xA428AF0804938826,0xADE41C341A8A53C7, + 0xAE7121EE77E6A85D,0xC47F5C4A25929E8C,0xB538E9AA55CDD863,0x06377AA9DAD8EB29, + 0xA18AE87BB3279895,0x6EDFDA6A35E48414,0x6B7D9D19825094A7,0xD41CFA55A4E86CBF, + 0xE5CAEDC9EA42C59C,0xA36C351C0E6FC179,0x5181E4DE6FABBF89,0xFFF0C530184D17D4, + 0x9D41EB1584045892,0x1C0D525028D73961,0xF178EC180CA8856A,0x9A0571018EF811CD, + 0x4091A27C3EF5EFCC,0x19AF15239F6329D2,0x347450EFF91EB990,0xE11B4A078DD27759, + 0xB9561DE5FC601331,0x912F1F5A2DA993C0,0x1654DCB65BA2191A,0x3E2DDE098A6B99EB, + 0x8A66D71E0F82E3FE,0x8C51ADB7D55A08D7,0x4533E50F8941FF7F,0x02E6DD67BD4859EC, + 0xE068AABA5DF6D52F,0xC24826E3FF4A75A5,0x6C39070D88ACDDF8,0x6486548C4691A46F, + 0xD1BEBD26135C7C0C,0xB30F93038F15334A,0x82D9849FC1BF9A69,0x9C320BA85420FAE4, + 0xFA528243AFF90767,0x9ED4D6CFE968A308,0xB825FD582C44B147,0x9B7691BC5EDCB3BB, + 0xC7EA619048FE6516,0x1063A61F817AF233,0x47D538683409A693,0x63C2CE984C6DED30, + 0x2A9FDFD86C81D91D,0x7B1E3B06032A6694,0x666089EBFBD9FD83,0x0A598EE67375207B, + 0x07449A140AFC495F,0x2CA8A571B6593234,0x1F986F8A45BBC2FB,0x381AA4A050B372C2, + 0x5423A3ADD81FAF3A,0x17273C0B8B86BB6C,0xFE83258DC869B5A2,0x287902BFD1C980F1, + 0xF5A94BD66B3837AF,0x88800A79B2CABA12,0x55504310083B0D4C,0xDF36940E07B9EEB2, + 0x04D1A7CE6790B2C5,0x612413FFF125B4DC,0x26F12B97C52C124F,0x86082351A62F28AC, + 0xEF93632F9937E5E7,0x3507B052293A1BE6,0xE72C30AE570A9C70,0xD3586041AE1425E0, + 0xDE4574B3D79D4CC4,0x92BA228040C5685A,0xF00B0CA5DC8C271C,0xBE1287F1F69C5A6E, + 0xF39E317FB1E0DC86,0x495D114020EC342D,0x699B407E3F18CD4B,0xDCA3A9D46AD51528, + 0x0D1D14F279896924,0x0000000000000000,0x593EB75FA196C61E,0x2E4E78160B116BD8, + 0x6D4AE7B058887F8E,0xE65FD013872E3E06,0x7A6DDBBBD30EC4E2,0xAC97FC89CAAEF1B1, + 0x09CCB33C1E19DBE1,0x89F3EAC462EE1864,0x7770CF49AA87ADC6,0x56C57ECA6557F6D6, + 0x03953DDA6D6CFB9A,0x36928D884456E07C,0x1EEB8F37959F608D,0x31D6179C4EAAA923, + 0x6FAC3AD7E5C02662,0x43049FA653991456,0xABD3669DC052B8EE,0xAF02C153A7C20A2B, + 0x3CCB036E3723C007,0x93C9C23D90E1CA2C,0xC33BC65E2F6ED7D3,0x4CFF56339758249E, + 0xB1E94E64325D6AA6,0x37E16D359472420A,0x79F8E661BE623F78,0x5214D90402C74413, + 0x482EF1FDF0C8965B,0x13F69BC5EC1609A9,0x0E88292814E592BE,0x4E198B542A107D72, + 0xCCC00FCBEBAFE71B,0x1B49C844222B703E,0x2564164DA840E9D5,0x20C6513E1FF4F966, + 0xBAC3203F910CE8AB,0xF2EDD1C261C47EF0,0x814CB945ACD361F3,0x95FEB8944A392105, + 0x5C9CF02C1622D6AD,0x971865F3F77178E9,0xBD87BA2B9BF0A1F4,0x444005B259655D09, + 0xED75BE48247FBC0B,0x7596122E17CFF42A,0xB44B091785E97A15,0x966B854E2755DA9F, + 0xEEE0839249134791,0x32432A4623C652B9,0xA8465B47AD3E4374,0xF8B45F2412B15E8B, + 0x2417F6F078644BA3,0xFB2162FE7FDDA511,0x4BBBCC279DA46DC1,0x0173E0BDD024A276, + 0x22208C59A2BCA08A,0x8FC4906DB836F34D,0xE4B90D743A6667EA,0x7147B5E0705F46EF, + 0x2782CB2A1508B039,0xEC065EF5F45B1E7D,0x21B5B183CFD05B10,0xDBE733C060295C77, + 0x9FA73672394C017E,0xCF55321186C31C81,0xD8720E1A0D45A7ED,0x3B8F997A3DDF8958, + 0x3AFC79C7EDFB2B2E,0xE9A4198643EF0ECE,0x5F09CDF67B4E2D37,0x4F6A6BE9FA34DF04, + 0xB6ADD47038A123F9,0x8D224D0A057EAAA1,0xC96248B85C1BF7A8,0xE3FD9760309A2EB5, + 0x0B2A6E5BA351820D,0xEB42C4E1FEA75722,0x948D58299A1D8373,0x7FCF9CC864BAD451, + 0xA55B4FB5D4B72A50,0x08BF5381CE3D7997,0x46A6D8D5E42D04E5,0xD22B80FC7E308796, + 0x57B69E77B57354A0,0x3969441D8097D0B4,0x3330CAFBF3E2F0CF,0xE28E77DDE0BE8CC3, + 0x62B12E259C494F46,0xA6CE726FB9DBD1CA,0x41E242C1EED14DBA,0x76032FF47AA30FB0 +},{ + 0x45B268A93ACDE4CC,0xAF7F0BE884549D08,0x048354B3C1468263,0x925435C2C80EFED2, + 0xEE4E37F27FDFFBA7,0x167A33920C60F14D,0xFB123B52EA03E584,0x4A0CAB53FDBB9007, + 0x9DEAF6380F788A19,0xCB48EC558F0CB32A,0xB59DC4B2D6FEF7E0,0xDCDBCA22F4F3ECB6, + 0x11DF5813549A9C40,0xE33FDEDF568ACED3,0xA0C1C8124322E9C3,0x07A56B8158FA6D0D, + 0x77279579B1E1F3DD,0xD9B18B74422AC004,0xB8EC2D9FFFABC294,0xF4ACF8A82D75914F, + 0x7BBF69B1EF2B6878,0xC4F62FAF487AC7E1,0x76CE809CC67E5D0C,0x6711D88F92E4C14C, + 0x627B99D9243DEDFE,0x234AA5C3DFB68B51,0x909B1F15262DBF6D,0x4F66EA054B62BCB5, + 0x1AE2CF5A52AA6AE8,0xBEA053FBD0CE0148,0xED6808C0E66314C9,0x43FE16CD15A82710, + 0xCD049231A06970F6,0xE7BC8A6C97CC4CB0,0x337CE835FCB3B9C0,0x65DEF2587CC780F3, + 0x52214EDE4132BB50,0x95F15E4390F493DF,0x870839625DD2E0F1,0x41313C1AFB8B66AF, + 0x91720AF051B211BC,0x477D427ED4EEA573,0x2E3B4CEEF6E3BE25,0x82627834EB0BCC43, + 0x9C03E3DD78E724C8,0x2877328AD9867DF9,0x14B51945E243B0F2,0x574B0F88F7EB97E2, + 0x88B6FA989AA4943A,0x19C4F068CB168586,0x50EE6409AF11FAEF,0x7DF317D5C04EABA4, + 0x7A567C5498B4C6A9,0xB6BBFB804F42188E,0x3CC22BCF3BC5CD0B,0xD04336EAAA397713, + 0xF02FAC1BEC33132C,0x2506DBA7F0D3488D,0xD7E65D6BF2C31A1E,0x5EB9B2161FF820F5, + 0x842E0650C46E0F9F,0x716BEB1D9E843001,0xA933758CAB315ED4,0x3FE414FDA2792265, + 0x27C9F1701EF00932,0x73A4C1CA70A771BE,0x94184BA6E76B3D0E,0x40D829FF8C14C87E, + 0x0FBEC3FAC77674CB,0x3616A9634A6A9572,0x8F139119C25EF937,0xF545ED4D5AEA3F9E, + 0xE802499650BA387B,0x6437E7BD0B582E22,0xE6559F89E053E261,0x80AD52E305288DFC, + 0x6DC55A23E34B9935,0xDE14E0F51AD0AD09,0xC6390578A659865E,0x96D7617109487CB1, + 0xE2D6CB3A21156002,0x01E915E5779FAED1,0xADB0213F6A77DCB7,0x9880B76EB9A1A6AB, + 0x5D9F8D248644CF9B,0xFD5E4536C5662658,0xF1C6B9FE9BACBDFD,0xEACD6341BE9979C4, + 0xEFA7221708405576,0x510771ECD88E543E,0xC2BA51CB671F043D,0x0AD482AC71AF5879, + 0xFE787A045CDAC936,0xB238AF338E049AED,0xBD866CC94972EE26,0x615DA6EBBD810290, + 0x3295FDD08B2C1711,0xF834046073BF0AEA,0xF3099329758FFC42,0x1CAEB13E7DCFA934, + 0xBA2307481188832B,0x24EFCE42874CE65C,0x0E57D61FB0E9DA1A,0xB3D1BAD6F99B343C, + 0xC0757B1C893C4582,0x2B510DB8403A9297,0x5C7698C1F1DB614A,0x3E0D0118D5E68CB4, + 0xD60F488E855CB4CF,0xAE961E0DF3CB33D9,0x3A8E55AB14A00ED7,0x42170328623789C1, + 0x838B6DD19C946292,0x895FEF7DED3B3AEB,0xCFCBB8E64E4A3149,0x064C7E642F65C3DC, + 0x3D2B3E2A4C5A63DA,0x5BD3F340A9210C47,0xB474D157A1615931,0xAC5934DA1DE87266, + 0x6EE365117AF7765B,0xC86ED36716B05C44,0x9BA6885C201D49C5,0xB905387A88346C45, + 0x131072C4BAB9DDFF,0xBF49461EA751AF99,0xD52977BC1CE05BA1,0xB0F785E46027DB52, + 0x546D30BA6E57788C,0x305AD707650F56AE,0xC987C682612FF295,0xA5AB8944F5FBC571, + 0x7ED528E759F244CA,0x8DDCBBCE2C7DB888,0xAA154ABE328DB1BA,0x1E619BE993ECE88B, + 0x09F2BD9EE813B717,0x7401AA4B285D1CB3,0x21858F143195CAEE,0x48C381841398D1B8, + 0xFCB750D3B2F98889,0x39A86A998D1CE1B9,0x1F888E0CE473465A,0x7899568376978716, + 0x02CF2AD7EE2341BF,0x85C713B5B3F1A14E,0xFF916FE12B4567E7,0x7C1A0230B7D10575, + 0x0C98FCC85ECA9BA5,0xA3E7F720DA9E06AD,0x6A6031A2BBB1F438,0x973E74947ED7D260, + 0x2CF4663918C0FF9A,0x5F50A7F368678E24,0x34D983B4A449D4CD,0x68AF1B755592B587, + 0x7F3C3D022E6DEA1B,0xABFC5F5B45121F6B,0x0D71E92D29553574,0xDFFDF5106D4F03D8, + 0x081BA87B9F8C19C6,0xDB7EA1A3AC0981BB,0xBBCA12AD66172DFA,0x79704366010829C7, + 0x179326777BFF5F9C,0x0000000000000000,0xEB2476A4C906D715,0x724DD42F0738DF6F, + 0xB752EE6538DDB65F,0x37FFBC863DF53BA3,0x8EFA84FCB5C157E6,0xE9EB5C73272596AA, + 0x1B0BDABF2535C439,0x86E12C872A4D4E20,0x9969A28BCE3E087A,0xFAFB2EB79D9C4B55, + 0x056A4156B6D92CB2,0x5A3AE6A5DEBEA296,0x22A3B026A8292580,0x53C85B3B36AD1581, + 0xB11E900117B87583,0xC51F3A4A3FE56930,0xE019E1EDCF3621BD,0xEC811D2591FCBA18, + 0x445B7D4C4D524A1D,0xA8DA6069DCAEF005,0x58F5CC72309DE329,0xD4C062596B7FF570, + 0xCE22AD0339D59F98,0x591CD99747024DF8,0x8B90C5AA03187B54,0xF663D27FC356D0F0, + 0xD8589E9135B56ED5,0x35309651D3D67A1C,0x12F96721CD26732E,0xD28C1C3D441A36AC, + 0x492A946164077F69,0x2D1D73DC6F5F514B,0x6F0A70F40D68D88A,0x60B4B30ECA1EAC41, + 0xD36509D83385987D,0x0B3D97490630F6A8,0x9ECCC90A96C46577,0xA20EE2C5AD01A87C, + 0xE49AB55E0E70A3DE,0xA4429CA182646BA0,0xDA97B446DB962F6A,0xCCED87D4D7F6DE27, + 0x2AB8185D37A53C46,0x9F25DCEFE15BCBA6,0xC19C6EF9FEA3EB53,0xA764A3931BD884CE, + 0x2FD2590B817C10F4,0x56A21A6D80743933,0xE573A0BB79EF0D0F,0x155C0CA095DC1E23, + 0x6C2C4FC694D437E4,0x10364DF623053291,0xDD32DFC7836C4267,0x03263F3299BCEF6E, + 0x66F8CD6AE57B6F9D,0x8C35AE2B5BE21659,0x31B3C2E21290F87F,0x93BD2027BF915003, + 0x69460E90220D1B56,0x299E276FAE19D328,0x63928C3C53A2432F,0x7082FEF8E91B9ED0, + 0xBC6F792C3EED40F7,0x4C40D537D2DE53DB,0x75E8BFAE5FC2B262,0x4DA9C0D2A541FD0A, + 0x4E8FFFE03CFD1264,0x2620E495696FA7E3,0xE1F0F408B8A98F6C,0xD1AA230FDDA6D9C2, + 0xC7D0109DD1C6288F,0x8A79D04F7487D585,0x4694579BA3710BA2,0x38417F7CFA834F68, + 0x1D47A4DB0A5007E5,0x206C9AF1460A643F,0xA128DDF734BD4712,0x8144470672B7232D, + 0xF2E086CC02105293,0x182DE58DBC892B57,0xCAA1F9B0F8931DFB,0x6B892447CC2E5AE9, + 0xF9DD11850420A43B,0x4BE5BEB68A243ED6,0x5584255F19C8D65D,0x3B67404E633FA006, + 0xA68DB6766C472A1F,0xF78AC79AB4C97E21,0xC353442E1080AAEC,0x9A4F9DB95782E714 +},{ + 0x05BA7BC82C9B3220,0x31A54665F8B65E4F,0xB1B651F77547F4D4,0x8BFA0D857BA46682, + 0x85A96C5AA16A98BB,0x990FAEF908EB79C9,0xA15E37A247F4A62D,0x76857DCD5D27741E, + 0xF8C50B800A1820BC,0xBE65DCB201F7A2B4,0x666D1B986F9426E7,0x4CC921BF53C4E648, + 0x95410A0F93D9CA42,0x20CDCCAA647BA4EF,0x429A4060890A1871,0x0C4EA4F69B32B38B, + 0xCCDA362DDE354CD3,0x96DC23BC7C5B2FA9,0xC309BB68AA851AB3,0xD26131A73648E013, + 0x021DC52941FC4DB2,0xCD5ADAB7704BE48A,0xA77965D984ED71E6,0x32386FD61734BBA4, + 0xE82D6DD538AB7245,0x5C2147EA6177B4B1,0x5DA1AB70CF091CE8,0xAC907FCE72B8BDFF, + 0x57C85DFD972278A8,0xA4E44C6A6B6F940D,0x3851995B4F1FDFE4,0x62578CCAED71BC9E, + 0xD9882BB0C01D2C0A,0x917B9D5D113C503B,0xA2C31E11A87643C6,0xE463C923A399C1CE, + 0xF71686C57EA876DC,0x87B4A973E096D509,0xAF0D567D9D3A5814,0xB40C2A3F59DCC6F4, + 0x3602F88495D121DD,0xD3E1DD3D9836484A,0xF945E71AA46688E5,0x7518547EB2A591F5, + 0x9366587450C01D89,0x9EA81018658C065B,0x4F54080CBC4603A3,0x2D0384C65137BF3D, + 0xDC325078EC861E2A,0xEA30A8FC79573FF7,0x214D2030CA050CB6,0x65F0322B8016C30C, + 0x69BE96DD1B247087,0xDB95EE9981E161B8,0xD1FC1814D9CA05F8,0x820ED2BBCC0DE729, + 0x63D76050430F14C7,0x3BCCB0E8A09D3A0F,0x8E40764D573F54A2,0x39D175C1E16177BD, + 0x12F5A37C734F1F4B,0xAB37C12F1FDFC26D,0x5648B167395CD0F1,0x6C04ED1537BF42A7, + 0xED97161D14304065,0x7D6C67DAAB72B807,0xEC17FA87BA4EE83C,0xDFAF79CB0304FBC1, + 0x733F060571BC463E,0x78D61C1287E98A27,0xD07CF48E77B4ADA1,0xB9C262536C90DD26, + 0xE2449B5860801605,0x8FC09AD7F941FCFB,0xFAD8CEA94BE46D0E,0xA343F28B0608EB9F, + 0x9B126BD04917347B,0x9A92874AE7699C22,0x1B017C42C4E69EE0,0x3A4C5C720EE39256, + 0x4B6E9F5E3EA399DA,0x6BA353F45AD83D35,0xE7FEE0904C1B2425,0x22D009832587E95D, + 0x842980C00F1430E2,0xC6B3C0A0861E2893,0x087433A419D729F2,0x341F3DADD42D6C6F, + 0xEE0A3FAEFBB2A58E,0x4AEE73C490DD3183,0xAAB72DB5B1A16A34,0xA92A04065E238FDF, + 0x7B4B35A1686B6FCC,0x6A23BF6EF4A6956C,0x191CB96B851AD352,0x55D598D4D6DE351A, + 0xC9604DE5F2AE7EF3,0x1CA6C2A3A981E172,0xDE2F9551AD7A5398,0x3025AAFF56C8F616, + 0x15521D9D1E2860D9,0x506FE31CFA45073A,0x189C55F12B647B0B,0x0180EC9AAE7EA859, + 0x7CEC8B40050C105E,0x2350E5198BF94104,0xEF8AD33455CC0DD7,0x07A7BEE16D677F92, + 0xE5E325B90DE76997,0x5A061591A26E637A,0xB611EF1618208B46,0x09F4DF3EB7A981AB, + 0x1EBB078AE87DACC0,0xB791038CB65E231F,0x0FD38D4574B05660,0x67EDF702C1EA8EBE, + 0xBA5F4BE0831238CD,0xE3C477C2CEFEBE5C,0x0DCE486C354C1BD2,0x8C5DB36416C31910, + 0x26EA9ED1A7627324,0x039D29B3EF82E5EB,0x9F28FC82CBF2AE02,0xA8AAE89CF05D2786, + 0x431AACFA2774B028,0xCF471F9E31B7A938,0x581BD0B8E3922EC8,0xBC78199B400BEF06, + 0x90FB71C7BF42F862,0x1F3BEB1046030499,0x683E7A47B55AD8DE,0x988F4263A695D190, + 0xD808C72A6E638453,0x0627527BC319D7CB,0xEBB04466D72997AE,0xE67E0C0AE2658C7C, + 0x14D2F107B056C880,0x7122C32C30400B8C,0x8A7AE11FD5DACEDB,0xA0DEDB38E98A0E74, + 0xAD109354DCC615A6,0x0BE91A17F655CC19,0x8DDD5FFEB8BDB149,0xBFE53028AF890AED, + 0xD65BA6F5B4AD7A6A,0x7956F0882997227E,0x10E8665532B352F9,0x0E5361DFDACEFE39, + 0xCEC7F3049FC90161,0xFF62B561677F5F2E,0x975CCF26D22587F0,0x51EF0F86543BAF63, + 0x2F1E41EF10CBF28F,0x52722635BBB94A88,0xAE8DBAE73344F04D,0x410769D36688FD9A, + 0xB3AB94DE34BBB966,0x801317928DF1AA9B,0xA564A0F0C5113C54,0xF131D4BEBDB1A117, + 0x7F71A2F3EA8EF5B5,0x40878549C8F655C3,0x7EF14E6944F05DEC,0xD44663DCF55137D8, + 0xF2ACFD0D523344FC,0x0000000000000000,0x5FBC6E598EF5515A,0x16CF342EF1AA8532, + 0xB036BD6DDB395C8D,0x13754FE6DD31B712,0xBBDFA77A2D6C9094,0x89E7C8AC3A582B30, + 0x3C6B0E09CDFA459D,0xC4AE0589C7E26521,0x49735A777F5FD468,0xCAFD64561D2C9B18, + 0xDA1502032F9FC9E1,0x8867243694268369,0x3782141E3BAF8984,0x9CB5D53124704BE9, + 0xD7DB4A6F1AD3D233,0xA6F989432A93D9BF,0x9D3539AB8A0EE3B0,0x53F2CAAF15C7E2D1, + 0x6E19283C76430F15,0x3DEBE2936384EDC4,0x5E3C82C3208BF903,0x33B8834CB94A13FD, + 0x6470DEB12E686B55,0x359FD1377A53C436,0x61CAA57902F35975,0x043A975282E59A79, + 0xFD7F70482683129C,0xC52EE913699CCD78,0x28B9FF0E7DAC8D1D,0x5455744E78A09D43, + 0xCB7D88CCB3523341,0x44BD121B4A13CFBA,0x4D49CD25FDBA4E11,0x3E76CB208C06082F, + 0x3FF627BA2278A076,0xC28957F204FBB2EA,0x453DFE81E46D67E3,0x94C1E6953DA7621B, + 0x2C83685CFF491764,0xF32C1197FC4DECA5,0x2B24D6BD922E68F6,0xB22B78449AC5113F, + 0x48F3B6EDD1217C31,0x2E9EAD75BEB55AD6,0x174FD8B45FD42D6B,0x4ED4E4961238ABFA, + 0x92E6B4EEFEBEB5D0,0x46A0D7320BEF8208,0x47203BA8A5912A51,0x24F75BF8E69E3E96, + 0xF0B1382413CF094E,0xFEE259FBC901F777,0x276A724B091CDB7D,0xBDF8F501EE75475F, + 0x599B3C224DEC8691,0x6D84018F99C1EAFE,0x7498B8E41CDB39AC,0xE0595E71217C5BB7, + 0x2AA43A273C50C0AF,0xF50B43EC3F543B6E,0x838E3E2162734F70,0xC09492DB4507FF58, + 0x72BFEA9FDFC2EE67,0x11688ACF9CCDFAA0,0x1A8190D86A9836B9,0x7ACBD93BC615C795, + 0xC7332C3A286080CA,0x863445E94EE87D50,0xF6966A5FD0D6DE85,0xE9AD814F96D5DA1C, + 0x70A22FB69E3EA3D5,0x0A69F68D582B6440,0xB8428EC9C2EE757F,0x604A49E3AC8DF12C, + 0x5B86F90B0C10CB23,0xE1D9B2EB8F02F3EE,0x29391394D3D22544,0xC8E0A17F5CD0D6AA, + 0xB58CC6A5F7A26EAD,0x8193FB08238F02C2,0xD5C68F465B2F9F81,0xFCFF9CD288FDBAC5, + 0x77059157F359DC47,0x1D262E3907FF492B,0xFB582233E59AC557,0xDDB2BCE242F8B673, + 0x2577B76248E096CF,0x6F99C4A6D83DA74C,0xC1147E41EB795701,0xF48BAF76912A9337 +},{ + 0x3EF29D249B2C0A19,0xE9E16322B6F8622F,0x5536994047757F7A,0x9F4D56D5A47B0B33, + 0x822567466AA1174C,0xB8F5057DEB082FB2,0xCC48C10BF4475F53,0x373088D4275DEC3A, + 0x968F4325180AED10,0x173D232CF7016151,0xAE4ED09F946FCC13,0xFD4B4741C4539873, + 0x1B5B3F0DD9933765,0x2FFCB0967B644052,0xE02376D20A89840C,0xA3AE3A70329B18D7, + 0x419CBD2335DE8526,0xFAFEBF115B7C3199,0x0397074F85AA9B0D,0xC58AD4FB4836B970, + 0xBEC60BE3FC4104A8,0x1EFF36DC4B708772,0x131FDC33ED8453B6,0x0844E33E341764D3, + 0x0FF11B6EAB38CD39,0x64351F0A7761B85A,0x3B5694F509CFBA0E,0x30857084B87245D0, + 0x47AFB3BD2297AE3C,0xF2BA5C2F6F6B554A,0x74BDC4761F4F70E1,0xCFDFC64471EDC45E, + 0xE610784C1DC0AF16,0x7ACA29D63C113F28,0x2DED411776A859AF,0xAC5F211E99A3D5EE, + 0xD484F949A87EF33B,0x3CE36CA596E013E4,0xD120F0983A9D432C,0x6BC40464DC597563, + 0x69D5F5E5D1956C9E,0x9AE95F043698BB24,0xC9ECC8DA66A4EF44,0xD69508C8A5B2EAC6, + 0xC40C2235C0503B80,0x38C193BA8C652103,0x1CEEC75D46BC9E8F,0xD331011937515AD1, + 0xD8E2E56886ECA50F,0xB137108D5779C991,0x709F3B6905CA4206,0x4FEB50831680CAEF, + 0xEC456AF3241BD238,0x58D673AFE181ABBE,0x242F54E7CAD9BF8C,0x0211F1810DCC19FD, + 0x90BC4DBB0F43C60A,0x9518446A9DA0761D,0xA1BFCBF13F57012A,0x2BDE4F8961E172B5, + 0x27B853A84F732481,0xB0B1E643DF1F4B61,0x18CC38425C39AC68,0xD2B7F7D7BF37D821, + 0x3103864A3014C720,0x14AA246372ABFA5C,0x6E600DB54EBAC574,0x394765740403A3F3, + 0x09C215F0BC71E623,0x2A58B947E987F045,0x7B4CDF18B477BDD8,0x9709B5EB906C6FE0, + 0x73083C268060D90B,0xFEDC400E41F9037E,0x284948C6E44BE9B8,0x728ECAE808065BFB, + 0x06330E9E17492B1A,0x5950856169E7294E,0xBAE4F4FCE6C4364F,0xCA7BCF95E30E7449, + 0x7D7FD186A33E96C2,0x52836110D85AD690,0x4DFAA1021B4CD312,0x913ABB75872544FA, + 0xDD46ECB9140F1518,0x3D659A6B1E869114,0xC23F2CABD719109A,0xD713FE062DD46836, + 0xD0A60656B2FBC1DC,0x221C5A79DD909496,0xEFD26DBCA1B14935,0x0E77EDA0235E4FC9, + 0xCBFD395B6B68F6B9,0x0DE0EAEFA6F4D4C4,0x0422FF1F1A8532E7,0xF969B85EDED6AA94, + 0x7F6E2007AEF28F3F,0x3AD0623B81A938FE,0x6624EE8B7AADA1A7,0xB682E8DDC856607B, + 0xA78CC56F281E2A30,0xC79B257A45FAA08D,0x5B4174E0642B30B3,0x5F638BFF7EAE0254, + 0x4BC9AF9C0C05F808,0xCE59308AF98B46AE,0x8FC58DA9CC55C388,0x803496C7676D0EB1, + 0xF33CAAE1E70DD7BA,0xBB6202326EA2B4BF,0xD5020F87201871CB,0x9D5CA754A9B712CE, + 0x841669D87DE83C56,0x8A6184785EB6739F,0x420BBA6CB0741E2B,0xF12D5B60EAC1CE47, + 0x76AC35F71283691C,0x2C6BB7D9FECEDB5F,0xFCCDB18F4C351A83,0x1F79C012C3160582, + 0xF0ABADAE62A74CB7,0xE1A5801C82EF06FC,0x67A21845F2CB2357,0x5114665F5DF04D9D, + 0xBF40FD2D74278658,0xA0393D3FB73183DA,0x05A409D192E3B017,0xA9FB28CF0B4065F9, + 0x25A9A22942BF3D7C,0xDB75E22703463E02,0xB326E10C5AB5D06C,0xE7968E8295A62DE6, + 0xB973F3B3636EAD42,0xDF571D3819C30CE5,0xEE549B7229D7CBC5,0x12992AFD65E2D146, + 0xF8EF4E9056B02864,0xB7041E134030E28B,0xC02EDD2ADAD50967,0x932B4AF48AE95D07, + 0x6FE6FB7BC6DC4784,0x239AACB755F61666,0x401A4BEDBDB807D6,0x485EA8D389AF6305, + 0xA41BC220ADB4B13D,0x753B32B89729F211,0x997E584BB3322029,0x1D683193CEDA1C7F, + 0xFF5AB6C0C99F818E,0x16BBD5E27F67E3A1,0xA59D34EE25D233CD,0x98F8AE853B54A2D9, + 0x6DF70AFACB105E79,0x795D2E99B9BBA425,0x8E437B6744334178,0x0186F6CE886682F0, + 0xEBF092A3BB347BD2,0xBCD7FA62F18D1D55,0xADD9D7D011C5571E,0x0BD3E471B1BDFFDE, + 0xAA6C2F808EEAFEF4,0x5EE57D31F6C880A4,0xF50FA47FF044FCA0,0x1ADDC9C351F5B595, + 0xEA76646D3352F922,0x0000000000000000,0x85909F16F58EBEA6,0x46294573AAF12CCC, + 0x0A5512BF39DB7D2E,0x78DBD85731DD26D5,0x29CFBE086C2D6B48,0x218B5D36583A0F9B, + 0x152CD2ADFACD78AC,0x83A39188E2C795BC,0xC3B9DA655F7F926A,0x9ECBA01B2C1D89C3, + 0x07B5F8509F2FA9EA,0x7EE8D6C926940DCF,0x36B67E1AAF3B6ECA,0x86079859702425AB, + 0xFB7849DFD31AB369,0x4C7C57CC932A51E2,0xD96413A60E8A27FF,0x263EA566C715A671, + 0x6C71FC344376DC89,0x4A4F595284637AF8,0xDAF314E98B20BCF2,0x572768C14AB96687, + 0x1088DB7C682EC8BB,0x887075F9537A6A62,0x2E7A4658F302C2A2,0x619116DBE582084D, + 0xA87DDE018326E709,0xDCC01A779C6997E8,0xEDC39C3DAC7D50C8,0xA60A33A1A078A8C0, + 0xC1A82BE452B38B97,0x3F746BEA134A88E9,0xA228CCBEBAFD9A27,0xABEAD94E068C7C04, + 0xF48952B178227E50,0x5CF48CB0FB049959,0x6017E0156DE48ABD,0x4438B4F2A73D3531, + 0x8C528AE649FF5885,0xB515EF924DFCFB76,0x0C661C212E925634,0xB493195CC59A7986, + 0x9CDA519A21D1903E,0x32948105B5BE5C2D,0x194ACE8CD45F2E98,0x438D4CA238129CDB, + 0x9B6FA9CABEFE39D4,0x81B26009EF0B8C41,0xDED1EBF691A58E15,0x4E6DA64D9EE6481F, + 0x54B06F8ECF13FD8A,0x49D85E1D01C9E1F5,0xAFC826511C094EE3,0xF698A33075EE67AD, + 0x5AC7822EEC4DB243,0x8DD47C28C199DA75,0x89F68337DB1CE892,0xCDCE37C57C21DDA3, + 0x530597DE503C5460,0x6A42F2AA543FF793,0x5D727A7E73621BA9,0xE232875307459DF1, + 0x56A19E0FC2DFE477,0xC61DD3B4CD9C227D,0xE5877F03986A341B,0x949EB2A415C6F4ED, + 0x6206119460289340,0x6380E75AE84E11B0,0x8BE772B6D6D0F16F,0x50929091D596CF6D, + 0xE86795EC3E9EE0DF,0x7CF927482B581432,0xC86A3E14EEC26DB4,0x7119CDA78DACC0F6, + 0xE40189CD100CB6EB,0x92ADBC3A028FDFF7,0xB2A017C2D2D3529C,0x200DABF8D05C8D6B, + 0x34A78F9BA2F77737,0xE3B4719D8F231F01,0x45BE423C2F5BB7C1,0xF71E55FEFD88E55D, + 0x6853032B59F3EE6E,0x65B3E9C4FF073AAA,0x772AC3399AE5EBEC,0x87816E97F842A75B, + 0x110E2DB2E0484A4B,0x331277CB3DD8DEDD,0xBD510CAC79EB9FA5,0x352179552A91F5C7 +},{ + 0x8AB0A96846E06A6D,0x43C7E80B4BF0B33A,0x08C9B3546B161EE5,0x39F1C235EBA990BE, + 0xC1BEF2376606C7B2,0x2C209233614569AA,0xEB01523B6FC3289A,0x946953AB935ACEDD, + 0x272838F63E13340E,0x8B0455ECA12BA052,0x77A1B2C4978FF8A2,0xA55122CA13E54086, + 0x2276135862D3F1CD,0xDB8DDFDE08B76CFE,0x5D1E12C89E4A178A,0x0E56816B03969867, + 0xEE5F79953303ED59,0xAFED748BAB78D71D,0x6D929F2DF93E53EE,0xF5D8A8F8BA798C2A, + 0xF619B1698E39CF6B,0x95DDAF2F749104E2,0xEC2A9C80E0886427,0xCE5C8FD8825B95EA, + 0xC4E0D9993AC60271,0x4699C3A5173076F9,0x3D1B151F50A29F42,0x9ED505EA2BC75946, + 0x34665ACFDC7F4B98,0x61B1FB53292342F7,0xC721C0080E864130,0x8693CD1696FD7B74, + 0x872731927136B14B,0xD3446C8A63A1721B,0x669A35E8A6680E4A,0xCAB658F239509A16, + 0xA4E5DE4EF42E8AB9,0x37A7435EE83F08D9,0x134E6239E26C7F96,0x82791A3C2DF67488, + 0x3F6EF00A8329163C,0x8E5A7E42FDEB6591,0x5CAAEE4C7981DDB5,0x19F234785AF1E80D, + 0x255DDDE3ED98BD70,0x50898A32A99CCCAC,0x28CA4519DA4E6656,0xAE59880F4CB31D22, + 0x0D9798FA37D6DB26,0x32F968F0B4FFCD1A,0xA00F09644F258545,0xFA3AD5175E24DE72, + 0xF46C547C5DB24615,0x713E80FBFF0F7E20,0x7843CF2B73D2AAFA,0xBD17EA36AEDF62B4, + 0xFD111BACD16F92CF,0x4ABAA7DBC72D67E0,0xB3416B5DAD49FAD3,0xBCA316B24914A88B, + 0x15D150068AECF914,0xE27C1DEBE31EFC40,0x4FE48C759BEDA223,0x7EDCFD141B522C78, + 0x4E5070F17C26681C,0xE696CAC15815F3BC,0x35D2A64B3BB481A7,0x800CFF29FE7DFDF6, + 0x1ED9FAC3D5BAA4B0,0x6C2663A91EF599D1,0x03C1199134404341,0xF7AD4DED69F20554, + 0xCD9D9649B61BD6AB,0xC8C3BDE7EADB1368,0xD131899FB02AFB65,0x1D18E352E1FAE7F1, + 0xDA39235AEF7CA6C1,0xA1BBF5E0A8EE4F7A,0x91377805CF9A0B1E,0x3138716180BF8E5B, + 0xD9F83ACBDB3CE580,0x0275E515D38B897E,0x472D3F21F0FBBCC6,0x2D946EB7868EA395, + 0xBA3C248D21942E09,0xE7223645BFDE3983,0xFF64FEB902E41BB1,0xC97741630D10D957, + 0xC3CB1722B58D4ECC,0xA27AEC719CAE0C3B,0x99FECB51A48C15FB,0x1465AC826D27332B, + 0xE1BD047AD75EBF01,0x79F733AF941960C5,0x672EC96C41A3C475,0xC27FEBA6524684F3, + 0x64EFD0FD75E38734,0xED9E60040743AE18,0xFB8E2993B9EF144D,0x38453EB10C625A81, + 0x6978480742355C12,0x48CF42CE14A6EE9E,0x1CAC1FD606312DCE,0x7B82D6BA4792E9BB, + 0x9D141C7B1F871A07,0x5616B80DC11C4A2E,0xB849C198F21FA777,0x7CA91801C8D9A506, + 0xB1348E487EC273AD,0x41B20D1E987B3A44,0x7460AB55A3CFBBE3,0x84E628034576F20A, + 0x1B87D16D897A6173,0x0FE27DEFE45D5258,0x83CDE6B8CA3DBEB7,0x0C23647ED01D1119, + 0x7A362A3EA0592384,0xB61F40F3F1893F10,0x75D457D1440471DC,0x4558DA34237035B8, + 0xDCA6116587FC2043,0x8D9B67D3C9AB26D0,0x2B0B5C88EE0E2517,0x6FE77A382AB5DA90, + 0x269CC472D9D8FE31,0x63C41E46FAA8CB89,0xB7ABBC771642F52F,0x7D1DE4852F126F39, + 0xA8C6BA3024339BA0,0x600507D7CEE888C8,0x8FEE82C61A20AFAE,0x57A2448926D78011, + 0xFCA5E72836A458F0,0x072BCEBB8F4B4CBD,0x497BBE4AF36D24A1,0x3CAFE99BB769557D, + 0x12FA9EBD05A7B5A9,0xE8C04BAA5B836BDB,0x4273148FAC3B7905,0x908384812851C121, + 0xE557D3506C55B0FD,0x72FF996ACB4F3D61,0x3EDA0C8E64E2DC03,0xF0868356E6B949E9, + 0x04EAD72ABB0B0FFC,0x17A4B5135967706A,0xE3C8E16F04D5367F,0xF84F30028DAF570C, + 0x1846C8FCBD3A2232,0x5B8120F7F6CA9108,0xD46FA231ECEA3EA6,0x334D947453340725, + 0x58403966C28AD249,0xBED6F3A79A9F21F5,0x68CCB483A5FE962D,0xD085751B57E1315A, + 0xFED0023DE52FD18E,0x4B0E5B5F20E6ADDF,0x1A332DE96EB1AB4C,0xA3CE10F57B65C604, + 0x108F7BA8D62C3CD7,0xAB07A3A11073D8E1,0x6B0DAD1291BED56C,0xF2F366433532C097, + 0x2E557726B2CEE0D4,0x0000000000000000,0xCB02A476DE9B5029,0xE4E32FD48B9E7AC2, + 0x734B65EE2C84F75E,0x6E5386BCCD7E10AF,0x01B4FC84E7CBCA3F,0xCFE8735C65905FD5, + 0x3613BFDA0FF4C2E6,0x113B872C31E7F6E8,0x2FE18BA255052AEB,0xE974B72EBC48A1E4, + 0x0ABC5641B89D979B,0xB46AA5E62202B66E,0x44EC26B0C4BBFF87,0xA6903B5B27A503C7, + 0x7F680190FC99E647,0x97A84A3AA71A8D9C,0xDD12EDE16037EA7C,0xC554251DDD0DC84E, + 0x88C54C7D956BE313,0x4D91696048662B5D,0xB08072CC9909B992,0xB5DE5962C5C97C51, + 0x81B803AD19B637C9,0xB2F597D94A8230EC,0x0B08AAC55F565DA4,0xF1327FD2017283D6, + 0xAD98919E78F35E63,0x6AB9519676751F53,0x24E921670A53774F,0xB9FD3D1C15D46D48, + 0x92F66194FBDA485F,0x5A35DC7311015B37,0xDED3F4705477A93D,0xC00A0EB381CD0D8D, + 0xBB88D809C65FE436,0x16104997BEACBA55,0x21B70AC95693B28C,0x59F4C5E225411876, + 0xD5DB5EB50B21F499,0x55D7A19CF55C096F,0xA97246B4C3F8519F,0x8552D487A2BD3835, + 0x54635D181297C350,0x23C2EFDC85183BF2,0x9F61F96ECC0C9379,0x534893A39DDC8FED, + 0x5EDF0B59AA0A54CB,0xAC2C6D1A9F38945C,0xD7AEBBA0D8AA7DE7,0x2ABFA00C09C5EF28, + 0xD84CC64F3CF72FBF,0x2003F64DB15878B3,0xA724C7DFC06EC9F8,0x069F323F68808682, + 0xCC296ACD51D01C94,0x055E2BAE5CC0C5C3,0x6270E2C21D6301B6,0x3B842720382219C0, + 0xD2F0900E846AB824,0x52FC6F277A1745D2,0xC6953C8CE94D8B0F,0xE009F8FE3095753E, + 0x655B2C7992284D0B,0x984A37D54347DFC4,0xEAB5AEBF8808E2A5,0x9A3FD2C090CC56BA, + 0x9CA0E0FFF84CD038,0x4C2595E4AFADE162,0xDF6708F4B3BC6302,0xBF620F237D54EBCA, + 0x93429D101C118260,0x097D4FD08CDDD4DA,0x8C2F9B572E60ECEF,0x708A7C7F18C4B41F, + 0x3A30DBA4DFE9D3FF,0x4006F19A7FB0F07B,0x5F6BF7DD4DC19EF4,0x1F6D064732716E8F, + 0xF9FBCC866A649D33,0x308C8DE567744464,0x8971B0F972A0292C,0xD61A47243F61B7D8, + 0xEFEB8511D4C82766,0x961CB6BE40D147A3,0xAAB35F25F7B812DE,0x76154E407044329D, + 0x513D76B64E570693,0xF3479AC7D2F90AA8,0x9B8B2E4477079C85,0x297EB99D3D85AC69 +},{ + 0x7E37E62DFC7D40C3,0x776F25A4EE939E5B,0xE045C850DD8FB5AD,0x86ED5BA711FF1952, + 0xE91D0BD9CF616B35,0x37E0AB256E408FFB,0x9607F6C031025A7A,0x0B02F5E116D23C9D, + 0xF3D8486BFB50650C,0x621CFF27C40875F5,0x7D40CB71FA5FD34A,0x6DAA6616DAA29062, + 0x9F5F354923EC84E2,0xEC847C3DC507C3B3,0x025A3668043CE205,0xA8BF9E6C4DAC0B19, + 0xFA808BE2E9BEBB94,0xB5B99C5277C74FA3,0x78D9BC95F0397BCC,0xE332E50CDBAD2624, + 0xC74FCE129332797E,0x1729ECEB2EA709AB,0xC2D6B9F69954D1F8,0x5D898CBFBAB8551A, + 0x859A76FB17DD8ADB,0x1BE85886362F7FB5,0xF6413F8FF136CD8A,0xD3110FA5BBB7E35C, + 0x0A2FEED514CC4D11,0xE83010EDCD7F1AB9,0xA1E75DE55F42D581,0xEEDE4A55C13B21B6, + 0xF2F5535FF94E1480,0x0CC1B46D1888761E,0xBCE15FDB6529913B,0x2D25E8975A7181C2, + 0x71817F1CE2D7A554,0x2E52C5CB5C53124B,0xF9F7A6BEEF9C281D,0x9E722E7D21F2F56E, + 0xCE170D9B81DCA7E6,0x0E9B82051CB4941B,0x1E712F623C49D733,0x21E45CFA42F9F7DC, + 0xCB8E7A7F8BBA0F60,0x8E98831A010FB646,0x474CCF0D8E895B23,0xA99285584FB27A95, + 0x8CC2B57205335443,0x42D5B8E984EFF3A5,0x012D1B34021E718C,0x57A6626AAE74180B, + 0xFF19FC06E3D81312,0x35BA9D4D6A7C6DFE,0xC9D44C178F86ED65,0x506523E6A02E5288, + 0x03772D5C06229389,0x8B01F4FE0B691EC0,0xF8DABD8AED825991,0x4C4E3AEC985B67BE, + 0xB10DF0827FBF96A9,0x6A69279AD4F8DAE1,0xE78689DCD3D5FF2E,0x812E1A2B1FA553D1, + 0xFBAD90D6EBA0CA18,0x1AC543B234310E39,0x1604F7DF2CB97827,0xA6241C6951189F02, + 0x753513CCEAAF7C5E,0x64F2A59FC84C4EFA,0x247D2B1E489F5F5A,0xDB64D718AB474C48, + 0x79F4A7A1F2270A40,0x1573DA832A9BEBAE,0x3497867968621C72,0x514838D2A2302304, + 0xF0AF6537FD72F685,0x1D06023E3A6B44BA,0x678588C3CE6EDD73,0x66A893F7CC70ACFF, + 0xD4D24E29B5EDA9DF,0x3856321470EA6A6C,0x07C3418C0E5A4A83,0x2BCBB22F5635BACD, + 0x04B46CD00878D90A,0x06EE5AB80C443B0F,0x3B211F4876C8F9E5,0x0958C38912EEDE98, + 0xD14B39CDBF8B0159,0x397B292072F41BE0,0x87C0409313E168DE,0xAD26E98847CAA39F, + 0x4E140C849C6785BB,0xD5FF551DB7F3D853,0xA0CA46D15D5CA40D,0xCD6020C787FE346F, + 0x84B76DCF15C3FB57,0xDEFDA0FCA121E4CE,0x4B8D7B6096012D3D,0x9AC642AD298A2C64, + 0x0875D8BD10F0AF14,0xB357C6EA7B8374AC,0x4D6321D89A451632,0xEDA96709C719B23F, + 0xF76C24BBF328BC06,0xC662D526912C08F2,0x3CE25EC47892B366,0xB978283F6F4F39BD, + 0xC08C8F9E9D6833FD,0x4F3917B09E79F437,0x593DE06FB2C08C10,0xD6887841B1D14BDA, + 0x19B26EEE32139DB0,0xB494876675D93E2F,0x825937771987C058,0x90E9AC783D466175, + 0xF1827E03FF6C8709,0x945DC0A8353EB87F,0x4516F9658AB5B926,0x3F9573987EB020EF, + 0xB855330B6D514831,0x2AE6A91B542BCB41,0x6331E413C6160479,0x408F8E8180D311A0, + 0xEFF35161C325503A,0xD06622F9BD9570D5,0x8876D9A20D4B8D49,0xA5533135573A0C8B, + 0xE168D364DF91C421,0xF41B09E7F50A2F8F,0x12B09B0F24C1A12D,0xDA49CC2CA9593DC4, + 0x1F5C34563E57A6BF,0x54D14F36A8568B82,0xAF7CDFE043F6419A,0xEA6A2685C943F8BC, + 0xE5DCBFB4D7E91D2B,0xB27ADDDE799D0520,0x6B443CAED6E6AB6D,0x7BAE91C9F61BE845, + 0x3EB868AC7CAE5163,0x11C7B65322E332A4,0xD23C1491B9A992D0,0x8FB5982E0311C7CA, + 0x70AC6428E0C9D4D8,0x895BC2960F55FCC5,0x76423E90EC8DEFD7,0x6FF0507EDE9E7267, + 0x3DCF45F07A8CC2EA,0x4AA06054941F5CB1,0x5810FB5BB0DEFD9C,0x5EFEA1E3BC9AC693, + 0x6EDD4B4ADC8003EB,0x741808F8E8B10DD2,0x145EC1B728859A22,0x28BC9F7350172944, + 0x270A06424EBDCCD3,0x972AEDF4331C2BF6,0x059977E40A66A886,0x2550302A4A812ED6, + 0xDD8A8DA0A7037747,0xC515F87A970E9B7B,0x3023EAA9601AC578,0xB7E3AA3A73FBADA6, + 0x0FB699311EAAE597,0x0000000000000000,0x310EF19D6204B4F4,0x229371A644DB6455, + 0x0DECAF591A960792,0x5CA4978BB8A62496,0x1C2B190A38753536,0x41A295B582CD602C, + 0x3279DCC16426277D,0xC1A194AA9F764271,0x139D803B26DFD0A1,0xAE51C4D441E83016, + 0xD813FA44AD65DFC1,0xAC0BF2BC45D4D213,0x23BE6A9246C515D9,0x49D74D08923DCF38, + 0x9D05032127D066E7,0x2F7FDEFF5E4D63C7,0xA47E2A0155247D07,0x99B16FF12FA8BFED, + 0x4661D4398C972AAF,0xDFD0BBC8A33F9542,0xDCA79694A51D06CB,0xB020EBB67DA1E725, + 0xBA0F0563696DAA34,0xE4F1A480D5F76CA7,0xC438E34E9510EAF7,0x939E81243B64F2FC, + 0x8DEFAE46072D25CF,0x2C08F3A3586FF04E,0xD7A56375B3CF3A56,0x20C947CE40E78650, + 0x43F8A3DD86F18229,0x568B795EAC6A6987,0x8003011F1DBB225D,0xF53612D3F7145E03, + 0x189F75DA300DEC3C,0x9570DB9C3720C9F3,0xBB221E576B73DBB8,0x72F65240E4F536DD, + 0x443BE25188ABC8AA,0xE21FFE38D9B357A8,0xFD43CA6EE7E4F117,0xCAA3614B89A47EEC, + 0xFE34E732E1C6629E,0x83742C431B99B1D4,0xCF3A16AF83C2D66A,0xAAE5A8044990E91C, + 0x26271D764CA3BD5F,0x91C4B74C3F5810F9,0x7C6DD045F841A2C6,0x7F1AFD19FE63314F, + 0xC8F957238D989CE9,0xA709075D5306EE8E,0x55FC5402AA48FA0E,0x48FA563C9023BEB4, + 0x65DFBEABCA523F76,0x6C877D22D8BCE1EE,0xCC4D3BF385E045E3,0xBEBB69B36115733E, + 0x10EAAD6720FD4328,0xB6CEB10E71E5DC2A,0xBDCC44EF6737E0B7,0x523F158EA412B08D, + 0x989C74C52DB6CE61,0x9BEB59992B945DE8,0x8A2CEFCA09776F4C,0xA3BD6B8D5B7E3784, + 0xEB473DB1CB5D8930,0xC3FBA2C29B4AA074,0x9C28181525CE176B,0x683311F2D0C438E4, + 0x5FD3BAD7BE84B71F,0xFC6ED15AE5FA809B,0x36CDB0116C5EFE77,0x29918447520958C8, + 0xA29070B959604608,0x53120EBAA60CC101,0x3A0C047C74D68869,0x691E0AC6D2DA4968, + 0x73DB4974E6EB4751,0x7A838AFDF40599C9,0x5A4ACD33B4E21F99,0x6046C94FC03497F0, + 0xE6AB92E8D1CB8EA2,0x3354C7F5663856F1,0xD93EE170AF7BAE4D,0x616BD27BC22AE67C, + 0x92B39A10397A8370,0xABC8B3304B8E9890,0xBF967287630B02B2,0x5B67D607B6FC6E15 +},{ + 0xD031C397CE553FE6,0x16BA5B01B006B525,0xA89BADE6296E70C8,0x6A1F525D77D3435B, + 0x6E103570573DFA0B,0x660EFB2A17FC95AB,0x76327A9E97634BF6,0x4BAD9D6462458BF5, + 0xF1830CAEDBC3F748,0xC5C8F542669131FF,0x95044A1CDC48B0CB,0x892962DF3CF8B866, + 0xB0B9E208E930C135,0xA14FB3F0611A767C,0x8D2605F21C160136,0xD6B71922FECC549E, + 0x37089438A5907D8B,0x0B5DA38E5803D49C,0x5A5BCC9CEA6F3CBC,0xEDAE246D3B73FFE5, + 0xD2B87E0FDE22EDCE,0x5E54ABB1CA8185EC,0x1DE7F88FE80561B9,0xAD5E1A870135A08C, + 0x2F2ADBD665CECC76,0x5780B5A782F58358,0x3EDC8A2EEDE47B3F,0xC9D95C3506BEE70F, + 0x83BE111D6C4E05EE,0xA603B90959367410,0x103C81B4809FDE5D,0x2C69B6027D0C774A, + 0x399080D7D5C87953,0x09D41E16487406B4,0xCDD63B1826505E5F,0xF99DC2F49B0298E8, + 0x9CD0540A943CB67F,0xBCA84B7F891F17C5,0x723D1DB3B78DF2A6,0x78AA6E71E73B4F2E, + 0x1433E699A071670D,0x84F21BE454620782,0x98DF3327B4D20F2F,0xF049DCE2D3769E5C, + 0xDB6C60199656EB7A,0x648746B2078B4783,0x32CD23598DCBADCF,0x1EA4955BF0C7DA85, + 0xE9A143401B9D46B5,0xFD92A5D9BBEC21B8,0xC8138C790E0B8E1B,0x2EE00B9A6D7BA562, + 0xF85712B893B7F1FC,0xEB28FED80BEA949D,0x564A65EB8A40EA4C,0x6C9988E8474A2823, + 0x4535898B121D8F2D,0xABD8C03231ACCBF4,0xBA2E91CAB9867CBD,0x7960BE3DEF8E263A, + 0x0C11A977602FD6F0,0xCB50E1AD16C93527,0xEAE22E94035FFD89,0x2866D12F5DE2CE1A, + 0xFF1B1841AB9BF390,0x9F9339DE8CFE0D43,0x964727C8C48A0BF7,0x524502C6AAAE531C, + 0x9B9C5EF3AC10B413,0x4FA2FA4942AB32A5,0x3F165A62E551122B,0xC74148DA76E6E3D7, + 0x924840E5E464B2A7,0xD372AE43D69784DA,0x233B72A105E11A86,0xA48A04914941A638, + 0xB4B68525C9DE7865,0xDDEABAACA6CF8002,0x0A9773C250B6BD88,0xC284FFBB5EBD3393, + 0x8BA0DF472C8F6A4E,0x2AEF6CB74D951C32,0x427983722A318D41,0x73F7CDFFBF389BB2, + 0x074C0AF9382C026C,0x8A6A0F0B243A035A,0x6FDAE53C5F88931F,0xC68B98967E538AC3, + 0x44FF59C71AA8E639,0xE2FCE0CE439E9229,0xA20CDE2479D8CD40,0x19E89FA2C8EBD8E9, + 0xF446BBCFF398270C,0x43B3533E2284E455,0xD82F0DCD8E945046,0x51066F12B26CE820, + 0xE73957AF6BC5426D,0x081ECE5A40C16FA0,0x3B193D4FC5BFAB7B,0x7FE66488DF174D42, + 0x0E9814EF705804D8,0x8137AC857C39D7C6,0xB1733244E185A821,0x695C3F896F11F867, + 0xF6CF0657E3EFF524,0x1AABF276D02963D5,0x2DA3664E75B91E5E,0x0289BD981077D228, + 0x90C1FD7DF413608F,0x3C5537B6FD93A917,0xAA12107E3919A2E0,0x0686DAB530996B78, + 0xDAA6B0559EE3826E,0xC34E2FF756085A87,0x6D5358A44FFF4137,0xFC587595B35948AC, + 0x7CA5095CC7D5F67E,0xFB147F6C8B754AC0,0xBFEB26AB91DDACF9,0x6896EFC567A49173, + 0xCA9A31E11E7C5C33,0xBBE44186B13315A9,0x0DDB793B689ABFE4,0x70B4A02BA7FA208E, + 0xE47A3A7B7307F951,0x8CECD5BE14A36822,0xEEED49B923B144D9,0x17708B4DB8B3DC31, + 0x6088219F2765FED3,0xB3FA8FDCF1F27A09,0x910B2D31FCA6099B,0x0F52C4A378ED6DCC, + 0x50CCBF5EBAD98134,0x6BD582117F662A4F,0x94CE9A50D4FDD9DF,0x2B25BCFB45207526, + 0x67C42B661F49FCBF,0x492420FC723259DD,0x03436DD418C2BB3C,0x1F6E4517F872B391, + 0xA08563BC69AF1F68,0xD43EA4BAEEBB86B6,0x01CAD04C08B56914,0xAC94CACB0980C998, + 0x54C3D8739A373864,0x26FEC5C02DBACAC2,0xDEA9D778BE0D3B3E,0x040F672D20EEB950, + 0xE5B0EA377BB29045,0xF30AB136CBB42560,0x62019C0737122CFB,0xE86B930C13282FA1, + 0xCC1CEB542EE5374B,0x538FD28AA21B3A08,0x1B61223AD89C0AC1,0x36C24474AD25149F, + 0x7A23D3E9F74C9D06,0xBE21F6E79968C5ED,0xCF5F868036278C77,0xF705D61BEB5A9C30, + 0x4D2B47D152DCE08D,0x5F9E7BFDC234ECF8,0x247778583DCD18EA,0x867BA67C4415D5AA, + 0x4CE1979D5A698999,0x0000000000000000,0xEC64F42133C696F1,0xB57C5569C16B1171, + 0xC1C7926F467F88AF,0x654D96FE0F3E2E97,0x15F936D5A8C40E19,0xB8A72C52A9F1AE95, + 0xA9517DAA21DB19DC,0x58D27104FA18EE94,0x5918A148F2AD8780,0x5CDD1629DAF657C4, + 0x8274C15164FB6CFA,0xD1FB13DBC6E056F2,0x7D6FD910CF609F6A,0xB63F38BDD9A9AA4D, + 0x3D9FE7FAF526C003,0x74BBC706871499DE,0xDF630734B6B8522A,0x3AD3ED03CD0AC26F, + 0xFADEAF2083C023D4,0xC00D42234ECAE1BB,0x8538CBA85CD76E96,0xC402250E6E2458EB, + 0x47BC3413026A5D05,0xAFD7A71F114272A4,0x978DF784CC3F62E3,0xB96DFC1EA144C781, + 0x21B2CF391596C8AE,0x318E4E8D950916F3,0xCE9556CC3E92E563,0x385A509BDD7D1047, + 0x358129A0B5E7AFA3,0xE6F387E363702B79,0xE0755D5653E94001,0x7BE903A5FFF9F412, + 0x12B53C2C90E80C75,0x3307F315857EC4DB,0x8FAFB86A0C61D31E,0xD9E5DD8186213952, + 0x77F8AAD29FD622E2,0x25BDA814357871FE,0x7571174A8FA1F0CA,0x137FEC60985D6561, + 0x30449EC19DBC7FE7,0xA540D4DD41F4CF2C,0xDC206AE0AE7AE916,0x5B911CD0E2DA55A8, + 0xB2305F90F947131D,0x344BF9ECBD52C6B7,0x5D17C665D2433ED0,0x18224FEEC05EB1FD, + 0x9E59E992844B6457,0x9A568EBFA4A5DD07,0xA3C60E68716DA454,0x7E2CB4C4D7A22456, + 0x87B176304CA0BCBE,0x413AEEA632F3367D,0x9915E36BBC67663B,0x40F03EEA3A465F69, + 0x1C2D28C3E0B008AD,0x4E682A054A1E5BB1,0x05C5B761285BD044,0xE1BF8D1A5B5C2915, + 0xF2C0617AC3014C74,0xB7F5E8F1D11CC359,0x63CB4C4B3FA745EF,0x9D1A84469C89DF6B, + 0xE33630824B2BFB3D,0xD5F474F6E60EEFA2,0xF58C6B83FB2D4E18,0x4676E45F0ADF3411, + 0x20781F751D23A1BA,0xBD629B3381AA7ED1,0xAE1D775319F71BB0,0xFED1C80DA32E9A84, + 0x5509083F92825170,0x29AC01635557A70E,0xA7C9694551831D04,0x8E65682604D4BA0A, + 0x11F651F8882AB749,0xD77DC96EF6793D8A,0xEF2799F52B042DCD,0x48EEF0B07A8730C9, + 0x22F1A2ED0D547392,0x6142F1D32FD097C7,0x4A674D286AF0E2E1,0x80FD7CC9748CBED2, + 0x717E7067AF4F499A,0x938290A9ECD1DBB3,0x88E3B293344DD172,0x2734158C250FA3D6 +}}; + +// Constant values for KeySchedule function +const unsigned char C[12][64] = {{ + 0xB1,0x08,0x5B,0xDA,0x1E,0xCA,0xDA,0xE9,0xEB,0xCB,0x2F,0x81,0xC0,0x65,0x7C,0x1F, + 0x2F,0x6A,0x76,0x43,0x2E,0x45,0xD0,0x16,0x71,0x4E,0xB8,0x8D,0x75,0x85,0xC4,0xFC, + 0x4B,0x7C,0xE0,0x91,0x92,0x67,0x69,0x01,0xA2,0x42,0x2A,0x08,0xA4,0x60,0xD3,0x15, + 0x05,0x76,0x74,0x36,0xCC,0x74,0x4D,0x23,0xDD,0x80,0x65,0x59,0xF2,0xA6,0x45,0x07 +},{ + 0x6F,0xA3,0xB5,0x8A,0xA9,0x9D,0x2F,0x1A,0x4F,0xE3,0x9D,0x46,0x0F,0x70,0xB5,0xD7, + 0xF3,0xFE,0xEA,0x72,0x0A,0x23,0x2B,0x98,0x61,0xD5,0x5E,0x0F,0x16,0xB5,0x01,0x31, + 0x9A,0xB5,0x17,0x6B,0x12,0xD6,0x99,0x58,0x5C,0xB5,0x61,0xC2,0xDB,0x0A,0xA7,0xCA, + 0x55,0xDD,0xA2,0x1B,0xD7,0xCB,0xCD,0x56,0xE6,0x79,0x04,0x70,0x21,0xB1,0x9B,0xB7 +},{ + 0xF5,0x74,0xDC,0xAC,0x2B,0xCE,0x2F,0xC7,0x0A,0x39,0xFC,0x28,0x6A,0x3D,0x84,0x35, + 0x06,0xF1,0x5E,0x5F,0x52,0x9C,0x1F,0x8B,0xF2,0xEA,0x75,0x14,0xB1,0x29,0x7B,0x7B, + 0xD3,0xE2,0x0F,0xE4,0x90,0x35,0x9E,0xB1,0xC1,0xC9,0x3A,0x37,0x60,0x62,0xDB,0x09, + 0xC2,0xB6,0xF4,0x43,0x86,0x7A,0xDB,0x31,0x99,0x1E,0x96,0xF5,0x0A,0xBA,0x0A,0xB2 +},{ + 0xEF,0x1F,0xDF,0xB3,0xE8,0x15,0x66,0xD2,0xF9,0x48,0xE1,0xA0,0x5D,0x71,0xE4,0xDD, + 0x48,0x8E,0x85,0x7E,0x33,0x5C,0x3C,0x7D,0x9D,0x72,0x1C,0xAD,0x68,0x5E,0x35,0x3F, + 0xA9,0xD7,0x2C,0x82,0xED,0x03,0xD6,0x75,0xD8,0xB7,0x13,0x33,0x93,0x52,0x03,0xBE, + 0x34,0x53,0xEA,0xA1,0x93,0xE8,0x37,0xF1,0x22,0x0C,0xBE,0xBC,0x84,0xE3,0xD1,0x2E +},{ + 0x4B,0xEA,0x6B,0xAC,0xAD,0x47,0x47,0x99,0x9A,0x3F,0x41,0x0C,0x6C,0xA9,0x23,0x63, + 0x7F,0x15,0x1C,0x1F,0x16,0x86,0x10,0x4A,0x35,0x9E,0x35,0xD7,0x80,0x0F,0xFF,0xBD, + 0xBF,0xCD,0x17,0x47,0x25,0x3A,0xF5,0xA3,0xDF,0xFF,0x00,0xB7,0x23,0x27,0x1A,0x16, + 0x7A,0x56,0xA2,0x7E,0xA9,0xEA,0x63,0xF5,0x60,0x17,0x58,0xFD,0x7C,0x6C,0xFE,0x57 +},{ + 0xAE,0x4F,0xAE,0xAE,0x1D,0x3A,0xD3,0xD9,0x6F,0xA4,0xC3,0x3B,0x7A,0x30,0x39,0xC0, + 0x2D,0x66,0xC4,0xF9,0x51,0x42,0xA4,0x6C,0x18,0x7F,0x9A,0xB4,0x9A,0xF0,0x8E,0xC6, + 0xCF,0xFA,0xA6,0xB7,0x1C,0x9A,0xB7,0xB4,0x0A,0xF2,0x1F,0x66,0xC2,0xBE,0xC6,0xB6, + 0xBF,0x71,0xC5,0x72,0x36,0x90,0x4F,0x35,0xFA,0x68,0x40,0x7A,0x46,0x64,0x7D,0x6E +},{ + 0xF4,0xC7,0x0E,0x16,0xEE,0xAA,0xC5,0xEC,0x51,0xAC,0x86,0xFE,0xBF,0x24,0x09,0x54, + 0x39,0x9E,0xC6,0xC7,0xE6,0xBF,0x87,0xC9,0xD3,0x47,0x3E,0x33,0x19,0x7A,0x93,0xC9, + 0x09,0x92,0xAB,0xC5,0x2D,0x82,0x2C,0x37,0x06,0x47,0x69,0x83,0x28,0x4A,0x05,0x04, + 0x35,0x17,0x45,0x4C,0xA2,0x3C,0x4A,0xF3,0x88,0x86,0x56,0x4D,0x3A,0x14,0xD4,0x93 +},{ + 0x9B,0x1F,0x5B,0x42,0x4D,0x93,0xC9,0xA7,0x03,0xE7,0xAA,0x02,0x0C,0x6E,0x41,0x41, + 0x4E,0xB7,0xF8,0x71,0x9C,0x36,0xDE,0x1E,0x89,0xB4,0x44,0x3B,0x4D,0xDB,0xC4,0x9A, + 0xF4,0x89,0x2B,0xCB,0x92,0x9B,0x06,0x90,0x69,0xD1,0x8D,0x2B,0xD1,0xA5,0xC4,0x2F, + 0x36,0xAC,0xC2,0x35,0x59,0x51,0xA8,0xD9,0xA4,0x7F,0x0D,0xD4,0xBF,0x02,0xE7,0x1E +},{ + 0x37,0x8F,0x5A,0x54,0x16,0x31,0x22,0x9B,0x94,0x4C,0x9A,0xD8,0xEC,0x16,0x5F,0xDE, + 0x3A,0x7D,0x3A,0x1B,0x25,0x89,0x42,0x24,0x3C,0xD9,0x55,0xB7,0xE0,0x0D,0x09,0x84, + 0x80,0x0A,0x44,0x0B,0xDB,0xB2,0xCE,0xB1,0x7B,0x2B,0x8A,0x9A,0xA6,0x07,0x9C,0x54, + 0x0E,0x38,0xDC,0x92,0xCB,0x1F,0x2A,0x60,0x72,0x61,0x44,0x51,0x83,0x23,0x5A,0xDB +},{ + 0xAB,0xBE,0xDE,0xA6,0x80,0x05,0x6F,0x52,0x38,0x2A,0xE5,0x48,0xB2,0xE4,0xF3,0xF3, + 0x89,0x41,0xE7,0x1C,0xFF,0x8A,0x78,0xDB,0x1F,0xFF,0xE1,0x8A,0x1B,0x33,0x61,0x03, + 0x9F,0xE7,0x67,0x02,0xAF,0x69,0x33,0x4B,0x7A,0x1E,0x6C,0x30,0x3B,0x76,0x52,0xF4, + 0x36,0x98,0xFA,0xD1,0x15,0x3B,0xB6,0xC3,0x74,0xB4,0xC7,0xFB,0x98,0x45,0x9C,0xED +},{ + 0x7B,0xCD,0x9E,0xD0,0xEF,0xC8,0x89,0xFB,0x30,0x02,0xC6,0xCD,0x63,0x5A,0xFE,0x94, + 0xD8,0xFA,0x6B,0xBB,0xEB,0xAB,0x07,0x61,0x20,0x01,0x80,0x21,0x14,0x84,0x66,0x79, + 0x8A,0x1D,0x71,0xEF,0xEA,0x48,0xB9,0xCA,0xEF,0xBA,0xCD,0x1D,0x7D,0x47,0x6E,0x98, + 0xDE,0xA2,0x59,0x4A,0xC0,0x6F,0xD8,0x5D,0x6B,0xCA,0xA4,0xCD,0x81,0xF3,0x2D,0x1B +},{ + 0x37,0x8E,0xE7,0x67,0xF1,0x16,0x31,0xBA,0xD2,0x13,0x80,0xB0,0x04,0x49,0xB1,0x7A, + 0xCD,0xA4,0x3C,0x32,0xBC,0xDF,0x1D,0x77,0xF8,0x20,0x12,0xD4,0x30,0x21,0x9F,0x9B, + 0x5D,0x80,0xEF,0x9D,0x18,0x91,0xCC,0x86,0xE7,0x1D,0xA4,0xAA,0x88,0xE1,0x28,0x52, + 0xFA,0xF4,0x17,0xD5,0xD9,0xB2,0x1B,0x99,0x48,0xBC,0x92,0x4A,0xF1,0x1B,0xD7,0x20 +}}; + + +static void AddModulo512(const void *a,const void *b,void *c) +{ + const unsigned char *A=a, *B=b; + unsigned char *C=c; + int t = 0; +#ifdef FULL_UNROLL +#define ADDBYTE_8(i) t = A[i] + B[i] + (t >> 8); C[i] = t & 0xFF; + + ADDBYTE_8(63) + ADDBYTE_8(62) + ADDBYTE_8(61) + ADDBYTE_8(60) + ADDBYTE_8(59) + ADDBYTE_8(58) + ADDBYTE_8(57) + ADDBYTE_8(56) + ADDBYTE_8(55) + ADDBYTE_8(54) + ADDBYTE_8(53) + ADDBYTE_8(52) + ADDBYTE_8(51) + ADDBYTE_8(50) + ADDBYTE_8(49) + ADDBYTE_8(48) + ADDBYTE_8(47) + ADDBYTE_8(46) + ADDBYTE_8(45) + ADDBYTE_8(44) + ADDBYTE_8(43) + ADDBYTE_8(42) + ADDBYTE_8(41) + ADDBYTE_8(40) + ADDBYTE_8(39) + ADDBYTE_8(38) + ADDBYTE_8(37) + ADDBYTE_8(36) + ADDBYTE_8(35) + ADDBYTE_8(34) + ADDBYTE_8(33) + ADDBYTE_8(32) + ADDBYTE_8(31) + ADDBYTE_8(30) + ADDBYTE_8(29) + ADDBYTE_8(28) + ADDBYTE_8(27) + ADDBYTE_8(26) + ADDBYTE_8(25) + ADDBYTE_8(24) + ADDBYTE_8(23) + ADDBYTE_8(22) + ADDBYTE_8(21) + ADDBYTE_8(20) + ADDBYTE_8(19) + ADDBYTE_8(18) + ADDBYTE_8(17) + ADDBYTE_8(16) + ADDBYTE_8(15) + ADDBYTE_8(14) + ADDBYTE_8(13) + ADDBYTE_8(12) + ADDBYTE_8(11) + ADDBYTE_8(10) + ADDBYTE_8(9) + ADDBYTE_8(8) + ADDBYTE_8(7) + ADDBYTE_8(6) + ADDBYTE_8(5) + ADDBYTE_8(4) + ADDBYTE_8(3) + ADDBYTE_8(2) + ADDBYTE_8(1) + ADDBYTE_8(0) + +#else + int i = 0; + + for(i=63;i>=0;i--) + { + t = A[i] + B[i] + (t >> 8); + C[i] = t & 0xFF; + } +#endif +} + +static void AddXor512(const void *a,const void *b,void *c) +{ + const unsigned long long *A=a, *B=b; + unsigned long long *C=c; +#ifdef FULL_UNROLL + C[0] = A[0] ^ B[0]; + C[1] = A[1] ^ B[1]; + C[2] = A[2] ^ B[2]; + C[3] = A[3] ^ B[3]; + C[4] = A[4] ^ B[4]; + C[5] = A[5] ^ B[5]; + C[6] = A[6] ^ B[6]; + C[7] = A[7] ^ B[7]; +#else + int i = 0; + + for(i=0; i<8; i++) { + C[i] = A[i] ^ B[i]; + } +#endif +} + +static void F(unsigned char *state) +{ + unsigned long long return_state[8]; + register unsigned long long r = 0; + r ^= TG[0][state[56]]; + r ^= TG[1][state[48]]; + r ^= TG[2][state[40]]; + r ^= TG[3][state[32]]; + r ^= TG[4][state[24]]; + r ^= TG[5][state[16]]; + r ^= TG[6][state[8]]; + r ^= TG[7][state[0]]; + return_state[0] = r; + r = 0; + + r ^= TG[0][state[57]]; + r ^= TG[1][state[49]]; + r ^= TG[2][state[41]]; + r ^= TG[3][state[33]]; + r ^= TG[4][state[25]]; + r ^= TG[5][state[17]]; + r ^= TG[6][state[9]]; + r ^= TG[7][state[1]]; + return_state[1] = r; + r = 0; + + r ^= TG[0][state[58]]; + r ^= TG[1][state[50]]; + r ^= TG[2][state[42]]; + r ^= TG[3][state[34]]; + r ^= TG[4][state[26]]; + r ^= TG[5][state[18]]; + r ^= TG[6][state[10]]; + r ^= TG[7][state[2]]; + return_state[2] = r; + r = 0; + + r ^= TG[0][state[59]]; + r ^= TG[1][state[51]]; + r ^= TG[2][state[43]]; + r ^= TG[3][state[35]]; + r ^= TG[4][state[27]]; + r ^= TG[5][state[19]]; + r ^= TG[6][state[11]]; + r ^= TG[7][state[3]]; + return_state[3] = r; + r = 0; + + r ^= TG[0][state[60]]; + r ^= TG[1][state[52]]; + r ^= TG[2][state[44]]; + r ^= TG[3][state[36]]; + r ^= TG[4][state[28]]; + r ^= TG[5][state[20]]; + r ^= TG[6][state[12]]; + r ^= TG[7][state[4]]; + return_state[4] = r; + r = 0; + + r ^= TG[0][state[61]]; + r ^= TG[1][state[53]]; + r ^= TG[2][state[45]]; + r ^= TG[3][state[37]]; + r ^= TG[4][state[29]]; + r ^= TG[5][state[21]]; + r ^= TG[6][state[13]]; + r ^= TG[7][state[5]]; + return_state[5] = r; + r = 0; + + r ^= TG[0][state[62]]; + r ^= TG[1][state[54]]; + r ^= TG[2][state[46]]; + r ^= TG[3][state[38]]; + r ^= TG[4][state[30]]; + r ^= TG[5][state[22]]; + r ^= TG[6][state[14]]; + r ^= TG[7][state[6]]; + return_state[6] = r; + r = 0; + + r ^= TG[0][state[63]]; + r ^= TG[1][state[55]]; + r ^= TG[2][state[47]]; + r ^= TG[3][state[39]]; + r ^= TG[4][state[31]]; + r ^= TG[5][state[23]]; + r ^= TG[6][state[15]]; + r ^= TG[7][state[7]]; + return_state[7] = r; + + memcpy(state,(unsigned char*)return_state,64); +} + +#define KeySchedule(K,i) AddXor512(K,C[i],K); F(K); + +static void E(unsigned char *K,const unsigned char *m, unsigned char *state) +{ +#ifdef FULL_UNROLL + AddXor512(m,K,state); + + F(state); + KeySchedule(K,0); + AddXor512(state,K,state); + + F(state); + KeySchedule(K,1); + AddXor512(state,K,state); + + F(state); + KeySchedule(K,2); + AddXor512(state,K,state); + + F(state); + KeySchedule(K,3); + AddXor512(state,K,state); + + F(state); + KeySchedule(K,4); + AddXor512(state,K,state); + + F(state); + KeySchedule(K,5); + AddXor512(state,K,state); + + F(state); + KeySchedule(K,6); + AddXor512(state,K,state); + + F(state); + KeySchedule(K,7); + AddXor512(state,K,state); + + F(state); + KeySchedule(K,8); + AddXor512(state,K,state); + + F(state); + KeySchedule(K,9); + AddXor512(state,K,state); + + F(state); + KeySchedule(K,10); + AddXor512(state,K,state); + + F(state); + KeySchedule(K,11); + AddXor512(state,K,state); +#else + int i = 0; + + AddXor512(m,K,state); + + for(i=0;i<12;i++) { + F(state); + KeySchedule(K,i); + AddXor512(state,K,state); + } +#endif +} + +static void g_N(const unsigned char *N,unsigned char *h,const unsigned char *m) +{ + unsigned char t[64], K[64]; + + AddXor512(N,h,K); + + F(K); + + E(K,m,t); + + AddXor512(t,h,t); + AddXor512(t,m,h); +} + +static void hash_X(unsigned char *IV,const unsigned char *message,unsigned long long length,unsigned char *out) +{ + unsigned char v512[64] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00 + }; + unsigned char v0[64] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; + unsigned char Sigma[64] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; + unsigned char N[64] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; + unsigned char m[64], *hash = IV; + unsigned long long len = length; + + // Stage 2 + while (len >= 512) + { + memcpy(m, message + len/8 - 63 - ( (len & 0x7) == 0 ), 64); + + g_N(N,hash,m); + AddModulo512(N,v512,N); + AddModulo512(Sigma,m,Sigma); + len -= 512; + } + + memset(m,0,64); + memcpy(m + 63 - len/8 + ( (len & 0x7) == 0 ), message, len/8 + 1 - ( (len & 0x7) == 0 )); + + // Stage 3 + m[ 63 - len/8 ] |= (1 << (len & 0x7)); + + g_N(N,hash,m); + v512[63] = len & 0xFF; + v512[62] = (unsigned char) (len >> 8); + AddModulo512(N,v512,N); + + AddModulo512(Sigma,m,Sigma); + + g_N(v0,hash,N); + g_N(v0,hash,Sigma); + + memcpy(out, hash, 64); +} + +static void hash_512(const unsigned char *message, unsigned long long length, unsigned char *out) +{ + unsigned char IV[64] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; + + hash_X(IV,message,length,out); +} + +static void hash_256(const unsigned char *message, unsigned long long length, unsigned char *out) +{ + unsigned char IV[64] = { + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 + }; + unsigned char hash[64]; + + hash_X(IV,message,length,hash); + + memcpy(out,hash,32); +} + + + + + +/* see sph_gost.h */ +void +sph_gost256_init(void *cc) +{ + //gost_init(cc, 256); +} + +/* see sph_gost.h */ +void +sph_gost256(void *cc, const void *data, size_t len) +{ + hash_256(data, 8*len, cc); +} + +/* see sph_gost.h */ +void +sph_gost256_close(void *cc, void *dst) +{ + //sph_gost256_addbits_and_close(cc, 0, 0, dst); + memcpy(dst, cc, 32); +} + +/* see sph_gost.h */ +void +sph_gost256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + //gost_close32(cc, ub, n, dst); +} + +/* see sph_gost.h */ +void +sph_gost512_init(void *cc) +{ + //gost_init(cc, 512); +} + +/* see sph_gost.h */ +void +sph_gost512(void *cc, const void *data, size_t len) +{ + hash_512(data, 8*len, cc); +} + +/* see sph_gost.h */ +void +sph_gost512_close(void *cc, void *dst) +{ + //sph_gost512_addbits_and_close(cc, 0, 0, dst); + memcpy(dst, cc, 64); +} + +/* see sph_gost.h */ +void +sph_gost512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + //gost_close64(cc, ub, n, dst); +} + + +#ifdef __cplusplus +} +#endif diff --git a/stratum/sha3/sph_streebog.h b/stratum/sha3/sph_streebog.h new file mode 100644 index 000000000..aa8f69d0d --- /dev/null +++ b/stratum/sha3/sph_streebog.h @@ -0,0 +1,185 @@ +/* $Id: sph_gost.h 216 2010-06-08 09:46:57Z tp $ */ +/** + * GOST interface. This is the interface for GOST R 12 with the + * recommended parameters for SHA-3, with output lengths 256 + * and 512 bits. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @file sph_gost.h + * @author Mish + */ + +#ifndef SPH_GOST_H__ +#define SPH_GOST_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include +#include "sph_types.h" + +/** + * Output size (in bits) for GOST-256. + */ +#define SPH_SIZE_gost256 256 + +/** + * Output size (in bits) for GOST-512. + */ +#define SPH_SIZE_gost512 512 + +/** + * This structure is a context for Keccak computations: it contains the + * intermediate values and some data from the last entered block. Once a + * GOST computation has been performed, the context can be reused for + * another computation. + * + * The contents of this structure are private. A running GOST computation + * can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ + +/** + * This structure is a context for Gost-256 computations. + */ + +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[32]; /* first field, for alignment */ + size_t ptr; + sph_u32 V[3][8]; +#endif +} sph_gost256_context; + +/** + * This structure is a context for Gost-512 computations. + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[64]; /* first field, for alignment */ + size_t ptr; + sph_u32 V[5][8]; +#endif +} sph_gost512_context; + + +/** + * Initialize a GOST-256 context. This process performs no memory allocation. + * + * @param cc the GOST-256 context (pointer to a + * sph_gost256_context) + */ +void sph_gost256_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Gost-256 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_gost256(void *cc, const void *data, size_t len); + +/** + * Terminate the current GOST-256 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (32 bytes). The context is automatically + * reinitialized. + * + * @param cc the GOST-256 context + * @param dst the destination buffer + */ +void sph_gost256_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (32 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the GOST-256 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_gost256_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a Gost-512 context. This process performs no memory allocation. + * + * @param cc the GOST-512 context (pointer to a + * sph_gost512_context) + */ +void sph_gost512_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the GOST-512 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_gost512(void *cc, const void *data, size_t len); + +/** + * Terminate the current GOST-512 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (64 bytes). The context is automatically + * reinitialized. + * + * @param cc the GOST-512 context + * @param dst the destination buffer + */ +void sph_gost512_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (64 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the GOST-512 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_gost512_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/stratum/stratum.cpp b/stratum/stratum.cpp index 47979ee0b..28dccf8f0 100644 --- a/stratum/stratum.cpp +++ b/stratum/stratum.cpp @@ -30,6 +30,9 @@ char g_stratum_coin_exclude[256]; char g_stratum_algo[256]; double g_stratum_difficulty; +double g_stratum_nicehash_difficulty; +double g_stratum_nicehash_min_diff; +double g_stratum_nicehash_max_diff; double g_stratum_min_diff; double g_stratum_max_diff; @@ -81,26 +84,7 @@ static void scrypt_hash(const char* input, char* output, uint32_t len) static void scryptn_hash(const char* input, char* output, uint32_t len) { - time_t time_table[][2] = - { - {2048, 1389306217}, - {4096, 1456415081}, - {8192, 1506746729}, - {16384, 1557078377}, - {32768, 1657741673}, - {65536, 1859068265}, - {131072, 2060394857}, - {262144, 1722307603}, - {524288, 1769642992}, - {0, 0}, - }; - - for(int i=0; time_table[i][0]; i++) - if(time(NULL) < time_table[i+1][1]) - { - scrypt_N_R_1_256(input, output, time_table[i][0], 1, len); - return; - } +scrypt_N_R_1_256(input, output, 2048, 1, len); } static void neoscrypt_hash(const char* input, char* output, uint32_t len) @@ -110,99 +94,105 @@ static void neoscrypt_hash(const char* input, char* output, uint32_t len) YAAMP_ALGO g_algos[] = { - {"sha256", sha256_double_hash, 1, 0, 0}, - {"scrypt", scrypt_hash, 0x10000, 0, 0}, - {"scryptn", scryptn_hash, 0x10000, 0, 0}, - {"neoscrypt", neoscrypt_hash, 0x10000, 0, 0}, - - {"c11", c11_hash, 1, 0, 0}, - {"x11", x11_hash, 1, 0, 0}, - {"x12", x12_hash, 1, 0, 0}, - {"x13", x13_hash, 1, 0, 0}, - {"x14", x14_hash, 1, 0, 0}, - {"x15", x15_hash, 1, 0, 0}, - {"x17", x17_hash, 1, 0, 0}, - {"x22i", x22i_hash, 1, 0, 0}, - - {"x11evo", x11evo_hash, 1, 0, 0}, - {"xevan", xevan_hash, 0x100, 0, 0}, - - {"x16r", x16r_hash, 0x100, 0, 0}, - {"x16s", x16s_hash, 0x100, 0, 0}, - {"timetravel", timetravel_hash, 0x100, 0, 0}, - {"bitcore", timetravel10_hash, 0x100, 0, 0}, - {"exosis", exosis_hash, 0x100, 0, 0}, - {"hsr", hsr_hash, 1, 0, 0}, - {"hmq1725", hmq17_hash, 0x10000, 0, 0}, - - {"jha", jha_hash, 0x10000, 0}, - + {"a5a", a5a_hash, 0x10000, 0, 0}, + {"aergo", aergo_hash, 1, 0, 0}, {"allium", allium_hash, 0x100, 0, 0}, - {"lyra2", lyra2re_hash, 0x80, 0, 0}, - {"lyra2v2", lyra2v2_hash, 0x100, 0, 0}, - {"lyra2z", lyra2z_hash, 0x100, 0, 0}, - + {"argon2d-crds", argon2d_crds_hash, 0x10000, 0, 0 }, // Credits Argon2d Implementation + {"argon2d-dyn", argon2d_dyn_hash, 0x10000, 0, 0 }, // Dynamic Argon2d Implementation + {"argon2d-uis", argon2d_uis_hash, 0x10000, 0, 0 }, // Argon2d Implementation + {"argon2m", argon2m_hash, 0x10000, 0, 0}, + {"astralhash", astralhash_hash, 0x100, 0, 0}, + {"balloon", balloon_hash, 1, 0, 0}, {"bastion", bastion_hash, 1, 0 }, + {"bcd", bcd_hash, 1, 0, 0}, + {"bitcore", timetravel10_hash, 0x100, 0, 0}, {"blake", blake_hash, 1, 0 }, - {"blakecoin", blakecoin_hash, 1 /*0x100*/, 0, sha256_hash_hex }, {"blake2b", blake2b_hash, 1, 0 }, {"blake2s", blake2s_hash, 1, 0 }, - {"vanilla", blakecoin_hash, 1, 0 }, + {"blakecoin", blakecoin_hash, 1 /*0x100*/, 0, sha256_hash_hex }, + {"bmw", bmw_hash, 1, 0, 0}, + {"bmw512", bmw512_hash, 0x100, 0, 0}, + {"c11", c11_hash, 1, 0, 0}, {"decred", decred_hash, 1, 0 }, - + {"dedal", dedal_hash, 0x100, 0, 0}, {"deep", deep_hash, 1, 0, 0}, + {"dmd-gr", groestl_hash, 0x100, 0, 0}, /* diamond (double groestl) */ + {"exosis", exosis_hash, 0x100, 0, 0}, {"fresh", fresh_hash, 0x100, 0, 0}, - {"quark", quark_hash, 1, 0, 0}, - {"nist5", nist5_hash, 1, 0, 0}, - {"qubit", qubit_hash, 1, 0, 0}, + {"geek", geek_hash, 1, 0, 0}, {"groestl", groestl_hash, 0x100, 0, sha256_hash_hex }, /* groestlcoin */ - {"dmd-gr", groestl_hash, 0x100, 0, 0}, /* diamond (double groestl) */ - {"myr-gr", groestlmyriad_hash, 1, 0, 0}, /* groestl + sha 64 */ - {"skein", skein_hash, 1, 0, 0}, - {"sonoa", sonoa_hash, 1, 0, 0}, - {"tribus", tribus_hash, 1, 0, 0}, + {"hex", hex_hash, 0x100, 0, sha256_hash_hex }, + {"hmq1725", hmq17_hash, 0x10000, 0, 0}, + {"hsr", hsr_hash, 1, 0, 0}, + {"jeonghash", jeonghash_hash, 0x100, 0, 0}, + {"jha", jha_hash, 0x10000, 0}, {"keccak", keccak256_hash, 0x80, 0, sha256_hash_hex }, {"keccakc", keccak256_hash, 0x100, 0, 0}, - {"hex", hex_hash, 0x100, 0, sha256_hash_hex }, - - {"phi", phi_hash, 1, 0, 0}, - {"phi2", phi2_hash, 0x100, 0, 0}, - - {"polytimos", polytimos_hash, 1, 0, 0}, - {"skunk", skunk_hash, 1, 0, 0}, - - {"bmw", bmw_hash, 1, 0, 0}, {"lbk3", lbk3_hash, 0x100, 0, 0}, {"lbry", lbry_hash, 0x100, 0, 0}, {"luffa", luffa_hash, 1, 0, 0}, + {"lyra2", lyra2re_hash, 0x80, 0, 0}, + {"lyra2v2", lyra2v2_hash, 0x100, 0, 0}, + {"lyra2v3", lyra2v3_hash, 0x100, 0, 0}, + {"lyra2vc0ban", lyra2vc0ban_hash, 0x100, 0, 0}, + {"lyra2z330", lyra2z330_hash, 0x100, 0, 0}, + {"lyra2z", lyra2z_hash, 0x100, 0, 0}, + {"lyra2zz", lyra2zz_hash, 0x100, 0, 0}, + {"m7m", m7m_hash, 0x10000, 0, 0}, + {"minotaur", minotaur_hash, 1, 0, 0}, + {"myr-gr", groestlmyriad_hash, 1, 0, 0}, /* groestl + sha 64 */ + {"neoscrypt", neoscrypt_hash, 0x10000, 0, 0}, + {"nist5", nist5_hash, 1, 0, 0}, + {"pawelhash", pawelhash_hash, 0x100, 0, 0}, {"penta", penta_hash, 1, 0, 0}, - {"rainforest", rainforest_hash, 0x100, 0, 0}, + {"phi", phi_hash, 1, 0, 0}, + {"phi2", phi2_hash, 0x100, 0, 0}, + {"phi1612", phi1612_hash, 1, 0, 0}, + {"pipe", pipe_hash, 1,0,0}, + {"polytimos", polytimos_hash, 1, 0, 0}, + {"quark", quark_hash, 1, 0, 0}, + {"qubit", qubit_hash, 1, 0, 0}, + {"rainforest", rainforest_hash, 1, 0, 0}, + {"scrypt", scrypt_hash, 0x10000, 0, 0}, + {"scryptn", scryptn_hash, 0x10000, 0, 0}, + {"sha256", sha256_double_hash, 1, 0, 0}, + {"sha256q", sha256q_hash, 1, 0, 0}, // sha256 4x + {"sha256t", sha256t_hash, 1, 0, 0}, // sha256 3x + {"sib", sib_hash, 1, 0, 0}, + {"skein", skein_hash, 1, 0, 0}, {"skein2", skein2_hash, 1, 0, 0}, - {"yescrypt", yescrypt_hash, 0x10000, 0, 0}, - {"yescryptR16", yescryptR16_hash, 0x10000, 0, 0 }, - {"yescryptR32", yescryptR32_hash, 0x10000, 0, 0 }, - {"zr5", zr5_hash, 1, 0, 0}, - - {"a5a", a5a_hash, 0x10000, 0, 0}, - {"hive", hive_hash, 0x10000, 0, 0}, - {"m7m", m7m_hash, 0x10000, 0, 0}, + {"skunk", skunk_hash, 1, 0, 0}, + {"sonoa", sonoa_hash, 1, 0, 0}, + {"timetravel", timetravel_hash, 0x100, 0, 0}, + {"tribus", tribus_hash, 1, 0, 0}, + {"vanilla", blakecoin_hash, 1, 0 }, {"veltor", veltor_hash, 1, 0, 0}, {"velvet", velvet_hash, 0x10000, 0, 0}, - {"argon2", argon2a_hash, 0x10000, 0, sha256_hash_hex }, - {"argon2d-dyn", argon2d_dyn_hash, 0x10000, 0, 0 }, // Dynamic Argon2d Implementation {"vitalium", vitalium_hash, 1, 0, 0}, - {"aergo", aergo_hash, 1, 0, 0}, - - {"sha256t", sha256t_hash, 1, 0, 0}, // sha256 3x - - {"sha256q", sha256q_hash, 1, 0, 0}, // sha256 4x - - {"sib", sib_hash, 1, 0, 0}, - {"whirlcoin", whirlpool_hash, 1, 0, sha256_hash_hex }, /* old sha merkleroot */ {"whirlpool", whirlpool_hash, 1, 0 }, /* sha256d merkleroot */ {"whirlpoolx", whirlpoolx_hash, 1, 0, 0}, - + {"x11", x11_hash, 1, 0, 0}, + {"x11evo", x11evo_hash, 1, 0, 0}, + {"x12", x12_hash, 1, 0, 0}, + {"x13", x13_hash, 1, 0, 0}, + {"x14", x14_hash, 1, 0, 0}, + {"x15", x15_hash, 1, 0, 0}, + {"x16r", x16r_hash, 0x100, 0, 0}, + {"x16rv2", x16rv2_hash, 0x100, 0, 0}, + {"x16rt", x16rt_hash, 0x100, 0, 0}, + {"x16s", x16s_hash, 0x100, 0, 0}, + {"x17", x17_hash, 1, 0, 0}, + {"x17r", x17r_hash, 1, 0, 0}, //ufo-project + {"x18", x18_hash, 1, 0, 0}, + {"x20r", x20r_hash, 0x100, 0, 0}, + {"x21s", x21s_hash, 0x100, 0, 0}, + {"x22i", x22i_hash, 1, 0, 0}, + {"x25x", x25x_hash, 1, 0, 0}, + {"xevan", xevan_hash, 0x100, 0, 0}, + {"yespower", yespower_hash, 0x10000, 0, 0}, + {"yespowerurx", yespowerurx_hash, 0x10000, 0, 0}, + {"zr5", zr5_hash, 1, 0, 0}, {"", NULL, 0, 0}, }; @@ -265,8 +255,11 @@ int main(int argc, char **argv) strcpy(g_stratum_algo, iniparser_getstring(ini, "STRATUM:algo", NULL)); g_stratum_difficulty = iniparser_getdouble(ini, "STRATUM:difficulty", 16); + g_stratum_nicehash_difficulty = iniparser_getdouble(ini, "STRATUM:nicehash", 16); g_stratum_min_diff = iniparser_getdouble(ini, "STRATUM:diff_min", g_stratum_difficulty/2); g_stratum_max_diff = iniparser_getdouble(ini, "STRATUM:diff_max", g_stratum_difficulty*8192); + g_stratum_nicehash_min_diff = iniparser_getdouble(ini, "STRATUM:nicehash_diff_min", g_stratum_nicehash_difficulty/2); + g_stratum_nicehash_max_diff = iniparser_getdouble(ini, "STRATUM:nicehash_diff_max", g_stratum_nicehash_difficulty*8192); g_stratum_max_cons = iniparser_getint(ini, "STRATUM:max_cons", 5000); g_stratum_max_ttf = iniparser_getint(ini, "STRATUM:max_ttf", 0x70000000); @@ -476,4 +469,3 @@ void *stratum_thread(void *p) pthread_detach(thread); } } - diff --git a/stratum/stratum.h b/stratum/stratum.h index 5aa4a75ba..4c235987c 100644 --- a/stratum/stratum.h +++ b/stratum/stratum.h @@ -83,6 +83,9 @@ extern char g_stratum_algo[256]; extern double g_stratum_difficulty; extern double g_stratum_min_diff; extern double g_stratum_max_diff; +extern double g_stratum_nicehash_difficulty; +extern double g_stratum_nicehash_min_diff; +extern double g_stratum_nicehash_max_diff; extern int g_stratum_max_cons; extern int g_stratum_max_ttf; @@ -147,70 +150,89 @@ void scrypt_N_R_1_256(const char* input, char* output, uint32_t N, uint32_t R, u void sha256_hash_hex(const char *input, char *output, unsigned int len); void sha256_double_hash_hex(const char *input, char *output, unsigned int len); + #include "algos/a5a.h" -#include "algos/c11.h" -#include "algos/x11.h" -#include "algos/x11evo.h" -#include "algos/x12.h" -#include "algos/x13.h" -#include "algos/x14.h" -#include "algos/x15.h" -#include "algos/x16r.h" -#include "algos/x16s.h" -#include "algos/x17.h" -#include "algos/x22i.h" -#include "algos/xevan.h" -#include "algos/hmq17.h" -#include "algos/nist5.h" -#include "algos/fresh.h" -#include "algos/hsr14.h" -#include "algos/quark.h" -#include "algos/neoscrypt.h" +#include "algos/aergo.h" #include "algos/allium.h" -#include "algos/lyra2re.h" -#include "algos/lyra2v2.h" -#include "algos/lyra2z.h" +#include "algos/argon2d.h" +#include "algos/argon2m.h" +#include "algos/balloon.h" +#include "algos/bastion.h" +#include "algos/bcd.h" +#include "algos/bitcore.h" #include "algos/blake.h" -#include "algos/blakecoin.h" #include "algos/blake2b.h" #include "algos/blake2s.h" -#include "algos/qubit.h" +#include "algos/blakecoin.h" +#include "algos/bmw.h" +#include "algos/bmw512.h" +#include "algos/c11.h" +#include "algos/dedal.h" +#include "algos/deep.h" +#include "algos/exosis.h" +#include "algos/fresh.h" +#include "algos/geek.h" +#include "algos/gltalgos.h" #include "algos/groestl.h" +#include "algos/hex.h" +#include "algos/hmq17.h" +#include "algos/hsr14.h" #include "algos/jha.h" -#include "algos/skein.h" #include "algos/keccak.h" -#include "algos/sha256t.h" -#include "algos/sha256q.h" -#include "algos/skunk.h" -#include "algos/timetravel.h" -#include "algos/bitcore.h" - -#include "algos/bastion.h" -#include "algos/bmw.h" -#include "algos/deep.h" #include "algos/lbk3.h" #include "algos/lbry.h" #include "algos/luffa.h" -#include "algos/pentablake.h" -#include "algos/rainforest.h" -#include "algos/whirlpool.h" -#include "algos/whirlpoolx.h" -#include "algos/skein2.h" -#include "algos/yescrypt.h" -#include "algos/zr5.h" -#include "algos/hive.h" -#include "algos/sib.h" +#include "algos/lyra2re.h" +#include "algos/lyra2v2.h" +#include "algos/lyra2v3.h" +#include "algos/lyra2vc0ban.h" +#include "algos/lyra2z.h" +#include "algos/lyra2zz.h" +#include "algos/lyra2z330.h" #include "algos/m7m.h" +#include "algos/minotaur.h" +#include "algos/neoscrypt.h" +#include "algos/nist5.h" +#include "algos/pentablake.h" #include "algos/phi.h" #include "algos/phi2.h" +#include "algos/phi1612.h" +#include "algos/pipehash.h" #include "algos/polytimos.h" +#include "algos/quark.h" +#include "algos/qubit.h" +#include "algos/rainforest.h" +#include "algos/sha256q.h" +#include "algos/sha256t.h" +#include "algos/sib.h" +#include "algos/skein.h" +#include "algos/skein2.h" +#include "algos/skunk.h" #include "algos/sonoa.h" +#include "algos/timetravel.h" #include "algos/tribus.h" #include "algos/veltor.h" #include "algos/velvet.h" -#include "algos/argon2a.h" #include "algos/vitalium.h" -#include "algos/aergo.h" -#include "algos/hex.h" -#include "algos/argon2d-dyn.h" -#include "algos/exosis.h" +#include "algos/whirlpool.h" +#include "algos/whirlpoolx.h" +#include "algos/x11.h" +#include "algos/x11evo.h" +#include "algos/x12.h" +#include "algos/x13.h" +#include "algos/x14.h" +#include "algos/x15.h" +#include "algos/x16r.h" +#include "algos/x16rv2.h" +#include "algos/x16rt.h" +#include "algos/x16s.h" +#include "algos/x17.h" +#include "algos/x17r.h" +#include "algos/x18.h" +#include "algos/x20r.h" +#include "algos/x21s.h" +#include "algos/x22i.h" +#include "algos/x25x.h" +#include "algos/xevan.h" +#include "algos/yespower/yespower.h" +#include "algos/zr5.h" diff --git a/stratum/util.cpp b/stratum/util.cpp index 92f284a80..a2760c4da 100644 --- a/stratum/util.cpp +++ b/stratum/util.cpp @@ -479,6 +479,26 @@ void ser_number(int n, char *a) // printf("ser_number %d, %s\n", n, a); } +void ser_compactsize(uint64_t nSize, char *a) +{ + if (nSize < 253) + { + sprintf(a, "%02lx", nSize); + } + else if (nSize <= (unsigned short)-1) + { + sprintf(a, "%02x%04lx", 253, nSize); + } + else if (nSize <= (unsigned int)-1) + { + sprintf(a, "%02x%08lx", 254, nSize); + } + else + { + sprintf(a, "%02x%016lx", 255, nSize); + } +} + void ser_string_be(const char *input, char *output, int len) { for(int i=0; i= (double)0x00800000) { + shift++; + ftarg /= 256.0; + } + uint32_t nBits = (int)ftarg + (shift << 24); + shift = (nBits >> 24) & 0x00ff; + nBits &= 0x00FFFFFF; + targ[shift - 1] = nBits >> 16; + targ[shift - 2] = nBits >> 8; + targ[shift - 3] = nBits; + uint64_t starget = * (uint64_t *) &targ[24]; + return (starget); +} + //def uint256_from_compact(c): // c = int(c) // nbytes = (c >> 24) & 0xFF @@ -769,3 +814,27 @@ void sha256_hash_hex(const char *input, char *output, unsigned int len) hexlify(output, (unsigned char *)output1, 32); } +uint64_t share_to_target(double diff) +{ + int i, shift = 29; + unsigned char targ[32]; + for (i=0; i<32; i++) + targ[i]=0; + double ftarg = (double)0x0000ffff / diff; + while (ftarg < (double)0x00008000) { + shift--; + ftarg *= 256.0; + } + while (ftarg >= (double)0x00800000) { + shift++; + ftarg /= 256.0; + } + uint32_t nBits = (int)ftarg + (shift << 24); + shift = (nBits >> 24) & 0x00ff; + nBits &= 0x00FFFFFF; + targ[shift - 1] = nBits >> 16; + targ[shift - 2] = nBits >> 8; + targ[shift - 3] = nBits; + uint64_t starget = * (uint64_t *) &targ[24]; + return (starget); +} diff --git a/stratum/util.h b/stratum/util.h index bf57bfd27..151f6d086 100644 --- a/stratum/util.h +++ b/stratum/util.h @@ -80,6 +80,7 @@ void base64_encode(char *base64, const char *normal); void base64_decode(char *normal, const char *base64); void ser_number(int n, char *s); +void ser_compactsize(uint64_t nSize, char *a); void ser_string_be(const char *input, char *output, int len); void ser_string_be2(const char *input, char *output, int len); @@ -96,6 +97,7 @@ unsigned int htoi(const char *s); uint64_t htoi64(const char *s); uint64_t decode_compact(const char *input); +uint64_t sharetotarg(double diff); uint64_t diff_to_target(double difficulty); double target_to_diff(uint64_t target); @@ -137,3 +139,6 @@ static inline uint32_t bswap32(uint32_t x) { __asm__ __volatile__ ("bswapl %0" : "=r" (x) : "0" (x)); return x; } + +uint64_t share_to_target(double diff); + diff --git a/web/blocks.sh b/web/blocks.sh deleted file mode 100755 index a6e5e3227..000000000 --- a/web/blocks.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -PHP_CLI='php -d max_execution_time=60' - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -cd ${DIR} - -date -echo started in ${DIR} - -while true; do - ${PHP_CLI} runconsole.php cronjob/runBlocks - sleep 20 -done -exec bash - - diff --git a/web/favicon.ico b/web/favicon.ico index d9e97b325..9b073e6a7 100644 Binary files a/web/favicon.ico and b/web/favicon.ico differ diff --git a/web/images/Facebook.png b/web/images/Facebook.png new file mode 100644 index 000000000..8751f5ff2 Binary files /dev/null and b/web/images/Facebook.png differ diff --git a/web/images/Github.png b/web/images/Github.png new file mode 100644 index 000000000..bd8c15ebe Binary files /dev/null and b/web/images/Github.png differ diff --git a/web/images/Twitter.png b/web/images/Twitter.png new file mode 100644 index 000000000..e6af29766 Binary files /dev/null and b/web/images/Twitter.png differ diff --git a/web/images/YouTube.png b/web/images/YouTube.png new file mode 100644 index 000000000..3d28a07ab Binary files /dev/null and b/web/images/YouTube.png differ diff --git a/web/images/cancel.png b/web/images/cancel.png new file mode 100644 index 000000000..81cd2d0c5 Binary files /dev/null and b/web/images/cancel.png differ diff --git a/web/images/coin-FLAX.png b/web/images/coin-FLAX.png index 21b6948fb..d28eaf30e 100644 Binary files a/web/images/coin-FLAX.png and b/web/images/coin-FLAX.png differ diff --git a/web/images/discord.png b/web/images/discord.png new file mode 100644 index 000000000..70bdf1781 Binary files /dev/null and b/web/images/discord.png differ diff --git a/web/images/ok.png b/web/images/ok.png new file mode 100644 index 000000000..304c35eb8 Binary files /dev/null and b/web/images/ok.png differ diff --git a/web/keys.sample.php b/web/keys.sample.php index 63509cae6..cd9b7ca49 100644 --- a/web/keys.sample.php +++ b/web/keys.sample.php @@ -3,6 +3,7 @@ define('YIIMP_MYSQLDUMP_USER', 'root'); define('YIIMP_MYSQLDUMP_PASS', ''); +define('YIIMP_MYSQLDUMP_PATH', '/root/backup'); /* Keys required to create/cancel orders and access your balances/deposit addresses */ define('EXCH_BITTREX_SECRET', ''); diff --git a/web/loop2.sh b/web/loop2.sh deleted file mode 100755 index f2395e797..000000000 --- a/web/loop2.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -PHP_CLI='php -d max_execution_time=120' - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -cd ${DIR} - -date -echo started in ${DIR} - -while true; do - ${PHP_CLI} runconsole.php cronjob/runLoop2 - sleep 60 -done -exec bash - diff --git a/web/main.sh b/web/main.sh deleted file mode 100755 index f41a6d048..000000000 --- a/web/main.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -PHP_CLI='php -d max_execution_time=120' - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -cd ${DIR} - -date -echo started in ${DIR} - -while true; do - ${PHP_CLI} runconsole.php cronjob/run - sleep 90 -done -exec bash - diff --git a/web/serverconfig.sample.php b/web/serverconfig.sample.php index edb4c8b82..3c09111d6 100644 --- a/web/serverconfig.sample.php +++ b/web/serverconfig.sample.php @@ -47,7 +47,6 @@ define('EXCH_POLONIEX_KEY', ''); define('EXCH_BITTREX_KEY', ''); define('EXCH_BLEUTRADE_KEY', ''); -define('EXCH_BTER_KEY', ''); define('EXCH_YOBIT_KEY', ''); define('EXCH_CCEX_KEY', ''); define('EXCH_CEXIO_ID', ''); @@ -55,6 +54,7 @@ define('EXCH_COINMARKETS_USER', ''); define('EXCH_COINMARKETS_PIN', ''); define('EXCH_CREX24_KEY', ''); +define('EXCH_CRYPTOBRIDGE_ID', ''); define('EXCH_BINANCE_KEY', ''); define('EXCH_BITSTAMP_ID',''); define('EXCH_BITSTAMP_KEY',''); diff --git a/web/yaamp/commands/CoinCommand.php b/web/yaamp/commands/CoinCommand.php index 12e1a21d0..bbf8a8551 100644 --- a/web/yaamp/commands/CoinCommand.php +++ b/web/yaamp/commands/CoinCommand.php @@ -12,391 +12,459 @@ */ class CoinCommand extends CConsoleCommand { - protected $basePath; - - /** - * Execute the action. - * @param array $args command line parameters specific for this command - * @return integer non zero application exit code after printing help - */ - public function run($args) - { - $runner=$this->getCommandRunner(); - $commands=$runner->commands; - - $root = realpath(Yii::app()->getBasePath().DIRECTORY_SEPARATOR.'..'); - $this->basePath = str_replace(DIRECTORY_SEPARATOR, '/', $root); - - $symbol = arraySafeVal($args, 0); - - if (!isset($args[1]) || $args[1] == 'help') { - - echo "Yiimp coin command\n"; - echo "Usage: yiimp coin delete - to delete with all related records\n"; - echo " yiimp coin purge - to clean users and history \n"; - echo " yiimp coin diff - to check if wallet diff is standard\n"; - echo " yiimp coin blocktime - estimate the chain blocktime\n"; - echo " yiimp coin checkblocks - recheck confirmed blocks\n"; - echo " yiimp coin generated [height] - search blocks not notified, set height to fix\n"; - echo " yiimp coin get \n"; - echo " yiimp coin set \n"; - echo " yiimp coin unset \n"; - echo " yiimp coin settings\n"; - return 1; - - } else if ($args[1] == 'delete') { - return $this->deleteCoin($symbol); - - } else if ($args[1] == 'purge') { - return $this->purgeCoin($symbol); - - } else if ($args[1] == 'diff') { - return $this->checkMiningDiff($symbol); - - } else if ($args[1] == 'blocktime') { - return $this->estimateBlockTime($symbol); - - } else if ($args[1] == 'checkblocks') { - return $this->checkConfirmedBlocks($symbol); - - } else if ($args[1] == 'generated') { - $start_height = arraySafeVal($args, 2, 0); - // if start_height is set, it will create missed block(s) - return $this->listGeneratedTxs($symbol, $start_height); - - } else if ($args[1] == 'get') { - return $this->getCoinSetting($args); - - } else if ($args[1] == 'set') { - return $this->setCoinSetting($args); - - } else if ($args[1] == 'unset') { - return $this->unsetCoinSetting($args); - - } else if ($args[1] == 'settings') { - return $this->listCoinSettings($args); - } - } - - /** - * Provides the command description. - * @return string the command description. - */ - public function getHelp() - { - return $this->run(array('help')); - } - - private function checkSymbol($symbol) - { - return dboscalar("SELECT COUNT(*) FROM coins WHERE symbol=:symbol", - array(':symbol'=>$symbol)); - } - - /** - * Purge coin by symbol - */ - public function purgeCoin($symbol) - { - $coins = new db_coins; - - if (!$coins instanceof CActiveRecord) - return; - - $coin = $coins->find(array('condition'=>'symbol=:sym', 'params'=>array(':sym'=>$symbol))); - if ($coin) - { - $nbAccounts = getdbocount('db_accounts', "coinid=".$coin->id); - $coin->deleteDeps(); - - echo "coin ".$coin->symbol." purged\n"; - if ($nbAccounts) { - $nbAccounts -= getdbocount('db_accounts', "coinid=".$coin->id); - echo " $nbAccounts accounts deleted\n"; - } - } - } - - /** - * Delete (and purge) coin by symbol - */ - public function deleteCoin($symbol) - { - $coins = new db_coins; - - if (!$coins instanceof CActiveRecord) - return; - - $coin = $coins->find(array('condition'=>'symbol=:sym', 'params'=>array(':sym'=>$symbol))); - if ($coin) - { - $this->purgeCoin($symbol); - - $coin->installed=0; - $coin->enable=0; - $coin->save(); - - $coin->delete(); - echo "coin ".$coin->symbol." deleted\n"; - } - } - - //////////////////////////////////////////////////////////////////////////////////// - - /** - * Compare getminininginfo difficulty and computed one (from the target hash) - */ - public function checkMiningDiff($symbol) - { - $coins = new db_coins; - - if (!$coins instanceof CActiveRecord) - return; - - $coin = $coins->find(array('condition'=>'symbol=:sym', 'params'=>array(':sym'=>$symbol))); - if ($coin) - { - $remote = new WalletRPC($coin); - $tpl = $remote->getblocktemplate(); - $mnf = $remote->getmininginfo(); - if (empty($tpl)) die("error {$remote->error} ".json_encode($tpl)."\n"); - - $target = arraySafeVal($tpl,"target",""); - $computed_diff = hash_to_difficulty($coin,$target); - $wallet_diff = arraySafeVal($mnf,"difficulty",0); - $factor = $computed_diff ? round($wallet_diff/$computed_diff,3) : 'NaN'; - - echo $coin->symbol.": network=".Itoa2(arraySafeVal($mnf,"networkhashps",0)*1000, 3)."H/s\n". - "bits=".arraySafeVal($tpl,"bits","")." target=$target\n". - "difficulty=$wallet_diff hash_to_difficulty(target)=$computed_diff factor=$factor\n"; - } - } - - /** - * Extract/Compute the average block time of a block chain - */ - public function estimateBlockTime($symbol) - { - $coins = new db_coins; - - if (!$coins instanceof CActiveRecord) - return; - - $coin = $coins->find(array('condition'=>'symbol=:sym', 'params'=>array(':sym'=>$symbol))); - if ($coin) - { - $remote = new WalletRPC($coin); - $nfo = $remote->getinfo(); - if (empty($nfo)) die("error {$remote->error} ".json_encode($nfo)."\n"); - $height = arraySafeVal($nfo,"blocks",0); - - $hash = $remote->getblockhash($height-1024); - if (empty($hash)) die("error {$remote->error} ".json_encode($hash)."\n"); - $block = $remote->getblock($hash); - $time1 = arraySafeVal($block, 'time', 0); - - $hash = $remote->getblockhash($height-512); - if (empty($hash)) die("error {$remote->error} ".json_encode($hash)."\n"); - $block = $remote->getblock($hash); - $time2 = arraySafeVal($block, 'time', 0); - - $hash = $remote->getblockhash($height-128); - if (empty($hash)) die("error {$remote->error} ".json_encode($hash)."\n"); - $block = $remote->getblock($hash); - $time3 = arraySafeVal($block, 'time', 0); - - $hash = $remote->getblockhash($height); - if (empty($hash)) die("error {$remote->error} ".json_encode($hash)."\n"); - $block = $remote->getblock($hash); - $time = arraySafeVal($block, 'time', 0); - - $t = intval($coin->block_time); - $human_time = sprintf('%dmn%02d', ($t/60), ($t%60)); - echo $coin->symbol.": current block_time set in the db $human_time ($t sec) \n"; - - $t = round(($time - $time1) / 1024); - $human_time = sprintf('%dmn%02d', ($t/60), ($t%60)); - echo $coin->symbol.": avg time for the last 1024 blocks = $human_time ($t sec) \n"; - if (empty($coin->block_time) && $t > 10) { - $coin->block_time = $t; - $coin->save(); - echo $coin->symbol.": db block_time set to $t\n"; - } - $t = round(($time - $time2) / 512); - $human_time = sprintf('%dmn%02d', ($t/60), ($t%60)); - echo $coin->symbol.": avg time for the last 512 blocks = $human_time ($t sec) \n"; - $t = round(($time - $time3) / 128); - $human_time = sprintf('%dmn%02d', ($t/60), ($t%60)); - echo $coin->symbol.": avg time for the last 128 blocks = $human_time ($t sec) \n"; - } - } - - //////////////////////////////////////////////////////////////////////////////////// - - public function checkConfirmedBlocks($symbol) - { - $coin = getdbosql('db_coins', 'symbol=:sym', array(':sym'=>$symbol)); - if (!$coin) return -1; - $blocks = new db_blocks; - - $data = $blocks->findAll(array('condition'=>"coin_id=:id AND category='generate'", 'order'=>'height DESC', 'params'=>array(':id'=>$coin->id))); - //echo count($data)." confirmed blocks to check...\n"; - if (!$data || !count($data)) return 0; - - $remote = new WalletRPC($coin); - $nbReset = 0; $totAmount = 0.0; - - foreach ($data as $block) { - $b = $remote->getblock($block->blockhash); - $confs = arraySafeVal($b,'confirmations', 0); - if ($confs <= 0 || !$b) { - $date = strftime("%Y-%m-%d %H:%M", arraySafeVal($b,'time', $block->time)); - $height = arraySafeVal($b,'height', $block->height); - $conf2 = $coin->block_height - $height; - echo arraySafeVal($b,'height')." $confs/$conf2 $date\n"; - $totAmount += $block->amount; - $block->amount = 0; - $block->category = 'orphan'; - $nbReset += dborun('UPDATE earnings SET amount=0 WHERE blockid='.$block->id); - $block->save(); - } - } - if ($totAmount) { - echo "found $totAmount $symbol orphaned after confirmed status ($nbReset earnings reset)!\n"; - } else { - echo count($data)." confirmed blocks verified\n"; - } - return $nbReset; - } - - //////////////////////////////////////////////////////////////////////////////////// - - public function listGeneratedTxs($symbol,$start_height=0) - { - $coin = getdbosql('db_coins', 'symbol=:sym', array(':sym'=>$symbol)); - if (!$coin) return -1; - - $remote = new WalletRPC($coin); - $cur_height = $remote->getblockcount(); - if (!$cur_height) { - echo "unable to query current block height!\n"; - return 0; - } - - // note: rpc not compatible with decred - $txs = $remote->listtransactions($coin->account, 900); - if(!$txs || !is_array($txs)) { - echo "no txs found!\n"; - return 0; - } - - $nbOk = $nbMissed = 0; - foreach($txs as $tx) { - if ($tx['category'] == 'generate' || $tx['category'] == 'immature') { - $height = $cur_height - $tx['confirmations'] + 1; - if ($tx['confirmations'] < 3) continue; // let the backend detect them... - $block = getdbosql('db_blocks', "coin_id={$coin->id} AND height=$height"); - if ($block) { - if ($block->category == 'orphan') { - if ($start_height > 0 && $height >= $start_height) { - $block->category = 'new'; - if ($block->save()) echo "Fixed orphan block id {$block->id}\n"; - $nbOk++; - } else { - echo("warning: orphan block {$block->height} with confirmations!\n"); - $nbMissed++; - } - } else - $nbOk++; - } else { - $time = round($tx['time'] / 900) * 900; - if ($time < time() - 2 * 24 * 3600) continue; - echo strftime("%Y-%m-%d %H:%M", $tx['time'])." $time missed block $height : ".json_encode($tx)."\n"; - $data = getdbolist('db_hashuser','algo=:algo AND time='.$time, array(':algo'=>$coin->algo)); - $b = new db_blocks; - $b->coin_id = $coin->id; - $b->height = $height; - $b->time = $tx['time']; - $b->category = 'new'; - $b->algo = $coin->algo; - $b->blockhash = $tx['blockhash']; - $b->txhash = $tx['txid']; - $b->isNewRecord = true; - if ($start_height > 0 && $height >= $start_height) { - if ($b->save()) echo "Added new block id {$b->id}\n"; - } - $nbMissed++; - } - } - } - echo "$nbOk blocks checked, $nbMissed missed by the backend\n"; - return 0; - } - - //////////////////////////////////////////////////////////////////////////////////// - - public function getCoinSetting($args) - { - if (count($args) < 3) - die("usage: yiimp coin get \n"); - $symbol = $args[0]; - $key = $args[2]; - if (!$this->checkSymbol($symbol)) { - echo "error: symbol '$symbol' does not exist!\n"; - return 1; - } - $value = coin_get($symbol, $key); - echo "$value\n"; - return 0; - } - - public function setCoinSetting($args) - { - if (count($args) < 4) - die("usage: yiimp coin set \n"); - $symbol = $args[0]; - $key = $args[2]; - $value = $args[3]; - if (!$this->checkSymbol($symbol)) { - echo "error: symbol '$symbol' does not exist!\n"; - return 1; - } - $res = coin_set($symbol, $key, $value); - $val = coin_get($symbol, $key); - echo ($res ? "$symbol $exchange $key ".json_encode($val) : "error") . "\n"; - return 0; - } - - public function unsetCoinSetting($args) - { - if (count($args) < 3) - die("usage: yiimp coin unset \n"); - $symbol = $args[0]; - $key = $args[2]; - if (!$this->checkSymbol($symbol)) { - echo "error: symbol '$symbol' does not exist!\n"; - return 1; - } - coin_unset($symbol, $key); - echo "ok\n"; - return 0; - } - - public function listCoinSettings($args) - { - if (count($args) < 2) - die("usage: yiimp coin settings\n"); - $symbol = $args[0]; - if (!$this->checkSymbol($symbol)) { - echo "error: symbol '$symbol' does not exist!\n"; - return 1; - } - $keys = coin_settings_prefetch($symbol); - foreach ($keys as $key => $value) { - if ($key == $symbol) continue; - echo "$key ".json_encode($value)."\n"; - } - return 0; - } + protected $basePath; + + /** + * Execute the action. + * @param array $args command line parameters specific for this command + * @return integer non zero application exit code after printing help + */ + public function run($args) + { + $runner = $this->getCommandRunner(); + $commands = $runner->commands; + + $root = realpath(Yii::app()->getBasePath() . DIRECTORY_SEPARATOR . '..'); + $this->basePath = str_replace(DIRECTORY_SEPARATOR, '/', $root); + + $symbol = arraySafeVal($args, 0); + + if (!isset($args[1]) || $args[1] == 'help') + { + + echo "Yiimp coin command\n"; + echo "Usage: yiimp coin delete - to delete with all related records\n"; + echo " yiimp coin purge - to clean users and history \n"; + echo " yiimp coin diff - to check if wallet diff is standard\n"; + echo " yiimp coin blocktime - estimate the chain blocktime\n"; + echo " yiimp coin checkblocks - recheck confirmed blocks\n"; + echo " yiimp coin generated [height] - search blocks not notified, set height to fix\n"; + echo " yiimp coin get \n"; + echo " yiimp coin set \n"; + echo " yiimp coin unset \n"; + echo " yiimp coin settings\n"; + return 1; + + } + else if ($args[1] == 'delete') + { + return $this->deleteCoin($symbol); + + } + else if ($args[1] == 'purge') + { + return $this->purgeCoin($symbol); + + } + else if ($args[1] == 'diff') + { + return $this->checkMiningDiff($symbol); + + } + else if ($args[1] == 'blocktime') + { + return $this->estimateBlockTime($symbol); + + } + else if ($args[1] == 'checkblocks') + { + return $this->checkConfirmedBlocks($symbol); + + } + else if ($args[1] == 'generated') + { + $start_height = arraySafeVal($args, 2, 0); + // if start_height is set, it will create missed block(s) + return $this->listGeneratedTxs($symbol, $start_height); + + } + else if ($args[1] == 'get') + { + return $this->getCoinSetting($args); + + } + else if ($args[1] == 'set') + { + return $this->setCoinSetting($args); + + } + else if ($args[1] == 'unset') + { + return $this->unsetCoinSetting($args); + + } + else if ($args[1] == 'settings') + { + return $this->listCoinSettings($args); + } + } + + /** + * Provides the command description. + * @return string the command description. + */ + public function getHelp() + { + return $this->run(array( + 'help' + )); + } + + private function checkSymbol($symbol) + { + return dboscalar("SELECT COUNT(*) FROM coins WHERE symbol=:symbol", array( + ':symbol' => $symbol + )); + } + + /** + * Purge coin by symbol + */ + public function purgeCoin($symbol) + { + $coins = new db_coins; + + if (!$coins instanceof CActiveRecord) return; + + $coin = $coins->find(array( + 'condition' => 'symbol=:sym', + 'params' => array( + ':sym' => $symbol + ) + )); + if ($coin) + { + $nbAccounts = getdbocount('db_accounts', "coinid=" . $coin->id); + $coin->deleteDeps(); + + echo "coin " . $coin->symbol . " purged\n"; + if ($nbAccounts) + { + $nbAccounts -= getdbocount('db_accounts', "coinid=" . $coin->id); + echo " $nbAccounts accounts deleted\n"; + } + } + } + + /** + * Delete (and purge) coin by symbol + */ + public function deleteCoin($symbol) + { + $coins = new db_coins; + + if (!$coins instanceof CActiveRecord) return; + + $coin = $coins->find(array( + 'condition' => 'symbol=:sym', + 'params' => array( + ':sym' => $symbol + ) + )); + if ($coin) + { + $this->purgeCoin($symbol); + + $coin->installed = 0; + $coin->enable = 0; + $coin->save(); + + $coin->delete(); + echo "coin " . $coin->symbol . " deleted\n"; + } + } + + //////////////////////////////////////////////////////////////////////////////////// + + /** + * Compare getminininginfo difficulty and computed one (from the target hash) + */ + public function checkMiningDiff($symbol) + { + $coins = new db_coins; + + if (!$coins instanceof CActiveRecord) return; + + $coin = $coins->find(array( + 'condition' => 'symbol=:sym', + 'params' => array( + ':sym' => $symbol + ) + )); + if ($coin) + { + $remote = new WalletRPC($coin); + $tpl = $remote->getblocktemplate(); + $mnf = $remote->getmininginfo(); + if (empty($tpl)) die("error {$remote->error} " . json_encode($tpl) . "\n"); + + $target = arraySafeVal($tpl, "target", ""); + $computed_diff = hash_to_difficulty($coin, $target); + $wallet_diff = arraySafeVal($mnf, "difficulty", 0); + $factor = $computed_diff ? round($wallet_diff / $computed_diff, 3) : 'NaN'; + + echo $coin->symbol . ": network=" . Itoa2(arraySafeVal($mnf, "networkhashps", 0) * 1000, 3) . "H/s\n" . "bits=" . arraySafeVal($tpl, "bits", "") . " target=$target\n" . "difficulty=$wallet_diff hash_to_difficulty(target)=$computed_diff factor=$factor\n"; + } + } + + /** + * Extract/Compute the average block time of a block chain + */ + public function estimateBlockTime($symbol) + { + $coins = new db_coins; + + if (!$coins instanceof CActiveRecord) return; + + $coin = $coins->find(array( + 'condition' => 'symbol=:sym', + 'params' => array( + ':sym' => $symbol + ) + )); + if ($coin) + { + $remote = new WalletRPC($coin); + $nfo = $remote->getinfo(); + if (empty($nfo)) die("error {$remote->error} " . json_encode($nfo) . "\n"); + $height = arraySafeVal($nfo, "blocks", 0); + + $hash = $remote->getblockhash($height - 1024); + if (empty($hash)) die("error {$remote->error} " . json_encode($hash) . "\n"); + $block = $remote->getblock($hash); + $time1 = arraySafeVal($block, 'time', 0); + + $hash = $remote->getblockhash($height - 512); + if (empty($hash)) die("error {$remote->error} " . json_encode($hash) . "\n"); + $block = $remote->getblock($hash); + $time2 = arraySafeVal($block, 'time', 0); + + $hash = $remote->getblockhash($height - 128); + if (empty($hash)) die("error {$remote->error} " . json_encode($hash) . "\n"); + $block = $remote->getblock($hash); + $time3 = arraySafeVal($block, 'time', 0); + + $hash = $remote->getblockhash($height); + if (empty($hash)) die("error {$remote->error} " . json_encode($hash) . "\n"); + $block = $remote->getblock($hash); + $time = arraySafeVal($block, 'time', 0); + + $t = intval($coin->block_time); + $human_time = sprintf('%dmn%02d', ($t / 60) , ($t % 60)); + echo $coin->symbol . ": current block_time set in the db $human_time ($t sec) \n"; + + $t = round(($time - $time1) / 1024); + $human_time = sprintf('%dmn%02d', ($t / 60) , ($t % 60)); + echo $coin->symbol . ": avg time for the last 1024 blocks = $human_time ($t sec) \n"; + if (empty($coin->block_time) && $t > 10) + { + $coin->block_time = $t; + $coin->save(); + echo $coin->symbol . ": db block_time set to $t\n"; + } + $t = round(($time - $time2) / 512); + $human_time = sprintf('%dmn%02d', ($t / 60) , ($t % 60)); + echo $coin->symbol . ": avg time for the last 512 blocks = $human_time ($t sec) \n"; + $t = round(($time - $time3) / 128); + $human_time = sprintf('%dmn%02d', ($t / 60) , ($t % 60)); + echo $coin->symbol . ": avg time for the last 128 blocks = $human_time ($t sec) \n"; + } + } + + //////////////////////////////////////////////////////////////////////////////////// + public function checkConfirmedBlocks($symbol) + { + $coin = getdbosql('db_coins', 'symbol=:sym', array( + ':sym' => $symbol + )); + if (!$coin) return -1; + $blocks = new db_blocks; + + $data = $blocks->findAll(array( + 'condition' => "coin_id=:id AND category='generate'", + 'order' => 'height DESC', + 'params' => array( + ':id' => $coin->id + ) + )); + //echo count($data)." confirmed blocks to check...\n"; + if (!$data || !count($data)) return 0; + + $remote = new WalletRPC($coin); + $nbReset = 0; + $totAmount = 0.0; + + foreach ($data as $block) + { + $b = $remote->getblock($block->blockhash); + $confs = arraySafeVal($b, 'confirmations', 0); + if ($confs <= 0 || !$b) + { + $date = strftime("%Y-%m-%d %H:%M", arraySafeVal($b, 'time', $block->time)); + $height = arraySafeVal($b, 'height', $block->height); + $conf2 = $coin->block_height - $height; + echo arraySafeVal($b, 'height') . " $confs/$conf2 $date\n"; + $totAmount += $block->amount; + $block->amount = 0; + $block->category = 'orphan'; + $nbReset += dborun('UPDATE earnings SET amount=0 WHERE blockid=' . $block->id); + $block->save(); + } + } + if ($totAmount) + { + echo "found $totAmount $symbol orphaned after confirmed status ($nbReset earnings reset)!\n"; + } + else + { + echo count($data) . " confirmed blocks verified\n"; + } + return $nbReset; + } + + //////////////////////////////////////////////////////////////////////////////////// + public function listGeneratedTxs($symbol, $start_height = 0) + { + $coin = getdbosql('db_coins', 'symbol=:sym', array( + ':sym' => $symbol + )); + if (!$coin) return -1; + + $remote = new WalletRPC($coin); + $cur_height = $remote->getblockcount(); + if (!$cur_height) + { + echo "unable to query current block height!\n"; + return 0; + } + + // note: rpc not compatible with decred + $txs = $remote->listtransactions($coin->account, 900); + if (!$txs || !is_array($txs)) + { + echo "no txs found!\n"; + return 0; + } + + $nbOk = $nbMissed = 0; + foreach ($txs as $tx) + { + if ($tx['category'] == 'generate' || $tx['category'] == 'immature') + { + $height = $cur_height - $tx['confirmations'] + 1; + if ($tx['confirmations'] < 3) continue; // let the backend detect them... + $block = getdbosql('db_blocks', "coin_id={$coin->id} AND height=$height"); + if ($block) + { + if ($block->category == 'orphan') + { + if ($start_height > 0 && $height >= $start_height) + { + $block->category = 'new'; + if ($block->save()) echo "Fixed orphan block id {$block->id}\n"; + $nbOk++; + } + else + { + echo ("warning: orphan block {$block->height} with confirmations!\n"); + $nbMissed++; + } + } + else $nbOk++; + } + else + { + $time = round($tx['time'] / 900) * 900; + if ($time < time() - 2 * 24 * 3600) continue; + echo strftime("%Y-%m-%d %H:%M", $tx['time']) . " $time missed block $height : " . json_encode($tx) . "\n"; + $data = getdbolist('db_hashuser', 'algo=:algo AND time=' . $time, array( + ':algo' => $coin->algo + )); + $b = new db_blocks; + $b->coin_id = $coin->id; + $b->height = $height; + $b->time = $tx['time']; + $b->category = 'new'; + $b->algo = $coin->algo; + $b->blockhash = $tx['blockhash']; + $b->txhash = $tx['txid']; + $b->isNewRecord = true; + if ($start_height > 0 && $height >= $start_height) + { + if ($b->save()) echo "Added new block id {$b->id}\n"; + } + $nbMissed++; + } + } + } + echo "$nbOk blocks checked, $nbMissed missed by the backend\n"; + return 0; + } + + //////////////////////////////////////////////////////////////////////////////////// + public function getCoinSetting($args) + { + if (count($args) < 3) die("usage: yiimp coin get \n"); + $symbol = $args[0]; + $key = $args[2]; + if (!$this->checkSymbol($symbol)) + { + echo "error: symbol '$symbol' does not exist!\n"; + return 1; + } + $value = coin_get($symbol, $key); + echo "$value\n"; + return 0; + } + + public function setCoinSetting($args) + { + if (count($args) < 4) die("usage: yiimp coin set \n"); + $symbol = $args[0]; + $key = $args[2]; + $value = $args[3]; + if (!$this->checkSymbol($symbol)) + { + echo "error: symbol '$symbol' does not exist!\n"; + return 1; + } + $res = coin_set($symbol, $key, $value); + $val = coin_get($symbol, $key); + echo ($res ? "$symbol $exchange $key " . json_encode($val) : "error") . "\n"; + return 0; + } + + public function unsetCoinSetting($args) + { + if (count($args) < 3) die("usage: yiimp coin unset \n"); + $symbol = $args[0]; + $key = $args[2]; + if (!$this->checkSymbol($symbol)) + { + echo "error: symbol '$symbol' does not exist!\n"; + return 1; + } + coin_unset($symbol, $key); + echo "ok\n"; + return 0; + } + + public function listCoinSettings($args) + { + if (count($args) < 2) die("usage: yiimp coin settings\n"); + $symbol = $args[0]; + if (!$this->checkSymbol($symbol)) + { + echo "error: symbol '$symbol' does not exist!\n"; + return 1; + } + $keys = coin_settings_prefetch($symbol); + foreach ($keys as $key => $value) + { + if ($key == $symbol) continue; + echo "$key " . json_encode($value) . "\n"; + } + return 0; + } } diff --git a/web/yaamp/commands/CoindbCommand.php b/web/yaamp/commands/CoindbCommand.php index 920fbf3fa..0b377c9ed 100644 --- a/web/yaamp/commands/CoindbCommand.php +++ b/web/yaamp/commands/CoindbCommand.php @@ -15,584 +15,589 @@ */ class CoindbCommand extends CConsoleCommand { - protected $basePath; - - /** - * Execute the action. - * @param array $args command line parameters specific for this command - * @return integer non zero application exit code after printing help - */ - public function run($args) - { - $runner=$this->getCommandRunner(); - $commands=$runner->commands; - - $root = realpath(Yii::app()->getBasePath().DIRECTORY_SEPARATOR.'..'); - $this->basePath = str_replace(DIRECTORY_SEPARATOR, '/', $root); - - if (!isset($args[0])) { - - echo "Yiimp coindb command\n"; - echo "Usage: yiimp coindb labels\n"; - echo " yiimp coindb icons\n"; - return 1; - - } elseif ($args[0] == 'labels') { - - $nbUpdated = $this->updateCryptopiaLabels(); - $nbUpdated += $this->updateCoinCapLabels(); - $nbUpdated += $this->updateLiveCoinLabels(); - $nbUpdated += $this->updateYiimpLabels("api.yiimp.eu"); - $nbUpdated += $this->updateFromJson(); - - echo "total updated: $nbUpdated\n"; - return 0; - - } elseif ($args[0] == 'icons') { - - $nbUpdated = $this->grabBterIcons(); - $nbUpdated += $this->grabCcexIcons(); - $nbUpdated += $this->grabCryptopiaIcons(); - $nbUpdated += $this->grabBittrexIcons(); // can be huge ones - $nbUpdated += $this->grabCoinExchangeIcons(); - $nbUpdated += $this->grabAlcurexIcons(); - $nbUpdated += $this->grabKuCoinIcons(); - $nbUpdated += $this->grabNovaIcons(); - - echo "total updated: $nbUpdated\n"; - return 0; - } - } - - /** - * Provides the command description. - * @return string the command description. - */ - public function getHelp() - { - return parent::getHelp().'coindb labels'; - } - - /** - * coincap.io api - */ - public static function getCoinCapData() - { - $json = file_get_contents('http://coincap.io/front'); - $data = json_decode($json,true); - $array = array(); - foreach ($data as $coin) { - $key = strtoupper($coin['short']); - if (empty($key)) continue; - $array[$key] = $coin; - } - return $array; - } - - public function updateCoinCapLabels() - { - $coins = new db_coins; - $nbUpdated = 0; - - $dataset = $coins->findAll(array( - 'condition'=>"name='unknown' OR name=symbol" - )); - - if (!empty($dataset)) - { - $json = self::getCoinCapData(); - if (empty($json)) return 0; - - foreach ($dataset as $coin) { - if ($coin->name == 'unknown' && isset($json[$coin->symbol])) { - $data = $json[$coin->symbol]; - if ($data['long'] != $coin->name) { - echo "{$coin->symbol}: {$data['long']}\n"; - $coin->name = trim($data['long']); - $nbUpdated += $coin->save(); - } - } - } - if ($nbUpdated) - echo "$nbUpdated coin labels updated from coincap.io\n"; - } - return $nbUpdated; - } - - /** - * Special for cryptopia coins - */ - protected function getCryptopiaCurrencies() - { - $array = array(); - require_once($this->basePath.'/yaamp/core/exchange/cryptopia.php'); - $data = cryptopia_api_query('GetCurrencies'); - - if (is_object($data) && !empty($data->Data)) - foreach ($data->Data as $coin) { - $key = strtoupper($coin->Symbol); - if (empty($key)) continue; - $array[$key] = $coin; - } - - return $array; - } - - public function updateCryptopiaLabels() - { - $coins = new db_coins; - $nbUpdated = 0; - - $dataset = $coins->findAll(array( - 'condition'=>"name=:u OR algo='' OR algo='scrypt'", - 'params'=>array(':u'=>'unknown') - )); - - if (!empty($dataset)) - { - $json = self::getCryptopiaCurrencies(); - - foreach ($dataset as $coin) { - if ($coin->name == 'unknown' && isset($json[$coin->symbol])) { - $cc = $json[$coin->symbol]; - if ($cc->Name != $coin->name) { - echo "{$coin->symbol}: {$cc->Name}\n"; - $coin->name = $cc->Name; - if ($cc->Algorithm != 'scrypt') - $coin->algo = strtolower($cc->Algorithm); - $nbUpdated += $coin->save(); - } - } - } - if ($nbUpdated) - echo "$nbUpdated coin labels updated from cryptopia\n"; - } - return $nbUpdated; - } - - public function updateLiveCoinLabels() - { - if (exchange_get('livecoin', 'disabled') == true) return 0; - - $coins = new db_coins; - $nbUpdated = 0; - - $dataset = $coins->findAll(array( - 'condition'=>"name='unknown' AND id IN (SELECT M.coinid FROM markets M WHERE M.name='livecoin')", - )); - - if (!empty($dataset)) - { - //echo count($dataset)." livecoin currencies without labels\n"; - $labels = array(); - $data = livecoin_api_query('info/coinInfo'); - if(objSafeVal($data,'success') !== true || !is_array($data->info)) return; - - foreach ($data->info as $c) { - $symbol = objSafeVal($c,'symbol',''); - $labels[$symbol] = objSafeVal($c,'name','unknown'); - } - - foreach ($dataset as $coin) { - if ($coin->name == 'unknown' && isset($labels[$coin->symbol])) { - $label = $labels[$coin->symbol]; - if ($label != $coin->name) { - echo "{$coin->symbol}: {$label}\n"; - $coin->name = $label; - $nbUpdated += $coin->save(); - } - } - } - if ($nbUpdated) - echo "$nbUpdated coin labels updated from livecoin coininfo\n"; - } - return $nbUpdated; - } - - public function updateYiimpLabels($pool) - { - $coins = new db_coins; - $nbUpdated = 0; $nbAlgos = 0; - - $dataset = $coins->findAll(array( - 'condition'=>"name=:u OR algo='' OR algo='scrypt'", - 'params'=>array(':u'=>'unknown') - )); - - if (!empty($dataset)) - { - $url = "http://{$pool}/api/currencies"; - $data = @ file_get_contents($url); - if (empty($data)) return 0; - $json = json_decode($data, true); - - if (!empty($json)) - foreach ($dataset as $coin) { - if (!isset($json[$coin->symbol])) continue; - $cc = $json[$coin->symbol]; - if ($coin->name == 'unknown') { - echo "{$coin->symbol}: {$cc['name']}\n"; - $coin->name = $cc['name']; - $nbUpdated += $coin->save(); - } - if (empty($cc['algo'])) continue; - if (empty($coin->algo) || $coin->algo != $cc['algo']) { - $coin->algo = strtolower($cc['algo']); - echo "{$coin->symbol}: algo set to {$cc['algo']}\n"; - $nbAlgos += $coin->save(); - } - } - if ($nbUpdated) - echo "$nbUpdated labels and $nbAlgos algos updated from $pool\n"; - } - return $nbUpdated; - } - - /** - * To import from a json file placed in the sql/ folder - */ - public function updateFromJson() - { - $sqlFolder = $this->basePath.'/../sql/'; - $jsonFile = $sqlFolder.'labels.json'; - //$jsonFile = $sqlFolder.'yobit.txt'; - if (!file_exists($jsonFile)) - return 0; - - $nbUpdated = 0; - - $json = json_decode(file_get_contents($jsonFile), true); - /* - $json = array(); - $txt = explode("\n", file_get_contents($jsonFile)); - foreach ($txt as $line) - { - $cells = explode("\t", $line); - if (count($cells) < 2) continue; - $json[$cells[0]] = $cells[1]; - } - */ - if (!empty($json)) - { - $coins = new db_coins; - $dataset = $coins->findAll(array( - 'condition'=>"name=:u", - 'params'=>array(':u'=>'unknown') - )); - - if (!empty($dataset)) - foreach ($dataset as $coin) { - if (isset($json[$coin->symbol])) { - $name = $json[$coin->symbol]; - echo "{$coin->symbol}: {$name}\n"; - $coin->name = $name; - $nbUpdated += $coin->save(); - } - } - if ($nbUpdated) - echo "$nbUpdated coin labels updated from labels.json file\n"; - } - return $nbUpdated; - } - - /** - * Icon grabber - Bter - */ - public function grabBterIcons() - { - $url = 'http://bter.com/images/coin_icon/64/'; - $nbUpdated = 0; - $sql = "SELECT DISTINCT coins.id FROM coins INNER JOIN markets M ON M.coinid = coins.id WHERE M.name='bter' AND IFNULL(coins.image,'') = ''"; - $coins = dbolist($sql); - if (empty($coins)) - return 0; - echo "bter: try to download new icons...\n"; - foreach ($coins as $coin) { - $coin = getdbo('db_coins', $coin["id"]); - $symbol = $coin->symbol; - if (!empty($coin->symbol2)) $symbol = $coin->symbol2; - $local = $this->basePath."/images/coin-{$symbol}.png"; - try { - $data = @ file_get_contents($url.strtolower($symbol).'.png'); - } catch (Exception $e) { - continue; - } - if (strlen($data) < 2048) continue; - echo $coin->symbol." icon found\n"; - file_put_contents($local, $data); - if (filesize($local) > 0) { - $coin->image = "/images/coin-{$symbol}.png"; - $nbUpdated += $coin->save(); - } - } - if ($nbUpdated) - echo "$nbUpdated icons downloaded from bter\n"; - return $nbUpdated; - } - - /** - * Icon grabber - Bittrex - */ - public function grabBittrexIcons() - { - $nbUpdated = 0; - $markets = bittrex_api_query('public/getmarkets'); - if (!is_object($markets) || !is_object($markets->result)) { - echo "bittrex api error\n"; - return $nbUpdated; - } - $sql = "SELECT DISTINCT coins.id FROM coins INNER JOIN markets M ON M.coinid = coins.id WHERE M.name='bittrex' AND IFNULL(coins.image,'') = ''"; - $coins = dbolist($sql); - if (empty($coins)) - return $nbUpdated; - echo "bittrex: try to download new icons...\n"; - foreach ($coins as $coin) { - $coin = getdbo('db_coins', $coin["id"]); - $symbol = $coin->symbol; - if (!empty($coin->symbol2)) $symbol = $coin->symbol2; - $local = $this->basePath."/images/coin-{$symbol}.png"; - $url = ''; - foreach ($markets->result as $m) { - if ($m->MarketCurrency == $symbol) { - $url = $m->LogoUrl; - break; - } - } - if (empty($url)) continue; - try { - $data = @ file_get_contents($url); - } catch (Exception $e) { - continue; - } - if (strlen($data) < 2048) continue; - file_put_contents($local, $data); - $size = filesize($local); - if ($size > 0) { - if ($size > 100*1024) { - echo "warning: $symbol icon is huge, ".round($size/1024,1)." KB ($url)\n"; - unlink($local); - } else { - echo $symbol." icon found\n"; - $coin->image = "/images/coin-{$symbol}.png"; - $nbUpdated += $coin->save(); - } - } - } - if ($nbUpdated) - echo "$nbUpdated icons downloaded from bittrex\n"; - return $nbUpdated; - } - - /** - * Icon grabber - Ccex - */ - public function grabCcexIcons() - { - $url = 'http://c-cex.com/i/l/'; - $nbUpdated = 0; - $sql = "SELECT DISTINCT coins.id FROM coins INNER JOIN markets M ON M.coinid = coins.id WHERE M.name='c-cex' AND IFNULL(coins.image,'') = ''"; - $coins = dbolist($sql); - if (empty($coins)) - return 0; - echo "c-cex: try to download new icons...\n"; - foreach ($coins as $coin) { - $coin = getdbo('db_coins', $coin["id"]); - $symbol = $coin->symbol; - if (!empty($coin->symbol2)) $symbol = $coin->symbol2; - $local = $this->basePath."/images/coin-{$symbol}.png"; - try { - $data = @ file_get_contents($url.strtolower($symbol).'.png'); - } catch (Exception $e) { - continue; - } - if (strlen($data) < 2048) continue; - echo $symbol." icon found\n"; - file_put_contents($local, $data); - if (filesize($local) > 0) { - $coin->image = "/images/coin-{$symbol}.png"; - $nbUpdated += $coin->save(); - } - } - if ($nbUpdated) - echo "$nbUpdated icons downloaded from c-cex\n"; - return $nbUpdated; - } - - /** - * Icon grabber - Cryptopia (slow https) - */ - public function grabCryptopiaIcons() - { - $url = 'https://www.cryptopia.co.nz/Content/Images/Coins/'; - $nbUpdated = 0; - $sql = "SELECT DISTINCT coins.id FROM coins INNER JOIN markets M ON M.coinid = coins.id ". - "WHERE M.name='cryptopia' AND IFNULL(coins.image,'') = ''"; - $coins = dbolist($sql); - if (empty($coins)) - return 0; - echo "cryptopia: try to download new icons...\n"; - foreach ($coins as $coin) { - $coin = getdbo('db_coins', $coin["id"]); - $symbol = $coin->symbol; - if (!empty($coin->symbol2)) $symbol = $coin->symbol2; - $local = $this->basePath."/images/coin-{$symbol}.png"; - try { - $data = @ file_get_contents($url.strtolower($symbol).'-medium.png'); - } catch (Exception $e) { - continue; - } - if (strlen($data) < 3000 || strstr($data, ' 0) { - $coin->image = "/images/coin-{$symbol}.png"; - $nbUpdated += $coin->save(); - } - } - if ($nbUpdated) - echo "$nbUpdated icons downloaded from cryptopia\n"; - return $nbUpdated; - } - - /** - * Icon grabber - CoinExchange - */ - public function grabCoinExchangeIcons() - { - $url = 'https://www.coinexchange.io/assets/currencies/'; - $nbUpdated = 0; - $sql = "SELECT DISTINCT coins.id FROM coins INNER JOIN markets M ON M.coinid = coins.id ". - "WHERE M.name='coinexchange' AND IFNULL(coins.image,'') = ''"; - $coins = dbolist($sql); - if (empty($coins)) - return 0; - echo "coinexchange: try to download new icons...\n"; - foreach ($coins as $coin) { - $coin = getdbo('db_coins', $coin["id"]); - $symbol = $coin->symbol; - if (!empty($coin->symbol2)) $symbol = $coin->symbol2; - $local = $this->basePath."/images/coin-{$symbol}.png"; - try { - $data = @ file_get_contents($url.strtolower($coin->name).'.png'); - } catch (Exception $e) { - continue; - } - if (strlen($data) < 2048) continue; - echo $symbol." icon found\n"; - file_put_contents($local, $data); - if (filesize($local) > 0) { - $coin->image = "/images/coin-{$symbol}.png"; - $nbUpdated += $coin->save(); - } - } - if ($nbUpdated) - echo "$nbUpdated icons downloaded from coinexchange\n"; - return $nbUpdated; - } - - /** - * Icon grabber - Alcurex - */ - public function grabAlcurexIcons() - { - $url = 'https://alcurex.com/CSS/img/coins/'; - $nbUpdated = 0; - $sql = "SELECT DISTINCT coins.id FROM coins INNER JOIN markets M ON M.coinid = coins.id ". - "WHERE M.name='alcurex' AND IFNULL(coins.image,'') = ''"; - $coins = dbolist($sql); - if (empty($coins)) - return 0; - echo "alcurex: try to download new icons...\n"; - foreach ($coins as $coin) { - $coin = getdbo('db_coins', $coin["id"]); - $symbol = $coin->getOfficialSymbol(); - $local = $this->basePath."/images/coin-{$symbol}.png"; - try { - $data = @ file_get_contents($url.strtoupper($symbol).'.png'); - } catch (Exception $e) { - continue; - } - if (strlen($data) < 2048) continue; - echo $symbol." icon found\n"; - file_put_contents($local, $data); - if (filesize($local) > 0) { - $coin->image = "/images/coin-{$symbol}.png"; - $nbUpdated += $coin->save(); - } - } - if ($nbUpdated) - echo "$nbUpdated icons downloaded from alcurex\n"; - return $nbUpdated; - } - - /** - * Icon grabber - KuCoin - */ - public function grabKuCoinIcons() - { - $url = 'https://assets.kucoin.com/www/1.2.0/assets/coins/';//QLC.png - $nbUpdated = 0; - $sql = "SELECT DISTINCT coins.id FROM coins INNER JOIN markets M ON M.coinid = coins.id ". - "WHERE M.name='kucoin' AND IFNULL(coins.image,'') = ''"; - $coins = dbolist($sql); - if (empty($coins)) - return 0; - echo "kucoin: try to download new icons...\n"; - foreach ($coins as $coin) { - $coin = getdbo('db_coins', $coin["id"]); - $symbol = $coin->getOfficialSymbol(); - $local = $this->basePath."/images/coin-{$symbol}.png"; - try { - $data = @ file_get_contents($url.$symbol.'.png'); - } catch (Exception $e) { - continue; - } - if (strlen($data) < 2048) continue; - echo $symbol." icon found\n"; - file_put_contents($local, $data); - if (filesize($local) > 0) { - $coin->image = "/images/coin-{$symbol}.png"; - $nbUpdated += $coin->save(); - } - } - if ($nbUpdated) - echo "$nbUpdated icons downloaded from kucoin\n"; - return $nbUpdated; - } - - /** - * Icon grabber - NovaExchange - */ - public function grabNovaIcons() - { - $url = 'http://novaexchange.com/static/symbols/'; - $nbUpdated = 0; - $sql = "SELECT DISTINCT coins.id FROM coins INNER JOIN markets M ON M.coinid = coins.id ". - "WHERE M.name='nova' AND IFNULL(coins.image,'') = ''"; - $coins = dbolist($sql); - if (empty($coins)) - return 0; - echo "nova: try to download new icons...\n"; - foreach ($coins as $coin) { - $coin = getdbo('db_coins', $coin["id"]); - $symbol = $coin->getOfficialSymbol(); - $local = $this->basePath."/images/coin-{$symbol}.png"; - try { - $data = @ file_get_contents($url.strtolower($symbol).'.png'); - } catch (Exception $e) { - continue; - } - if (strlen($data) < 2048) continue; - echo $symbol." icon found\n"; - file_put_contents($local, $data); - if (filesize($local) > 0) { - $coin->image = "/images/coin-{$symbol}.png"; - $nbUpdated += $coin->save(); - } - } - if ($nbUpdated) - echo "$nbUpdated icons downloaded from novaexchange\n"; - return $nbUpdated; - } + protected $basePath; + + /** + * Execute the action. + * @param array $args command line parameters specific for this command + * @return integer non zero application exit code after printing help + */ + public function run($args) + { + $runner = $this->getCommandRunner(); + $commands = $runner->commands; + + $root = realpath(Yii::app()->getBasePath() . DIRECTORY_SEPARATOR . '..'); + $this->basePath = str_replace(DIRECTORY_SEPARATOR, '/', $root); + + if (!isset($args[0])) + { + + echo "Yiimp coindb command\n"; + echo "Usage: yiimp coindb labels\n"; + echo " yiimp coindb icons\n"; + return 1; + + } + elseif ($args[0] == 'labels') + { + + $nbUpdated = $this->updateCryptopiaLabels(); + $nbUpdated += $this->updateCoinCapLabels(); + $nbUpdated += $this->updateLiveCoinLabels(); + $nbUpdated += $this->updateYiimpLabels("api.yiimp.eu"); + $nbUpdated += $this->updateFromJson(); + + echo "total updated: $nbUpdated\n"; + return 0; + + } + elseif ($args[0] == 'icons') + { + + $nbUpdated = $this->grabCcexIcons(); + $nbUpdated += $this->grabCryptopiaIcons(); + $nbUpdated += $this->grabBittrexIcons(); // can be huge ones + $nbUpdated += $this->grabCoinExchangeIcons(); + $nbUpdated += $this->grabAlcurexIcons(); + $nbUpdated += $this->grabKuCoinIcons(); + $nbUpdated += $this->grabNovaIcons(); + + echo "total updated: $nbUpdated\n"; + return 0; + } + } + + /** + * Provides the command description. + * @return string the command description. + */ + public function getHelp() + { + return parent::getHelp() . 'coindb labels'; + } + + /** + * coincap.io api + */ + public static function getCoinCapData() + { + $json = file_get_contents('http://coincap.io/front'); + $data = json_decode($json, true); + $array = array(); + foreach ($data as $coin) + { + $key = strtoupper($coin['short']); + if (empty($key)) continue; + $array[$key] = $coin; + } + return $array; + } + + public function updateCoinCapLabels() + { + $coins = new db_coins; + $nbUpdated = 0; + + $dataset = $coins->findAll(array( + 'condition' => "name='unknown' OR name=symbol" + )); + + if (!empty($dataset)) + { + $json = self::getCoinCapData(); + if (empty($json)) return 0; + + foreach ($dataset as $coin) + { + if ($coin->name == 'unknown' && isset($json[$coin->symbol])) + { + $data = $json[$coin->symbol]; + if ($data['long'] != $coin->name) + { + echo "{$coin->symbol}: {$data['long']}\n"; + $coin->name = trim($data['long']); + $nbUpdated += $coin->save(); + } + } + } + if ($nbUpdated) echo "$nbUpdated coin labels updated from coincap.io\n"; + } + return $nbUpdated; + } + + /** + * Special for cryptopia coins + */ + protected function getCryptopiaCurrencies() + { + $array = array(); + require_once ($this->basePath . '/yaamp/core/exchange/cryptopia.php'); + $data = cryptopia_api_query('GetCurrencies'); + + if (is_object($data) && !empty($data->Data)) foreach ($data->Data as $coin) + { + $key = strtoupper($coin->Symbol); + if (empty($key)) continue; + $array[$key] = $coin; + } + + return $array; + } + + public function updateCryptopiaLabels() + { + $coins = new db_coins; + $nbUpdated = 0; + + $dataset = $coins->findAll(array( + 'condition' => "name=:u OR algo='' OR algo='scrypt'", + 'params' => array( + ':u' => 'unknown' + ) + )); + + if (!empty($dataset)) + { + $json = self::getCryptopiaCurrencies(); + + foreach ($dataset as $coin) + { + if ($coin->name == 'unknown' && isset($json[$coin->symbol])) + { + $cc = $json[$coin->symbol]; + if ($cc->Name != $coin->name) + { + echo "{$coin->symbol}: {$cc->Name}\n"; + $coin->name = $cc->Name; + if ($cc->Algorithm != 'scrypt') $coin->algo = strtolower($cc->Algorithm); + $nbUpdated += $coin->save(); + } + } + } + if ($nbUpdated) echo "$nbUpdated coin labels updated from cryptopia\n"; + } + return $nbUpdated; + } + + public function updateLiveCoinLabels() + { + if (exchange_get('livecoin', 'disabled') == true) return 0; + + $coins = new db_coins; + $nbUpdated = 0; + + $dataset = $coins->findAll(array( + 'condition' => "name='unknown' AND id IN (SELECT M.coinid FROM markets M WHERE M.name='livecoin')", + )); + + if (!empty($dataset)) + { + //echo count($dataset)." livecoin currencies without labels\n"; + $labels = array(); + $data = livecoin_api_query('info/coinInfo'); + if (objSafeVal($data, 'success') !== true || !is_array($data->info)) return; + + foreach ($data->info as $c) + { + $symbol = objSafeVal($c, 'symbol', ''); + $labels[$symbol] = objSafeVal($c, 'name', 'unknown'); + } + + foreach ($dataset as $coin) + { + if ($coin->name == 'unknown' && isset($labels[$coin->symbol])) + { + $label = $labels[$coin->symbol]; + if ($label != $coin->name) + { + echo "{$coin->symbol}: {$label}\n"; + $coin->name = $label; + $nbUpdated += $coin->save(); + } + } + } + if ($nbUpdated) echo "$nbUpdated coin labels updated from livecoin coininfo\n"; + } + return $nbUpdated; + } + + public function updateYiimpLabels($pool) + { + $coins = new db_coins; + $nbUpdated = 0; + $nbAlgos = 0; + + $dataset = $coins->findAll(array( + 'condition' => "name=:u OR algo='' OR algo='scrypt'", + 'params' => array( + ':u' => 'unknown' + ) + )); + + if (!empty($dataset)) + { + $url = "http://{$pool}/api/currencies"; + $data = @file_get_contents($url); + if (empty($data)) return 0; + $json = json_decode($data, true); + + if (!empty($json)) foreach ($dataset as $coin) + { + if (!isset($json[$coin->symbol])) continue; + $cc = $json[$coin->symbol]; + if ($coin->name == 'unknown') + { + echo "{$coin->symbol}: {$cc['name']}\n"; + $coin->name = $cc['name']; + $nbUpdated += $coin->save(); + } + if (empty($cc['algo'])) continue; + if (empty($coin->algo) || $coin->algo != $cc['algo']) + { + $coin->algo = strtolower($cc['algo']); + echo "{$coin->symbol}: algo set to {$cc['algo']}\n"; + $nbAlgos += $coin->save(); + } + } + if ($nbUpdated) echo "$nbUpdated labels and $nbAlgos algos updated from $pool\n"; + } + return $nbUpdated; + } + + /** + * To import from a json file placed in the sql/ folder + */ + public function updateFromJson() + { + $sqlFolder = $this->basePath . '/../sql/'; + $jsonFile = $sqlFolder . 'labels.json'; + //$jsonFile = $sqlFolder.'yobit.txt'; + if (!file_exists($jsonFile)) return 0; + + $nbUpdated = 0; + + $json = json_decode(file_get_contents($jsonFile) , true); + /* + $json = array(); + $txt = explode("\n", file_get_contents($jsonFile)); + foreach ($txt as $line) + { + $cells = explode("\t", $line); + if (count($cells) < 2) continue; + $json[$cells[0]] = $cells[1]; + } + */ + if (!empty($json)) + { + $coins = new db_coins; + $dataset = $coins->findAll(array( + 'condition' => "name=:u", + 'params' => array( + ':u' => 'unknown' + ) + )); + + if (!empty($dataset)) foreach ($dataset as $coin) + { + if (isset($json[$coin->symbol])) + { + $name = $json[$coin->symbol]; + echo "{$coin->symbol}: {$name}\n"; + $coin->name = $name; + $nbUpdated += $coin->save(); + } + } + if ($nbUpdated) echo "$nbUpdated coin labels updated from labels.json file\n"; + } + return $nbUpdated; + } + + /** + * Icon grabber - Bittrex + */ + public function grabBittrexIcons() + { + $nbUpdated = 0; + $markets = bittrex_api_query('public/getmarkets'); + if (!is_object($markets) || !is_object($markets->result)) + { + echo "bittrex api error\n"; + return $nbUpdated; + } + $sql = "SELECT DISTINCT coins.id FROM coins INNER JOIN markets M ON M.coinid = coins.id WHERE M.name='bittrex' AND IFNULL(coins.image,'') = ''"; + $coins = dbolist($sql); + if (empty($coins)) return $nbUpdated; + echo "bittrex: try to download new icons...\n"; + foreach ($coins as $coin) + { + $coin = getdbo('db_coins', $coin["id"]); + $symbol = $coin->symbol; + if (!empty($coin->symbol2)) $symbol = $coin->symbol2; + $local = $this->basePath . "/images/coin-{$symbol}.png"; + $url = ''; + foreach ($markets->result as $m) + { + if ($m->MarketCurrency == $symbol) + { + $url = $m->LogoUrl; + break; + } + } + if (empty($url)) continue; + try + { + $data = @file_get_contents($url); + } + catch(Exception $e) + { + continue; + } + if (strlen($data) < 2048) continue; + file_put_contents($local, $data); + $size = filesize($local); + if ($size > 0) + { + if ($size > 100 * 1024) + { + echo "warning: $symbol icon is huge, " . round($size / 1024, 1) . " KB ($url)\n"; + unlink($local); + } + else + { + echo $symbol . " icon found\n"; + $coin->image = "/images/coin-{$symbol}.png"; + $nbUpdated += $coin->save(); + } + } + } + if ($nbUpdated) echo "$nbUpdated icons downloaded from bittrex\n"; + return $nbUpdated; + } + + /** + * Icon grabber - Ccex + */ + public function grabCcexIcons() + { + $url = 'http://c-cex.com/i/l/'; + $nbUpdated = 0; + $sql = "SELECT DISTINCT coins.id FROM coins INNER JOIN markets M ON M.coinid = coins.id WHERE M.name='c-cex' AND IFNULL(coins.image,'') = ''"; + $coins = dbolist($sql); + if (empty($coins)) return 0; + echo "c-cex: try to download new icons...\n"; + foreach ($coins as $coin) + { + $coin = getdbo('db_coins', $coin["id"]); + $symbol = $coin->symbol; + if (!empty($coin->symbol2)) $symbol = $coin->symbol2; + $local = $this->basePath . "/images/coin-{$symbol}.png"; + try + { + $data = @file_get_contents($url . strtolower($symbol) . '.png'); + } + catch(Exception $e) + { + continue; + } + if (strlen($data) < 2048) continue; + echo $symbol . " icon found\n"; + file_put_contents($local, $data); + if (filesize($local) > 0) + { + $coin->image = "/images/coin-{$symbol}.png"; + $nbUpdated += $coin->save(); + } + } + if ($nbUpdated) echo "$nbUpdated icons downloaded from c-cex\n"; + return $nbUpdated; + } + + /** + * Icon grabber - Cryptopia (slow https) + */ + public function grabCryptopiaIcons() + { + $url = 'https://www.cryptopia.co.nz/Content/Images/Coins/'; + $nbUpdated = 0; + $sql = "SELECT DISTINCT coins.id FROM coins INNER JOIN markets M ON M.coinid = coins.id " . "WHERE M.name='cryptopia' AND IFNULL(coins.image,'') = ''"; + $coins = dbolist($sql); + if (empty($coins)) return 0; + echo "cryptopia: try to download new icons...\n"; + foreach ($coins as $coin) + { + $coin = getdbo('db_coins', $coin["id"]); + $symbol = $coin->symbol; + if (!empty($coin->symbol2)) $symbol = $coin->symbol2; + $local = $this->basePath . "/images/coin-{$symbol}.png"; + try + { + $data = @file_get_contents($url . strtolower($symbol) . '-medium.png'); + } + catch(Exception $e) + { + continue; + } + if (strlen($data) < 3000 || strstr($data, ' 0) + { + $coin->image = "/images/coin-{$symbol}.png"; + $nbUpdated += $coin->save(); + } + } + if ($nbUpdated) echo "$nbUpdated icons downloaded from cryptopia\n"; + return $nbUpdated; + } + + /** + * Icon grabber - CoinExchange + */ + public function grabCoinExchangeIcons() + { + $url = 'https://www.coinexchange.io/assets/currencies/'; + $nbUpdated = 0; + $sql = "SELECT DISTINCT coins.id FROM coins INNER JOIN markets M ON M.coinid = coins.id " . "WHERE M.name='coinexchange' AND IFNULL(coins.image,'') = ''"; + $coins = dbolist($sql); + if (empty($coins)) return 0; + echo "coinexchange: try to download new icons...\n"; + foreach ($coins as $coin) + { + $coin = getdbo('db_coins', $coin["id"]); + $symbol = $coin->symbol; + if (!empty($coin->symbol2)) $symbol = $coin->symbol2; + $local = $this->basePath . "/images/coin-{$symbol}.png"; + try + { + $data = @file_get_contents($url . strtolower($coin->name) . '.png'); + } + catch(Exception $e) + { + continue; + } + if (strlen($data) < 2048) continue; + echo $symbol . " icon found\n"; + file_put_contents($local, $data); + if (filesize($local) > 0) + { + $coin->image = "/images/coin-{$symbol}.png"; + $nbUpdated += $coin->save(); + } + } + if ($nbUpdated) echo "$nbUpdated icons downloaded from coinexchange\n"; + return $nbUpdated; + } + + /** + * Icon grabber - Alcurex + */ + public function grabAlcurexIcons() + { + $url = 'https://alcurex.com/CSS/img/coins/'; + $nbUpdated = 0; + $sql = "SELECT DISTINCT coins.id FROM coins INNER JOIN markets M ON M.coinid = coins.id " . "WHERE M.name='alcurex' AND IFNULL(coins.image,'') = ''"; + $coins = dbolist($sql); + if (empty($coins)) return 0; + echo "alcurex: try to download new icons...\n"; + foreach ($coins as $coin) + { + $coin = getdbo('db_coins', $coin["id"]); + $symbol = $coin->getOfficialSymbol(); + $local = $this->basePath . "/images/coin-{$symbol}.png"; + try + { + $data = @file_get_contents($url . strtoupper($symbol) . '.png'); + } + catch(Exception $e) + { + continue; + } + if (strlen($data) < 2048) continue; + echo $symbol . " icon found\n"; + file_put_contents($local, $data); + if (filesize($local) > 0) + { + $coin->image = "/images/coin-{$symbol}.png"; + $nbUpdated += $coin->save(); + } + } + if ($nbUpdated) echo "$nbUpdated icons downloaded from alcurex\n"; + return $nbUpdated; + } + + /** + * Icon grabber - KuCoin + */ + public function grabKuCoinIcons() + { + $url = 'https://assets.kucoin.com/www/coin/pc/'; //GRIN.png + $nbUpdated = 0; + $sql = "SELECT DISTINCT coins.id FROM coins INNER JOIN markets M ON M.coinid = coins.id " . "WHERE M.name='kucoin' AND IFNULL(coins.image,'') = ''"; + $coins = dbolist($sql); + if (empty($coins)) return 0; + echo "kucoin: try to download new icons...\n"; + foreach ($coins as $coin) + { + $coin = getdbo('db_coins', $coin["id"]); + $symbol = $coin->getOfficialSymbol(); + $local = $this->basePath . "/images/coin-{$symbol}.png"; + try + { + $data = @file_get_contents($url . $symbol . '.png'); + } + catch(Exception $e) + { + continue; + } + if (strlen($data) < 2048) continue; + echo $symbol . " icon found\n"; + file_put_contents($local, $data); + if (filesize($local) > 0) + { + $coin->image = "/images/coin-{$symbol}.png"; + $nbUpdated += $coin->save(); + } + } + if ($nbUpdated) echo "$nbUpdated icons downloaded from kucoin\n"; + return $nbUpdated; + } + + /** + * Icon grabber - NovaExchange + */ + public function grabNovaIcons() + { + $url = 'http://novaexchange.com/static/symbols/'; + $nbUpdated = 0; + $sql = "SELECT DISTINCT coins.id FROM coins INNER JOIN markets M ON M.coinid = coins.id " . "WHERE M.name='nova' AND IFNULL(coins.image,'') = ''"; + $coins = dbolist($sql); + if (empty($coins)) return 0; + echo "nova: try to download new icons...\n"; + foreach ($coins as $coin) + { + $coin = getdbo('db_coins', $coin["id"]); + $symbol = $coin->getOfficialSymbol(); + $local = $this->basePath . "/images/coin-{$symbol}.png"; + try + { + $data = @file_get_contents($url . strtolower($symbol) . '.png'); + } + catch(Exception $e) + { + continue; + } + if (strlen($data) < 2048) continue; + echo $symbol . " icon found\n"; + file_put_contents($local, $data); + if (filesize($local) > 0) + { + $coin->image = "/images/coin-{$symbol}.png"; + $nbUpdated += $coin->save(); + } + } + if ($nbUpdated) echo "$nbUpdated icons downloaded from novaexchange\n"; + return $nbUpdated; + } } diff --git a/web/yaamp/commands/ExchangeCommand.php b/web/yaamp/commands/ExchangeCommand.php index 03b4abd4f..e6599170e 100644 --- a/web/yaamp/commands/ExchangeCommand.php +++ b/web/yaamp/commands/ExchangeCommand.php @@ -153,11 +153,6 @@ public function testApiKeys() if (!is_object($balance)) echo "bleutrade error\n"; else echo("bleutrade btc: ".json_encode($balance->result)."\n"); } - if (!empty(EXCH_BTER_KEY)) { - $info = bter_api_user('getfunds'); - if (!$info || arraySafeVal($info,'result') != 'true' || !isset($info['available_funds'])) echo "bter error\n"; - else echo("bter available: ".json_encode($info['available_funds'])."\n"); - } if (!empty(EXCH_CCEX_KEY)) { $ccex = new CcexAPI; $balances = $ccex->getBalances(); @@ -196,8 +191,8 @@ public function testApiKeys() $balance = kraken_api_user('Balance'); echo("kraken btc: ".json_encode($balance)."\n"); } - if (!empty(EXCH_KUCOIN_KEY)) { - $balance = kucoin_api_user('account/BTC/balance'); + if (!empty(EXCH_KUCOIN_KEY) && !empty(EXCH_KUCOIN_PASSPHRASE)) { + $balance = kucoin_api_user('accounts',array('currency'=>'BTC')); if (!is_object($balance) || !isset($balance->data)) echo "kucoin error ".json_encode($balance)."\n"; else echo("kucoin: ".json_encode($balance->data)."\n"); } diff --git a/web/yaamp/core/backend/bench.php b/web/yaamp/core/backend/bench.php index 54e4627c6..e8558984e 100644 --- a/web/yaamp/core/backend/bench.php +++ b/web/yaamp/core/backend/bench.php @@ -4,101 +4,118 @@ function BenchUpdateChips() { - require_once(app()->getModulePath().'/bench/functions.php'); + require_once(app()->getModulePath() . '/bench/functions.php'); - // some data cleanup tasks... - dborun("UPDATE benchmarks SET device=TRIM(device) WHERE type='cpu'"); - dborun("UPDATE benchmarks SET power=NULL WHERE power<=3"); - dborun("UPDATE benchmarks SET plimit=NULL WHERE plimit=0"); - dborun("UPDATE benchmarks SET freq=NULL WHERE freq=0"); - dborun("UPDATE benchmarks SET memf=NULL WHERE memf=0"); - dborun("UPDATE benchmarks SET realmemf=NULL WHERE realmemf<=100"); - dborun("UPDATE benchmarks SET realfreq=NULL WHERE realfreq<=200"); - // bug in nvml 378.x and 381.x (linux + win) fixed in 382.05 - dborun("UPDATE benchmarks SET realfreq=NULL WHERE realfreq<=200 AND driver LIKE '% 378.%'"); - dborun("UPDATE benchmarks SET realfreq=NULL WHERE realfreq<=200 AND driver LIKE '% 381.%'"); - // sanity check on long fields (no html wanted) - dborun("DELETE FROM benchmarks WHERE device LIKE '%<%' OR client LIKE '%<%'"); + // some data cleanup tasks... + dborun("UPDATE benchmarks SET device=TRIM(device) WHERE type='cpu'"); + dborun("UPDATE benchmarks SET power=NULL WHERE power<=3"); + dborun("UPDATE benchmarks SET plimit=NULL WHERE plimit=0"); + dborun("UPDATE benchmarks SET freq=NULL WHERE freq=0"); + dborun("UPDATE benchmarks SET memf=NULL WHERE memf=0"); + dborun("UPDATE benchmarks SET realmemf=NULL WHERE realmemf<=100"); + dborun("UPDATE benchmarks SET realfreq=NULL WHERE realfreq<=200"); + // bug in nvml 378.x and 381.x (linux + win) fixed in 382.05 + dborun("UPDATE benchmarks SET realfreq=NULL WHERE realfreq<=200 AND driver LIKE '% 378.%'"); + dborun("UPDATE benchmarks SET realfreq=NULL WHERE realfreq<=200 AND driver LIKE '% 381.%'"); + // sanity check on long fields (no html wanted) + dborun("DELETE FROM benchmarks WHERE device LIKE '%<%' OR client LIKE '%<%'"); - $benchs = getdbolist('db_benchmarks', "IFNULL(chip,'')=''"); - foreach ($benchs as $bench) { - if (empty($bench->vendorid) || empty($bench->device)) continue; + $benchs = getdbolist('db_benchmarks', "IFNULL(chip,'')=''"); + foreach ($benchs as $bench) { + if (empty($bench->vendorid) || empty($bench->device)) + continue; - if ($bench->algo == 'x16r') { // not constant, inaccurate - $bench->delete(); - continue; - } + if ($bench->algo == 'x16r') { // not constant, inaccurate + $bench->delete(); + continue; + } - $rawdata = json_encode($bench->attributes); - if (strpos($rawdata,"script")) { - debuglog("bench record deleted : $rawdata"); - $bench->delete(); - continue; - } + $rawdata = json_encode($bench->attributes); + if (strpos($rawdata, "script")) { + debuglog("bench record deleted : $rawdata"); + $bench->delete(); + continue; + } - $dups = getdbocount('db_benchmarks', "vendorid=:vid AND client=:client AND os=:os AND driver=:drv AND throughput=:thr AND userid=:uid", - array(':vid'=>$bench->vendorid, ':client'=>$bench->client, ':os'=>$bench->os, ':drv'=>$bench->driver,':thr'=>$bench->throughput,':uid'=>$bench->userid) - ); - if ($dups > 10 || round($bench->khps,3) == 0) { - //debuglog("bench: {$bench->device} ignored ($dups records already present)"); - $bench->delete(); - continue; - } + $dups = getdbocount('db_benchmarks', "vendorid=:vid AND client=:client AND os=:os AND driver=:drv AND throughput=:thr AND userid=:uid", array( + ':vid' => $bench->vendorid, + ':client' => $bench->client, + ':os' => $bench->os, + ':drv' => $bench->driver, + ':thr' => $bench->throughput, + ':uid' => $bench->userid + )); + if ($dups > 10 || round($bench->khps, 3) == 0) { + //debuglog("bench: {$bench->device} ignored ($dups records already present)"); + $bench->delete(); + continue; + } - $chip = getChipName($bench->attributes); - if (!empty($chip) && $chip != '-') { - $bench->chip = $chip; - $rates = dborow("SELECT AVG(khps) AS avg, COUNT(id) as cnt FROM benchmarks WHERE algo=:algo AND chip=:chip", - array(':algo'=>$bench->algo, ':chip'=>$chip) - ); - $avg = (double) $rates['avg']; - $cnt = intval($rates['cnt']); - if ($cnt > 250) { - $bench->delete(); - continue; - } elseif ($cnt > 5 && $bench->khps < $avg / 2) { - $user = getdbo('db_accounts', $bench->userid); - debuglog("bench: {$bench->device} ignored, bad {$bench->algo} hashrate {$bench->khps} kHs by {$user->username}"); - $bench->delete(); - continue; - } - if ($bench->chip == 'GPU' || $bench->chip == 'Graphics Device') { - $bench->delete(); - continue; - } - debuglog("bench: {$bench->device} ($chip)..."); - $bench->save(); - } - } + $chip = getChipName($bench->attributes); + if (!empty($chip) && $chip != '-') { + $bench->chip = $chip; + $rates = dborow("SELECT AVG(khps) AS avg, COUNT(id) as cnt FROM benchmarks WHERE algo=:algo AND chip=:chip", array( + ':algo' => $bench->algo, + ':chip' => $chip + )); + $avg = (double) $rates['avg']; + $cnt = intval($rates['cnt']); + if ($cnt > 250) { + $bench->delete(); + continue; + } elseif ($cnt > 5 && $bench->khps < $avg / 2) { + $user = getdbo('db_accounts', $bench->userid); + debuglog("bench: {$bench->device} ignored, bad {$bench->algo} hashrate {$bench->khps} kHs by {$user->username}"); + $bench->delete(); + continue; + } + if ($bench->chip == 'GPU' || $bench->chip == 'Graphics Device') { + $bench->delete(); + continue; + } + debuglog("bench: {$bench->device} ($chip)..."); + $bench->save(); + } + } - // add new chips - $rows = dbolist('SELECT DISTINCT B.chip, B.type FROM benchmarks B WHERE B.chip NOT IN ( - SELECT DISTINCT C.chip FROM bench_chips C WHERE C.devicetype = B.type - )'); + // add new chips + $rows = dbolist('SELECT DISTINCT B.chip, B.type FROM benchmarks B WHERE B.chip NOT IN ( + SELECT DISTINCT C.chip FROM bench_chips C WHERE C.devicetype = B.type + )'); - foreach ($rows as $row) { - if (empty($row['chip']) || empty($row['type'])) continue; - $chip = new db_bench_chips; - $chip->chip = $row['chip']; - $chip->devicetype = $row['type']; - if ($chip->insert()) { - debuglog("bench: added {$chip->devicetype} chip {$chip->chip}"); - dborun('UPDATE benchmarks SET idchip=:id WHERE chip=:chip AND type=:type', array( - ':id'=>$chip->id, ':chip'=>$row['chip'], ':type'=>$row['type'], - )); - } - } + foreach ($rows as $row) { + if (empty($row['chip']) || empty($row['type'])) + continue; + $chip = new db_bench_chips; + $chip->chip = $row['chip']; + $chip->devicetype = $row['type']; + if ($chip->insert()) { + debuglog("bench: added {$chip->devicetype} chip {$chip->chip}"); + dborun('UPDATE benchmarks SET idchip=:id WHERE chip=:chip AND type=:type', array( + ':id' => $chip->id, + ':chip' => $row['chip'], + ':type' => $row['type'] + )); + } + } - // update existing ones - $rows = dbolist('SELECT DISTINCT chip, type FROM benchmarks WHERE idchip IS NULL'); - foreach ($rows as $row) { - if (empty($row['chip']) || empty($row['type'])) continue; - $chip = getdbosql('db_bench_chips', 'chip=:name AND devicetype=:type', array(':name'=>$row['chip'], ':type'=>$row['type'])); - if (!$chip || !$chip->id) continue; - dborun('UPDATE benchmarks SET idchip=:id WHERE chip=:chip AND type=:type', array( - ':id'=>$chip->id, ':chip'=>$row['chip'], ':type'=>$row['type'], - )); - } + // update existing ones + $rows = dbolist('SELECT DISTINCT chip, type FROM benchmarks WHERE idchip IS NULL'); + foreach ($rows as $row) { + if (empty($row['chip']) || empty($row['type'])) + continue; + $chip = getdbosql('db_bench_chips', 'chip=:name AND devicetype=:type', array( + ':name' => $row['chip'], + ':type' => $row['type'] + )); + if (!$chip || !$chip->id) + continue; + dborun('UPDATE benchmarks SET idchip=:id WHERE chip=:chip AND type=:type', array( + ':id' => $chip->id, + ':chip' => $row['chip'], + ':type' => $row['type'] + )); + } } diff --git a/web/yaamp/core/backend/blocks.php b/web/yaamp/core/backend/blocks.php index 5854f1571..84bca41b8 100644 --- a/web/yaamp/core/backend/blocks.php +++ b/web/yaamp/core/backend/blocks.php @@ -2,81 +2,97 @@ function BackendBlockNew($coin, $db_block) { -// debuglog("NEW BLOCK $coin->name $db_block->height"); - $reward = $db_block->amount; - if(!$reward || $db_block->algo == 'PoS' || $db_block->algo == 'MN') return; - if($db_block->category == 'stake' || $db_block->category == 'generated') return; - - $sqlCond = "valid = 1"; - if(!YAAMP_ALLOW_EXCHANGE) // only one coin mined - $sqlCond .= " AND coinid = ".intval($coin->id); - - $total_hash_power = dboscalar("SELECT SUM(difficulty) FROM shares WHERE $sqlCond AND algo=:algo", array(':algo'=>$coin->algo)); - if(!$total_hash_power) return; - - $list = dbolist("SELECT userid, SUM(difficulty) AS total FROM shares WHERE $sqlCond AND algo=:algo GROUP BY userid", - array(':algo'=>$coin->algo)); - - foreach($list as $item) - { - $hash_power = $item['total']; - if(!$hash_power) continue; - - $user = getdbo('db_accounts', $item['userid']); - if(!$user) continue; - - $amount = $reward * $hash_power / $total_hash_power; - if(!$user->no_fees) $amount = take_yaamp_fee($amount, $coin->algo); - if(!empty($user->donation)) { - $amount = take_yaamp_fee($amount, $coin->algo, $user->donation); - if ($amount <= 0) continue; - } - - $earning = new db_earnings; - $earning->userid = $user->id; - $earning->coinid = $coin->id; - $earning->blockid = $db_block->id; - $earning->create_time = $db_block->time; - $earning->amount = $amount; - $earning->price = $coin->price; - - if($db_block->category == 'generate') - { - $earning->mature_time = time(); - $earning->status = 1; - } - else // immature - $earning->status = 0; - - $ucoin = getdbo('db_coins', $user->coinid); - if(!YAAMP_ALLOW_EXCHANGE && $ucoin && $ucoin->algo != $coin->algo) { - debuglog($coin->symbol.": invalid earning for {$user->username}, user coin is {$ucoin->symbol}"); - $earning->status = -1; - } - - if (!$earning->save()) - debuglog(__FUNCTION__.": Unable to insert earning!"); - - $user->last_earning = time(); - $user->save(); - } - - $delay = time() - 5*60; - $sqlCond = "time < $delay"; - if(!YAAMP_ALLOW_EXCHANGE) // only one coin mined - $sqlCond .= " AND coinid = ".intval($coin->id); - - try { - dborun("DELETE FROM shares WHERE algo=:algo AND $sqlCond", array(':algo'=>$coin->algo)); - - } catch (CDbException $e) { - - debuglog("unable to delete shares $sqlCond retrying..."); - sleep(1); - dborun("DELETE FROM shares WHERE algo=:algo AND $sqlCond", array(':algo'=>$coin->algo)); - // [errorInfo] => array(0 => 'HY000', 1 => 1205, 2 => 'Lock wait timeout exceeded; try restarting transaction') - // [*:message] => 'CDbCommand failed to execute the SQL statement: SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction' - } + // debuglog("NEW BLOCK $coin->name $db_block->height"); + $reward = $db_block->amount; + if (!$reward || $db_block->algo == 'PoS' || $db_block->algo == 'MN') + return; + if ($db_block->category == 'stake' || $db_block->category == 'generated') + return; + + $sqlCond = "valid = 1"; + if (!YAAMP_ALLOW_EXCHANGE) // only one coin mined + $sqlCond .= " AND coinid = " . intval($coin->id); + + $total_hash_power = dboscalar("SELECT SUM(difficulty) FROM shares WHERE $sqlCond AND algo=:algo", array( + ':algo' => $coin->algo + )); + if (!$total_hash_power) + return; + + $list = dbolist("SELECT userid, SUM(difficulty) AS total FROM shares WHERE $sqlCond AND algo=:algo GROUP BY userid", array( + ':algo' => $coin->algo + )); + + foreach ($list as $item) { + $hash_power = $item['total']; + if (!$hash_power) + continue; + + $user = getdbo('db_accounts', $item['userid']); + if (!$user) + continue; + + $amount = $reward * $hash_power / $total_hash_power; + if (!$user->no_fees) + $amount = take_yaamp_fee($amount, $coin->algo); + if (!empty($user->donation)) { + $amount = take_yaamp_fee($amount, $coin->algo, $user->donation); + if ($amount <= 0) + continue; + } + + $earning = new db_earnings; + $earning->userid = $user->id; + $earning->coinid = $coin->id; + $earning->blockid = $db_block->id; + $earning->create_time = $db_block->time; + $earning->amount = $amount; + $earning->price = $coin->price; + + if ($db_block->category == 'generate') { + $earning->mature_time = time(); + $earning->status = 1; + } else // immature + $earning->status = 0; + + $ucoin = (object) dborow("SELECT algo,symbol FROM coins WHERE id=:id", array( + ':id' => $user->coinid + )); + if (!YAAMP_ALLOW_EXCHANGE && $ucoin && $ucoin->algo != $coin->algo) { + debuglog($coin->symbol . ": invalid earning for {$user->username}, user coin is {$ucoin->symbol}"); + $earning->status = -1; + } + + if (!$earning->save()) + debuglog(__FUNCTION__ . ": Unable to insert earning!"); + + dborun('UPDATE accounts SET last_earning=:time WHERE id=:id', array( + ':id' => $user->id, + ':time' => time() + )); + } + + $delay = time() - 5 * 60; + $sqlCond = "time < $delay"; + if (!YAAMP_ALLOW_EXCHANGE) // only one coin mined + $sqlCond .= " AND coinid = " . intval($coin->id); + + try { + dborun("DELETE FROM shares WHERE algo=:algo AND $sqlCond", array( + ':algo' => $coin->algo + )); + + } + catch (CDbException $e) { + + debuglog("unable to delete shares $sqlCond retrying..."); + sleep(1); + dborun("DELETE FROM shares WHERE algo=:algo AND $sqlCond", array( + ':algo' => $coin->algo + )); + // [errorInfo] => array(0 => 'HY000', 1 => 1205, 2 => 'Lock wait timeout exceeded; try restarting transaction') + // [*:message] => 'CDbCommand failed to execute the SQL statement: SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction' + } } ///////////////////////////////////////////////////////////////////////////////////////////////// @@ -84,90 +100,91 @@ function BackendBlockNew($coin, $db_block) function BackendBlockFind1($coinid = NULL) { - $sqlFilter = $coinid ? " AND coin_id=".intval($coinid) : ''; - -// debuglog(__METHOD__); - $list = getdbolist('db_blocks', "category='new' $sqlFilter ORDER BY time"); - foreach($list as $db_block) - { - $coin = getdbo('db_coins', $db_block->coin_id); - if(!$coin || !$db_block->coin_id) { - debuglog("warning: bad coin id {$db_block->coin_id} for block id {$db_block->id}!"); - $db_block->delete(); - continue; - } - if(!$coin->enable) continue; - if($coin->rpcencoding == 'DCR' && !$coin->auto_ready) continue; - - $dblock = getdbosql('db_blocks', "coin_id=:coinid AND blockhash=:hash AND height=:height AND id!=:blockid", - array(':coinid'=>$coin->id, ':hash'=>$db_block->blockhash, ':height'=>$db_block->height, ':blockid'=>$db_block->id) - ); - - if($dblock) { - debuglog("warning: Doubled {$coin->symbol} block found for block height {$db_block->height}!"); - $db_block->delete(); - continue; - } - - $db_block->category = 'orphan'; - $remote = new WalletRPC($coin); - - $block = $remote->getblock($db_block->blockhash); - $block_age = time() - $db_block->time; - if($coin->rpcencoding == 'DCR' && $block_age < 2000) { - // DCR generated blocks need some time to be accepted by the network (gettransaction) - if (!$block) continue; - $txid = $block['tx'][0]; - $tx = $remote->gettransaction($txid); - if (!$tx || !isset($tx['details'])) continue; - debuglog("{$coin->symbol} {$db_block->height} confirmed after ".$block_age." seconds"); - } - else if(!$block || !isset($block['tx']) || !isset($block['tx'][0])) - { - $db_block->amount = 0; - $db_block->save(); - debuglog("{$coin->symbol} orphan {$db_block->height} after ".(time() - $db_block->time)." seconds"); - continue; - } - else if ($coin->rpcencoding == 'POS' && arraySafeVal($block,'nonce') == 0) { - $db_block->category = 'stake'; - $db_block->save(); - continue; - } - - $tx = $remote->gettransaction($block['tx'][0]); - if(!$tx || !isset($tx['details']) || !isset($tx['details'][0])) - { - $db_block->amount = 0; - $db_block->save(); - continue; - } - - $db_block->txhash = $block['tx'][0]; - $db_block->category = 'immature'; //$tx['details'][0]['category']; - $db_block->amount = $tx['details'][0]['amount']; - $db_block->confirmations = $tx['confirmations']; - $db_block->price = $coin->price; - - // save worker to compute blocs found per worker (current workers stats) - // now made directly in stratum - require DB update 2015-09-20 - if (empty($db_block->workerid) && $db_block->userid > 0) { - $db_block->workerid = (int) dboscalar( - "SELECT workerid FROM shares WHERE userid=:user AND coinid=:coin AND valid=1 AND time <= :time ". - "ORDER BY difficulty DESC LIMIT 1", array( - ':user' => $db_block->userid, - ':coin' => $db_block->coin_id, - ':time' => $db_block->time - )); - if (!$db_block->workerid) $db_block->workerid = NULL; - } - - if (!$db_block->save()) - debuglog(__FUNCTION__.": unable to insert block!"); - - if($db_block->category != 'orphan') - BackendBlockNew($coin, $db_block); // will drop shares - } + $sqlFilter = $coinid ? " AND coin_id=" . intval($coinid) : ''; + + // debuglog(__METHOD__); + $list = getdbolist('db_blocks', "category='new' $sqlFilter ORDER BY time"); + foreach ($list as $db_block) { + $coin = getdbo('db_coins', $db_block->coin_id); + if (!$coin || !$db_block->coin_id) { + debuglog("warning: bad coin id {$db_block->coin_id} for block id {$db_block->id}!"); + $db_block->delete(); + continue; + } + if (!$coin->enable) + continue; + if ($coin->rpcencoding == 'DCR' && !$coin->auto_ready) + continue; + + $dblock = getdbosql('db_blocks', "coin_id=:coinid AND blockhash=:hash AND height=:height AND id!=:blockid", array( + ':coinid' => $coin->id, + ':hash' => $db_block->blockhash, + ':height' => $db_block->height, + ':blockid' => $db_block->id + )); + + if ($dblock) { + debuglog("warning: Doubled {$coin->symbol} block found for block height {$db_block->height}!"); + $db_block->delete(); + continue; + } + + $db_block->category = 'orphan'; + $remote = new WalletRPC($coin); + + $block = $remote->getblock($db_block->blockhash); + $block_age = time() - $db_block->time; + if ($coin->rpcencoding == 'DCR' && $block_age < 2000) { + // DCR generated blocks need some time to be accepted by the network (gettransaction) + if (!$block) + continue; + $txid = $block['tx'][0]; + $tx = $remote->gettransaction($txid); + if (!$tx || !isset($tx['details'])) + continue; + debuglog("{$coin->symbol} {$db_block->height} confirmed after " . $block_age . " seconds"); + } else if (!$block || !isset($block['tx']) || !isset($block['tx'][0])) { + $db_block->amount = 0; + $db_block->save(); + debuglog("{$coin->symbol} orphan {$db_block->height} after " . (time() - $db_block->time) . " seconds"); + continue; + } else if ($coin->rpcencoding == 'POS' && arraySafeVal($block, 'nonce') == 0) { + $db_block->category = 'stake'; + $db_block->save(); + continue; + } + + $tx = $remote->gettransaction($block['tx'][0]); + if (!$tx || !isset($tx['details']) || !isset($tx['details'][0])) { + $db_block->amount = 0; + $db_block->save(); + continue; + } + + $db_block->txhash = $block['tx'][0]; + $db_block->category = 'immature'; //$tx['details'][0]['category']; + $db_block->amount = $tx['details'][0]['amount']; + $db_block->confirmations = $tx['confirmations']; + $db_block->price = $coin->price; + + // save worker to compute blocs found per worker (current workers stats) + // now made directly in stratum - require DB update 2015-09-20 + if (empty($db_block->workerid) && $db_block->userid > 0) { + $db_block->workerid = (int) dboscalar("SELECT workerid FROM shares WHERE userid=:user AND coinid=:coin AND valid=1 AND time <= :time " . "ORDER BY difficulty DESC LIMIT 1", array( + ':user' => $db_block->userid, + ':coin' => $db_block->coin_id, + ':time' => $db_block->time + )); + if (!$db_block->workerid) + $db_block->workerid = NULL; + } + + if (!$db_block->save()) + debuglog(__FUNCTION__ . ": unable to insert block!"); + + if ($db_block->category != 'orphan') + BackendBlockNew($coin, $db_block); // will drop shares + } } ///////////////////////////////////////////////////////////////////////////////// @@ -175,128 +192,126 @@ function BackendBlockFind1($coinid = NULL) function BackendBlocksUpdate($coinid = NULL) { -// debuglog(__METHOD__); - $t1 = microtime(true); - - $sqlFilter = $coinid ? " AND coin_id=".intval($coinid) : ''; - - $list = getdbolist('db_blocks', "category IN ('immature','stake','orphan') $sqlFilter ORDER BY time"); - foreach($list as $block) - { - $coin = getdbo('db_coins', $block->coin_id); - if(!$block->coin_id || !$coin) { - debuglog("warning: bad coin id {$block->coin_id} for block id {$block->id}!"); - $block->delete(); - continue; - } - - if (!$coin->auto_ready || ($coin->target_height && $coin->target_height > $coin->block_height)) { - continue; - } - - $remote = new WalletRPC($coin); - if(empty($block->txhash)) - { - $blockext = $remote->getblock($block->blockhash); - - if ($coin->rpcencoding == 'POS' && arraySafeVal($blockext,'nonce') == 0) { - $block->category = 'stake'; - $block->save(); - } - - if(!$blockext || !isset($blockext['tx'][0])) continue; - - $block->txhash = $blockext['tx'][0]; - - if(empty($block->txhash)) continue; - } - - $tx = $remote->gettransaction($block->txhash); - if(!$tx && $block->category != 'orphan') { - if ($coin->enable) { - debuglog("{$coin->name} unable to find {$block->category} block {$block->height} tx {$block->txhash}!"); - // DCR orphaned confirmations are not(no more) -1! - if($coin->rpcencoding == 'DCR' && $block->category == 'immature' && $coin->auto_ready) { - $blockext = $remote->getblock($block->blockhash); - $conf = arraySafeVal($blockext,'confirmations',-1); - if ($conf == -1 || ($conf > 2 && arraySafeVal($blockext,'nextblockhash','') == '')) { - debuglog("{$coin->name} orphan block {$block->height} detected! (after $conf confirmations)"); - $block->confirmations = -1; - $block->amount = 0; - $block->category = 'orphan'; - $block->save(); - continue; - } - } - } - else if ((time() - $block->time) > (7 * 24 * 3600)) { - debuglog("{$coin->name} outdated immature block {$block->height} detected!"); - $block->category = 'orphan'; - } - $block->save(); - continue; - } - - if ($block->category == 'orphan') { - // LUX doing multiple reorg ? Only seen on this wallet - if ($coin->enable && (time() - $block->time) < 3600) { - $blockext = $remote->getblock($block->blockhash); - $conf = arraySafeVal($blockext,'confirmations',-1); - if ($conf > 2 && arraySafeVal($blockext,'nextblockhash','') != '') { - debuglog("{$coin->name} orphan block {$block->height} is not anymore! ($conf confirmations)"); - $block->category = 'new'; // will set amount and restore user earnings - $block->save(); - } - } - continue; - } - - $block->confirmations = $tx['confirmations']; - - $category = $block->category; - if($block->confirmations == -1 && $coin->enable && $coin->auto_ready) { - $category = 'orphan'; - $block->amount = 0; - } - - else if(isset($tx['details']) && isset($tx['details'][0])) - $category = $tx['details'][0]['category']; - - else if(isset($tx['category'])) - $category = $tx['category']; - - // PoS blocks - if ($block->category == 'stake') { - if ($category == 'generate') { - $block->category = 'generated'; - } else if ($category == 'orphan') { - $block->category = 'orphan'; - } - $block->save(); - continue; - } - - // PoW blocks - $block->category = $category; - $block->save(); - - if($category == 'generate') { - dborun("UPDATE earnings SET status=1, mature_time=UNIX_TIMESTAMP() WHERE blockid=".intval($block->id)." AND status!=-1"); - - // auto update mature_blocks - if ($block->confirmations > 0 && $block->confirmations < $coin->mature_blocks || empty($coin->mature_blocks)) { - $coin = getdbo('db_coins', $block->coin_id); // refresh coin data - debuglog("{$coin->symbol} mature_blocks updated to {$block->confirmations}"); - $coin->mature_blocks = $block->confirmations; - $coin->save(); - } - } - else if($category != 'immature') - dborun("DELETE FROM earnings WHERE blockid=".intval($block->id)." AND status!=-1"); - } - - $d1 = microtime(true) - $t1; - controller()->memcache->add_monitoring_function(__METHOD__, $d1); + // debuglog(__METHOD__); + $t1 = microtime(true); + + $sqlFilter = $coinid ? " AND coin_id=" . intval($coinid) : ''; + + $list = getdbolist('db_blocks', "category IN ('immature','stake','orphan') $sqlFilter ORDER BY time"); + foreach ($list as $block) { + $coin = getdbo('db_coins', $block->coin_id); + if (!$block->coin_id || !$coin) { + debuglog("warning: bad coin id {$block->coin_id} for block id {$block->id}!"); + $block->delete(); + continue; + } + + if (!$coin->auto_ready || ($coin->target_height && $coin->target_height > $coin->block_height)) { + continue; + } + + $remote = new WalletRPC($coin); + if (empty($block->txhash)) { + $blockext = $remote->getblock($block->blockhash); + + if ($coin->rpcencoding == 'POS' && arraySafeVal($blockext, 'nonce') == 0) { + $block->category = 'stake'; + $block->save(); + } + + if (!$blockext || !isset($blockext['tx'][0])) + continue; + + $block->txhash = $blockext['tx'][0]; + + if (empty($block->txhash)) + continue; + } + + $tx = $remote->gettransaction($block->txhash); + if (!$tx && $block->category != 'orphan') { + if ($coin->enable) { + debuglog("{$coin->name} unable to find {$block->category} block {$block->height} tx {$block->txhash}!"); + // DCR orphaned confirmations are not(no more) -1! + if ($coin->rpcencoding == 'DCR' && $block->category == 'immature' && $coin->auto_ready) { + $blockext = $remote->getblock($block->blockhash); + $conf = arraySafeVal($blockext, 'confirmations', -1); + if ($conf == -1 || ($conf > 2 && arraySafeVal($blockext, 'nextblockhash', '') == '')) { + debuglog("{$coin->name} orphan block {$block->height} detected! (after $conf confirmations)"); + $block->confirmations = -1; + $block->amount = 0; + $block->category = 'orphan'; + $block->save(); + continue; + } + } + } else if ((time() - $block->time) > (7 * 24 * 3600)) { + debuglog("{$coin->name} outdated immature block {$block->height} detected!"); + $block->category = 'orphan'; + } + $block->save(); + continue; + } + + if ($block->category == 'orphan') { + // LUX doing multiple reorg ? Only seen on this wallet + if ($coin->enable && (time() - $block->time) < 3600) { + $blockext = $remote->getblock($block->blockhash); + $conf = arraySafeVal($blockext, 'confirmations', -1); + if ($conf > 2 && arraySafeVal($blockext, 'nextblockhash', '') != '') { + debuglog("{$coin->name} orphan block {$block->height} is not anymore! ($conf confirmations)"); + $block->category = 'new'; // will set amount and restore user earnings + $block->save(); + } + } + continue; + } + + $block->confirmations = $tx['confirmations']; + + $category = $block->category; + if ($block->confirmations == -1 && $coin->enable && $coin->auto_ready) { + $category = 'orphan'; + $block->amount = 0; + } + + else if (isset($tx['details']) && isset($tx['details'][0])) + $category = $tx['details'][0]['category']; + + else if (isset($tx['category'])) + $category = $tx['category']; + + // PoS blocks + if ($block->category == 'stake') { + if ($category == 'generate') { + $block->category = 'generated'; + } else if ($category == 'orphan') { + $block->category = 'orphan'; + } + $block->save(); + continue; + } + + // PoW blocks + $block->category = $category; + $block->save(); + + if ($category == 'generate') { + dborun("UPDATE earnings SET status=1, mature_time=UNIX_TIMESTAMP() WHERE blockid=" . intval($block->id) . " AND status!=-1"); + + // auto update mature_blocks + if ($block->confirmations > 0 && $block->confirmations < $coin->mature_blocks || empty($coin->mature_blocks)) { + $coin = getdbo('db_coins', $block->coin_id); // refresh coin data + debuglog("{$coin->symbol} mature_blocks updated to {$block->confirmations}"); + $coin->mature_blocks = $block->confirmations; + $coin->save(); + } + } else if ($category != 'immature') + dborun("DELETE FROM earnings WHERE blockid=" . intval($block->id) . " AND status!=-1"); + } + + $d1 = microtime(true) - $t1; + controller()->memcache->add_monitoring_function(__METHOD__, $d1); } //////////////////////////////////////////////////////////////////////////////////////////// @@ -304,98 +319,107 @@ function BackendBlocksUpdate($coinid = NULL) function BackendBlockFind2($coinid = NULL) { - $t1 = microtime(true); - - $sqlFilter = $coinid ? "id=".intval($coinid) : 'enable=1'; - - $coins = getdbolist('db_coins', $sqlFilter); - foreach($coins as $coin) - { - if($coin->symbol == 'BTC') continue; - $remote = new WalletRPC($coin); - - $timerpc = microtime(true); - $mostrecent = 0; - if(empty($coin->lastblock)) $coin->lastblock = ''; - $list = $remote->listsinceblock($coin->lastblock); - $rpcdelay = microtime(true) - $timerpc; - if ($rpcdelay > 0.5) - screenlog(__FUNCTION__.": {$coin->symbol} listsinceblock took ".round($rpcdelay,3)." sec, ". - (is_array($list) ? count($list) : 0). "txs"); - if(!$list) continue; - - foreach($list['transactions'] as $transaction) - { - if(!isset($transaction['blockhash'])) continue; - if($transaction['time'] > time() - 5*60) continue; - if($transaction['time'] < time() - 60*60) continue; - if($transaction['category'] != 'generate' && $transaction['category'] != 'immature') continue; - - $blockext = $remote->getblock($transaction['blockhash']); - if(!$blockext) continue; - - $db_block = getdbosql('db_blocks', "coin_id=:id AND (blockhash=:hash OR height=:height)", - array(':id'=>$coin->id, ':hash'=>$transaction['blockhash'], ':height'=>$blockext['height']) - ); - if($db_block) continue; - - if ($coin->rpcencoding == 'DCR') - debuglog("{$coin->name} generated block {$blockext['height']} detected!"); - - if($transaction['time'] > $mostrecent) { - $coin = getdbo('db_coins', $coin->id); // refresh coin data - $coin->lastblock = $transaction['blockhash']; - $coin->save(); - $mostrecent = $transaction['time']; - } - - $db_block = new db_blocks; - $db_block->blockhash = $transaction['blockhash']; - $db_block->coin_id = $coin->id; - $db_block->category = 'immature'; //$transaction['category']; - $db_block->time = $transaction['time']; - $db_block->amount = $transaction['amount']; - $db_block->algo = $coin->algo; - - if (arraySafeVal($blockext,'nonce',0) != 0) { - $db_block->difficulty_user = hash_to_difficulty($coin, $transaction['blockhash']); - } else if ($coin->rpcencoding == 'POS') { - $db_block->category = 'stake'; - } - - // masternode earnings... - if (empty($db_block->userid) && $transaction['amount'] == 0 && $transaction['generated']) { - $db_block->algo = 'MN'; - $tx = $remote->getrawtransaction($transaction['txid'], 1); - - // assume the MN amount is in the last vout record (should check "addresses") - if (isset($tx['vout']) && !empty($tx['vout'])) { - $vout = end($tx['vout']); - $db_block->amount = $vout['value']; - debuglog("MN ".bitcoinvaluetoa($db_block->amount).' '.$coin->symbol.' ('.$blockext['height'].')'); - } - - if (!$coin->hasmasternodes) { - $coin = getdbo('db_coins', $coin->id); // refresh coin data - $coin->hasmasternodes = true; - $coin->save(); - } - } - - $db_block->confirmations = $transaction['confirmations']; - $db_block->height = $blockext['height']; - $db_block->difficulty = $blockext['difficulty']; - $db_block->price = $coin->price; - if (!$db_block->save()) - debuglog(__FUNCTION__.": unable to insert block!"); - - BackendBlockNew($coin, $db_block); - } // tx - } - - $d1 = microtime(true) - $t1; - controller()->memcache->add_monitoring_function(__FUNCTION__, $d1); - if ($d1 > 3.0) screenlog(__FUNCTION__.": took ".round($d1,3)." sec"); + $t1 = microtime(true); + + $sqlFilter = $coinid ? "id=" . intval($coinid) : 'enable=1'; + + $coins = getdbolist('db_coins', $sqlFilter); + foreach ($coins as $coin) { + if ($coin->symbol == 'BTC') + continue; + $remote = new WalletRPC($coin); + + $timerpc = microtime(true); + $mostrecent = 0; + if (empty($coin->lastblock)) + $coin->lastblock = ''; + $list = $remote->listsinceblock($coin->lastblock); + $rpcdelay = microtime(true) - $timerpc; + if ($rpcdelay > 0.5) + screenlog(__FUNCTION__ . ": {$coin->symbol} listsinceblock took " . round($rpcdelay, 3) . " sec, " . (is_array($list) ? count($list) : 0) . "txs"); + if (!$list) + continue; + + foreach ($list['transactions'] as $transaction) { + if (!isset($transaction['blockhash'])) + continue; + if ($transaction['time'] > time() - 5 * 60) + continue; + if ($transaction['time'] < time() - 60 * 60) + continue; + if ($transaction['category'] != 'generate' && $transaction['category'] != 'immature') + continue; + + $blockext = $remote->getblock($transaction['blockhash']); + if (!$blockext) + continue; + + $db_block = getdbosql('db_blocks', "coin_id=:id AND (blockhash=:hash OR height=:height)", array( + ':id' => $coin->id, + ':hash' => $transaction['blockhash'], + ':height' => $blockext['height'] + )); + if ($db_block) + continue; + + if ($coin->rpcencoding == 'DCR') + debuglog("{$coin->name} generated block {$blockext['height']} detected!"); + + if ($transaction['time'] > $mostrecent) { + $coin = getdbo('db_coins', $coin->id); // refresh coin data + $coin->lastblock = $transaction['blockhash']; + $coin->save(); + $mostrecent = $transaction['time']; + } + + $db_block = new db_blocks; + $db_block->blockhash = $transaction['blockhash']; + $db_block->coin_id = $coin->id; + $db_block->category = 'immature'; //$transaction['category']; + $db_block->time = $transaction['time']; + $db_block->amount = $transaction['amount']; + $db_block->algo = $coin->algo; + + if (arraySafeVal($blockext, 'nonce', 0) != 0) { + $db_block->difficulty_user = hash_to_difficulty($coin, $transaction['blockhash']); + } else if ($coin->rpcencoding == 'POS') { + $db_block->category = 'stake'; + } + + // masternode earnings... + if (empty($db_block->userid) && $transaction['amount'] == 0 && $transaction['generated']) { + $db_block->algo = 'MN'; + $tx = $remote->getrawtransaction($transaction['txid'], 1); + + // assume the MN amount is in the last vout record (should check "addresses") + if (isset($tx['vout']) && !empty($tx['vout'])) { + $vout = end($tx['vout']); + $db_block->amount = $vout['value']; + debuglog("MN " . bitcoinvaluetoa($db_block->amount) . ' ' . $coin->symbol . ' (' . $blockext['height'] . ')'); + } + + if (!$coin->hasmasternodes) { + $coin = getdbo('db_coins', $coin->id); // refresh coin data + $coin->hasmasternodes = true; + $coin->save(); + } + } + + $db_block->confirmations = $transaction['confirmations']; + $db_block->height = $blockext['height']; + $db_block->difficulty = $blockext['difficulty']; + $db_block->price = $coin->price; + if (!$db_block->save()) + debuglog(__FUNCTION__ . ": unable to insert block!"); + + BackendBlockNew($coin, $db_block); + } // tx + } + + $d1 = microtime(true) - $t1; + controller()->memcache->add_monitoring_function(__FUNCTION__, $d1); + if ($d1 > 3.0) + screenlog(__FUNCTION__ . ": took " . round($d1, 3) . " sec"); } //////////////////////////////////////////////////////////////////////////////////////////// @@ -403,74 +427,78 @@ function BackendBlockFind2($coinid = NULL) function BackendUpdatePoolBalances($coinid = NULL) { - $t1 = microtime(true); - - $sqlFilter = 'enable=1'; - - if ($coinid) { // used from wallet manual send - $sqlFilter = "id=".intval($coinid); - // refresh balance field from the wallet info - $coin = getdbo('db_coins', $coinid); - $remote = new WalletRPC($coin); - $info = $remote->getinfo(); - if(isset($info['balance'])) { - $coin->balance = $info['balance']; - $coin->save(); - } - } - - $coins = getdbolist('db_coins', $sqlFilter); - foreach($coins as $coin) - { - $coin->immature = (double) dboscalar("SELECT SUM(amount) FROM blocks WHERE category='immature' AND coin_id=".intval($coin->id)); - $coin->cleared = (double) dboscalar("SELECT SUM(balance) FROM accounts WHERE coinid=".intval($coin->id)); - $pending = (double) dboscalar("SELECT SUM(amount) FROM earnings WHERE status=1 AND coinid=".intval($coin->id)); // (to be cleared) - $coin->available = (double) $coin->balance - $coin->cleared - $pending; - //if ($pending) debuglog("{$coin->symbol} immature {$coin->immature}, cleared {$coin->cleared}, pending {$pending}, available {$coin->available}"); - $coin->save(); - } - - $d1 = microtime(true) - $t1; - controller()->memcache->add_monitoring_function(__FUNCTION__, $d1); - //debuglog(__FUNCTION__." took ".round($d1,3)." sec"); + $t1 = microtime(true); + + $sqlFilter = 'enable=1'; + + if ($coinid) { // used from wallet manual send + $sqlFilter = "id=" . intval($coinid); + // refresh balance field from the wallet info + $coin = getdbo('db_coins', $coinid); + $remote = new WalletRPC($coin); + $info = $remote->getinfo(); + if (isset($info['balance'])) { + $coin->balance = $info['balance']; + $coin->save(); + } + } + + $coins = getdbolist('db_coins', $sqlFilter); + foreach ($coins as $coin) { + $coin->immature = (double) dboscalar("SELECT SUM(amount) FROM blocks WHERE category='immature' AND coin_id=" . intval($coin->id)); + $coin->cleared = (double) dboscalar("SELECT SUM(balance) FROM accounts WHERE coinid=" . intval($coin->id)); + $pending = (double) dboscalar("SELECT SUM(amount) FROM earnings WHERE status=1 AND coinid=" . intval($coin->id)); // (to be cleared) + $coin->available = (double) $coin->balance - $coin->cleared - $pending; + //if ($pending) debuglog("{$coin->symbol} immature {$coin->immature}, cleared {$coin->cleared}, pending {$pending}, available {$coin->available}"); + $coin->save(); + } + + $d1 = microtime(true) - $t1; + controller()->memcache->add_monitoring_function(__FUNCTION__, $d1); + //debuglog(__FUNCTION__." took ".round($d1,3)." sec"); } //////////////////////////////////////////////////////////////////////////////////////////// function MonitorBTC() { -// debuglog(__FUNCTION__); + // debuglog(__FUNCTION__); - $coin = getdbosql('db_coins', "symbol='BTC'"); - if(!$coin) return; + $coin = getdbosql('db_coins', "symbol='BTC'"); + if (!$coin) + return; - $remote = new WalletRPC($coin); - if(!$remote) return; + $remote = new WalletRPC($coin); + if (!$remote) + return; - $mostrecent = 0; - if($coin->lastblock == null) $coin->lastblock = ''; - $list = $remote->listsinceblock($coin->lastblock); - if(!$list) return; + $mostrecent = 0; + if ($coin->lastblock == null) + $coin->lastblock = ''; + $list = $remote->listsinceblock($coin->lastblock); + if (!$list) + return; - $coin->lastblock = $list['lastblock']; - $coin->save(); + $coin->lastblock = $list['lastblock']; + $coin->save(); - foreach($list['transactions'] as $transaction) - { - if(!isset($transaction['blockhash'])) continue; - if($transaction['confirmations'] == 0) continue; - if($transaction['category'] != 'send') continue; - //if($transaction['fee'] != -0.0001) continue; + foreach ($list['transactions'] as $transaction) { + if (!isset($transaction['blockhash'])) + continue; + if ($transaction['confirmations'] == 0) + continue; + if ($transaction['category'] != 'send') + continue; + //if($transaction['fee'] != -0.0001) continue; - debuglog(__FUNCTION__); - debuglog($transaction); + debuglog(__FUNCTION__); + debuglog($transaction); - $txurl = "https://blockchain.info/tx/{$transaction['txid']}"; + $txurl = "https://blockchain.info/tx/{$transaction['txid']}"; - $b = mail(YAAMP_ADMIN_EMAIL, "withdraw {$transaction['amount']}", - "{$transaction['address']}"); + $b = mail(YAAMP_ADMIN_EMAIL, "withdraw {$transaction['amount']}", "{$transaction['address']}"); - if(!$b) debuglog('error sending email'); - } + if (!$b) + debuglog('error sending email'); + } } - diff --git a/web/yaamp/core/backend/clear.php b/web/yaamp/core/backend/clear.php index 0e64849fb..39e8a06db 100644 --- a/web/yaamp/core/backend/clear.php +++ b/web/yaamp/core/backend/clear.php @@ -2,54 +2,50 @@ function BackendClearEarnings($coinid = NULL) { -// debuglog(__FUNCTION__); - - if (YAAMP_ALLOW_EXCHANGE) - $delay = time() - (int) YAAMP_PAYMENTS_FREQ; - else - $delay = time() - (YAAMP_PAYMENTS_FREQ / 2); - $total_cleared = 0.0; - - $sqlFilter = $coinid ? " AND coinid=".intval($coinid) : ''; - - $list = getdbolist('db_earnings', "status=1 AND mature_time<$delay $sqlFilter"); - foreach($list as $earning) - { - $user = getdbo('db_accounts', $earning->userid); - if(!$user) - { - $earning->delete(); - continue; - } - - $coin = getdbo('db_coins', $earning->coinid); - if(!$coin) - { - $earning->delete(); - continue; - } - - $earning->status = 2; // cleared - $earning->price = $coin->price; - $earning->save(); - -// $refcoin = getdbo('db_coins', $user->coinid); -// if($refcoin && $refcoin->price<=0) continue; -// $value = $earning->amount * $coin->price / ($refcoin? $refcoin->price: 1); - - $value = yaamp_convert_amount_user($coin, $earning->amount, $user); - - if($user->coinid == 6 && !YAAMP_ALLOW_EXCHANGE) - continue; - - $user->balance += $value; - $user->save(); - - if($user->coinid == 6) - $total_cleared += $value; - } - - if($total_cleared>0) - debuglog("total cleared from mining $total_cleared BTC"); -} + // debuglog(__FUNCTION__); + + if (YAAMP_ALLOW_EXCHANGE) + $delay = time() - (int) YAAMP_PAYMENTS_FREQ; + else + $delay = time() - (YAAMP_PAYMENTS_FREQ / 2); + $total_cleared = 0.0; + + $sqlFilter = $coinid ? " AND coinid=" . intval($coinid) : ''; + + $list = getdbolist('db_earnings', "status=1 AND mature_time<$delay $sqlFilter"); + foreach ($list as $earning) { + $user = getdbo('db_accounts', $earning->userid); + if (!$user) { + $earning->delete(); + continue; + } + + $coin = getdbo('db_coins', $earning->coinid); + if (!$coin) { + $earning->delete(); + continue; + } + + $earning->status = 2; // cleared + $earning->price = $coin->price; + $earning->save(); + // $refcoin = getdbo('db_coins', $user->coinid); + // if($refcoin && $refcoin->price<=0) continue; + // $value = $earning->amount * $coin->price / ($refcoin? $refcoin->price: 1); + + $value = yaamp_convert_amount_user($coin, $earning->amount, $user); + + if ($user->coinid == 6 && !YAAMP_ALLOW_EXCHANGE) + continue; + + $user->balance += $value; + $user->save(); + + if ($user->coinid == 6) + $total_cleared += $value; + } + + if ($total_cleared > 0) + debuglog("total cleared from mining $total_cleared BTC"); +} diff --git a/web/yaamp/core/backend/coins.php b/web/yaamp/core/backend/coins.php index 11126716c..8a3e4be16 100644 --- a/web/yaamp/core/backend/coins.php +++ b/web/yaamp/core/backend/coins.php @@ -2,312 +2,305 @@ function percent_feedback($v, $n, $p) { - return ($v*(100-$p) + $n*$p) / 100; + return ($v * (100 - $p) + $n * $p) / 100; } function string_to_hashrate($s) { - $value = floatval(trim(preg_replace('/,/', '', $s))); + $value = floatval(trim(preg_replace('/,/', '', $s))); - if(stripos($s, 'kh/s')) $value *= 1000; - if(stripos($s, 'mh/s')) $value *= 1000000; - if(stripos($s, 'gh/s')) $value *= 1000000000; + if (stripos($s, 'kh/s')) + $value *= 1000; + if (stripos($s, 'mh/s')) + $value *= 1000000; + if (stripos($s, 'gh/s')) + $value *= 1000000000; - return $value; + return $value; } ///////////////////////////////////////////////////////////////////////////////////////////// function BackendCoinsUpdate() { - $debug = false; - -// debuglog(__FUNCTION__); - $t1 = microtime(true); - - $pool_rate = array(); - foreach(yaamp_get_algos() as $algo) - $pool_rate[$algo] = yaamp_pool_rate($algo); - - $coins = getdbolist('db_coins', "installed"); - foreach($coins as $coin) - { -// debuglog("doing $coin->name"); - - $remote = new WalletRPC($coin); - - $info = $remote->getinfo(); - if(!$info && $coin->enable) - { - debuglog("{$coin->symbol} no getinfo answer, retrying..."); - sleep(3); - $info = $remote->getinfo(); - if (!$info) { - debuglog("{$coin->symbol} disabled, no answer after 2 attempts. {$remote->error}"); - $coin->enable = false; - $coin->connections = 0; - $coin->save(); - continue; - } - } - - // auto-enable if auto_ready is set - if($coin->auto_ready && !empty($info)) - $coin->enable = true; - else if (empty($info)) - continue; - - if ($debug) echo "{$coin->symbol}\n"; - - if(isset($info['difficulty'])) - $difficulty = $info['difficulty']; - else - $difficulty = $remote->getdifficulty(); - - if(is_array($difficulty)) { - $coin->difficulty = arraySafeVal($difficulty,'proof-of-work'); - $coin->difficulty_pos = arraySafeVal($difficulty,'proof-of-stake'); - } - else - $coin->difficulty = $difficulty; - - if($coin->algo == 'quark') - $coin->difficulty /= 0x100; - - if($coin->difficulty == 0) - $coin->difficulty = 1; - - $coin->errors = isset($info['errors'])? $info['errors']: ''; - $coin->txfee = isset($info['paytxfee'])? $info['paytxfee']: ''; - $coin->connections = isset($info['connections'])? $info['connections']: ''; - $coin->multialgos = (int) isset($info['pow_algo_id']); - $coin->balance = isset($info['balance'])? $info['balance']: 0; - $coin->stake = isset($info['stake'])? $info['stake'] : $coin->stake; - $coin->mint = dboscalar("select sum(amount) from blocks where coin_id=$coin->id and category='immature'"); - - if(empty($coin->master_wallet)) - { - if ($coin->rpcencoding == 'DCR' && empty($coin->account)) $coin->account = 'default'; - $coin->master_wallet = $remote->getaccountaddress($coin->account); - } - - if(empty($coin->rpcencoding)) - { - $difficulty = $remote->getdifficulty(); - if(is_array($difficulty)) - $coin->rpcencoding = 'POS'; - else if ($coin->symbol == 'DCR') - $coin->rpcencoding = 'DCR'; - else if ($coin->symbol == 'ETH') - $coin->rpcencoding = 'GETH'; - else if ($coin->symbol == 'NIRO') - $coin->rpcencoding = 'NIRO'; - else - $coin->rpcencoding = 'POW'; - } - - if($coin->hassubmitblock == NULL) - { - $remote->submitblock(''); - if(strcasecmp($remote->error, 'method not found') == 0) - $coin->hassubmitblock = false; - else - $coin->hassubmitblock = true; - } - - if($coin->auxpow == NULL) - { - $ret = $remote->getauxblock(); - - if(strcasecmp($remote->error, 'method not found') == 0) - $coin->auxpow = false; - else - $coin->auxpow = true; - } - -// if($coin->symbol != 'BTC') -// { -// if($coin->symbol == 'PPC') -// $template = $remote->getblocktemplate(''); -// else - $template = $remote->getblocktemplate('{}'); - - if($template && isset($template['coinbasevalue'])) - { - $coin->reward = $template['coinbasevalue']/100000000*$coin->reward_mul; - - if($coin->symbol == 'TAC' && isset($template['_V2'])) - $coin->charity_amount = $template['_V2']/100000000; - - if(isset($template['payee_amount']) && $coin->symbol != 'LIMX') { - $coin->charity_amount = doubleval($template['payee_amount'])/100000000; - $coin->reward -= $coin->charity_amount; - } - - else if(isset($template['masternode']) && arraySafeVal($template,'masternode_payments_enforced')) { - if (arraySafeVal($template,'masternode_payments_started')) - $coin->reward -= arraySafeVal($template['masternode'],'amount',0)/100000000; - $coin->hasmasternodes = true; - } - - else if($coin->symbol == 'XZC') { - // coinbasevalue here is the amount available for miners, not the full block amount - $coin->reward = arraySafeVal($template,'coinbasevalue')/100000000 * $coin->reward_mul; - $coin->charity_amount = $coin->reward * $coin->charity_percent / 100; - } - - else if(!empty($coin->charity_address)) { - if(!$coin->charity_amount) - $coin->reward -= $coin->reward * $coin->charity_percent / 100; - } - - if(isset($template['bits'])) - { - $target = decode_compact($template['bits']); - $coin->difficulty = target_to_diff($target); - } - } - - else if ($coin->rpcencoding == 'GETH' || $coin->rpcencoding == 'NIRO') - { - $coin->auto_ready = ($coin->connections > 0); - } - - else if(strcasecmp($remote->error, 'method not found') == 0) - { - $template = $remote->getmemorypool(); - if($template && isset($template['coinbasevalue'])) - { - $coin->usememorypool = true; - $coin->reward = $template['coinbasevalue']/100000000*$coin->reward_mul; - - if(isset($template['bits'])) - { - $target = decode_compact($template['bits']); - $coin->difficulty = target_to_diff($target); - } - } else { - $coin->auto_ready = false; - $coin->errors = $remote->error; - } - } - - else if ($coin->symbol == 'ZEC' || $coin->rpcencoding == 'ZEC') - { - if($template && isset($template['coinbasetxn'])) - { - // no coinbasevalue in ZEC blocktemplate :/ - $txn = $template['coinbasetxn']; - $coin->charity_amount = arraySafeVal($txn,'foundersreward',0)/100000000; - $coin->reward = $coin->charity_amount * 4 + arraySafeVal($txn,'fee',0)/100000000; - // getmininginfo show current diff, getinfo the last block one - $mininginfo = $remote->getmininginfo(); - $coin->difficulty = ArraySafeVal($mininginfo,'difficulty',$coin->difficulty); - //$target = decode_compact($template['bits']); - //$diff = target_to_diff($target); // seems not standard 0.358557563 vs 187989.937 in getmininginfo - //target 00000002c0930000000000000000000000000000000000000000000000000000 => 0.358557563 (bits 1d02c093) - //$diff = hash_to_difficulty($coin, $template['target']); - //debuglog("ZEC target {$template['bits']} -> $diff"); - } else { - $coin->auto_ready = false; - $coin->errors = $remote->error; - } - } - - else if ($coin->rpcencoding == 'DCR') - { - $wi = $remote->walletinfo(); - $coin->auto_ready = ($coin->connections > 0 && arraySafeVal($wi,"daemonconnected")); - if ($coin->auto_ready && arraySafeVal($wi,"unlocked",false) == false) { - debuglog($coin->symbol." wallet is not unlocked!"); - } - } - - else - { - $coin->auto_ready = false; - $coin->errors = $remote->error; - } - - if(strcasecmp($coin->errors, 'No more PoW blocks') == 0) - { - $coin->dontsell = true; - $coin->auto_ready = false; - } -// } - - if($coin->block_height != $info['blocks']) - { - $count = $info['blocks'] - $coin->block_height; - $ttf = $count > 0 ? (time() - $coin->last_network_found) / $count : 0; - - if(empty($coin->actual_ttf)) $coin->actual_ttf = $ttf; - - $coin->actual_ttf = percent_feedback($coin->actual_ttf, $ttf, 5); - $coin->last_network_found = time(); - } - - $coin->version = substr($info['version'], 0, 32); - $coin->block_height = $info['blocks']; - - if($coin->powend_height > 0 && $coin->block_height > $coin->powend_height) { - if ($coin->auto_ready) { - $coin->auto_ready = false; - $coin->errors = 'PoW end reached'; - } - } - - $coin->save(); - - if ($coin->available < 0 || $coin->cleared > $coin->balance) { - // can happen after a payout (waiting first confirmation) - BackendUpdatePoolBalances($coin->id); - } - // debuglog(" end $coin->name"); - - } - - $coins = getdbolist('db_coins', "enable order by auxpow desc"); - foreach($coins as $coin) - { - $coin = getdbo('db_coins', $coin->id); - if(!$coin) continue; - - if($coin->difficulty) - { - $coin->index_avg = $coin->reward * $coin->price * 10000 / $coin->difficulty; - if(!$coin->auxpow && $coin->rpcencoding == 'POW') - { - $indexaux = dboscalar("SELECT SUM(index_avg) FROM coins WHERE enable AND visible AND auto_ready AND auxpow AND algo='{$coin->algo}'"); - $coin->index_avg += $indexaux; - } - } - - if($coin->network_hash) { - $coin->network_ttf = intval($coin->difficulty * 0x100000000 / $coin->network_hash); - if($coin->network_ttf > 2147483647) $coin->network_ttf = 2147483647; - } - - if(isset($pool_rate[$coin->algo])) - $coin->pool_ttf = intval($coin->difficulty * 0x100000000 / $pool_rate[$coin->algo]); - if($coin->pool_ttf > 2147483647) $coin->pool_ttf = 2147483647; - - if(strstr($coin->image, 'http')) - { - $data = file_get_contents($coin->image); - $coin->image = "/images/coin-$coin->id.png"; - - @unlink(YAAMP_HTDOCS.$coin->image); - file_put_contents(YAAMP_HTDOCS.$coin->image, $data); - } - - $coin->save(); - } - - $d1 = microtime(true) - $t1; - controller()->memcache->add_monitoring_function(__METHOD__, $d1); + $debug = false; + + // debuglog(__FUNCTION__); + $t1 = microtime(true); + + $pool_rate = array(); + foreach (yaamp_get_algos() as $algo) + $pool_rate[$algo] = yaamp_pool_rate($algo); + + $coins = getdbolist('db_coins', "installed"); + foreach ($coins as $coin) { + // debuglog("doing $coin->name"); + + $remote = new WalletRPC($coin); + + $info = $remote->getinfo(); + if (!$info && $coin->enable) { + debuglog("{$coin->symbol} no getinfo answer, retrying..."); + sleep(3); + $info = $remote->getinfo(); + if (!$info) { + debuglog("{$coin->symbol} disabled, no answer after 2 attempts. {$remote->error}"); + $coin->enable = false; + $coin->connections = 0; + $coin->save(); + continue; + } + } + + // auto-enable if auto_ready is set + if ($coin->auto_ready && !empty($info)) + $coin->enable = true; + else if (empty($info)) + continue; + + if ($debug) + echo "{$coin->symbol}\n"; + + if (isset($info['difficulty'])) + $difficulty = $info['difficulty']; + else + $difficulty = $remote->getdifficulty(); + + if (is_array($difficulty)) { + $coin->difficulty = arraySafeVal($difficulty, 'proof-of-work'); + $coin->difficulty_pos = arraySafeVal($difficulty, 'proof-of-stake'); + } else + $coin->difficulty = $difficulty; + + if ($coin->algo == 'quark') + $coin->difficulty /= 0x100; + + if ($coin->difficulty == 0) + $coin->difficulty = 1; + + $coin->errors = isset($info['errors']) ? $info['errors'] : ''; + $coin->txfee = isset($info['paytxfee']) ? $info['paytxfee'] : ''; + $coin->connections = isset($info['connections']) ? $info['connections'] : ''; + $coin->multialgos = (int) isset($info['pow_algo_id']); + $coin->balance = isset($info['balance']) ? $info['balance'] : 0; + $coin->stake = isset($info['stake']) ? $info['stake'] : $coin->stake; + $coin->mint = dboscalar("select sum(amount) from blocks where coin_id=$coin->id and category='immature'"); + + if (empty($coin->master_wallet)) { + if ($coin->rpcencoding == 'DCR' && empty($coin->account)) + $coin->account = 'default'; + $coin->master_wallet = $remote->getaccountaddress($coin->account); + } + + if (empty($coin->rpcencoding)) { + $difficulty = $remote->getdifficulty(); + if (is_array($difficulty)) + $coin->rpcencoding = 'POS'; + else if ($coin->symbol == 'DCR') + $coin->rpcencoding = 'DCR'; + else if ($coin->symbol == 'ETH') + $coin->rpcencoding = 'GETH'; + else if ($coin->symbol == 'NIRO') + $coin->rpcencoding = 'NIRO'; + else + $coin->rpcencoding = 'POW'; + } + + if ($coin->hassubmitblock == NULL) { + $remote->submitblock(''); + if (strcasecmp($remote->error, 'method not found') == 0) + $coin->hassubmitblock = false; + else + $coin->hassubmitblock = true; + } + + if ($coin->auxpow == NULL) { + $ret = $remote->getauxblock(); + + if (strcasecmp($remote->error, 'method not found') == 0) + $coin->auxpow = false; + else + $coin->auxpow = true; + } + + // Change for segwit + if ($coin->usesegwit) { + $template = $remote->getblocktemplate('{"rules":["segwit"]}'); + } else { + $template = $remote->getblocktemplate('{}'); + } + // Change for segwit end + + if ($template && isset($template['coinbasevalue'])) { + $coin->reward = $template['coinbasevalue'] / 100000000 * $coin->reward_mul; + + if ($coin->symbol == 'TAC' && isset($template['_V2'])) + $coin->charity_amount = $template['_V2'] / 100000000; + + if (isset($template['payee_amount']) && $coin->symbol != 'LIMX') { + $coin->charity_amount = doubleval($template['payee_amount']) / 100000000; + $coin->reward -= $coin->charity_amount; + } + + else if (isset($template['masternode']) && arraySafeVal($template, 'masternode_payments_enforced')) { + if (arraySafeVal($template, 'masternode_payments_started')) + $coin->reward -= arraySafeVal($template['masternode'], 'amount', 0) / 100000000; + $coin->hasmasternodes = true; + } + + else if ($coin->symbol == 'XZC') { + // coinbasevalue here is the amount available for miners, not the full block amount + $coin->reward = arraySafeVal($template, 'coinbasevalue') / 100000000 * $coin->reward_mul; + $coin->charity_amount = $coin->reward * $coin->charity_percent / 100; + } + + else if ($coin->symbol == 'BNODE') { + if (isset($template['masternode'])) { + if (arraySafeVal($template, 'masternode_payments_started')) + $coin->reward -= arraySafeVal($template['masternode'], 'amount', 0) / 100000000; + } + if (isset($template['evolution'])) { + $coin->reward -= arraySafeVal($template['evolution'], 'amount', 10000000) / 100000000; + } + } + + else if (!empty($coin->charity_address)) { + if (!$coin->charity_amount) + $coin->reward -= $coin->reward * $coin->charity_percent / 100; + } + + if (isset($template['bits'])) { + $target = decode_compact($template['bits']); + $coin->difficulty = target_to_diff($target); + } + } + + else if ($coin->rpcencoding == 'GETH' || $coin->rpcencoding == 'NIRO') { + $coin->auto_ready = ($coin->connections > 0); + } + + else if (strcasecmp($remote->error, 'method not found') == 0) { + $template = $remote->getmemorypool(); + if ($template && isset($template['coinbasevalue'])) { + $coin->usememorypool = true; + $coin->reward = $template['coinbasevalue'] / 100000000 * $coin->reward_mul; + + if (isset($template['bits'])) { + $target = decode_compact($template['bits']); + $coin->difficulty = target_to_diff($target); + } + } else { + $coin->auto_ready = false; + $coin->errors = $remote->error; + } + } + + else if ($coin->symbol == 'ZEC' || $coin->rpcencoding == 'ZEC') { + if ($template && isset($template['coinbasetxn'])) { + // no coinbasevalue in ZEC blocktemplate :/ + $txn = $template['coinbasetxn']; + $coin->charity_amount = arraySafeVal($txn, 'foundersreward', 0) / 100000000; + $coin->reward = $coin->charity_amount * 4 + arraySafeVal($txn, 'fee', 0) / 100000000; + // getmininginfo show current diff, getinfo the last block one + $mininginfo = $remote->getmininginfo(); + $coin->difficulty = ArraySafeVal($mininginfo, 'difficulty', $coin->difficulty); + //$target = decode_compact($template['bits']); + //$diff = target_to_diff($target); // seems not standard 0.358557563 vs 187989.937 in getmininginfo + //target 00000002c0930000000000000000000000000000000000000000000000000000 => 0.358557563 (bits 1d02c093) + //$diff = hash_to_difficulty($coin, $template['target']); + //debuglog("ZEC target {$template['bits']} -> $diff"); + } else { + $coin->auto_ready = false; + $coin->errors = $remote->error; + } + } + + else if ($coin->rpcencoding == 'DCR') { + $wi = $remote->walletinfo(); + $coin->auto_ready = ($coin->connections > 0 && arraySafeVal($wi, "daemonconnected")); + if ($coin->auto_ready && arraySafeVal($wi, "unlocked", false) == false) { + debuglog($coin->symbol . " wallet is not unlocked!"); + } + } + + else { + $coin->auto_ready = false; + $coin->errors = $remote->error; + } + + if (strcasecmp($coin->errors, 'No more PoW blocks') == 0) { + $coin->dontsell = true; + $coin->auto_ready = false; + } + // } + + if ($coin->block_height != $info['blocks']) { + $count = $info['blocks'] - $coin->block_height; + $ttf = $count > 0 ? (time() - $coin->last_network_found) / $count : 0; + + if (empty($coin->actual_ttf)) + $coin->actual_ttf = $ttf; + + $coin->actual_ttf = percent_feedback($coin->actual_ttf, $ttf, 5); + $coin->last_network_found = time(); + } + + $coin->version = substr($info['version'], 0, 32); + $coin->block_height = $info['blocks']; + + if ($coin->powend_height > 0 && $coin->block_height > $coin->powend_height) { + if ($coin->auto_ready) { + $coin->auto_ready = false; + $coin->errors = 'PoW end reached'; + } + } + + $coin->save(); + + if ($coin->available < 0 || $coin->cleared > $coin->balance) { + // can happen after a payout (waiting first confirmation) + BackendUpdatePoolBalances($coin->id); + } + // debuglog(" end $coin->name"); + + } + + $coins = getdbolist('db_coins', "enable order by auxpow desc"); + foreach ($coins as $coin) { + $coin = getdbo('db_coins', $coin->id); + if (!$coin) + continue; + + if ($coin->difficulty) { + $coin->index_avg = $coin->reward * $coin->price * 10000 / $coin->difficulty; + if (!$coin->auxpow && $coin->rpcencoding == 'POW') { + $indexaux = dboscalar("SELECT SUM(index_avg) FROM coins WHERE enable AND visible AND auto_ready AND auxpow AND algo='{$coin->algo}'"); + $coin->index_avg += $indexaux; + } + } + + if ($coin->network_hash) { + $coin->network_ttf = intval($coin->difficulty * 0x100000000 / $coin->network_hash); + if ($coin->network_ttf > 2147483647) + $coin->network_ttf = 2147483647; + } + + if (isset($pool_rate[$coin->algo])) + $coin->pool_ttf = intval($coin->difficulty * 0x100000000 / $pool_rate[$coin->algo]); + if ($coin->pool_ttf > 2147483647) + $coin->pool_ttf = 2147483647; + + if (strstr($coin->image, 'http')) { + $data = file_get_contents($coin->image); + $coin->image = "/images/coin-$coin->id.png"; + + @unlink(YAAMP_HTDOCS . $coin->image); + file_put_contents(YAAMP_HTDOCS . $coin->image, $data); + } + + $coin->save(); + } + + $d1 = microtime(true) - $t1; + controller()->memcache->add_monitoring_function(__METHOD__, $d1); } - - - - diff --git a/web/yaamp/core/backend/markets.php b/web/yaamp/core/backend/markets.php index 7413cae80..3a0ba856b 100644 --- a/web/yaamp/core/backend/markets.php +++ b/web/yaamp/core/backend/markets.php @@ -1,1960 +1,2114 @@ symbol2'"); - if(!$coin) continue; - - $list = getdbolist('db_markets', "coinid=$coin->id"); - foreach($list as $market) - { - $market2 = getdbosql('db_markets', "coinid=$coin2->id and name='$market->name'"); - if(!$market2) continue; - - $market2->price = $market->price; - $market2->price2 = $market->price2; - $market2->deposit_address = $market->deposit_address; - $market2->pricetime = $market->pricetime; - - $market2->save(); - } - } - - $coins = getdbolist('db_coins', "installed and id in (select distinct coinid from markets)"); - foreach($coins as $coin) - { - if($coin->symbol=='BTC') { - $coin->price = 1; - $coin->price2 = 1; - $coin->save(); - continue; - } - - $market = getBestMarket($coin); - if($market) - { - $coin->price = $market->price*(1-YAAMP_FEES_EXCHANGE/100); - $coin->price2 = $market->price2; - - $base_coin = !empty($market->base_coin)? getdbosql('db_coins', "symbol='{$market->base_coin}'"): null; - if($base_coin) - { - $coin->price *= $base_coin->price; - $coin->price2 *= $base_coin->price; - } - } - else { - $coin->price = 0; - $coin->price2 = 0; - } - - $coin->save(); - dborun("UPDATE earnings SET price={$coin->price} WHERE status!=2 AND coinid={$coin->id}"); - dborun("UPDATE markets SET message=NULL WHERE disabled=0 AND message='disabled from settings'"); - } + // debuglog(__FUNCTION__); + market_set_default('c-cex', 'DCR', 'disabled', true); // no deposit + market_set_default('yobit', 'DCR', 'disabled', true); // no withdraw + settings_prefetch_all(); + + updateBittrexMarkets(); + updateBitzMarkets(); + updatePoloniexMarkets(); + updateBleutradeMarkets(); + updateCryptoBridgeMarkets(); + updateEscoDexMarkets(); + updateGateioMarkets(); + updateGraviexMarkets(); + updateKrakenMarkets(); + updateKuCoinMarkets(); + updateCCexMarkets(); + updateCoinbeneMarkets(); + updateCrex24Markets(); + updateCryptopiaMarkets(); + updateHitBTCMarkets(); + updateYobitMarkets(); + updateAlcurexMarkets(); + updateBinanceMarkets(); + //updateEmpoexMarkets(); + updateJubiMarkets(); + updateLiveCoinMarkets(); + updateNovaMarkets(); + updateCoinExchangeMarkets(); + updateCoinsMarketsMarkets(); + updateStocksExchangeMarkets(); + updateTradeSatoshiMarkets(); + + updateShapeShiftMarkets(); + updateOtherMarkets(); + + $list2 = getdbolist('db_coins', "installed AND IFNULL(symbol2,'') != ''"); + foreach ($list2 as $coin2) + { + $coin = getdbosql('db_coins', "symbol='$coin2->symbol2'"); + if (!$coin) continue; + + $list = getdbolist('db_markets', "coinid=$coin->id"); + foreach ($list as $market) + { + $market2 = getdbosql('db_markets', "coinid=$coin2->id and name='$market->name'"); + if (!$market2) continue; + + $market2->price = $market->price; + $market2->price2 = $market->price2; + $market2->deposit_address = $market->deposit_address; + $market2->pricetime = $market->pricetime; + + $market2->save(); + } + } + + $coins = getdbolist('db_coins', "installed and id in (select distinct coinid from markets)"); + foreach ($coins as $coin) + { + if ($coin->symbol == 'BTC') + { + $coin->price = 1; + $coin->price2 = 1; + $coin->save(); + continue; + } + + $market = getBestMarket($coin); + if ($market) + { + $coin->price = $market->price * (1 - YAAMP_FEES_EXCHANGE / 100); + $coin->price2 = $market->price2; + + $base_coin = !empty($market->base_coin) ? getdbosql('db_coins', "symbol='{$market->base_coin}'") : null; + if ($base_coin) + { + $coin->price *= $base_coin->price; + $coin->price2 *= $base_coin->price; + } + } + else + { + $coin->price = 0; + $coin->price2 = 0; + } + + $coin->save(); + dborun("UPDATE earnings SET price={$coin->price} WHERE status!=2 AND coinid={$coin->id}"); + dborun("UPDATE markets SET message=NULL WHERE disabled=0 AND message='disabled from settings'"); + } } -function BackendWatchMarkets($marketname=NULL) +function BackendWatchMarkets($marketname = NULL) { - // temporary to fill new coin 'watch' field - if (defined('YIIMP_WATCH_CURRENCIES')) { - $watched = explode(',', YIIMP_WATCH_CURRENCIES); - foreach ($watched as $symbol) { - dborun("UPDATE coins SET watch=1 WHERE symbol=:sym", array(':sym'=>$symbol)); - } - } - - $coins = new db_coins; - $coins = $coins->findAllByAttributes(array('watch'=>1)); - foreach ($coins as $coin) - { - // track btc/usd for history analysis - if ($coin->symbol == 'BTC') { - if ($marketname) continue; - $mh = new db_market_history; - $mh->time = time(); - $mh->idcoin = $coin->id; - $mh->idmarket = NULL; - $mh->price = dboscalar("SELECT usdbtc FROM mining LIMIT 1"); - if (YIIMP_FIAT_ALTERNATIVE == 'EUR') - $mh->price2 = kraken_btceur(); - $mh->balance = dboscalar("SELECT SUM(balance) AS btc FROM balances"); - $mh->save(); - continue; - } else if ($coin->installed) { - // "yiimp" prices and balance history - $mh = new db_market_history; - $mh->time = time(); - $mh->idcoin = $coin->id; - $mh->idmarket = NULL; - $mh->price = $coin->price; - $mh->price2 = $coin->price2; - $mh->balance = $coin->balance; - $mh->save(); - } - - if ($coin->rpcencoding == 'DCR') { - // hack to store the locked balance history as a "stake" market - $remote = new WalletRPC($coin); - $stake = 0.; //(double) $remote->getbalance('*',0,'locked'); - $balances = $remote->getbalance('*',0); - if (isset($balances["balances"])) { - foreach ($balances["balances"] as $accb) { - $stake += (double) arraySafeVal($accb, 'lockedbytickets', 0); - } - } - $info = $remote->getstakeinfo(); - if (empty($remote->error) && isset($info['difficulty'])) - dborun("UPDATE markets SET balance=0, ontrade=:stake, balancetime=:time, + // temporary to fill new coin 'watch' field + if (defined('YIIMP_WATCH_CURRENCIES')) + { + $watched = explode(',', YIIMP_WATCH_CURRENCIES); + foreach ($watched as $symbol) + { + dborun("UPDATE coins SET watch=1 WHERE symbol=:sym", array( + ':sym' => $symbol + )); + } + } + + $coins = new db_coins; + $coins = $coins->findAllByAttributes(array( + 'watch' => 1 + )); + foreach ($coins as $coin) + { + // track btc/usd for history analysis + if ($coin->symbol == 'BTC') + { + if ($marketname) continue; + $mh = new db_market_history; + $mh->time = time(); + $mh->idcoin = $coin->id; + $mh->idmarket = NULL; + $mh->price = dboscalar("SELECT usdbtc FROM mining LIMIT 1"); + if (YIIMP_FIAT_ALTERNATIVE == 'EUR') $mh->price2 = kraken_btceur(); + $mh->balance = dboscalar("SELECT SUM(balance) AS btc FROM balances"); + $mh->save(); + continue; + } + else if ($coin->installed) + { + // "yiimp" prices and balance history + $mh = new db_market_history; + $mh->time = time(); + $mh->idcoin = $coin->id; + $mh->idmarket = NULL; + $mh->price = $coin->price; + $mh->price2 = $coin->price2; + $mh->balance = $coin->balance; + $mh->save(); + } + + if ($coin->rpcencoding == 'DCR') + { + // hack to store the locked balance history as a "stake" market + $remote = new WalletRPC($coin); + $stake = 0.; //(double) $remote->getbalance('*',0,'locked'); + $balances = $remote->getbalance('*', 0); + if (isset($balances["balances"])) + { + foreach ($balances["balances"] as $accb) + { + $stake += (double)arraySafeVal($accb, 'lockedbytickets', 0); + } + } + $info = $remote->getstakeinfo(); + if (empty($remote->error) && isset($info['difficulty'])) dborun("UPDATE markets SET balance=0, ontrade=:stake, balancetime=:time, price=:ticketprice, price2=:live, pricetime=NULL WHERE coinid=:id AND name='stake'", array( - ':ticketprice'=>$info['difficulty'], ':live'=>$info['live'], ':stake'=>$stake, - ':id'=>$coin->id, ':time'=>time() - )); - } - - // user watched currencies - $markets = getdbolist('db_markets', "coinid={$coin->id} AND NOT disabled"); - foreach($markets as $market) { - if ($marketname && $market->name != $marketname) continue; - if (!empty($market->base_coin)) continue; // todo ? - if (empty($market->price)) continue; - $mh = new db_market_history; - $mh->time = time(); // max(intval($market->balancetime), intval($market->pricetime)); - $mh->idcoin = $coin->id; - $mh->idmarket = $market->id; - $mh->price = $market->price; - $mh->price2 = $market->price2; - $mh->balance = (double) ($market->balance) + (double) ($market->ontrade); - $mh->save(); - } - } + ':ticketprice' => $info['difficulty'], + ':live' => $info['live'], + ':stake' => $stake, + ':id' => $coin->id, + ':time' => time() + )); + } + + // user watched currencies + $markets = getdbolist('db_markets', "coinid={$coin->id} AND NOT disabled"); + foreach ($markets as $market) + { + if ($marketname && $market->name != $marketname) continue; + if (!empty($market->base_coin)) continue; // todo ? + if (empty($market->price)) continue; + $mh = new db_market_history; + $mh->time = time(); // max(intval($market->balancetime), intval($market->pricetime)); + $mh->idcoin = $coin->id; + $mh->idmarket = $market->id; + $mh->price = $market->price; + $mh->price2 = $market->price2; + $mh->balance = (double)($market->balance) + (double)($market->ontrade); + $mh->save(); + } + } } function getBestMarket($coin) { - $market = NULL; - if ($coin->symbol == 'BTC') - return NULL; - - if (!empty($coin->symbol2)) { - $alt = getdbosql('db_coins', "symbol=:symbol", array(':symbol'=>$coin->symbol2)); - if ($alt && $alt->symbol2 != $coin->symbol2) - return getBestMarket($alt); - } - - if (!empty($coin->market)) { - // get coin market first (if set) - if ($coin->market != 'BEST' && $coin->market != 'unknown') - $market = getdbosql('db_markets', "coinid={$coin->id} AND price!=0 AND NOT deleted AND - NOT disabled AND IFNULL(deposit_address,'') != '' AND name=:name", - array(':name'=>$coin->market)); - else - // else take one of the big exchanges... - $market = getdbosql('db_markets', "coinid={$coin->id} AND price!=0 AND NOT deleted AND + $market = NULL; + if ($coin->symbol == 'BTC') return NULL; + + if (!empty($coin->symbol2)) + { + $alt = getdbosql('db_coins', "symbol=:symbol", array( + ':symbol' => $coin->symbol2 + )); + if ($alt && $alt->symbol2 != $coin->symbol2) return getBestMarket($alt); + } + + if (!empty($coin->market)) + { + // get coin market first (if set) + if ($coin->market != 'BEST' && $coin->market != 'unknown') $market = getdbosql('db_markets', "coinid={$coin->id} AND price!=0 AND NOT deleted AND + NOT disabled AND IFNULL(deposit_address,'') != '' AND name=:name", array( + ':name' => $coin->market + )); + else + // else take one of the big exchanges... + $market = getdbosql('db_markets', "coinid={$coin->id} AND price!=0 AND NOT deleted AND NOT disabled AND IFNULL(deposit_address,'') != '' AND name IN ('poloniex','bittrex') ORDER BY priority DESC, price DESC"); - } + } - if(!$market) { - $market = getdbosql('db_markets', "coinid={$coin->id} AND price!=0 AND NOT deleted AND + if (!$market) + { + $market = getdbosql('db_markets', "coinid={$coin->id} AND price!=0 AND NOT deleted AND NOT disabled AND IFNULL(deposit_address,'') != '' ORDER BY priority DESC, price DESC"); - } + } - if (!$market && empty($coin->market)) { - debuglog("best market for {$coin->symbol} is unknown"); - $coin->market = 'unknown'; - $coin->save(); - } + if (!$market && empty($coin->market)) + { + debuglog("best market for {$coin->symbol} is unknown"); + $coin->market = 'unknown'; + $coin->save(); + } - return $market; + return $market; } function AverageIncrement($value1, $value2) { - $percent = 80; - $value = ($value1*(100-$percent) + $value2*$percent) / 100; + $percent = 80; + $value = ($value1 * (100 - $percent) + $value2 * $percent) / 100; - return $value; + return $value; } /////////////////////////////////////////////////////////////////////////////////////////////////// - function updateBleutradeMarkets() { - $exchange = 'bleutrade'; - if (exchange_get($exchange, 'disabled')) return; - - $count = (int) dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); - if ($count == 0) return; - - $list = bleutrade_api_query('public/getcurrencies'); - if(!is_object($list)) return; - - foreach($list->result as $currency) - { - // debuglog($currency); - if($currency->Currency == 'BTC') continue; - - $coin = getdbosql('db_coins', "symbol='{$currency->Currency}'"); - if(!$coin) continue; - - $market = getdbosql('db_markets', "coinid={$coin->id} and name='$exchange'"); - if(!$market) continue; - - $market->txfee = $currency->TxFee; - if($market->disabled < 9) $market->disabled = !$currency->IsActive; - - $symbol = $coin->getOfficialSymbol(); - if (market_get($exchange, $symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - } - - $market->save(); - - if($market->disabled) continue; - - sleep(1); - $pair = "{$symbol}_BTC"; - $ticker = bleutrade_api_query('public/getticker', '&market='.$pair); - if(!$ticker || !$ticker->success || !$ticker->result) continue; - - $price2 = ($ticker->result[0]->Bid+$ticker->result[0]->Ask)/2; - $market->price2 = AverageIncrement($market->price2, $price2); - $market->price = AverageIncrement($market->price, $ticker->result[0]->Bid); - $market->pricetime = time(); - - if(!empty(EXCH_BLEUTRADE_KEY)) - { - $last_checked = cache()->get($exchange.'-deposit_address-check-'.$symbol); - if(empty($market->deposit_address) && !$last_checked) - { - sleep(1); - $address = bleutrade_api_query('account/getdepositaddress', '¤cy='.$symbol); - if(is_object($address) && is_object($address->result)) { - $addr = $address->result->Address; - if (!empty($addr) && $addr != $market->deposit_address) { - $market->deposit_address = $addr; - debuglog("$exchange: deposit address for {$coin->symbol} updated"); - } - } - } - cache()->set($exchange.'-deposit_address-check-'.$symbol, time(), 24*3600); - } - - $market->save(); - -// debuglog("$exchange: update $coin->symbol: $market->price $market->price2"); - } + $exchange = 'bleutrade'; + if (exchange_get($exchange, 'disabled')) return; + + $count = (int)dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); + if ($count == 0) return; + + $list = bleutrade_api_query('public/getcurrencies'); + if (!is_object($list)) return; + + foreach ($list->result as $currency) + { + // debuglog($currency); + if ($currency->Currency == 'BTC') continue; + + $coin = getdbosql('db_coins', "symbol='{$currency->Currency}'"); + if (!$coin) continue; + + $market = getdbosql('db_markets', "coinid={$coin->id} and name='$exchange'"); + if (!$market) continue; + + $market->txfee = $currency->TxFee; + if ($market->disabled < 9) $market->disabled = !$currency->IsActive; + + $symbol = $coin->getOfficialSymbol(); + if (market_get($exchange, $symbol, "disabled")) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + } + + $market->save(); + + if ($market->disabled) continue; + + sleep(1); + $pair = "{$symbol}_BTC"; + $ticker = bleutrade_api_query('public/getticker', '&market=' . $pair); + if (!$ticker || !$ticker->success || !$ticker->result) continue; + + $price2 = ($ticker->result[0]->Bid + $ticker->result[0] + ->Ask) / 2; + $market->price2 = AverageIncrement($market->price2, $price2); + $market->price = AverageIncrement($market->price, $ticker->result[0] + ->Bid); + $market->pricetime = time(); + + if (!empty(EXCH_BLEUTRADE_KEY)) + { + $last_checked = cache()->get($exchange . '-deposit_address-check-' . $symbol); + if (empty($market->deposit_address) && !$last_checked) + { + sleep(1); + $address = bleutrade_api_query('account/getdepositaddress', '¤cy=' . $symbol); + if (is_object($address) && is_object($address->result)) + { + $addr = $address + ->result->Address; + if (!empty($addr) && $addr != $market->deposit_address) + { + $market->deposit_address = $addr; + debuglog("$exchange: deposit address for {$coin->symbol} updated"); + } + } + } + cache() + ->set($exchange . '-deposit_address-check-' . $symbol, time() , 24 * 3600); + } + + $market->save(); + + // debuglog("$exchange: update $coin->symbol: $market->price $market->price2"); + + } } - ///////////////////////////////////////////////////////////////////////////////////////////// - +///////////////////////////////////////////////////////////////////////////////////////////// function updateBitzMarkets($force = false) { - $exchange = 'bitz'; - if (exchange_get($exchange, 'disabled')) return; - - $markets = bitz_api_query('tickerall'); - - foreach($markets as $c => $ticker) - { - $pairs = explode('_', $c); - $symbol = strtoupper(reset($pairs)); $base = end($pairs); - if($symbol == 'BTC' || $base != 'btc') continue; - - if (market_get($exchange, $symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - } - $coin = getdbosql('db_coins', "symbol='{$symbol}'"); - if(!$coin) continue; - if(!$coin->installed && !$coin->watch) continue; - $market = getdbosql('db_markets', "coinid={$coin->id} and name='{$exchange}'"); - - if(!$market) continue; - $price2 = ($ticker->bidPrice + $ticker->askPrice)/2; - $market->price2 = AverageIncrement($market->price2, $price2); - $market->price = AverageIncrement($market->price, $ticker->bidPrice); - $market->pricetime = time(); - $market->priority = -1; - $market->txfee = 0.2; // trade pct - $market->save(); - // debuglog("$exchange: update $symbol: {$market->price} {$market->price2}"); - } + $exchange = 'bitz'; + if (exchange_get($exchange, 'disabled')) return; + + $markets = bitz_api_query('tickerall'); + + foreach ($markets as $c => $ticker) + { + $pairs = explode('_', $c); + $symbol = strtoupper(reset($pairs)); + $base = end($pairs); + if ($symbol == 'BTC' || $base != 'btc') continue; + + if (market_get($exchange, $symbol, "disabled")) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + } + $coin = getdbosql('db_coins', "symbol='{$symbol}'"); + if (!$coin) continue; + if (!$coin->installed && !$coin->watch) continue; + $market = getdbosql('db_markets', "coinid={$coin->id} and name='{$exchange}'"); + + if (!$market) continue; + $price2 = ($ticker->bidPrice + $ticker->askPrice) / 2; + $market->price2 = AverageIncrement($market->price2, $price2); + $market->price = AverageIncrement($market->price, $ticker->bidPrice); + $market->pricetime = time(); + $market->priority = - 1; + $market->txfee = 0.2; // trade pct + $market->save(); + // debuglog("$exchange: update $symbol: {$market->price} {$market->price2}"); + + } } ///////////////////////////////////////////////////////////////////////////////////////////// - function updateCryptoBridgeMarkets($force = false) { - $exchange = 'cryptobridge'; - if (exchange_get($exchange, 'disabled')) return; - - $count = (int) dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); - if ($count == 0) return; - - $result = cryptobridge_api_query('ticker'); - if(!is_array($result)) return; - - foreach($result as $ticker) - { - if (is_null(objSafeVal($ticker,'id'))) continue; - $pairs = explode('_', $ticker->id); - $symbol = reset($pairs); $base = end($pairs); - if($symbol == 'BTC' || $base != 'BTC') continue; - - if (market_get($exchange, $symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - } - - $coin = getdbosql('db_coins', "symbol='{$symbol}'"); - if(!$coin) continue; - if(!$coin->installed && !$coin->watch) continue; - - $market = getdbosql('db_markets', "coinid={$coin->id} and name='{$exchange}'"); - if(!$market) continue; - - $price2 = ($ticker->bid + $ticker->ask)/2; - $market->price2 = AverageIncrement($market->price2, $price2); - $market->price = AverageIncrement($market->price, $ticker->bid); - $market->pricetime = time(); - $market->priority = -1; - $market->txfee = 0.2; // trade pct - $market->save(); - - //debuglog("$exchange: update $symbol: {$market->price} {$market->price2}"); - } + $exchange = 'cryptobridge'; + if (exchange_get($exchange, 'disabled')) return; + + $count = (int)dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); + if ($count == 0) return; + + $result = cryptobridge_api_query('ticker'); + if (!is_array($result)) return; + + foreach ($result as $ticker) + { + if (is_null(objSafeVal($ticker, 'id'))) continue; + $pairs = explode('_', $ticker->id); + $symbol = reset($pairs); + $base = end($pairs); + if ($symbol == 'BTC' || $base != 'BTC') continue; + + if (market_get($exchange, $symbol, "disabled")) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + } + + $coin = getdbosql('db_coins', "symbol='{$symbol}'"); + if (!$coin) continue; + if (!$coin->installed && !$coin->watch) continue; + + $market = getdbosql('db_markets', "coinid={$coin->id} and name='{$exchange}'"); + if (!$market) continue; + + $price2 = ($ticker->bid + $ticker->ask) / 2; + $market->price2 = AverageIncrement($market->price2, $price2); + $market->price = AverageIncrement($market->price, $ticker->bid); + $market->pricetime = time(); + $market->priority = - 1; + $market->txfee = 0.2; // trade pct + $market->save(); + + //debuglog("$exchange: update $symbol: {$market->price} {$market->price2}"); + + } } function updateEscoDexMarkets($force = false) { - $exchange = 'escodex'; - if (exchange_get($exchange, 'disabled')) return; - - $count = (int) dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); - if ($count == 0) return; - $result = escodex_api_query('ticker'); - if(!is_array($result)) return; - foreach($result as $ticker) - { - if (is_null(objSafeVal($ticker,'id'))) continue; - #$pairs = explode('_', $ticker->id); - $symbol = $ticker->quote; $base = $ticker->base; - if($symbol == 'BTC' || $base != 'BTC') continue; - if (market_get($exchange, $symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - } - - $coin = getdbosql('db_coins', "symbol='{$symbol}'"); - if(!$coin) continue; - if(!$coin->installed && !$coin->watch) continue; - $market = getdbosql('db_markets', "coinid={$coin->id} and name='{$exchange}'"); - if(!$market) continue; - - $price2 = ($ticker->highest_bid + $ticker->lowest_ask)/2; - $market->price2 = AverageIncrement($market->price2, $price2); - $market->price = AverageIncrement($market->price, $ticker->highest_bid); - $market->pricetime = time(); - $market->priority = -1; - $market->txfee = 0.2; // trade pct - $market->save(); - //debuglog("$exchange: update $symbol: {$market->price} {$market->price2}"); - if ((empty($coin->price))||(empty($coin->price2))) { - $coin->price = $market->price; - $coin->price2 = $market->price2; - $coin->market = $exchange; - $coin->save(); - } - } + $exchange = 'escodex'; + if (exchange_get($exchange, 'disabled')) return; + + $count = (int)dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); + if ($count == 0) return; + $result = escodex_api_query('ticker'); + if (!is_array($result)) return; + foreach ($result as $ticker) + { + if (is_null(objSafeVal($ticker, 'id'))) continue; + #$pairs = explode('_', $ticker->id); + $symbol = $ticker->quote; + $base = $ticker->base; + if ($symbol == 'BTC' || $base != 'BTC') continue; + if (market_get($exchange, $symbol, "disabled")) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + } + + $coin = getdbosql('db_coins', "symbol='{$symbol}'"); + if (!$coin) continue; + if (!$coin->installed && !$coin->watch) continue; + $market = getdbosql('db_markets', "coinid={$coin->id} and name='{$exchange}'"); + if (!$market) continue; + + $price2 = ($ticker->highest_bid + $ticker->lowest_ask) / 2; + $market->price2 = AverageIncrement($market->price2, $price2); + $market->price = AverageIncrement($market->price, $ticker->highest_bid); + $market->pricetime = time(); + $market->priority = - 1; + $market->txfee = 0.2; // trade pct + $market->save(); + //debuglog("$exchange: update $symbol: {$market->price} {$market->price2}"); + if ((empty($coin->price)) || (empty($coin->price2))) + { + $coin->price = $market->price; + $coin->price2 = $market->price2; + $coin->market = $exchange; + $coin->save(); + } + } } ///////////////////////////////////////////////////////////////////////////////////////////// - function updateGateioMarkets($force = false) { - $exchange = 'gateio'; - if (exchange_get($exchange, 'disabled')) return; - - $list = getdbolist('db_markets', "name LIKE '$exchange%'"); - if (empty($list)) return; - - $markets = gateio_api_query('tickers'); - if(!is_array($markets)) return; - - foreach($list as $market) - { - $coin = getdbo('db_coins', $market->coinid); - if(!$coin) continue; - - $symbol = $coin->getOfficialSymbol(); - if (market_get($exchange, $symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - $market->save(); - continue; - } - - $dbpair = strtolower($symbol).'_btc'; - foreach ($markets as $pair => $ticker) { - if ($pair != $dbpair) continue; - $price2 = (doubleval($ticker['highestBid']) + doubleval($ticker['lowestAsk'])) / 2; - $market->price = AverageIncrement($market->price, doubleval($ticker['highestBid'])); - $market->price2 = AverageIncrement($market->price2, $price2); - $market->pricetime = time(); - $market->priority = -1; - $market->txfee = 0.2; // trade pct - $market->save(); - - if (empty($coin->price2)) { - $coin->price = $market->price; - $coin->price2 = $market->price2; - $coin->market = $exchange; - $coin->save(); - } - } - } + $exchange = 'gateio'; + if (exchange_get($exchange, 'disabled')) return; + + $list = getdbolist('db_markets', "name LIKE '$exchange%'"); + if (empty($list)) return; + + $markets = gateio_api_query('tickers'); + if (!is_array($markets)) return; + + foreach ($list as $market) + { + $coin = getdbo('db_coins', $market->coinid); + if (!$coin) continue; + + $symbol = $coin->getOfficialSymbol(); + if (market_get($exchange, $symbol, "disabled")) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + $market->save(); + continue; + } + + $dbpair = strtolower($symbol) . '_btc'; + foreach ($markets as $pair => $ticker) + { + if ($pair != $dbpair) continue; + $price2 = (doubleval($ticker['highestBid']) + doubleval($ticker['lowestAsk'])) / 2; + $market->price = AverageIncrement($market->price, doubleval($ticker['highestBid'])); + $market->price2 = AverageIncrement($market->price2, $price2); + $market->pricetime = time(); + $market->priority = - 1; + $market->txfee = 0.2; // trade pct + $market->save(); + + if (empty($coin->price2)) + { + $coin->price = $market->price; + $coin->price2 = $market->price2; + $coin->market = $exchange; + $coin->save(); + } + } + } } ///////////////////////////////////////////////////////////////////////////////////////////// - function updateGraviexMarkets($force = false) { - $exchange = 'graviex'; - if (exchange_get($exchange, 'disabled')) return; - - $list = getdbolist('db_markets', "name LIKE '$exchange%'"); - if (empty($list)) return; - - $markets = graviex_api_query('tickers'); - if(!is_array($markets)) return; - - foreach($list as $market) - { - $coin = getdbo('db_coins', $market->coinid); - if(!$coin) continue; - - $symbol = $coin->getOfficialSymbol(); - if (market_get($exchange, $symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - $market->save(); - continue; - } - - $symbol = strtolower($symbol); - $dbpair = $symbol.'btc'; - foreach ($markets as $pair => $ticker) { - if ($pair != $dbpair) continue; - $price2 = ($ticker['ticker']['buy']+$ticker['ticker']['sell'])/2; - $market->price = AverageIncrement($market->price, $ticker['ticker']['buy']); - $market->price2 = AverageIncrement($market->price2, $price2); - $market->pricetime = time(); - $market->save(); - - if (empty($coin->price2)) { - $coin->price = $market->price; - $coin->price2 = $market->price2; - $coin->market = $exchange; - $coin->save(); - } - } - } + $exchange = 'graviex'; + if (exchange_get($exchange, 'disabled')) return; + + $list = getdbolist('db_markets', "name LIKE '$exchange%'"); + if (empty($list)) return; + + $markets = graviex_api_query('tickers'); + if (!is_array($markets)) return; + + foreach ($list as $market) + { + $coin = getdbo('db_coins', $market->coinid); + if (!$coin) continue; + + $symbol = $coin->getOfficialSymbol(); + if (market_get($exchange, $symbol, "disabled")) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + $market->save(); + continue; + } + + $symbol = strtolower($symbol); + $dbpair = $symbol . 'btc'; + foreach ($markets as $pair => $ticker) + { + if ($pair != $dbpair) continue; + $price2 = ($ticker['ticker']['buy'] + $ticker['ticker']['sell']) / 2; + $market->price = AverageIncrement($market->price, $ticker['ticker']['buy']); + $market->price2 = AverageIncrement($market->price2, $price2); + $market->pricetime = time(); + $market->save(); + + if (empty($coin->price2)) + { + $coin->price = $market->price; + $coin->price2 = $market->price2; + $coin->market = $exchange; + $coin->save(); + } + } + } } ///////////////////////////////////////////////////////////////////////////////////////////// - function updateKrakenMarkets($force = false) { - $exchange = 'kraken'; - if (exchange_get($exchange, 'disabled')) return; - - $count = (int) dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); - if ($count == 0) return; - - $result = kraken_api_query('AssetPairs'); - if(!is_array($result)) return; - - foreach($result as $pair => $data) - { - $pairs = explode('-', $pair); - $base = reset($pairs); $symbol = end($pairs); - if($symbol == 'BTC' || $base != 'BTC') continue; - if(in_array($symbol, array('GBP','CAD','EUR','USD','JPY'))) continue; - if(strpos($symbol,'.d') !== false) continue; - - $coin = getdbosql('db_coins', "symbol='{$symbol}'"); - if(!$coin) continue; - if(!$coin->installed && !$coin->watch) continue; - - $fees = reset($data['fees']); - $feepct = is_array($fees) ? end($fees) : null; - $market = getdbosql('db_markets', "coinid={$coin->id} and name='{$exchange}'"); - if(!$market) continue; - - $market->txfee = $feepct; - - if (market_get($exchange, $symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - } - - $market->save(); - if($market->disabled || $market->deleted) continue; - - sleep(1); - $ticker = kraken_api_query('Ticker', $symbol); - if(!is_array($ticker) || !isset($ticker[$pair])) continue; - - $ticker = arraySafeVal($ticker, $pair); - if(!is_array($ticker) || !isset($ticker['b'])) continue; - - $price1 = (double) $ticker['a'][0]; // a = ask - $price2 = (double) $ticker['b'][0]; // b = bid, c = last - - // Alt markets on kraken (LTC/DOGE/NMC) are "reversed" against BTC (1/x) - if ($price2 > $price1) { - $price = $price2 ? 1 / $price2 : 0; - $price2 = $price1 ? 1 / $price1 : 0; - } else { - $price = $price1 ? 1 / $price1 : 0; - $price2 = $price2 ? 1 / $price2 : 0; - } - - $market->price = AverageIncrement($market->price, $price); - $market->price2 = AverageIncrement($market->price2, $price2); - $market->pricetime = time(); - - $market->save(); - } + $exchange = 'kraken'; + if (exchange_get($exchange, 'disabled')) return; + + $count = (int)dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); + if ($count == 0) return; + + $result = kraken_api_query('AssetPairs'); + if (!is_array($result)) return; + + foreach ($result as $pair => $data) + { + $pairs = explode('-', $pair); + $base = reset($pairs); + $symbol = end($pairs); + if ($symbol == 'BTC' || $base != 'BTC') continue; + if (in_array($symbol, array( + 'GBP', + 'CAD', + 'EUR', + 'USD', + 'JPY' + ))) continue; + if (strpos($symbol, '.d') !== false) continue; + + $coin = getdbosql('db_coins', "symbol='{$symbol}'"); + if (!$coin) continue; + if (!$coin->installed && !$coin->watch) continue; + + $fees = reset($data['fees']); + $feepct = is_array($fees) ? end($fees) : null; + $market = getdbosql('db_markets', "coinid={$coin->id} and name='{$exchange}'"); + if (!$market) continue; + + $market->txfee = $feepct; + + if (market_get($exchange, $symbol, "disabled")) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + } + + $market->save(); + if ($market->disabled || $market->deleted) continue; + + sleep(1); + $ticker = kraken_api_query('Ticker', $symbol); + if (!is_array($ticker) || !isset($ticker[$pair])) continue; + + $ticker = arraySafeVal($ticker, $pair); + if (!is_array($ticker) || !isset($ticker['b'])) continue; + + $price1 = (double)$ticker['a'][0]; // a = ask + $price2 = (double)$ticker['b'][0]; // b = bid, c = last + // Alt markets on kraken (LTC/DOGE/NMC) are "reversed" against BTC (1/x) + if ($price2 > $price1) + { + $price = $price2 ? 1 / $price2 : 0; + $price2 = $price1 ? 1 / $price1 : 0; + } + else + { + $price = $price1 ? 1 / $price1 : 0; + $price2 = $price2 ? 1 / $price2 : 0; + } + + $market->price = AverageIncrement($market->price, $price); + $market->price2 = AverageIncrement($market->price2, $price2); + $market->pricetime = time(); + + $market->save(); + } } ///////////////////////////////////////////////////////////////////////////////////////////// - function updateBittrexMarkets($force = false) { - $exchange = 'bittrex'; - if (exchange_get($exchange, 'disabled')) return; - - $count = (int) dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); - if ($count == 0) return; - - $list = bittrex_api_query('public/getcurrencies'); - if(!is_object($list)) return; - foreach($list->result as $currency) - { - $market = objSafeVal($currency,'Currency',''); - if(empty($market) || $market == 'BTC') continue; - - $coin = getdbosql('db_coins', "symbol=:sym", array(':sym'=>$currency->Currency)); - if(!$coin) continue; - - $market = getdbosql('db_markets', "coinid={$coin->id} AND name='$exchange'"); - if(!$market) continue; - - $market->txfee = $currency->TxFee; // withdraw cost, not a percent! - $market->message = $currency->Notice; - if($market->disabled < 9) $market->disabled = !$currency->IsActive; - - $market->save(); - } - - sleep(1); - - $list = bittrex_api_query('public/getmarketsummaries'); - if(!is_object($list)) return; - - foreach($list->result as $m) - { - $a = explode('-', $m->MarketName); - if(!isset($a[1])) continue; - if($a[0] != 'BTC') continue; - $symbol = $a[1]; - if($symbol == 'BTC') continue; - - $coin = getdbosql('db_coins', "symbol=:sym", array(':sym'=>$symbol)); - if(!$coin) continue; - - $market = getdbosql('db_markets', "coinid={$coin->id} AND name='$exchange'"); - if(!$market) continue; - - if (market_get($exchange, $symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - } - - $price2 = ($m->Bid + $m->Ask)/2; - $market->price2 = AverageIncrement($market->price2, $price2); - $market->price = AverageIncrement($market->price, $m->Bid); - $market->pricetime = time(); - $market->save(); - - // deposit address - if(!empty(EXCH_BITTREX_KEY)) - { - $last_checked = cache()->get($exchange.'-deposit_address-check-'.$symbol); - if($force || (empty($market->deposit_address) && !$last_checked)) - { - $address = bittrex_api_query('account/getdepositaddress', "¤cy={$symbol}"); - if(is_object($address) && isset($address->result)) { - $addr = $address->result->Address; - if (!empty($addr) && $addr != $market->deposit_address) { - $market->deposit_address = $addr; - $market->save(); - debuglog("$exchange: deposit address for {$coin->symbol} updated"); - } - } - } - cache()->set($exchange.'-deposit_address-check-'.$coin->symbol, time(), 12*3600); - } - -// debuglog("$exchange: update $coin->symbol: $market->price $market->price2"); - } + $exchange = 'bittrex'; + if (exchange_get($exchange, 'disabled')) return; + + $count = (int)dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); + if ($count == 0) return; + + $list = bittrex_api_query('public/getcurrencies'); + if (!is_object($list)) return; + foreach ($list->result as $currency) + { + $market = objSafeVal($currency, 'Currency', ''); + if (empty($market) || $market == 'BTC') continue; + + $coin = getdbosql('db_coins', "symbol=:sym", array( + ':sym' => $currency->Currency + )); + if (!$coin) continue; + + $market = getdbosql('db_markets', "coinid={$coin->id} AND name='$exchange'"); + if (!$market) continue; + + $market->txfee = $currency->TxFee; // withdraw cost, not a percent! + $market->message = $currency->Notice; + if ($market->disabled < 9) $market->disabled = !$currency->IsActive; + + $market->save(); + } + + sleep(1); + + $list = bittrex_api_query('public/getmarketsummaries'); + if (!is_object($list)) return; + + foreach ($list->result as $m) + { + $a = explode('-', $m->MarketName); + if (!isset($a[1])) continue; + if ($a[0] != 'BTC') continue; + $symbol = $a[1]; + if ($symbol == 'BTC') continue; + + $coin = getdbosql('db_coins', "symbol=:sym", array( + ':sym' => $symbol + )); + if (!$coin) continue; + + $market = getdbosql('db_markets', "coinid={$coin->id} AND name='$exchange'"); + if (!$market) continue; + + if (market_get($exchange, $symbol, "disabled")) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + } + + $price2 = ($m->Bid + $m->Ask) / 2; + $market->price2 = AverageIncrement($market->price2, $price2); + $market->price = AverageIncrement($market->price, $m->Bid); + $market->pricetime = time(); + $market->save(); + + // deposit address + if (!empty(EXCH_BITTREX_KEY)) + { + $last_checked = cache()->get($exchange . '-deposit_address-check-' . $symbol); + if ($force || (empty($market->deposit_address) && !$last_checked)) + { + $address = bittrex_api_query('account/getdepositaddress', "¤cy={$symbol}"); + if (is_object($address) && isset($address->result)) + { + $addr = $address + ->result->Address; + if (!empty($addr) && $addr != $market->deposit_address) + { + $market->deposit_address = $addr; + $market->save(); + debuglog("$exchange: deposit address for {$coin->symbol} updated"); + } + } + } + cache() + ->set($exchange . '-deposit_address-check-' . $coin->symbol, time() , 12 * 3600); + } + + // debuglog("$exchange: update $coin->symbol: $market->price $market->price2"); + + } } //////////////////////////////////////////////////////////////////////////////////// - function updateCCexMarkets() { - $exchange = 'c-cex'; - if (exchange_get($exchange, 'disabled')) return; - - $count = (int) dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); - if ($count == 0) return; - - $ccex = new CcexAPI; - $list = $ccex->getMarketSummaries(); - if (!is_array($list)) return; - - foreach($list as $ticker) - { - if(!isset($ticker['MarketName'])) continue; - $e = explode('-', $ticker['MarketName']); - - $symbol = strtoupper($e[0]); - $base_symbol = strtoupper($e[1]); - - $sqlFilter = ''; - if ($base_symbol != 'BTC') { - // Only track ALT markets (LTC, DOGE) if the market record exists in the DB, sample market name "c-cex LTC" - $in_db = (int) dboscalar("SELECT count(M.id) FROM markets M INNER JOIN coins C ON C.id=M.coinid - WHERE C.installed AND C.symbol=:sym AND M.base_coin=:base", array(':sym'=>$symbol,':base'=>$base_symbol)); - if (!$in_db) continue; - $sqlFilter = "AND base_coin='$base_symbol'"; - } - - $coin = getdbosql('db_coins', "symbol=:symbol", array(':symbol'=>$symbol)); - if (!$coin) continue; - if (!$coin->installed && !$coin->watch) continue; - - $market = getdbosql('db_markets', "coinid={$coin->id} AND name LIKE '$exchange%' $sqlFilter"); - if (!$market) continue; - //if ($market->disabled < 9) $market->disabled = !$ticker['IsActive']; // only in GetMarkets() - if ($market->disabled < 9) $market->disabled = ($ticker['OpenBuyOrders'] <= 1); - - if (market_get($exchange, $symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - } - - $market->save(); - - if ($market->disabled || $market->deleted) continue; - - $price2 = ($ticker['Bid']+$ticker['Ask'])/2; - $market->price2 = AverageIncrement($market->price2, $price2); - $market->price = AverageIncrement($market->price, $ticker['Bid']); - $market->pricetime = time(); - $market->save(); - - if (empty($coin->price2) && $base_symbol=='BTC') { - $coin->price = $market->price; - $coin->price2 = $market->price2; - $coin->save(); - } - - if(!empty(EXCH_CCEX_KEY)) - { - $last_checked = cache()->get($exchange.'-deposit_address-check-'.$symbol); - if(empty($market->deposit_address) && !$last_checked) - { - sleep(1); - $address = $ccex->getDepositAddress($symbol); - if(!empty($address)) { - $addr = arraySafeVal($address,'return'); - if (!empty($addr) && $addr != $market->deposit_address) { - if (strpos($addr, 'Error') !== false) { - $market->message = $addr; - debuglog("$exchange: deposit address for $symbol returned $addr"); - } else { - $market->deposit_address = $addr; - $market->message = null; - debuglog("$exchange: deposit address for {$coin->symbol} updated"); - } - $market->save(); - } - } - } - cache()->set($exchange.'-deposit_address-check-'.$coin->symbol, time(), 24*3600); - } - -// debuglog("$exchange: update $coin->symbol: $market->price $market->price2"); - } + $exchange = 'c-cex'; + if (exchange_get($exchange, 'disabled')) return; + + $count = (int)dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); + if ($count == 0) return; + + $ccex = new CcexAPI; + $list = $ccex->getMarketSummaries(); + if (!is_array($list)) return; + + foreach ($list as $ticker) + { + if (!isset($ticker['MarketName'])) continue; + $e = explode('-', $ticker['MarketName']); + + $symbol = strtoupper($e[0]); + $base_symbol = strtoupper($e[1]); + + $sqlFilter = ''; + if ($base_symbol != 'BTC') + { + // Only track ALT markets (LTC, DOGE) if the market record exists in the DB, sample market name "c-cex LTC" + $in_db = (int)dboscalar("SELECT count(M.id) FROM markets M INNER JOIN coins C ON C.id=M.coinid + WHERE C.installed AND C.symbol=:sym AND M.base_coin=:base", array( + ':sym' => $symbol, + ':base' => $base_symbol + )); + if (!$in_db) continue; + $sqlFilter = "AND base_coin='$base_symbol'"; + } + + $coin = getdbosql('db_coins', "symbol=:symbol", array( + ':symbol' => $symbol + )); + if (!$coin) continue; + if (!$coin->installed && !$coin->watch) continue; + + $market = getdbosql('db_markets', "coinid={$coin->id} AND name LIKE '$exchange%' $sqlFilter"); + if (!$market) continue; + //if ($market->disabled < 9) $market->disabled = !$ticker['IsActive']; // only in GetMarkets() + if ($market->disabled < 9) $market->disabled = ($ticker['OpenBuyOrders'] <= 1); + + if (market_get($exchange, $symbol, "disabled")) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + } + + $market->save(); + + if ($market->disabled || $market->deleted) continue; + + $price2 = ($ticker['Bid'] + $ticker['Ask']) / 2; + $market->price2 = AverageIncrement($market->price2, $price2); + $market->price = AverageIncrement($market->price, $ticker['Bid']); + $market->pricetime = time(); + $market->save(); + + if (empty($coin->price2) && $base_symbol == 'BTC') + { + $coin->price = $market->price; + $coin->price2 = $market->price2; + $coin->save(); + } + + if (!empty(EXCH_CCEX_KEY)) + { + $last_checked = cache()->get($exchange . '-deposit_address-check-' . $symbol); + if (empty($market->deposit_address) && !$last_checked) + { + sleep(1); + $address = $ccex->getDepositAddress($symbol); + if (!empty($address)) + { + $addr = arraySafeVal($address, 'return'); + if (!empty($addr) && $addr != $market->deposit_address) + { + if (strpos($addr, 'Error') !== false) + { + $market->message = $addr; + debuglog("$exchange: deposit address for $symbol returned $addr"); + } + else + { + $market->deposit_address = $addr; + $market->message = null; + debuglog("$exchange: deposit address for {$coin->symbol} updated"); + } + $market->save(); + } + } + } + cache() + ->set($exchange . '-deposit_address-check-' . $coin->symbol, time() , 24 * 3600); + } + + // debuglog("$exchange: update $coin->symbol: $market->price $market->price2"); + + } } //////////////////////////////////////////////////////////////////////////////////// - function updatePoloniexMarkets() { - $exchange = 'poloniex'; - if (exchange_get($exchange, 'disabled')) return; - - $count = (int) dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); - if ($count == 0) return; - - $poloniex = new poloniex; - - $tickers = $poloniex->get_ticker(); - if(!is_array($tickers)) return; - - foreach($tickers as $symbol=>$ticker) - { - $a = explode('_', $symbol); - if(!isset($a[1])) continue; - if($a[0] != 'BTC') continue; - - $symbol = $a[1]; - - $coin = getdbosql('db_coins', "symbol=:symbol", array(':symbol'=>$symbol)); - if(!$coin) continue; - - $market = getdbosql('db_markets', "coinid={$coin->id} and name='poloniex'"); - if(!$market) continue; - - if (market_get($exchange, $symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - $market->save(); - } - - if($market->disabled || $market->deleted) continue; - - $price2 = ($ticker['highestBid']+$ticker['lowestAsk'])/2; - $market->price2 = AverageIncrement($market->price2, $price2); - $market->price = AverageIncrement($market->price, $ticker['highestBid']); - $market->pricetime = time(); - - $market->save(); - - if(empty($market->deposit_address) && $coin->installed && !empty(EXCH_POLONIEX_KEY)) { - $last_checked = cache()->get($exchange.'-deposit_address-check'); - if (time() - $last_checked < 3600) { - // if still empty after get_deposit_addresses(), generate one - $poloniex->generate_address($coin->symbol); - sleep(1); - } - // empty address found, so force get_deposit_addresses check - cache()->set($exchange.'-deposit_address-check', 0, 10); - } - -// debuglog("$exchange: update $coin->symbol: $market->price $market->price2"); - } - - // deposit addresses - if(!empty(EXCH_POLONIEX_KEY)) - { - $list = array(); - $last_checked = cache()->get($exchange.'-deposit_address-check'); - if (!$last_checked) { - $list = $poloniex->get_deposit_addresses(); - if (!is_array($list)) return; - } - - foreach($list as $symbol=>$item) - { - if($symbol == 'BTC') continue; - - $coin = getdbosql('db_coins', "symbol=:symbol", array(':symbol'=>$symbol)); - if(!$coin) continue; - - $market = getdbosql('db_markets', "coinid=$coin->id and name='poloniex'"); - if(!$market) continue; - - if ($market->deposit_address != $item) { - $market->deposit_address = $item; - $market->save(); - debuglog("$exchange: deposit address for {$coin->symbol} updated"); - } - } - cache()->set($exchange.'-deposit_address-check', time(), 12*3600); - } + $exchange = 'poloniex'; + if (exchange_get($exchange, 'disabled')) return; + + $count = (int)dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); + if ($count == 0) return; + + $poloniex = new poloniex; + + $tickers = $poloniex->get_ticker(); + if (!is_array($tickers)) return; + + foreach ($tickers as $symbol => $ticker) + { + $a = explode('_', $symbol); + if (!isset($a[1])) continue; + if ($a[0] != 'BTC') continue; + + $symbol = $a[1]; + + $coin = getdbosql('db_coins', "symbol=:symbol", array( + ':symbol' => $symbol + )); + if (!$coin) continue; + + $market = getdbosql('db_markets', "coinid={$coin->id} and name='poloniex'"); + if (!$market) continue; + + if (market_get($exchange, $symbol, "disabled")) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + $market->save(); + } + + if ($market->disabled || $market->deleted) continue; + + $price2 = ($ticker['highestBid'] + $ticker['lowestAsk']) / 2; + $market->price2 = AverageIncrement($market->price2, $price2); + $market->price = AverageIncrement($market->price, $ticker['highestBid']); + $market->pricetime = time(); + + $market->save(); + + if (empty($market->deposit_address) && $coin->installed && !empty(EXCH_POLONIEX_KEY)) + { + $last_checked = cache()->get($exchange . '-deposit_address-check'); + if (time() - $last_checked < 3600) + { + // if still empty after get_deposit_addresses(), generate one + $poloniex->generate_address($coin->symbol); + sleep(1); + } + // empty address found, so force get_deposit_addresses check + cache() + ->set($exchange . '-deposit_address-check', 0, 10); + } + + // debuglog("$exchange: update $coin->symbol: $market->price $market->price2"); + + } + + // deposit addresses + if (!empty(EXCH_POLONIEX_KEY)) + { + $list = array(); + $last_checked = cache()->get($exchange . '-deposit_address-check'); + if (!$last_checked) + { + $list = $poloniex->get_deposit_addresses(); + if (!is_array($list)) return; + } + + foreach ($list as $symbol => $item) + { + if ($symbol == 'BTC') continue; + + $coin = getdbosql('db_coins', "symbol=:symbol", array( + ':symbol' => $symbol + )); + if (!$coin) continue; + + $market = getdbosql('db_markets', "coinid=$coin->id and name='poloniex'"); + if (!$market) continue; + + if ($market->deposit_address != $item) + { + $market->deposit_address = $item; + $market->save(); + debuglog("$exchange: deposit address for {$coin->symbol} updated"); + } + } + cache() + ->set($exchange . '-deposit_address-check', time() , 12 * 3600); + } } //////////////////////////////////////////////////////////////////////////////////// - function updateYobitMarkets() { - $exchange = 'yobit'; - if (exchange_get($exchange, 'disabled')) return; - - $count = (int) dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); - if ($count == 0) return; - - $res = yobit_api_query('info'); - if(!is_object($res)) return; - - foreach($res->pairs as $i=>$item) - { - $e = explode('_', $i); - $symbol = strtoupper($e[0]); - $base_symbol = strtoupper($e[1]); - - if($symbol == 'BTC') continue; - - $coin = getdbosql('db_coins', "symbol=:symbol", array(':symbol'=>$symbol)); - if(!$coin) continue; - - $sqlFilter = "AND IFNULL(base_coin,'')=''"; - if ($base_symbol != 'BTC') { - // Only track ALT markets (ETH, DOGE) if the market record exists in the DB, sample market name "yobit DOGE" - $in_db = (int) dboscalar("SELECT count(M.id) FROM markets M INNER JOIN coins C ON C.id=M.coinid ". - " WHERE C.installed AND C.symbol=:sym AND M.name LIKE '$exchange %' AND M.base_coin=:base", - array(':sym'=>$symbol,':base'=>$base_symbol) - ); - if (!$in_db) continue; - $sqlFilter = "AND base_coin='$base_symbol'"; - } - - $market = getdbosql('db_markets', "coinid={$coin->id} AND name LIKE '$exchange%' $sqlFilter"); - if(!$market) continue; - - $market->txfee = objSafeVal($item,'fee',0.2); - if ($market->disabled < 9) $market->disabled = arraySafeVal($item,'hidden',0); - if (time() - $market->pricetime > 6*3600) $market->price = 0; - - if (market_get($exchange, $symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - } - - $market->save(); - - if ($market->deleted || $market->disabled) continue; - if (!$coin->installed && !$coin->watch) continue; - - $symbol = $coin->getOfficialSymbol(); - $pair = strtolower($symbol.'_'.$base_symbol); - - $ticker = yobit_api_query("ticker/$pair"); - if(!$ticker || objSafeVal($ticker,$pair) === NULL) continue; - if(objSafeVal($ticker->$pair,'buy') === NULL) { - debuglog("$exchange: invalid data received for $pair ticker"); - continue; - } - - $price2 = ($ticker->$pair->buy + $ticker->$pair->sell) / 2; - $market->price2 = AverageIncrement($market->price2, $price2); - $market->price = AverageIncrement($market->price, $ticker->$pair->buy); - if ($ticker->$pair->buy < $market->price) $market->price = $ticker->$pair->buy; - $market->pricetime = time(); - $market->save(); - - if(!empty(EXCH_YOBIT_KEY)) - { - $last_checked = cache()->get($exchange.'-deposit_address-check-'.$symbol); - if ($last_checked) continue; - - sleep(1); // for the api nonce - $address = yobit_api_query2('GetDepositAddress', array("coinName"=>$symbol)); - if (!empty($address) && isset($address['return']) && $address['success']) { - $addr = $address['return']['address']; - if (!empty($addr) && $addr != $market->deposit_address) { - $market->deposit_address = $addr; - debuglog("$exchange: deposit address for {$symbol} updated"); - $market->save(); - } - } - cache()->set($exchange.'-deposit_address-check-'.$symbol, time(), 24*3600); - } - } + $exchange = 'yobit'; + if (exchange_get($exchange, 'disabled')) return; + + $count = (int)dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); + if ($count == 0) return; + + $res = yobit_api_query('info'); + if (!is_object($res)) return; + + foreach ($res->pairs as $i => $item) + { + $e = explode('_', $i); + $symbol = strtoupper($e[0]); + $base_symbol = strtoupper($e[1]); + + if ($symbol == 'BTC') continue; + + $coin = getdbosql('db_coins', "symbol=:symbol", array( + ':symbol' => $symbol + )); + if (!$coin) continue; + + $sqlFilter = "AND IFNULL(base_coin,'')=''"; + if ($base_symbol != 'BTC') + { + // Only track ALT markets (ETH, DOGE) if the market record exists in the DB, sample market name "yobit DOGE" + $in_db = (int)dboscalar("SELECT count(M.id) FROM markets M INNER JOIN coins C ON C.id=M.coinid " . " WHERE C.installed AND C.symbol=:sym AND M.name LIKE '$exchange %' AND M.base_coin=:base", array( + ':sym' => $symbol, + ':base' => $base_symbol + )); + if (!$in_db) continue; + $sqlFilter = "AND base_coin='$base_symbol'"; + } + + $market = getdbosql('db_markets', "coinid={$coin->id} AND name LIKE '$exchange%' $sqlFilter"); + if (!$market) continue; + + $market->txfee = objSafeVal($item, 'fee', 0.2); + if ($market->disabled < 9) $market->disabled = arraySafeVal($item, 'hidden', 0); + if (time() - $market->pricetime > 6 * 3600) $market->price = 0; + + if (market_get($exchange, $symbol, "disabled")) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + } + + $market->save(); + + if ($market->deleted || $market->disabled) continue; + if (!$coin->installed && !$coin->watch) continue; + + $symbol = $coin->getOfficialSymbol(); + $pair = strtolower($symbol . '_' . $base_symbol); + + $ticker = yobit_api_query("ticker/$pair"); + if (!$ticker || objSafeVal($ticker, $pair) === NULL) continue; + if (objSafeVal($ticker->$pair, 'buy') === NULL) + { + debuglog("$exchange: invalid data received for $pair ticker"); + continue; + } + + $price2 = ($ticker + ->$pair->buy + $ticker + ->$pair->sell) / 2; + $market->price2 = AverageIncrement($market->price2, $price2); + $market->price = AverageIncrement($market->price, $ticker + ->$pair->buy); + if ($ticker + ->$pair->buy < $market->price) $market->price = $ticker + ->$pair->buy; + $market->pricetime = time(); + $market->save(); + + if (!empty(EXCH_YOBIT_KEY)) + { + $last_checked = cache()->get($exchange . '-deposit_address-check-' . $symbol); + if ($last_checked) continue; + + sleep(1); // for the api nonce + $address = yobit_api_query2('GetDepositAddress', array( + "coinName" => $symbol + )); + if (!empty($address) && isset($address['return']) && $address['success']) + { + $addr = $address['return']['address']; + if (!empty($addr) && $addr != $market->deposit_address) + { + $market->deposit_address = $addr; + debuglog("$exchange: deposit address for {$symbol} updated"); + $market->save(); + } + } + cache() + ->set($exchange . '-deposit_address-check-' . $symbol, time() , 24 * 3600); + } + } } // http://www.jubi.com/ ? function updateJubiMarkets() { - $exchange = 'jubi'; - if (exchange_get($exchange, 'disabled')) return; - - $list = getdbolist('db_markets', "name LIKE '$exchange%'"); - if (empty($list)) return; - - $btc = jubi_api_query('ticker', "?coin=btc"); - if(!is_object($btc)) return; - - foreach($list as $market) - { - $coin = getdbo('db_coins', $market->coinid); - if(!$coin) continue; - - $symbol = $coin->getOfficialSymbol(); - if (market_get($exchange, $symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - $market->save(); - continue; - } - - $ticker = jubi_api_query('ticker', "?coin=".strtolower($symbol)); - if(!$ticker || !is_object($ticker)) continue; - if(objSafeVal($ticker,'buy') === NULL) { - debuglog("$exchange: invalid data received for $symbol ticker"); - continue; - } - - if (isset($btc->sell) && $btc->sell != 0.) - $ticker->buy /= $btc->sell; - if (isset($btc->buy) && $btc->buy != 0.) - $ticker->sell /= $btc->buy; - - $price2 = ($ticker->buy+$ticker->sell)/2; - $market->price2 = AverageIncrement($market->price2, $price2); - $market->price = AverageIncrement($market->price, $ticker->buy*0.95); - $market->pricetime = time(); - -// debuglog("jubi update $symbol: $market->price $market->price2"); - - $market->save(); - } + $exchange = 'jubi'; + if (exchange_get($exchange, 'disabled')) return; + + $list = getdbolist('db_markets', "name LIKE '$exchange%'"); + if (empty($list)) return; + + $btc = jubi_api_query('ticker', "?coin=btc"); + if (!is_object($btc)) return; + + foreach ($list as $market) + { + $coin = getdbo('db_coins', $market->coinid); + if (!$coin) continue; + + $symbol = $coin->getOfficialSymbol(); + if (market_get($exchange, $symbol, "disabled")) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + $market->save(); + continue; + } + + $ticker = jubi_api_query('ticker', "?coin=" . strtolower($symbol)); + if (!$ticker || !is_object($ticker)) continue; + if (objSafeVal($ticker, 'buy') === NULL) + { + debuglog("$exchange: invalid data received for $symbol ticker"); + continue; + } + + if (isset($btc->sell) && $btc->sell != 0.) $ticker->buy /= $btc->sell; + if (isset($btc->buy) && $btc->buy != 0.) $ticker->sell /= $btc->buy; + + $price2 = ($ticker->buy + $ticker->sell) / 2; + $market->price2 = AverageIncrement($market->price2, $price2); + $market->price = AverageIncrement($market->price, $ticker->buy * 0.95); + $market->pricetime = time(); + + // debuglog("jubi update $symbol: $market->price $market->price2"); + $market->save(); + } } function updateAlcurexMarkets() { - $exchange = 'alcurex'; - if (exchange_get($exchange, 'disabled')) return; - - $list = getdbolist('db_markets', "name LIKE '$exchange%'"); - if (empty($list)) return; - - $data = alcurex_api_query('market', "?info=on"); - if(!is_object($data)) return; - - foreach($list as $market) - { - $coin = getdbo('db_coins', $market->coinid); - if(!$coin) continue; - if (!$coin->installed && !$coin->watch) continue; - - $symbol = $coin->getOfficialSymbol(); - if (market_get($exchange, $symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - $market->save(); - continue; - } - - $pair = strtoupper($symbol).'_BTC'; - foreach ($data->MARKETS as $ticker) { - if ($ticker->Pair === $pair) { - $lpair = strtolower($pair); - $last = alcurex_api_query('market', "?pair=$lpair&last=last"); - if (is_object($last) && !empty($last->$lpair)) { - $last = $last->$lpair; - $market->price = AverageIncrement($market->price, $last->price); - $market->pricetime = time(); - $market->save(); - } - $last = alcurex_api_query('market', "?pair=$lpair&last=sell"); - if (is_object($last) && !empty($last->$lpair)) { - $last = $last->$lpair; - $market->price2 = AverageIncrement($market->price2, $last->price); - $market->pricetime = time(); - $market->save(); - } - if (empty($coin->price)) { - $coin->price = $market->price; - $coin->price2 = $market->price2; - $coin->save(); - } - //debuglog("$exchange: $pair price updated to {$market->price}"); - break; - } - } - } + $exchange = 'alcurex'; + if (exchange_get($exchange, 'disabled')) return; + + $list = getdbolist('db_markets', "name LIKE '$exchange%'"); + if (empty($list)) return; + + $data = alcurex_api_query('market', "?info=on"); + if (!is_object($data)) return; + + foreach ($list as $market) + { + $coin = getdbo('db_coins', $market->coinid); + if (!$coin) continue; + if (!$coin->installed && !$coin->watch) continue; + + $symbol = $coin->getOfficialSymbol(); + if (market_get($exchange, $symbol, "disabled")) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + $market->save(); + continue; + } + + $pair = strtoupper($symbol) . '_BTC'; + foreach ($data->MARKETS as $ticker) + { + if ($ticker->Pair === $pair) + { + $lpair = strtolower($pair); + $last = alcurex_api_query('market', "?pair=$lpair&last=last"); + if (is_object($last) && !empty($last->$lpair)) + { + $last = $last->$lpair; + $market->price = AverageIncrement($market->price, $last->price); + $market->pricetime = time(); + $market->save(); + } + $last = alcurex_api_query('market', "?pair=$lpair&last=sell"); + if (is_object($last) && !empty($last->$lpair)) + { + $last = $last->$lpair; + $market->price2 = AverageIncrement($market->price2, $last->price); + $market->pricetime = time(); + $market->save(); + } + if (empty($coin->price)) + { + $coin->price = $market->price; + $coin->price2 = $market->price2; + $coin->save(); + } + //debuglog("$exchange: $pair price updated to {$market->price}"); + break; + } + } + } } function updateCoinbeneMarkets() { - $exchange = 'coinbene'; - if (exchange_get($exchange, 'disabled')) return; - - $list = getdbolist('db_markets', "name LIKE '$exchange%'"); - if (empty($list)) return; - - $data = coinbene_api_query('market/ticker', 'symbol=all'); - $data = objSafeVal($data,'ticker'); - if(!is_array($data)) return; - - foreach($list as $market) { - $coin = getdbo('db_coins', $market->coinid); - if(!$coin) continue; - if(!$coin->installed && !$coin->watch) continue; - - $symbol = $coin->getOfficialSymbol(); - if (market_get($exchange, $symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - $market->save(); - continue; - } - - $pair = $symbol.'BTC'; - foreach($data as $ticker) { - if ($ticker->symbol != $pair) continue; - - $price2 = ($ticker->bid+$ticker->ask)/2; - $market->price2 = AverageIncrement($market->price2, $price2); - $market->price = AverageIncrement($market->price, $ticker->bid); - $market->pricetime = time(); - $market->save(); - - break; - } - } + $exchange = 'coinbene'; + if (exchange_get($exchange, 'disabled')) return; + + $list = getdbolist('db_markets', "name LIKE '$exchange%'"); + if (empty($list)) return; + + $data = coinbene_api_query('market/ticker', 'symbol=all'); + $data = objSafeVal($data, 'ticker'); + if (!is_array($data)) return; + + foreach ($list as $market) + { + $coin = getdbo('db_coins', $market->coinid); + if (!$coin) continue; + if (!$coin->installed && !$coin->watch) continue; + + $symbol = $coin->getOfficialSymbol(); + if (market_get($exchange, $symbol, "disabled")) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + $market->save(); + continue; + } + + $pair = $symbol . 'BTC'; + foreach ($data as $ticker) + { + if ($ticker->symbol != $pair) continue; + + $price2 = ($ticker->bid + $ticker->ask) / 2; + $market->price2 = AverageIncrement($market->price2, $price2); + $market->price = AverageIncrement($market->price, $ticker->bid); + $market->pricetime = time(); + $market->save(); + + break; + } + } } function updateCrex24Markets() { - $exchange = 'crex24'; - if (exchange_get($exchange, 'disabled')) return; - - $list = getdbolist('db_markets', "name LIKE '$exchange%'"); - if (empty($list)) return; - - $data = crex24_api_query('tickers'); - if(!is_array($data)) return; - - foreach($list as $market) - { - $coin = getdbo('db_coins', $market->coinid); - if(!$coin) continue; - - $symbol = $coin->getOfficialSymbol(); - $pair = strtoupper($symbol).'-BTC'; - - $sqlFilter = ''; - if (!empty($market->base_coin)) { - $pair = strtoupper($symbol.'-'.$market->base_coin); - $sqlFilter = "AND base_coin='{$market->base_coin}'"; - } - - if (market_get($exchange, $symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - $market->save(); - continue; - } - - foreach ($data as $ticker) { - if ($ticker->instrument === $pair) { - if ($market->disabled < 9) { - $nbm = (int) dboscalar("SELECT COUNT(id) FROM markets WHERE coinid={$coin->id} $sqlFilter"); - $market->disabled = ($ticker->bid < $ticker->ask/2) && ($nbm > 1); - } - - $price2 = ($ticker->bid+$ticker->ask)/2; - $market->price2 = AverageIncrement($market->price2, $price2); - $market->price = AverageIncrement($market->price, $ticker->bid); - $market->pricetime = time(); // $ticker->timestamp "2018-08-31T12:48:56Z" - $market->save(); - - if (empty($coin->price) && $ticker->ask) { - $coin->price = $market->price; - $coin->price2 = $price2; - $coin->save(); - } - //debuglog("$exchange: $pair price updated to {$market->price}"); - break; - } - } - } + $exchange = 'crex24'; + if (exchange_get($exchange, 'disabled')) return; + + $list = getdbolist('db_markets', "name LIKE '$exchange%'"); + if (empty($list)) return; + + $data = crex24_api_query('tickers'); + if (!is_array($data)) return; + + foreach ($list as $market) + { + $coin = getdbo('db_coins', $market->coinid); + if (!$coin) continue; + + $symbol = $coin->getOfficialSymbol(); + $pair = strtoupper($symbol) . '-BTC'; + + $sqlFilter = ''; + if (!empty($market->base_coin)) + { + $pair = strtoupper($symbol . '-' . $market->base_coin); + $sqlFilter = "AND base_coin='{$market->base_coin}'"; + } + + if (market_get($exchange, $symbol, "disabled")) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + $market->save(); + continue; + } + + foreach ($data as $ticker) + { + if ($ticker->instrument === $pair) + { + if ($market->disabled < 9) + { + $nbm = (int)dboscalar("SELECT COUNT(id) FROM markets WHERE coinid={$coin->id} $sqlFilter"); + $market->disabled = ($ticker->bid < $ticker->ask / 2) && ($nbm > 1); + } + + $price2 = ($ticker->bid + $ticker->ask) / 2; + $market->price2 = AverageIncrement($market->price2, $price2); + $market->price = AverageIncrement($market->price, $ticker->bid); + $market->pricetime = time(); // $ticker->timestamp "2018-08-31T12:48:56Z" + $market->save(); + + if (empty($coin->price) && $ticker->ask) + { + $coin->price = $market->price; + $coin->price2 = $price2; + $coin->save(); + } + //debuglog("$exchange: $pair price updated to {$market->price}"); + break; + } + } + } } function updateCryptopiaMarkets() { - $exchange = 'cryptopia'; - if (exchange_get($exchange, 'disabled')) return; - - $list = getdbolist('db_markets', "name LIKE '$exchange%'"); - if (empty($list)) return; - - $data = cryptopia_api_query('GetMarkets', 24); - if(!is_object($data)) return; - - foreach($list as $market) - { - $coin = getdbo('db_coins', $market->coinid); - if(!$coin) continue; - - $symbol = $coin->getOfficialSymbol(); - $pair = strtoupper($symbol).'/BTC'; - - $sqlFilter = ''; - if (!empty($market->base_coin)) { - $pair = strtoupper($symbol.'/'.$market->base_coin); - $sqlFilter = "AND base_coin='{$market->base_coin}'"; - } - - if (market_get($exchange, $symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - $market->save(); - continue; - } else if ($market->message == 'disabled from settings') { - $market->disabled = 0; - $market->message = ''; - $market->save(); - } - - foreach ($data->Data as $ticker) { - if ($ticker->Label === $pair) { - - if ($market->disabled < 9) { - $nbm = (int) dboscalar("SELECT COUNT(id) FROM markets WHERE coinid={$coin->id} $sqlFilter"); - $market->disabled = ($ticker->BidPrice < $ticker->AskPrice/2) && ($nbm > 1); - } - - $price2 = ($ticker->BidPrice+$ticker->AskPrice)/2; - $market->price2 = AverageIncrement($market->price2, $price2); - $market->price = AverageIncrement($market->price, $ticker->BidPrice*0.98); - $market->marketid = $ticker->TradePairId; - $market->pricetime = time(); - $market->save(); - - if (empty($coin->price) && !$market->disabled && strpos($pair,'BTC')) { - $coin->price = $market->price; - $coin->price2 = $market->price2; - $coin->save(); - } -// debuglog("$exchange: $pair $market->price ".bitcoinvaluetoa($market->price2)); - break; - } - } - } - - if(empty(EXCH_CRYPTOPIA_KEY)) return; - - $last_checked = cache()->get($exchange.'-deposit_address-check'); - if ($last_checked) return; - - $addresses = array(); - sleep(1); - $query = cryptopia_api_user('GetBalance'); - if (is_object($query) && is_array($query->Data)) - foreach($query->Data as $balance) { - $addr = objSafeVal($balance,'Address'); - if (!empty($addr)) $addresses[$balance->Symbol] = $addr; - } - // for some reason, no more available in global GetBalance api - $needCurrencyQueries = empty($addresses); - - if (!empty($list)) - foreach($list as $market) { - $coin = getdbo('db_coins', $market->coinid); - if(!$coin) continue; - - $symbol = $coin->getOfficialSymbol(); - $addr = arraySafeVal($addresses, $symbol); - if ($needCurrencyQueries) { - if(!$coin->installed) continue; - sleep(2); - $query = cryptopia_api_user('GetDepositAddress', array('Currency'=>$symbol)); - $dep = objSafeVal($query,'Data'); - $addr = objSafeVal($dep,'Address'); - } - if (!empty($addr) && $market->deposit_address != $addr) { - debuglog("$exchange: deposit address for {$symbol} updated"); - $market->deposit_address = $addr; - $market->save(); - } - } - cache()->set($exchange.'-deposit_address-check', time(), 12*3600); + $exchange = 'cryptopia'; + if (exchange_get($exchange, 'disabled')) return; + + $list = getdbolist('db_markets', "name LIKE '$exchange%'"); + if (empty($list)) return; + + $data = cryptopia_api_query('GetMarkets', 24); + if (!is_object($data)) return; + + foreach ($list as $market) + { + $coin = getdbo('db_coins', $market->coinid); + if (!$coin) continue; + + $symbol = $coin->getOfficialSymbol(); + $pair = strtoupper($symbol) . '/BTC'; + + $sqlFilter = ''; + if (!empty($market->base_coin)) + { + $pair = strtoupper($symbol . '/' . $market->base_coin); + $sqlFilter = "AND base_coin='{$market->base_coin}'"; + } + + if (market_get($exchange, $symbol, "disabled")) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + $market->save(); + continue; + } + else if ($market->message == 'disabled from settings') + { + $market->disabled = 0; + $market->message = ''; + $market->save(); + } + + foreach ($data->Data as $ticker) + { + if ($ticker->Label === $pair) + { + + if ($market->disabled < 9) + { + $nbm = (int)dboscalar("SELECT COUNT(id) FROM markets WHERE coinid={$coin->id} $sqlFilter"); + $market->disabled = ($ticker->BidPrice < $ticker->AskPrice / 2) && ($nbm > 1); + } + + $price2 = ($ticker->BidPrice + $ticker->AskPrice) / 2; + $market->price2 = AverageIncrement($market->price2, $price2); + $market->price = AverageIncrement($market->price, $ticker->BidPrice * 0.98); + $market->marketid = $ticker->TradePairId; + $market->pricetime = time(); + $market->save(); + + if (empty($coin->price) && !$market->disabled && strpos($pair, 'BTC')) + { + $coin->price = $market->price; + $coin->price2 = $market->price2; + $coin->save(); + } + // debuglog("$exchange: $pair $market->price ".bitcoinvaluetoa($market->price2)); + break; + } + } + } + + if (empty(EXCH_CRYPTOPIA_KEY)) return; + + $last_checked = cache()->get($exchange . '-deposit_address-check'); + if ($last_checked) return; + + $addresses = array(); + sleep(1); + $query = cryptopia_api_user('GetBalance'); + if (is_object($query) && is_array($query->Data)) foreach ($query->Data as $balance) + { + $addr = objSafeVal($balance, 'Address'); + if (!empty($addr)) $addresses[$balance->Symbol] = $addr; + } + // for some reason, no more available in global GetBalance api + $needCurrencyQueries = empty($addresses); + + if (!empty($list)) foreach ($list as $market) + { + $coin = getdbo('db_coins', $market->coinid); + if (!$coin) continue; + + $symbol = $coin->getOfficialSymbol(); + $addr = arraySafeVal($addresses, $symbol); + if ($needCurrencyQueries) + { + if (!$coin->installed) continue; + sleep(2); + $query = cryptopia_api_user('GetDepositAddress', array( + 'Currency' => $symbol + )); + $dep = objSafeVal($query, 'Data'); + $addr = objSafeVal($dep, 'Address'); + } + if (!empty($addr) && $market->deposit_address != $addr) + { + debuglog("$exchange: deposit address for {$symbol} updated"); + $market->deposit_address = $addr; + $market->save(); + } + } + cache() + ->set($exchange . '-deposit_address-check', time() , 12 * 3600); } function updateHitBTCMarkets() { - $exchange = 'hitbtc'; - if (exchange_get($exchange, 'disabled')) return; - - $markets = getdbolist('db_markets', "name LIKE '$exchange%'"); // allow "hitbtc LTC" - if(empty($markets)) return; - - $data = hitbtc_api_query('ticker','','array'); - if(!is_array($data) || empty($data)) return; - - foreach($markets as $market) - { - $coin = getdbo('db_coins', $market->coinid); - if(!$coin) continue; - - $base = 'BTC'; - $symbol = $coin->getOfficialSymbol(); - $pair = strtoupper($symbol).$base; - - $sqlFilter = ''; - if (!empty($market->base_coin)) { - $base = $market->base_coin; - $pair = strtoupper($market->base_coin.$symbol); - $sqlFilter = "AND base_coin='{$market->base_coin}'"; - } - - if (market_get($exchange, $symbol, "disabled", false, $base)) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - $market->save(); - continue; - } - - foreach ($data as $p => $ticker) - { - if ($p === $pair) { - $price2 = ((double)$ticker['bid'] + (double)$ticker['ask'])/2; - $market->price = AverageIncrement($market->price, (double)$ticker['bid']); - $market->price2 = AverageIncrement($market->price2, $price2); - $market->pricetime = time(); // $ticker->timestamp - $market->priority = -1; - $market->save(); - - if (empty($coin->price2) && strpos($pair,'BTC') !== false) { - $coin->price = $market->price; - $coin->price2 = $market->price2; - $coin->save(); - } - //debuglog("$exchange: $pair $market->price ".bitcoinvaluetoa($market->price2)); - break; - } - } - - if(!empty(EXCH_HITBTC_KEY)) - { - $last_checked = cache()->get($exchange.'-deposit_address-check-'.$symbol); - if($coin->installed && !$last_checked && empty($market->deposit_address)) - { - sleep(1); - $res = hitbtc_api_user('payment/address/'.$symbol); // GET method - if(is_object($res) && isset($res->address)) { - if (!empty($res->address)) { - $market->deposit_address = $res->address; - debuglog("$exchange: deposit address for {$symbol} updated"); - $market->save(); - if ($symbol == 'WAVES' || $symbol == 'LSK') // Wallet address + Public key - debuglog("$exchange: $symbol deposit address data: ".json_encode($res)); - } - } - cache()->set($exchange.'-deposit_address-check-'.$symbol, time(), 24*3600); - } - } - } + $exchange = 'hitbtc'; + if (exchange_get($exchange, 'disabled')) return; + + $markets = getdbolist('db_markets', "name LIKE '$exchange%'"); // allow "hitbtc LTC" + if (empty($markets)) return; + + $data = hitbtc_api_query('ticker', '', 'array'); + if (!is_array($data) || empty($data)) return; + + foreach ($markets as $market) + { + $coin = getdbo('db_coins', $market->coinid); + if (!$coin) continue; + + $base = 'BTC'; + $symbol = $coin->getOfficialSymbol(); + $pair = strtoupper($symbol) . $base; + + $sqlFilter = ''; + if (!empty($market->base_coin)) + { + $base = $market->base_coin; + $pair = strtoupper($market->base_coin . $symbol); + $sqlFilter = "AND base_coin='{$market->base_coin}'"; + } + + if (market_get($exchange, $symbol, "disabled", false, $base)) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + $market->save(); + continue; + } + + foreach ($data as $p => $ticker) + { + if ($p === $pair) + { + $price2 = ((double)$ticker['bid'] + (double)$ticker['ask']) / 2; + $market->price = AverageIncrement($market->price, (double)$ticker['bid']); + $market->price2 = AverageIncrement($market->price2, $price2); + $market->pricetime = time(); // $ticker->timestamp + $market->priority = - 1; + $market->save(); + + if (empty($coin->price2) && strpos($pair, 'BTC') !== false) + { + $coin->price = $market->price; + $coin->price2 = $market->price2; + $coin->save(); + } + //debuglog("$exchange: $pair $market->price ".bitcoinvaluetoa($market->price2)); + break; + } + } + + if (!empty(EXCH_HITBTC_KEY)) + { + $last_checked = cache()->get($exchange . '-deposit_address-check-' . $symbol); + if ($coin->installed && !$last_checked && empty($market->deposit_address)) + { + sleep(1); + $res = hitbtc_api_user('payment/address/' . $symbol); // GET method + if (is_object($res) && isset($res->address)) + { + if (!empty($res->address)) + { + $market->deposit_address = $res->address; + debuglog("$exchange: deposit address for {$symbol} updated"); + $market->save(); + if ($symbol == 'WAVES' || $symbol == 'LSK') // Wallet address + Public key + debuglog("$exchange: $symbol deposit address data: " . json_encode($res)); + } + } + cache()->set($exchange . '-deposit_address-check-' . $symbol, time() , 24 * 3600); + } + } + } } function updateNovaMarkets() { - $exchange = 'nova'; - if (exchange_get($exchange, 'disabled')) return; - - $markets = getdbolist('db_markets', "name LIKE '$exchange%'"); // allow "nova LTC" - if(empty($markets)) return; - - $data = nova_api_query('markets'); - if(!is_object($data) || $data->status != 'success' || !is_array($data->markets)) return; - - foreach($markets as $market) - { - $coin = getdbo('db_coins', $market->coinid); - if(!$coin) continue; - - $base = 'BTC'; - $symbol = $coin->getOfficialSymbol(); - $pair = $base.'_'.strtoupper($symbol); - - $sqlFilter = ''; - if (!empty($market->base_coin)) { - $base = $market->base_coin; - $pair = strtoupper($market->base_coin.'_'.$symbol); - $sqlFilter = "AND base_coin='{$market->base_coin}'"; - } - - if (market_get($exchange, $symbol, "disabled", false, $base)) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - $market->save(); - continue; - } - - foreach ($data->markets as $ticker) { - if ($ticker->marketname === $pair) { - - $market->marketid = $ticker->marketid; - - if ($market->disabled < 9) { - $nbm = (int) dboscalar("SELECT COUNT(id) FROM markets WHERE coinid={$coin->id} $sqlFilter"); - $market->disabled = (floatval($ticker->volume24h) <= 0.005) && $nbm > 1; // in btc - } - - if (!$market->disabled) { - $market->price = AverageIncrement($market->price, $ticker->bid); - $market->price2 = AverageIncrement($market->price2, $ticker->last_price); - $market->pricetime = time(); - $market->save(); - - if (empty($coin->price2) && strpos($pair,'BTC') !== false) { - $coin->price = $market->price; - $coin->price2 = $market->price2; - $coin->save(); - } - } - break; - } - } - - if(!empty(EXCH_NOVA_KEY)) - { - $last_checked = cache()->get($exchange.'-deposit_address-check-'.$symbol); - if(empty($market->deposit_address) && !$last_checked) - { - sleep(1); - $res = nova_api_user('getdepositaddress/'.$symbol); - if(objSafeVal($res,'status') == 'success') { - $addr = objSafeVal($res, 'address'); - if (!empty($addr)) { - $market->deposit_address = $addr; - // delimiter "::" for memo / payment id - $market->message = null; - debuglog("$exchange: deposit address for {$symbol} updated"); - $market->save(); - } else { - debuglog("$exchange: Failed to update $symbol deposit address, ".json_encode($res)); - } - } - cache()->set($exchange.'-deposit_address-check-'.$symbol, time(), 24*3600); - } - } - } + $exchange = 'nova'; + if (exchange_get($exchange, 'disabled')) return; + + $markets = getdbolist('db_markets', "name LIKE '$exchange%'"); // allow "nova LTC" + if (empty($markets)) return; + + $data = nova_api_query('markets'); + if (!is_object($data) || $data->status != 'success' || !is_array($data->markets)) return; + + foreach ($markets as $market) + { + $coin = getdbo('db_coins', $market->coinid); + if (!$coin) continue; + + $base = 'BTC'; + $symbol = $coin->getOfficialSymbol(); + $pair = $base . '_' . strtoupper($symbol); + + $sqlFilter = ''; + if (!empty($market->base_coin)) + { + $base = $market->base_coin; + $pair = strtoupper($market->base_coin . '_' . $symbol); + $sqlFilter = "AND base_coin='{$market->base_coin}'"; + } + + if (market_get($exchange, $symbol, "disabled", false, $base)) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + $market->save(); + continue; + } + + foreach ($data->markets as $ticker) + { + if ($ticker->marketname === $pair) + { + + $market->marketid = $ticker->marketid; + + if ($market->disabled < 9) + { + $nbm = (int)dboscalar("SELECT COUNT(id) FROM markets WHERE coinid={$coin->id} $sqlFilter"); + $market->disabled = (floatval($ticker->volume24h) <= 0.005) && $nbm > 1; // in btc + + } + + if (!$market->disabled) + { + $market->price = AverageIncrement($market->price, $ticker->bid); + $market->price2 = AverageIncrement($market->price2, $ticker->last_price); + $market->pricetime = time(); + $market->save(); + + if (empty($coin->price2) && strpos($pair, 'BTC') !== false) + { + $coin->price = $market->price; + $coin->price2 = $market->price2; + $coin->save(); + } + } + break; + } + } + + if (!empty(EXCH_NOVA_KEY)) + { + $last_checked = cache()->get($exchange . '-deposit_address-check-' . $symbol); + if (empty($market->deposit_address) && !$last_checked) + { + sleep(1); + $res = nova_api_user('getdepositaddress/' . $symbol); + if (objSafeVal($res, 'status') == 'success') + { + $addr = objSafeVal($res, 'address'); + if (!empty($addr)) + { + $market->deposit_address = $addr; + // delimiter "::" for memo / payment id + $market->message = null; + debuglog("$exchange: deposit address for {$symbol} updated"); + $market->save(); + } + else + { + debuglog("$exchange: Failed to update $symbol deposit address, " . json_encode($res)); + } + } + cache()->set($exchange . '-deposit_address-check-' . $symbol, time() , 24 * 3600); + } + } + } } function updateBinanceMarkets() { - $exchange = 'binance'; - if (exchange_get($exchange, 'disabled')) return; - - $list = getdbolist('db_markets', "name LIKE '$exchange%'"); - if (empty($list)) return; - - $tickers = binance_api_query('ticker/allBookTickers'); - if(!is_array($tickers)) return; - - foreach($list as $market) - { - $coin = getdbo('db_coins', $market->coinid); - if(!$coin) continue; - - $symbol = $coin->getOfficialSymbol(); - if (market_get($exchange, $symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - $market->save(); - continue; - } - - $pair = $symbol.'BTC'; - foreach ($tickers as $ticker) { - if ($pair != $ticker->symbol) continue; - - $price2 = ($ticker->bidPrice+$ticker->askPrice)/2; - $market->price = AverageIncrement($market->price, $ticker->bidPrice); - $market->price2 = AverageIncrement($market->price2, $price2); - $market->pricetime = time(); - if ($market->disabled < 9) $market->disabled = (floatval($ticker->bidQty) < 0.01); - $market->save(); - - if (empty($coin->price2)) { - $coin->price = $market->price; - $coin->price2 = $market->price2; - $coin->save(); - } - } - } -} - -function updateBterMarkets() -{ - $exchange = 'bter'; - if (exchange_get($exchange, 'disabled')) return; - - $list = getdbolist('db_markets', "name LIKE '$exchange%'"); - if (empty($list)) return; - - $markets = bter_api_query('tickers'); - if(!is_array($markets)) return; - - foreach($list as $market) - { - $coin = getdbo('db_coins', $market->coinid); - if(!$coin) continue; - - $symbol = $coin->getOfficialSymbol(); - if (market_get($exchange, $symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - $market->save(); - continue; - } - - $dbpair = strtolower($symbol).'_btc'; - foreach ($markets as $pair => $ticker) { - if ($pair != $dbpair) continue; - - $market->price = AverageIncrement($market->price, $ticker['buy']); - $market->price2 = AverageIncrement($market->price2, $ticker['avg']); - $market->pricetime = time(); - if ($market->disabled < 9) $market->disabled = (floatval($ticker['vol_btc']) < 0.01); - $market->save(); - - if (empty($coin->price2)) { - $coin->price = $market->price; - $coin->price2 = $market->price2; - $coin->save(); - } - } - } + $exchange = 'binance'; + if (exchange_get($exchange, 'disabled')) return; + + $list = getdbolist('db_markets', "name LIKE '$exchange%'"); + if (empty($list)) return; + + $tickers = binance_api_query('ticker/allBookTickers'); + if (!is_array($tickers)) return; + + foreach ($list as $market) + { + $coin = getdbo('db_coins', $market->coinid); + if (!$coin) continue; + + $symbol = $coin->getOfficialSymbol(); + if (market_get($exchange, $symbol, "disabled")) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + $market->save(); + continue; + } + + $pair = $symbol . 'BTC'; + foreach ($tickers as $ticker) + { + if ($pair != $ticker->symbol) continue; + + $price2 = ($ticker->bidPrice + $ticker->askPrice) / 2; + $market->price = AverageIncrement($market->price, $ticker->bidPrice); + $market->price2 = AverageIncrement($market->price2, $price2); + $market->pricetime = time(); + if ($market->disabled < 9) $market->disabled = (floatval($ticker->bidQty) < 0.01); + $market->save(); + + if (empty($coin->price2)) + { + $coin->price = $market->price; + $coin->price2 = $market->price2; + $coin->save(); + } + } + } } function updateEmpoexMarkets() { - $exchange = 'empoex'; - if (exchange_get($exchange, 'disabled')) return; - - $list = getdbolist('db_markets', "name LIKE '$exchange%'"); - if (empty($list)) return; - - $markets = empoex_api_query('marketinfo'); - if(!is_array($markets)) return; - - foreach($list as $market) - { - $coin = getdbo('db_coins', $market->coinid); - if(!$coin) continue; - - $symbol = $coin->getOfficialSymbol(); - if (market_get($exchange, $symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - $market->save(); - continue; - } - - $pair = strtoupper($symbol).'-BTC'; - - foreach ($markets as $ticker) { - if ($ticker->pairname != $pair) continue; - - $market->price = AverageIncrement($market->price, $ticker->bid); - $market->price2 = AverageIncrement($market->price2, $ticker->ask); - $market->pricetime = time(); - - if (floatval($ticker->base_volume_24hr) > 0.01) - $market->save(); - - if (empty($coin->price2)) { - $coin->price = $market->price; - $coin->price2 = $market->price2; - $coin->market = 'empoex'; - $coin->save(); - } - } - } + $exchange = 'empoex'; + if (exchange_get($exchange, 'disabled')) return; + + $list = getdbolist('db_markets', "name LIKE '$exchange%'"); + if (empty($list)) return; + + $markets = empoex_api_query('marketinfo'); + if (!is_array($markets)) return; + + foreach ($list as $market) + { + $coin = getdbo('db_coins', $market->coinid); + if (!$coin) continue; + + $symbol = $coin->getOfficialSymbol(); + if (market_get($exchange, $symbol, "disabled")) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + $market->save(); + continue; + } + + $pair = strtoupper($symbol) . '-BTC'; + + foreach ($markets as $ticker) + { + if ($ticker->pairname != $pair) continue; + + $market->price = AverageIncrement($market->price, $ticker->bid); + $market->price2 = AverageIncrement($market->price2, $ticker->ask); + $market->pricetime = time(); + + if (floatval($ticker->base_volume_24hr) > 0.01) $market->save(); + + if (empty($coin->price2)) + { + $coin->price = $market->price; + $coin->price2 = $market->price2; + $coin->market = 'empoex'; + $coin->save(); + } + } + } } function updateKuCoinMarkets() { - $exchange = 'kucoin'; - if (exchange_get($exchange, 'disabled')) return; - - $list = getdbolist('db_markets', "name LIKE '$exchange%'"); - if (empty($list)) return; - - $markets = kucoin_api_query('open/symbols','market=BTC'); - if(!kucoin_result_valid($markets) || empty($markets->data)) return; - - $coininfo = NULL; //kucoin_api_query('market/open/coins'); - if(!kucoin_result_valid($coininfo) || empty($coininfo->data)) { - $coininfo = NULL; - } - - foreach($list as $market) - { - $coin = getdbo('db_coins', $market->coinid); - if(!$coin) continue; - - $symbol = $coin->getOfficialSymbol(); - if (market_get($exchange, $symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - $market->save(); - continue; - } - - $pair = strtoupper($symbol).'-BTC'; - - foreach ($markets->data as $ticker) { - if ($ticker->symbol != $pair) continue; - if (objSafeVal($ticker,'buy',-1) == -1) continue; - - $market->price = AverageIncrement($market->price, $ticker->buy); - $market->price2 = AverageIncrement($market->price2, objSafeVal($ticker,'sell',$ticker->buy)); - if (!empty($coininfo)) foreach ($coininfo->data as $info) { - if ($info->coin == $symbol) { - //todo: $market->withdrawfee = $info->withdrawMinFee; - break; - } - } - $market->txfee = $ticker->feeRate * 100; // is 0.1% for trades (0.001) - $market->priority = -1; - $market->pricetime = time(); - - if (floatval($ticker->vol) > 0.01) - $market->save(); - - if (empty($coin->price2)) { - $coin->price = $market->price; - $coin->price2 = $market->price2; - $coin->save(); - } - } - } + $exchange = 'kucoin'; + if (exchange_get($exchange, 'disabled')) return; + + $list = getdbolist('db_markets', "name LIKE '$exchange%'"); + if (empty($list)) return; + + $symbols = kucoin_api_query('symbols', 'market=BTC'); + if (!kucoin_result_valid($symbols) || empty($symbols->data)) return; + + usleep(500); + $markets = kucoin_api_query('market/allTickers'); + if (!kucoin_result_valid($markets) || empty($markets->data)) return; + if (!isset($markets + ->data + ->ticker) || !is_array($markets + ->data + ->ticker)) return; + $tickers = $markets + ->data->ticker; + + foreach ($list as $market) + { + $coin = getdbo('db_coins', $market->coinid); + if (!$coin) continue; + + $symbol = $coin->getOfficialSymbol(); + if (market_get($exchange, $symbol, "disabled")) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + $market->save(); + continue; + } + + $pair = strtoupper($symbol) . '-BTC'; + + $enableTrading = false; + foreach ($symbols->data as $sym) + { + if (objSafeVal($sym, 'symbol') != $pair) continue; + $enableTrading = objSafeVal($sym, 'enableTrading', false); + break; + } + + if ($market->disabled == $enableTrading) + { + $market->disabled = (int)(!$enableTrading); + $market->save(); + if ($market->disabled) continue; + } + + foreach ($tickers as $ticker) + { + if ($ticker->symbol != $pair) continue; + if (objSafeVal($ticker, 'buy', -1) == - 1) continue; + + $market->price = AverageIncrement($market->price, $ticker->buy); + $market->price2 = AverageIncrement($market->price2, objSafeVal($ticker, 'sell', $ticker->buy)); + $market->priority = - 1; + $market->pricetime = time(); + + if (floatval($ticker->vol) > 0.01) $market->save(); + + if (empty($coin->price2)) + { + $coin->price = $market->price; + $coin->price2 = $market->price2; + $coin->save(); + } + } + } } function updateLiveCoinMarkets() { - $exchange = 'livecoin'; - if (exchange_get($exchange, 'disabled')) return; - - $list = getdbolist('db_markets', "name LIKE '$exchange%'"); - if (empty($list)) return; - - $markets = livecoin_api_query('exchange/ticker'); - if(!is_array($markets)) return; - - foreach($list as $market) - { - $coin = getdbo('db_coins', $market->coinid); - if(!$coin) continue; - - $symbol = $coin->getOfficialSymbol(); - if (market_get($exchange, $symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - $market->save(); - continue; - } - - $pair = strtoupper($symbol).'/BTC'; - - foreach ($markets as $ticker) { - if ($ticker->symbol != $pair) continue; - - $market->price = AverageIncrement($market->price, $ticker->best_bid); - $market->price2 = AverageIncrement($market->price2, $ticker->best_ask); - $market->txfee = 0.2; - $market->priority = 0; - $market->pricetime = time(); - - if (floatval($ticker->volume) > 0.01) - $market->save(); - - if (empty($coin->price2)) { - $coin->price = $market->price; - $coin->price2 = $market->price2; - $coin->save(); - } - - if(!empty(EXCH_LIVECOIN_KEY) && $market->disabled == 0) - { - $last_checked = cache()->get($exchange.'-deposit_address-check-'.$symbol); - if(empty($market->deposit_address) && !$last_checked) - { - sleep(1); - $livecoin = new LiveCoinApi(); - $data = $livecoin->getDepositAddress($symbol); - if(!empty($data) && objSafeVal($data, 'wallet', '') != '') { - $addr = arraySafeVal($data, 'wallet'); - if (!empty($addr)) { - $market->deposit_address = $addr; - // delimiter "::" for memo / payment id - $market->message = null; - debuglog("$exchange: deposit address for {$coin->symbol} updated"); - $market->save(); - } else { - debuglog("$exchange: Failed to update $symbol deposit address, ".json_decode($data)); - } - } - } - cache()->set($exchange.'-deposit_address-check-'.$symbol, time(), 24*3600); - } - } - } + $exchange = 'livecoin'; + if (exchange_get($exchange, 'disabled')) return; + + $list = getdbolist('db_markets', "name LIKE '$exchange%'"); + if (empty($list)) return; + + $markets = livecoin_api_query('exchange/ticker'); + if (!is_array($markets)) return; + + foreach ($list as $market) + { + $coin = getdbo('db_coins', $market->coinid); + if (!$coin) continue; + + $symbol = $coin->getOfficialSymbol(); + if (market_get($exchange, $symbol, "disabled")) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + $market->save(); + continue; + } + + $pair = strtoupper($symbol) . '/BTC'; + + foreach ($markets as $ticker) + { + if ($ticker->symbol != $pair) continue; + + $market->price = AverageIncrement($market->price, $ticker->best_bid); + $market->price2 = AverageIncrement($market->price2, $ticker->best_ask); + $market->txfee = 0.2; + $market->priority = 0; + $market->pricetime = time(); + + if (floatval($ticker->volume) > 0.01) $market->save(); + + if (empty($coin->price2)) + { + $coin->price = $market->price; + $coin->price2 = $market->price2; + $coin->save(); + } + + if (!empty(EXCH_LIVECOIN_KEY) && $market->disabled == 0) + { + $last_checked = cache()->get($exchange . '-deposit_address-check-' . $symbol); + if (empty($market->deposit_address) && !$last_checked) + { + sleep(1); + $livecoin = new LiveCoinApi(); + $data = $livecoin->getDepositAddress($symbol); + if (!empty($data) && objSafeVal($data, 'wallet', '') != '') + { + $addr = arraySafeVal($data, 'wallet'); + if (!empty($addr)) + { + $market->deposit_address = $addr; + // delimiter "::" for memo / payment id + $market->message = null; + debuglog("$exchange: deposit address for {$coin->symbol} updated"); + $market->save(); + } + else + { + debuglog("$exchange: Failed to update $symbol deposit address, " . json_decode($data)); + } + } + } + cache()->set($exchange . '-deposit_address-check-' . $symbol, time() , 24 * 3600); + } + } + } } function updateCoinExchangeMarkets() { - $exchange = 'coinexchange'; - if (exchange_get($exchange, 'disabled')) return; - - $count = (int) dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); - if ($count == 0) return; - - $list = coinexchange_api_query('getmarkets'); - if(!is_object($list)) return; - $markets = coinexchange_api_query('getmarketsummaries'); - if(!is_object($markets)) return; - foreach($list->result as $currency) - { - $symbol = objSafeVal($currency,'MarketAssetCode',''); - $exchid = objSafeVal($currency,'MarketID',0); - if(empty($symbol) || !$exchid || $symbol == 'BTC') continue; - - $coin = getdbosql('db_coins', "symbol=:sym", array(':sym'=>$symbol)); - if(!$coin) continue; - - $market = getdbosql('db_markets', "coinid={$coin->id} AND name='$exchange' AND IFNULL(base_coin,'') IN ('','BTC')"); - $base = objSafeVal($currency,'BaseCurrencyCode',''); - if ($base != 'BTC') { - $market = getdbosql('db_markets', "coinid={$coin->id} AND name='$exchange' AND base_coin=:base", array(':base'=>$base)); - } - if(!$market) continue; - - $symbol = $coin->getOfficialSymbol(); - if($market->disabled < 9) $market->disabled = !$currency->Active; - - if (market_get($exchange, $symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - $market->save(); - continue; - } - - if($currency->Active && $coin->enable) { - // check wallet status (deposit/withdrawals) - $status = coinexchange_api_query('getcurrency', 'ticker_code='.$symbol); - if(is_object($status) && is_object($status->result)) { - $res = $status->result; - if($market->disabled < 9) $market->disabled = (objSafeVal($res,'WalletStatus') == "offline"); - $market->message = $market->disabled ? $res->WalletStatus : ''; - //debuglog("$exchange: $symbol wallet is {$res->WalletStatus}"); - } - } - - $market->save(); - - if($market->disabled || $market->deleted) continue; - - foreach ($markets->result as $m) { - if ($m->MarketID == $exchid) { - $price2 = ((double) $m->BidPrice + (double) $m->AskPrice)/2; - $market->price2 = AverageIncrement($market->price2, $price2); - $market->price = AverageIncrement($market->price, (double) $m->BidPrice); - $market->pricetime = time(); - $market->marketid = $exchid; - $market->priority = -1; // not ready for trading - $market->save(); - //debuglog("$exchange: $symbol price set to ".bitcoinvaluetoa($market->price)); - if (empty($coin->price2)) { - $coin->price = $market->price; - $coin->price2 = $market->price2; - $coin->save(); - } - break; - } - } - } + $exchange = 'coinexchange'; + if (exchange_get($exchange, 'disabled')) return; + + $count = (int)dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); + if ($count == 0) return; + + $list = coinexchange_api_query('getmarkets'); + if (!is_object($list)) return; + $markets = coinexchange_api_query('getmarketsummaries'); + if (!is_object($markets)) return; + foreach ($list->result as $currency) + { + $symbol = objSafeVal($currency, 'MarketAssetCode', ''); + $exchid = objSafeVal($currency, 'MarketID', 0); + if (empty($symbol) || !$exchid || $symbol == 'BTC') continue; + + $coin = getdbosql('db_coins', "symbol=:sym", array( + ':sym' => $symbol + )); + if (!$coin) continue; + + $market = getdbosql('db_markets', "coinid={$coin->id} AND name='$exchange' AND IFNULL(base_coin,'') IN ('','BTC')"); + $base = objSafeVal($currency, 'BaseCurrencyCode', ''); + if ($base != 'BTC') + { + $market = getdbosql('db_markets', "coinid={$coin->id} AND name='$exchange' AND base_coin=:base", array( + ':base' => $base + )); + } + if (!$market) continue; + + $symbol = $coin->getOfficialSymbol(); + if ($market->disabled < 9) $market->disabled = !$currency->Active; + + if (market_get($exchange, $symbol, "disabled")) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + $market->save(); + continue; + } + + if ($currency->Active && $coin->enable) + { + // check wallet status (deposit/withdrawals) + $status = coinexchange_api_query('getcurrency', 'ticker_code=' . $symbol); + if (is_object($status) && is_object($status->result)) + { + $res = $status->result; + if ($market->disabled < 9) $market->disabled = (objSafeVal($res, 'WalletStatus') == "offline"); + $market->message = $market->disabled ? $res->WalletStatus : ''; + //debuglog("$exchange: $symbol wallet is {$res->WalletStatus}"); + + } + } + + $market->save(); + + if ($market->disabled || $market->deleted) continue; + + foreach ($markets->result as $m) + { + if ($m->MarketID == $exchid) + { + $price2 = ((double)$m->BidPrice + (double)$m->AskPrice) / 2; + $market->price2 = AverageIncrement($market->price2, $price2); + $market->price = AverageIncrement($market->price, (double)$m->BidPrice); + $market->pricetime = time(); + $market->marketid = $exchid; + $market->priority = - 1; // not ready for trading + $market->save(); + //debuglog("$exchange: $symbol price set to ".bitcoinvaluetoa($market->price)); + if (empty($coin->price2)) + { + $coin->price = $market->price; + $coin->price2 = $market->price2; + $coin->save(); + } + break; + } + } + } } function updateCoinsMarketsMarkets() { - $exchange = 'coinsmarkets'; - if (exchange_get($exchange, 'disabled')) return; - - $count = (int) dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); - if ($count == 0) return; - - $list = coinsmarkets_api_query('apicoin'); - if(empty($list) || !is_array($list)) return; - foreach($list as $pair=>$data) - { - $e = explode('_', $pair); - $base = $e[0]; $symbol = strtoupper($e[1]); - //if($pair == 'DOG_BTC') todo: handle reverted DOG_BTC - if($base != 'BTC') continue; - - $coin = getdbosql('db_coins', "symbol=:sym", array(':sym'=>$symbol)); - if(!$coin) continue; - - $market = getdbosql('db_markets', "coinid={$coin->id} AND name='$exchange' AND IFNULL(base_coin,'') IN ('','BTC')"); - if(!$market) continue; - - $symbol = $coin->getOfficialSymbol(); - if (market_get($exchange, $symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - $market->save(); - continue; - } - - $price2 = ((double)$data['lowestAsk'] + (double)$data['highestBid'])/2; - $market->price2 = AverageIncrement($market->price2, $price2); - $market->price = AverageIncrement($market->price, (double)$data['highestBid']); - $market->price = min($market->price, $market->price2); // reversed bid/ask ? - - $market->marketid = arraySafeVal($data,'id'); - $market->priority = -1; // not ready for trading - - if ($price2 < $market->price*2) { - // 24htrade field seems not filled in json - //if ($market->disabled == 1) $market->disabled = 0; - } else { - // reduce price2 - $market->price2 = AverageIncrement($market->price2, $market->price); - //if (!$market->disabled) $market->disabled = 1; - } - - //debuglog("$exchange: $symbol price set to ".bitcoinvaluetoa($market->price)); - $market->pricetime = time(); - $market->save(); - - if (empty($coin->price2)) { - $coin->price = $market->price; - $coin->price2 = $market->price2; - $coin->save(); - } - } + $exchange = 'coinsmarkets'; + if (exchange_get($exchange, 'disabled')) return; + + $count = (int)dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); + if ($count == 0) return; + + $list = coinsmarkets_api_query('apicoin'); + if (empty($list) || !is_array($list)) return; + foreach ($list as $pair => $data) + { + $e = explode('_', $pair); + $base = $e[0]; + $symbol = strtoupper($e[1]); + //if($pair == 'DOG_BTC') todo: handle reverted DOG_BTC + if ($base != 'BTC') continue; + + $coin = getdbosql('db_coins', "symbol=:sym", array( + ':sym' => $symbol + )); + if (!$coin) continue; + + $market = getdbosql('db_markets', "coinid={$coin->id} AND name='$exchange' AND IFNULL(base_coin,'') IN ('','BTC')"); + if (!$market) continue; + + $symbol = $coin->getOfficialSymbol(); + if (market_get($exchange, $symbol, "disabled")) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + $market->save(); + continue; + } + + $price2 = ((double)$data['lowestAsk'] + (double)$data['highestBid']) / 2; + $market->price2 = AverageIncrement($market->price2, $price2); + $market->price = AverageIncrement($market->price, (double)$data['highestBid']); + $market->price = min($market->price, $market->price2); // reversed bid/ask ? + $market->marketid = arraySafeVal($data, 'id'); + $market->priority = - 1; // not ready for trading + if ($price2 < $market->price * 2) + { + // 24htrade field seems not filled in json + //if ($market->disabled == 1) $market->disabled = 0; + + } + else + { + // reduce price2 + $market->price2 = AverageIncrement($market->price2, $market->price); + //if (!$market->disabled) $market->disabled = 1; + + } + + //debuglog("$exchange: $symbol price set to ".bitcoinvaluetoa($market->price)); + $market->pricetime = time(); + $market->save(); + + if (empty($coin->price2)) + { + $coin->price = $market->price; + $coin->price2 = $market->price2; + $coin->save(); + } + } } function updateStocksExchangeMarkets() { - $exchange = 'stocksexchange'; - if (exchange_get($exchange, 'disabled')) return; - - $count = (int) dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); - if ($count == 0) return; - - $list = stocksexchange_api_query('ticker'); - if(empty($list) || !is_array($list)) return; - foreach($list as $m) - { - $e = explode('_', $m->market_name); - $symbol = strtoupper($e[0]); $base = $e[1]; - if($base != 'BTC') continue; - - $coin = getdbosql('db_coins', "symbol=:sym", array(':sym'=>$symbol)); - if(!$coin) continue; - - $market = getdbosql('db_markets', "coinid={$coin->id} AND name='$exchange' AND IFNULL(base_coin,'') IN ('','BTC')"); - if(!$market) continue; - - $symbol = $coin->getOfficialSymbol(); - if (market_get($exchange, $symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - $market->save(); - continue; - } - - $market->disabled = ($m->bid == 0); - - $price2 = ((double)$m->ask + (double)$m->bid)/2; - $market->price2 = AverageIncrement($market->price2, $price2); - $market->price = AverageIncrement($market->price, (double)$m->bid); - $market->priority = -1; // not ready for trading - $market->txfee = $m->sell_fee_percent; - - //debuglog("$exchange: $symbol price set to ".bitcoinvaluetoa($market->price)); - $market->pricetime = time(); // $m->updated_time; - $market->save(); - - if (empty($coin->price2)) { - $coin->price = $market->price; - $coin->price2 = $market->price2; - $coin->save(); - } - } + $exchange = 'stocksexchange'; + if (exchange_get($exchange, 'disabled')) return; + + $count = (int)dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); + if ($count == 0) return; + + $list = stocksexchange_api_query('ticker'); + if (empty($list) || !is_array($list)) return; + foreach ($list as $m) + { + $e = explode('_', $m->market_name); + $symbol = strtoupper($e[0]); + $base = $e[1]; + if ($base != 'BTC') continue; + + $coin = getdbosql('db_coins', "symbol=:sym", array( + ':sym' => $symbol + )); + if (!$coin) continue; + + $market = getdbosql('db_markets', "coinid={$coin->id} AND name='$exchange' AND IFNULL(base_coin,'') IN ('','BTC')"); + if (!$market) continue; + + $symbol = $coin->getOfficialSymbol(); + if (market_get($exchange, $symbol, "disabled")) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + $market->save(); + continue; + } + + $market->disabled = ($m->bid == 0); + + $price2 = ((double)$m->ask + (double)$m->bid) / 2; + $market->price2 = AverageIncrement($market->price2, $price2); + $market->price = AverageIncrement($market->price, (double)$m->bid); + $market->priority = - 1; // not ready for trading + $market->txfee = $m->sell_fee_percent; + + //debuglog("$exchange: $symbol price set to ".bitcoinvaluetoa($market->price)); + $market->pricetime = time(); // $m->updated_time; + $market->save(); + + if (empty($coin->price2)) + { + $coin->price = $market->price; + $coin->price2 = $market->price2; + $coin->save(); + } + } } function updateTradeSatoshiMarkets() { - $exchange = 'tradesatoshi'; - if (exchange_get($exchange, 'disabled')) return; - - $count = (int) dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); - if ($count == 0) return; - - $data = tradesatoshi_api_query('getmarketsummaries'); - if(!is_object($data) || !$data->success || !is_array($data->result)) return; - foreach($data->result as $m) - { - $e = explode('_', $m->market); - $symbol = strtoupper($e[0]); $base = $e[1]; - if($base != 'BTC') continue; - - $coin = getdbosql('db_coins', "symbol=:sym", array(':sym'=>$symbol)); - if(!$coin) continue; - - $market = getdbosql('db_markets', "coinid={$coin->id} AND name='$exchange' AND IFNULL(base_coin,'') IN ('','BTC')"); - if(!$market) continue; - - $symbol = $coin->getOfficialSymbol(); - if (market_get($exchange, $symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - $market->save(); - continue; - } - - $market->disabled = ($m->openBuyOrders == 0); - - $price2 = ((double)$m->ask + (double)$m->bid)/2; - $market->price2 = AverageIncrement($market->price2, $price2); - $market->price = AverageIncrement($market->price, (double)$m->bid); - $market->priority = -1; // not ready for trading - - //debuglog("$exchange: $symbol price set to ".bitcoinvaluetoa($market->price)); - $market->pricetime = time(); - $market->save(); - - if (empty($coin->price2)) { - $coin->price = $market->price; - $coin->price2 = $market->price2; - $coin->save(); - } - } + $exchange = 'tradesatoshi'; + if (exchange_get($exchange, 'disabled')) return; + + $count = (int)dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); + if ($count == 0) return; + + $data = tradesatoshi_api_query('getmarketsummaries'); + if (!is_object($data) || !$data->success || !is_array($data->result)) return; + foreach ($data->result as $m) + { + $e = explode('_', $m->market); + $symbol = strtoupper($e[0]); + $base = $e[1]; + if ($base != 'BTC') continue; + + $coin = getdbosql('db_coins', "symbol=:sym", array( + ':sym' => $symbol + )); + if (!$coin) continue; + + $market = getdbosql('db_markets', "coinid={$coin->id} AND name='$exchange' AND IFNULL(base_coin,'') IN ('','BTC')"); + if (!$market) continue; + + $symbol = $coin->getOfficialSymbol(); + if (market_get($exchange, $symbol, "disabled")) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + $market->save(); + continue; + } + + $market->disabled = ($m->openBuyOrders == 0); + + $price2 = ((double)$m->ask + (double)$m->bid) / 2; + $market->price2 = AverageIncrement($market->price2, $price2); + $market->price = AverageIncrement($market->price, (double)$m->bid); + $market->priority = - 1; // not ready for trading + //debuglog("$exchange: $symbol price set to ".bitcoinvaluetoa($market->price)); + $market->pricetime = time(); + $market->save(); + + if (empty($coin->price2)) + { + $coin->price = $market->price; + $coin->price2 = $market->price2; + $coin->save(); + } + } } // todo: store min/max txs limits function updateShapeShiftMarkets() { - $exchange = 'shapeshift'; - if (exchange_get($exchange, 'disabled')) return; - - $list = getdbolist('db_markets', "name LIKE '$exchange%'"); - if (empty($list)) return; - - $markets = shapeshift_api_query('marketinfo'); - if(!is_array($markets) || empty($markets)) return; - - foreach($list as $market) - { - $coin = getdbo('db_coins', $market->coinid); - if(!$coin) continue; - - if (market_get($exchange, $coin->symbol, "disabled")) { - $market->disabled = 1; - $market->message = 'disabled from settings'; - $market->save(); - continue; - } - - $symbol = $coin->getOfficialSymbol(); - $pair = strtoupper($symbol).'_BTC'; - if (!empty($market->base_coin)) - $pair = strtoupper($symbol).'_'.strtoupper($market->base_coin); - - foreach ($markets as $ticker) { - if ($ticker['pair'] != $pair) continue; - - $market->price = AverageIncrement($market->price, $ticker['rate']); - $market->price2 = AverageIncrement($market->price2, $ticker['rate']); - $market->txfee = $ticker['minerFee'] * 100; - $market->pricetime = time(); - $market->priority = -1; // not ready for trading - $market->save(); - - if (empty($coin->price2)) { - $coin->price = $market->price; - $coin->price2 = $market->price2; - //$coin->market = 'shapeshift'; - $coin->save(); - } - } - } + $exchange = 'shapeshift'; + if (exchange_get($exchange, 'disabled')) return; + + $list = getdbolist('db_markets', "name LIKE '$exchange%'"); + if (empty($list)) return; + + $markets = shapeshift_api_query('marketinfo'); + if (!is_array($markets) || empty($markets)) return; + + foreach ($list as $market) + { + $coin = getdbo('db_coins', $market->coinid); + if (!$coin) continue; + + if (market_get($exchange, $coin->symbol, "disabled")) + { + $market->disabled = 1; + $market->message = 'disabled from settings'; + $market->save(); + continue; + } + + $symbol = $coin->getOfficialSymbol(); + $pair = strtoupper($symbol) . '_BTC'; + if (!empty($market->base_coin)) $pair = strtoupper($symbol) . '_' . strtoupper($market->base_coin); + + foreach ($markets as $ticker) + { + if ($ticker['pair'] != $pair) continue; + + $market->price = AverageIncrement($market->price, $ticker['rate']); + $market->price2 = AverageIncrement($market->price2, $ticker['rate']); + $market->txfee = $ticker['minerFee'] * 100; + $market->pricetime = time(); + $market->priority = - 1; // not ready for trading + $market->save(); + + if (empty($coin->price2)) + { + $coin->price = $market->price; + $coin->price2 = $market->price2; + //$coin->market = 'shapeshift'; + $coin->save(); + } + } + } } // update other installed coins price from cryptonator function updateOtherMarkets() { - $coins = getdbolist('db_coins', "installed AND IFNULL(price,0.0) = 0.0"); - foreach($coins as $coin) - { - $symbol = $coin->getOfficialSymbol(); - if (market_get("cryptonator", $coin->symbol, "disabled")) { - continue; - } - - $json = @ file_get_contents("https://www.cryptonator.com/api/full/".strtolower($symbol)."-btc"); - $object = json_decode($json); - if (empty($object)) continue; - - if (is_object($object) && isset($object->ticker)) { - $ticker = $object->ticker; - if ($ticker->target == 'BTC' && $ticker->volume > 1) { - $coin->price2 = $ticker->price; - $coin->price = AverageIncrement((float)$coin->price, (float)$coin->price2); - if ($coin->save()) { - debuglog("cryptonator: $symbol price set to ".bitcoinvaluetoa($coin->price)); - } - } - } - } + $coins = getdbolist('db_coins', "installed AND IFNULL(price,0.0) = 0.0"); + foreach ($coins as $coin) + { + $symbol = $coin->getOfficialSymbol(); + if (market_get("cryptonator", $coin->symbol, "disabled")) + { + continue; + } + + $json = @file_get_contents("https://www.cryptonator.com/api/full/" . strtolower($symbol) . "-btc"); + $object = json_decode($json); + if (empty($object)) continue; + + if (is_object($object) && isset($object->ticker)) + { + $ticker = $object->ticker; + if ($ticker->target == 'BTC' && $ticker->volume > 1) + { + $coin->price2 = $ticker->price; + $coin->price = AverageIncrement((float)$coin->price, (float)$coin->price2); + if ($coin->save()) + { + debuglog("cryptonator: $symbol price set to " . bitcoinvaluetoa($coin->price)); + } + } + } + } } diff --git a/web/yaamp/core/backend/notify.php b/web/yaamp/core/backend/notify.php index 5e6e4d305..2695497ff 100644 --- a/web/yaamp/core/backend/notify.php +++ b/web/yaamp/core/backend/notify.php @@ -1,143 +1,148 @@ with('coin')->findAll( - "enabled AND lastchecked <= {$since} ". - " AND (nc.installed OR nc.enable OR nc.watch)" - ); - - foreach($notifications as $rule) - { - $coin = $rule->coin; - - $condw = explode(" ", $rule->conditiontype); - $field = $condw[0]; - if (count($condw) < 2) { - debuglog("notify: invalid conditiontype for {coin->symbol}, need at least one space like 'price >'"); - continue; - } - $comp = $condw[1]; - - $triggered = false; - if (array_key_exists($field, $rule->coin->attributes)) { - $value = $rule->coin->attributes[$field]; - $valref = $rule->conditionvalue; - switch ($comp) { - case '<': - $triggered = $value < $valref; - break; - case '>': - $triggered = $value > $valref; - break; - case '<=': - $triggered = $value <= $valref; - break; - case '>=': - $triggered = $value >= $valref; - break; - case '=': - case '==': - $triggered = $value == $valref; - break; - } - } else { - debuglog("notify: invalid field '{$field}' in conditiontype for {$coin->symbol}!"); - continue; - } - - if ($triggered && $rule->lasttriggered == $rule->lastchecked) { - // already notified - $rule->lasttriggered = $time; - $rule->lastchecked = $time; - $rule->save(); - continue; - } else { - $rule->lasttriggered = $triggered ? $time : 0; - $rule->lastchecked = $time; - $rule->save(); - } - - if (!$triggered) continue; - - $value = bitcoinvaluetoa($value); - debuglog("trigger: {$coin->symbol} {$rule->notifytype} {$rule->conditiontype} {$rule->conditionvalue} ({$value})"); - - switch ($rule->notifytype) - { - case 'email': - $subject = "[{$coin->symbol}] Trigger {$rule->conditiontype} {$rule->conditionvalue} ({$value})"; - - $message = "Description: {$rule->description}\n\n"; - - $message .= "Field: {$field}\n"; - $message .= "Value: {$value} at ".strftime("%Y-%m-%d %T %z", $time)."\n"; - - // replace some possible vars in message (description) - $message = str_replace('$X', $value, $message); - $message = str_replace('$F', $field, $message); - $message = str_replace('$T', $rule->conditiontype, $message); - $message = str_replace('$V', $rule->conditionvalue, $message); - $message = str_replace('$N', $coin->name, $message); - $message = str_replace('$SYM', $coin->symbol, $message); - $message = str_replace('$S2', $coin->symbol2, $message); - $message = str_replace('$A', $coin->master_wallet, $message); - - $dest = YAAMP_ADMIN_EMAIL; - if (!empty($rule->notifycmd) && strstr($rule->notifycmd, "@")) { - $dest = $rule->notifycmd; - } - - $res = mail($dest, $subject, $message); - if (!$res) - debuglog("notify: {$coin->symbol} unable to send mail to {$dest}!"); - break; - - case 'rpc': - - $command = $rule->notifycmd; - - // replace some possible vars in user command - $command = str_replace('$X', $value, $command); - $command = str_replace('$F', $field, $command); - $command = str_replace('$T', $rule->conditiontype, $command); - $command = str_replace('$V', $rule->conditionvalue, $command); - $command = str_replace('$N', $coin->name, $command); - $command = str_replace('$SYM', $coin->symbol, $command); - $command = str_replace('$S2', $coin->symbol2, $command); - $command = str_replace('$A', $coin->master_wallet, $command); - - $remote = new WalletRPC($coin); - - $res = $remote->execute($command); - if ($res === false) - debuglog("trigger: {$coin->symbol} rpc error '{$command}' {$remote->error}"); - else - debuglog("trigger: {$coin->symbol} rpc -> $res"); - break; - - case 'system': - - $command = $rule->notifycmd; - - // replace some possible vars in user command - $command = str_replace('$X', $value, $command); - $command = str_replace('$F', $field, $command); - $command = str_replace('$T', $rule->conditiontype, $command); - $command = str_replace('$V', $rule->conditionvalue, $command); - $command = str_replace('$N', $coin->name, $command); - $command = str_replace('$SYM', $coin->symbol, $command); - $command = str_replace('$S2', $coin->symbol2, $command); - $command = str_replace('$A', $coin->master_wallet, $command); - - $res = system($command); - if ($res === false) - debuglog("trigger: {$coin->symbol} unable to execute '{$command}'!"); - break; - } - } -} + $time = time(); + $since = $time - (10 * 60); // for later cmdline check, cron doesn't need that + $search = new db_notifications; + $notifications = $search->with('coin') + ->findAll("enabled AND lastchecked <= {$since} " . " AND (nc.installed OR nc.enable OR nc.watch)"); + + foreach ($notifications as $rule) + { + $coin = $rule->coin; + + $condw = explode(" ", $rule->conditiontype); + $field = $condw[0]; + if (count($condw) < 2) + { + debuglog("notify: invalid conditiontype for {coin->symbol}, need at least one space like 'price >'"); + continue; + } + $comp = $condw[1]; + + $triggered = false; + if (array_key_exists($field, $rule + ->coin + ->attributes)) + { + $value = $rule + ->coin + ->attributes[$field]; + $valref = $rule->conditionvalue; + switch ($comp) + { + case '<': + $triggered = $value < $valref; + break; + case '>': + $triggered = $value > $valref; + break; + case '<=': + $triggered = $value <= $valref; + break; + case '>=': + $triggered = $value >= $valref; + break; + case '=': + case '==': + $triggered = $value == $valref; + break; + } + } + else + { + debuglog("notify: invalid field '{$field}' in conditiontype for {$coin->symbol}!"); + continue; + } + + if ($triggered && $rule->lasttriggered == $rule->lastchecked) + { + // already notified + $rule->lasttriggered = $time; + $rule->lastchecked = $time; + $rule->save(); + continue; + } + else + { + $rule->lasttriggered = $triggered ? $time : 0; + $rule->lastchecked = $time; + $rule->save(); + } + + if (!$triggered) continue; + + $value = bitcoinvaluetoa($value); + debuglog("trigger: {$coin->symbol} {$rule->notifytype} {$rule->conditiontype} {$rule->conditionvalue} ({$value})"); + + switch ($rule->notifytype) + { + case 'email': + $subject = "[{$coin->symbol}] Trigger {$rule->conditiontype} {$rule->conditionvalue} ({$value})"; + + $message = "Description: {$rule->description}\n\n"; + + $message .= "Field: {$field}\n"; + $message .= "Value: {$value} at " . strftime("%Y-%m-%d %T %z", $time) . "\n"; + + // replace some possible vars in message (description) + $message = str_replace('$X', $value, $message); + $message = str_replace('$F', $field, $message); + $message = str_replace('$T', $rule->conditiontype, $message); + $message = str_replace('$V', $rule->conditionvalue, $message); + $message = str_replace('$N', $coin->name, $message); + $message = str_replace('$SYM', $coin->symbol, $message); + $message = str_replace('$S2', $coin->symbol2, $message); + $message = str_replace('$A', $coin->master_wallet, $message); + + $dest = YAAMP_ADMIN_EMAIL; + if (!empty($rule->notifycmd) && strstr($rule->notifycmd, "@")) + { + $dest = $rule->notifycmd; + } + + $res = mail($dest, $subject, $message); + if (!$res) debuglog("notify: {$coin->symbol} unable to send mail to {$dest}!"); + break; + + case 'rpc': + + $command = $rule->notifycmd; + + // replace some possible vars in user command + $command = str_replace('$X', $value, $command); + $command = str_replace('$F', $field, $command); + $command = str_replace('$T', $rule->conditiontype, $command); + $command = str_replace('$V', $rule->conditionvalue, $command); + $command = str_replace('$N', $coin->name, $command); + $command = str_replace('$SYM', $coin->symbol, $command); + $command = str_replace('$S2', $coin->symbol2, $command); + $command = str_replace('$A', $coin->master_wallet, $command); + + $remote = new WalletRPC($coin); + + $res = $remote->execute($command); + if ($res === false) debuglog("trigger: {$coin->symbol} rpc error '{$command}' {$remote->error}"); + else debuglog("trigger: {$coin->symbol} rpc -> $res"); + break; + + case 'system': + + $command = $rule->notifycmd; + + // replace some possible vars in user command + $command = str_replace('$X', $value, $command); + $command = str_replace('$F', $field, $command); + $command = str_replace('$T', $rule->conditiontype, $command); + $command = str_replace('$V', $rule->conditionvalue, $command); + $command = str_replace('$N', $coin->name, $command); + $command = str_replace('$SYM', $coin->symbol, $command); + $command = str_replace('$S2', $coin->symbol2, $command); + $command = str_replace('$A', $coin->master_wallet, $command); + + $res = system($command); + if ($res === false) debuglog("trigger: {$coin->symbol} unable to execute '{$command}'!"); + break; + } + } + } diff --git a/web/yaamp/core/backend/payment.php b/web/yaamp/core/backend/payment.php index b3704ea95..2598bd6b3 100644 --- a/web/yaamp/core/backend/payment.php +++ b/web/yaamp/core/backend/payment.php @@ -2,326 +2,328 @@ function BackendPayments() { - // attempt to increase max execution time limit for the cron job - set_time_limit(300); + // attempt to increase max execution time limit for the cron job + set_time_limit(300); - $list = getdbolist('db_coins', "enable and id in (select distinct coinid from accounts)"); - foreach($list as $coin) - BackendCoinPayments($coin); + $list = getdbolist('db_coins', "enable and id in (select distinct coinid from accounts)"); + foreach ($list as $coin) + BackendCoinPayments($coin); - dborun("update accounts set balance=0 where coinid=0"); + dborun("update accounts set balance=0 where coinid=0"); } function BackendUserCancelFailedPayment($userid) { - $user = getdbo('db_accounts', intval($userid)); - if(!$user) return false; - - $amount_failed = 0.0; - $failed = getdbolist('db_payouts', "account_id=:uid AND IFNULL(tx,'') = ''", array(':uid'=>$user->id)); - if (!empty($failed)) { - foreach ($failed as $payout) { - $amount_failed += floatval($payout->amount); - $payout->delete(); - } - $user->balance += $amount_failed; - $user->save(); - return $amount_failed; - } - - return 0.0; + $user = getdbo('db_accounts', intval($userid)); + if (!$user) + return false; + + $amount_failed = 0.0; + $failed = getdbolist('db_payouts', "account_id=:uid AND IFNULL(tx,'') = ''", array( + ':uid' => $user->id + )); + if (!empty($failed)) { + foreach ($failed as $payout) { + $amount_failed += floatval($payout->amount); + $payout->delete(); + } + $user->balance += $amount_failed; + $user->save(); + return $amount_failed; + } + + return 0.0; } function BackendCoinPayments($coin) { -// debuglog("BackendCoinPayments $coin->symbol"); - $remote = new WalletRPC($coin); - - $info = $remote->getinfo(); - if(!$info) { - debuglog("payment: can't connect to {$coin->symbol} wallet"); - return; - } - - $txfee = floatval($coin->txfee); - $min_payout = max(floatval(YAAMP_PAYMENTS_MINI), floatval($coin->payout_min), $txfee); - - if(date("w", time()) == 0 && date("H", time()) > 18) { // sunday evening, minimum reduced - $min_payout = max($min_payout/10, $txfee); - if($coin->symbol == 'DCR') $min_payout = 0.01005; - } - - $users = getdbolist('db_accounts', "balance>$min_payout AND coinid={$coin->id} ORDER BY balance DESC"); - - // todo: enhance/detect payout_max from normal sendmany error - if($coin->symbol == 'BOD' || $coin->symbol == 'DIME' || $coin->symbol == 'BTCRY' || !empty($coin->payout_max)) - { - foreach($users as $user) - { - $user = getdbo('db_accounts', $user->id); - if(!$user) continue; - - $amount = $user->balance; - while($user->balance > $min_payout && $amount > $min_payout) - { - debuglog("$coin->symbol sendtoaddress $user->username $amount"); - $tx = $remote->sendtoaddress($user->username, round($amount, 8)); - if(!$tx) - { - $error = $remote->error; - debuglog("RPC $error, {$user->username}, $amount"); - if (stripos($error,'transaction too large') !== false || stripos($error,'invalid amount') !== false - || stripos($error,'insufficient funds') !== false || stripos($error,'transaction creation failed') !== false - ) { - $coin->payout_max = min((double) $amount, (double) $coin->payout_max); - $coin->save(); - $amount /= 2; - continue; - } - break; - } - - $payout = new db_payouts; - $payout->account_id = $user->id; - $payout->time = time(); - $payout->amount = bitcoinvaluetoa($amount); - $payout->fee = 0; - $payout->tx = $tx; - $payout->idcoin = $coin->id; - $payout->save(); - - $user->balance -= $amount; - $user->save(); - } - } - - debuglog("payment done"); - return; - } - - $total_to_pay = 0; - $addresses = array(); - - foreach($users as $user) - { - $total_to_pay += round($user->balance, 8); - $addresses[$user->username] = round($user->balance, 8); - // transaction xxx has too many sigops: 1035 > 1000 - if ($coin->symbol == 'DCR' && count($addresses) > 990) { - debuglog("payment: more than 990 {$coin->symbol} users to pay, limit to top balances..."); - break; - } - } - - if(!$total_to_pay) - { - // debuglog("nothing to pay"); - return; - } - - $coef = 1.0; - if($info['balance']-$txfee < $total_to_pay && $coin->symbol!='BTC') - { - $msg = "$coin->symbol: insufficient funds for payment {$info['balance']} < $total_to_pay!"; - debuglog($msg); - send_email_alert('payouts', "$coin->symbol payout problem detected", $msg); - - $coef = 0.5; // so pay half for now... - $total_to_pay = $total_to_pay * $coef; - foreach ($addresses as $key => $val) { - $addresses[$key] = $val * $coef; - } - // still not possible, skip payment - if ($info['balance']-$txfee < $total_to_pay) - return; - } - - if($coin->symbol=='BTC') - { - global $cold_wallet_table; - - $balance = $info['balance']; - $stats = getdbosql('db_stats', "1 order by time desc"); - - $renter = dboscalar("select sum(balance) from renters"); - $pie = $balance - $total_to_pay - $renter - 1; - - debuglog("pie to split is $pie"); - if($pie>0) - { - foreach($cold_wallet_table as $coldwallet=>$percent) - { - $coldamount = round($pie * $percent, 8); - if($coldamount < $min_payout) break; - - debuglog("paying cold wallet $coldwallet $coldamount"); - - $addresses[$coldwallet] = $coldamount; - $total_to_pay += $coldamount; - } - } - } - - debuglog("paying $total_to_pay {$coin->symbol}"); - - $payouts = array(); - foreach($users as $user) - { - $user = getdbo('db_accounts', $user->id); - if(!$user) continue; - if(!isset($addresses[$user->username])) continue; - - $payment_amount = bitcoinvaluetoa($addresses[$user->username]); - - $payout = new db_payouts; - $payout->account_id = $user->id; - $payout->time = time(); - $payout->amount = $payment_amount; - $payout->fee = 0; - $payout->idcoin = $coin->id; - - if ($payout->save()) { - $payouts[$payout->id] = $user->id; - - $user->balance = bitcoinvaluetoa(floatval($user->balance) - $payment_amount); - $user->save(); - } - } - - // sometimes the wallet take too much time to answer, so use tx field to double check - set_time_limit(120); - - // default account - $account = $coin->account; - - if (!$coin->txmessage) - $tx = $remote->sendmany($account, $addresses); - else - $tx = $remote->sendmany($account, $addresses, 1, YAAMP_SITE_NAME); - - $errmsg = NULL; - if(!$tx) { - debuglog("sendmany: unable to send $total_to_pay {$remote->error} ".json_encode($addresses)); - $errmsg = $remote->error; - } - else if(!is_string($tx)) { - debuglog("sendmany: result is not a string tx=".json_encode($tx)); - $errmsg = json_encode($tx); - } - - // save processed payouts (tx) - foreach($payouts as $id => $uid) { - $payout = getdbo('db_payouts', $id); - if ($payout && $payout->id == $id) { - $payout->errmsg = $errmsg; - if (empty($errmsg)) { - $payout->tx = $tx; - $payout->completed = 1; - } - $payout->save(); - } else { - debuglog("payout $id for $uid not found!"); - } - } - - if (!empty($errmsg)) { - return; - } - - debuglog("{$coin->symbol} payment done"); - - sleep(2); - - // Search for previous payouts not executed (no tx) - $addresses = array(); $payouts = array(); - $mailmsg = ''; $mailwarn = ''; - foreach($users as $user) - { - $amount_failed = 0.0; - $failed = getdbolist('db_payouts', "account_id=:uid AND IFNULL(tx,'') = '' ORDER BY time", array(':uid'=>$user->id)); - if (!empty($failed)) { - if ($coin->symbol == 'CHC') { - // tx made but payment rpc timed out - foreach ($failed as $payout) $amount_failed += floatval($payout->amount); - $notice = "payment: Found buggy payout without tx for {$user->username}!! $amount_failed {$coin->symbol}"; - debuglog($notice); - $mailwarn .= "$notice\r\n"; - continue; - } - foreach ($failed as $payout) { - $amount_failed += floatval($payout->amount); - $payout->delete(); - } - if ($amount_failed > 0.0) { - debuglog("Found failed payment(s) for {$user->username}, $amount_failed {$coin->symbol}!"); - if ($coin->rpcencoding == 'DCR') { - $data = $remote->validateaddress($user->username); - if (!$data['isvalid']) { - debuglog("Found bad address {$user->username}!! ($amount_failed {$coin->symbol})"); - $user->is_locked = 1; - $user->save(); - continue; - } - } - $payout = new db_payouts; - $payout->account_id = $user->id; - $payout->time = time(); - $payout->amount = $amount_failed; - $payout->fee = 0; - $payout->idcoin = $coin->id; - if ($payout->save() && $amount_failed > $min_payout) { - $payouts[$payout->id] = $user->id; - $addresses[$user->username] = $amount_failed; - $mailmsg .= "{$amount_failed} {$coin->symbol} to {$user->username} - user id {$user->id}\n"; - } - } - } - } - - if (!empty($mailwarn)) { - send_email_alert('payouts', "{$coin->symbol} payout tx problems to check", - "$mailwarn\r\nCheck your wallet recent transactions to know if the payment was made, the RPC call timed out." - ); - } - - // redo failed payouts - if (!empty($addresses)) - { - if (!$coin->txmessage) - $tx = $remote->sendmany($account, $addresses); - else - $tx = $remote->sendmany($account, $addresses, 1, YAAMP_SITE_NAME." retry"); - - if(empty($tx)) { - debuglog($remote->error); - - foreach ($payouts as $id => $uid) { - $payout = getdbo('db_payouts', $id); - if ($payout && $payout->id == $id) { - $payout->errmsg = $remote->error; - $payout->save(); - } - } - - send_email_alert('payouts', "{$coin->symbol} payout problems detected\n {$remote->error}", $mailmsg); - - } else { - - foreach ($payouts as $id => $uid) { - $payout = getdbo('db_payouts', $id); - if ($payout && $payout->id == $id) { - $payout->tx = $tx; - $payout->save(); - } else { - debuglog("payout retry $id for $uid not found!"); - } - } - - $mailmsg .= "\ntxid $tx\n"; - send_email_alert('payouts', "{$coin->symbol} payout problems resolved", $mailmsg); - } - } + // debuglog("BackendCoinPayments $coin->symbol"); + $remote = new WalletRPC($coin); + + $info = $remote->getinfo(); + if (!$info) { + debuglog("payment: can't connect to {$coin->symbol} wallet"); + return; + } + + $txfee = floatval($coin->txfee); + $min_payout = max(floatval(YAAMP_PAYMENTS_MINI), floatval($coin->payout_min), $txfee); + + if (date("w", time()) == 0 && date("H", time()) > 18) { // sunday evening, minimum reduced + $min_payout = max($min_payout / 10, $txfee); + if ($coin->symbol == 'DCR') + $min_payout = 0.01005; + } + + $users = getdbolist('db_accounts', "balance>$min_payout AND coinid={$coin->id} ORDER BY balance DESC"); + + // todo: enhance/detect payout_max from normal sendmany error + if ($coin->symbol == 'BOD' || $coin->symbol == 'DIME' || $coin->symbol == 'BTCRY' || !empty($coin->payout_max)) { + foreach ($users as $user) { + $user = getdbo('db_accounts', $user->id); + if (!$user) + continue; + + $amount = $user->balance; + while ($user->balance > $min_payout && $amount > $min_payout) { + debuglog("$coin->symbol sendtoaddress $user->username $amount"); + if ($coin->symbol == 'MBC') + $tx = $remote->sendtoaddress($user->username, round($amount, 4)); + else + $tx = $remote->sendtoaddress($user->username, round($amount, 6)); + if (!$tx) { + $error = $remote->error; + debuglog("RPC $error, {$user->username}, $amount"); + if (stripos($error, 'transaction too large') !== false || stripos($error, 'invalid amount') !== false || stripos($error, 'insufficient funds') !== false || stripos($error, 'transaction creation failed') !== false) { + $coin->payout_max = min((double) $amount, (double) $coin->payout_max); + $coin->save(); + $amount /= 2; + continue; + } + break; + } + + $payout = new db_payouts; + $payout->account_id = $user->id; + $payout->time = time(); + $payout->amount = bitcoinvaluetoa($amount); + $payout->fee = 0; + $payout->tx = $tx; + $payout->idcoin = $coin->id; + $payout->save(); + + $user->balance -= $amount; + $user->save(); + } + } + + debuglog("payment done"); + return; + } + + $total_to_pay = 0; + $addresses = array(); + + + if ($coin->symbol == 'MBC') + foreach ($users as $user) { + $total_to_pay -= round($user->balance, 4); + $addresses[$user->username] = round($user->balance, 4); + } else + foreach ($users as $user) { + $total_to_pay += round($user->balance, 6); + $addresses[$user->username] = round($user->balance, 6); + // transaction xxx has too many sigops: 1035 > 1000 + if ($coin->symbol == 'DCR' && count($addresses) > 990) { + debuglog("payment: more than 990 {$coin->symbol} users to pay, limit to top balances..."); + break; + } + } + + if (!$total_to_pay) { + // debuglog("nothing to pay"); + return; + } + + $coef = 1.0; + if ($info['balance'] - $txfee < $total_to_pay && $coin->symbol != 'BTC') { + $msg = "$coin->symbol: insufficient funds for payment {$info['balance']} < $total_to_pay!"; + debuglog($msg); + send_email_alert('payouts', "$coin->symbol payout problem detected", $msg); + + $coef = 0.5; // so pay half for now... + $total_to_pay = $total_to_pay * $coef; + foreach ($addresses as $key => $val) { + $addresses[$key] = $val * $coef; + } + // still not possible, skip payment + if ($info['balance'] - $txfee < $total_to_pay) + return; + } + + if ($coin->symbol == 'BTC') { + global $cold_wallet_table; + + $balance = $info['balance']; + $stats = getdbosql('db_stats', "1 order by time desc"); + + $renter = dboscalar("select sum(balance) from renters"); + $pie = $balance - $total_to_pay - $renter - 1; + + debuglog("pie to split is $pie"); + if ($pie > 0) { + foreach ($cold_wallet_table as $coldwallet => $percent) { + $coldamount = round($pie * $percent, 6); + if ($coldamount < $min_payout) + break; + + debuglog("paying cold wallet $coldwallet $coldamount"); + + $addresses[$coldwallet] = $coldamount; + $total_to_pay += $coldamount; + } + } + } + + debuglog("paying $total_to_pay {$coin->symbol}"); + + $payouts = array(); + foreach ($users as $user) { + $user = getdbo('db_accounts', $user->id); + if (!$user) + continue; + if (!isset($addresses[$user->username])) + continue; + + $payment_amount = bitcoinvaluetoa($addresses[$user->username]); + + $payout = new db_payouts; + $payout->account_id = $user->id; + $payout->time = time(); + $payout->amount = $payment_amount; + $payout->fee = 0; + $payout->idcoin = $coin->id; + + if ($payout->save()) { + $payouts[$payout->id] = $user->id; + + $user->balance = bitcoinvaluetoa(floatval($user->balance) - $payment_amount); + $user->save(); + } + } + + // sometimes the wallet take too much time to answer, so use tx field to double check + set_time_limit(120); + + // default account + $account = $coin->account; + + if (!$coin->txmessage) + $tx = $remote->sendmany($account, $addresses); + else + $tx = $remote->sendmany($account, $addresses, 1, YAAMP_SITE_NAME); + + $errmsg = NULL; + if (!$tx) { + debuglog("sendmany: unable to send $total_to_pay {$remote->error} " . json_encode($addresses)); + $errmsg = $remote->error; + } else if (!is_string($tx)) { + debuglog("sendmany: result is not a string tx=" . json_encode($tx)); + $errmsg = json_encode($tx); + } + + // save processed payouts (tx) + foreach ($payouts as $id => $uid) { + $payout = getdbo('db_payouts', $id); + if ($payout && $payout->id == $id) { + $payout->errmsg = $errmsg; + if (empty($errmsg)) { + $payout->tx = $tx; + $payout->completed = 1; + } + $payout->save(); + } else { + debuglog("payout $id for $uid not found!"); + } + } + + if (!empty($errmsg)) { + return; + } + + debuglog("{$coin->symbol} payment done"); + + sleep(2); + + // Search for previous payouts not executed (no tx) + $addresses = array(); + $payouts = array(); + $mailmsg = ''; + $mailwarn = ''; + foreach ($users as $user) { + $amount_failed = 0.0; + $failed = getdbolist('db_payouts', "account_id=:uid AND IFNULL(tx,'') = '' ORDER BY time", array( + ':uid' => $user->id + )); + if (!empty($failed)) { + if ($coin->symbol == 'CHC') { + // tx made but payment rpc timed out + foreach ($failed as $payout) + $amount_failed += floatval($payout->amount); + $notice = "payment: Found buggy payout without tx for {$user->username}!! $amount_failed {$coin->symbol}"; + debuglog($notice); + $mailwarn .= "$notice\r\n"; + continue; + } + foreach ($failed as $payout) { + $amount_failed += floatval($payout->amount); + $payout->delete(); + } + if ($amount_failed > 0.0) { + debuglog("Found failed payment(s) for {$user->username}, $amount_failed {$coin->symbol}!"); + if ($coin->rpcencoding == 'DCR') { + $data = $remote->validateaddress($user->username); + if (!$data['isvalid']) { + debuglog("Found bad address {$user->username}!! ($amount_failed {$coin->symbol})"); + $user->is_locked = 1; + $user->save(); + continue; + } + } + $payout = new db_payouts; + $payout->account_id = $user->id; + $payout->time = time(); + $payout->amount = $amount_failed; + $payout->fee = 0; + $payout->idcoin = $coin->id; + if ($payout->save() && $amount_failed > $min_payout) { + $payouts[$payout->id] = $user->id; + $addresses[$user->username] = $amount_failed; + $mailmsg .= "{$amount_failed} {$coin->symbol} to {$user->username} - user id {$user->id}\n"; + } + } + } + } + + if (!empty($mailwarn)) { + send_email_alert('payouts', "{$coin->symbol} payout tx problems to check", "$mailwarn\r\nCheck your wallet recent transactions to know if the payment was made, the RPC call timed out."); + } + + // redo failed payouts + if (!empty($addresses)) { + if (!$coin->txmessage) + $tx = $remote->sendmany($account, $addresses); + else + $tx = $remote->sendmany($account, $addresses, 1, YAAMP_SITE_NAME . " retry"); + + if (empty($tx)) { + debuglog($remote->error); + + foreach ($payouts as $id => $uid) { + $payout = getdbo('db_payouts', $id); + if ($payout && $payout->id == $id) { + $payout->errmsg = $remote->error; + $payout->save(); + } + } + + send_email_alert('payouts', "{$coin->symbol} payout problems detected\n {$remote->error}", $mailmsg); + + } else { + + foreach ($payouts as $id => $uid) { + $payout = getdbo('db_payouts', $id); + if ($payout && $payout->id == $id) { + $payout->tx = $tx; + $payout->save(); + } else { + debuglog("payout retry $id for $uid not found!"); + } + } + + $mailmsg .= "\ntxid $tx\n"; + send_email_alert('payouts', "{$coin->symbol} payout problems resolved", $mailmsg); + } + } } - - diff --git a/web/yaamp/core/backend/rawcoins.php b/web/yaamp/core/backend/rawcoins.php index 8a289b249..a8c62dd8f 100644 --- a/web/yaamp/core/backend/rawcoins.php +++ b/web/yaamp/core/backend/rawcoins.php @@ -5,525 +5,515 @@ */ function updateRawcoins() { -// debuglog(__FUNCTION__); - - exchange_set_default('alcurex', 'disabled', true); - exchange_set_default('binance', 'disabled', true); - exchange_set_default('bter', 'disabled', true); - exchange_set_default('empoex', 'disabled', true); - exchange_set_default('coinbene', 'disabled', true); - exchange_set_default('coinexchange', 'disabled', true); - exchange_set_default('coinsmarkets', 'disabled', true); - exchange_set_default('escodex', 'disabled', true); - exchange_set_default('gateio', 'disabled', true); - exchange_set_default('jubi', 'disabled', true); - exchange_set_default('nova', 'disabled', true); - exchange_set_default('stocksexchange', 'disabled', true); - exchange_set_default('tradesatoshi', 'disabled', true); - - settings_prefetch_all(); - - if (!exchange_get('bittrex', 'disabled')) { - $list = bittrex_api_query('public/getcurrencies'); - if(isset($list->result) && !empty($list->result)) - { - dborun("UPDATE markets SET deleted=true WHERE name='bittrex'"); - foreach($list->result as $currency) { - if ($currency->Currency == 'BTC') { - exchange_set('bittrex', 'withdraw_fee_btc', $currency->TxFee); - continue; - } - updateRawCoin('bittrex', $currency->Currency, $currency->CurrencyLong); - } - } - } - - if (!exchange_get('bitz', 'disabled')) { - $list = bitz_api_query('tickerall'); - if (!empty($list)) { - dborun("UPDATE markets SET deleted=true WHERE name='bitz'"); - foreach($list as $c => $ticker) { - $e = explode('_', $c); - if (strtoupper($e[1]) !== 'BTC') - continue; - $symbol = strtoupper($e[0]); - updateRawCoin('bitz', $symbol); - } - } - } - - if (!exchange_get('bleutrade', 'disabled')) { - $list = bleutrade_api_query('public/getcurrencies'); - if(isset($list->result) && !empty($list->result)) - { - dborun("UPDATE markets SET deleted=true WHERE name='bleutrade'"); - foreach($list->result as $currency) { - if ($currency->Currency == 'BTC') { - exchange_set('bleutrade', 'withdraw_fee_btc', $currency->TxFee); - continue; - } - updateRawCoin('bleutrade', $currency->Currency, $currency->CurrencyLong); - } - } - } - - if (!exchange_get('coinbene', 'disabled')) { - $data = coinbene_api_query('market/symbol'); - $list = objSafeVal($data, 'symbol'); - if(is_array($list) && !empty($list)) { - dborun("UPDATE markets SET deleted=true WHERE name='coinbene'"); - foreach($list as $ticker) { - if ($ticker->quoteAsset != 'BTC') continue; - $symbol = $ticker->baseAsset; - updateRawCoin('coinbene', $symbol); - } - } - } - - if (!exchange_get('crex24', 'disabled')) { - $list = crex24_api_query('currencies'); - if(is_array($list) && !empty($list)) { - dborun("UPDATE markets SET deleted=true WHERE name='crex24'"); - foreach ($list as $currency) { - $symbol = objSafeVal($currency, 'symbol'); - $name = objSafeVal($currency, 'name'); - if ($currency->isFiat || $currency->isDelisted) continue; - updateRawCoin('crex24', $symbol, $name); - } - } - } - - if (!exchange_get('poloniex', 'disabled')) { - $poloniex = new poloniex; - $tickers = $poloniex->get_currencies(); - if (!$tickers) - $tickers = array(); - else - dborun("UPDATE markets SET deleted=true WHERE name='poloniex'"); - foreach($tickers as $symbol=>$ticker) - { - if(arraySafeVal($ticker,'disabled')) continue; - if(arraySafeVal($ticker,'delisted')) continue; - updateRawCoin('poloniex', $symbol); - } - } - - if (!exchange_get('c-cex', 'disabled')) { - $ccex = new CcexAPI; - $list = $ccex->getPairs(); - if($list) - { - sleep(1); - $names = $ccex->getCoinNames(); - - dborun("UPDATE markets SET deleted=true WHERE name='c-cex'"); - foreach($list as $item) - { - $e = explode('-', $item); - $symbol = strtoupper($e[0]); - - updateRawCoin('c-cex', $symbol, arraySafeVal($names, $e[0], 'unknown')); - } - } - } - - if (!exchange_get('bter', 'disabled')) { - $list = bter_api_query('marketlist'); - if(is_object($list) && is_array($list->data)) - { - dborun("UPDATE markets SET deleted=true WHERE name='bter'"); - foreach($list->data as $item) { - if (strtoupper($item->curr_b) !== 'BTC') - continue; - if (strpos($item->name, 'Asset') !== false) - continue; - if (strpos($item->name, 'BitShares') !== false && $item->symbol != 'BTS') - continue; - // ignore some dead coins and assets - if (in_array($item->symbol, array('BITGLD','DICE','ROX','TOKEN'))) - continue; - updateRawCoin('bter', $item->symbol, $item->name); - } - } - } - - if (!exchange_get('yobit', 'disabled')) { - $res = yobit_api_query('info'); - if($res) - { - dborun("UPDATE markets SET deleted=true WHERE name='yobit'"); - foreach($res->pairs as $i=>$item) - { - $e = explode('_', $i); - $symbol = strtoupper($e[0]); - updateRawCoin('yobit', $symbol); - } - } - } - - if (!exchange_get('coinexchange', 'disabled')) { - $list = coinexchange_api_query('getmarkets'); - if(isset($list->result) && !empty($list->result)) - { - dborun("UPDATE markets SET deleted=true WHERE name='coinexchange'"); - foreach($list->result as $item) { - if ($item->BaseCurrencyCode != 'BTC') - continue; - $symbol = $item->MarketAssetCode; - $label = objSafeVal($item, 'MarketAssetName'); - updateRawCoin('coinexchange', $symbol, $label); - } - } - } - - if (!exchange_get('coinsmarkets', 'disabled')) { - $list = coinsmarkets_api_query('apicoin'); - if(!empty($list) && is_array($list)) - { - dborun("UPDATE markets SET deleted=true WHERE name='coinsmarkets'"); - foreach($list as $pair=>$data) { - $e = explode('_', $pair); - if ($e[0] != 'BTC') continue; - $symbol = strtoupper($e[1]); - updateRawCoin('coinsmarkets', $symbol); - } - } - } - - if (!exchange_get('cryptopia', 'disabled')) { - $list = cryptopia_api_query('GetMarkets'); - if(isset($list->Data)) - { - dborun("UPDATE markets SET deleted=true WHERE name='cryptopia'"); - foreach($list->Data as $item) { - $e = explode('/', $item->Label); - if (strtoupper($e[1]) !== 'BTC') - continue; - $symbol = strtoupper($e[0]); - updateRawCoin('cryptopia', $symbol); - } - } - } - - if (!exchange_get('cryptobridge', 'disabled')) { - $list = cryptobridge_api_query('ticker'); - if(is_array($list) && !empty($list)) - { - dborun("UPDATE markets SET deleted=true WHERE name='cryptobridge'"); - foreach($list as $ticker) { - $e = explode('_', $ticker->id); - if (strtoupper($e[1]) !== 'BTC') - continue; - $symbol = strtoupper($e[0]); - updateRawCoin('cryptobridge', $symbol); - } - } - } - - if (!exchange_get('escodex', 'disabled')) { - $list = escodex_api_query('ticker'); - if(is_array($list) && !empty($list)) - { - dborun("UPDATE markets SET deleted=true WHERE name='escodex'"); - foreach($list as $ticker) { - #debuglog (json_encode($ticker)); - if (strtoupper($ticker->base) !== 'BTC') - continue; - $symbol = strtoupper($ticker->quote); - updateRawCoin('escodex', $symbol); - } - } - } - - if (!exchange_get('hitbtc', 'disabled')) { - $list = hitbtc_api_query('symbols'); - if(is_object($list) && isset($list->symbols) && is_array($list->symbols)) - { - dborun("UPDATE markets SET deleted=true WHERE name='hitbtc'"); - foreach($list->symbols as $data) { - $base = strtoupper($data->currency); - if ($base != 'BTC') continue; - $symbol = strtoupper($data->commodity); - updateRawCoin('hitbtc', $symbol); - } - } - } - - if (!exchange_get('kraken', 'disabled')) { - $list = kraken_api_query('AssetPairs'); - if(is_array($list)) - { - dborun("UPDATE markets SET deleted=true WHERE name='kraken'"); - foreach($list as $pair => $item) { - $pairs = explode('-', $pair); - $base = reset($pairs); $symbol = end($pairs); - if($symbol == 'BTC' || $base != 'BTC') continue; - if(in_array($symbol, array('GBP','CAD','EUR','USD','JPY'))) continue; - if(strpos($symbol,'.d') !== false) continue; - $symbol = strtoupper($symbol); - updateRawCoin('kraken', $symbol); - } - } - } - - if (!exchange_get('alcurex', 'disabled')) { - $list = alcurex_api_query('market','?info=on'); - if(is_object($list) && isset($list->MARKETS)) - { - dborun("UPDATE markets SET deleted=true WHERE name='alcurex'"); - foreach($list->MARKETS as $item) { - $e = explode('_', $item->Pair); - $symbol = strtoupper($e[0]); - updateRawCoin('alcurex', $symbol); - } - } - } - - if (!exchange_get('binance', 'disabled')) { - $list = binance_api_query('ticker/allBookTickers'); - if(is_array($list)) - { - dborun("UPDATE markets SET deleted=true WHERE name='binance'"); - foreach($list as $ticker) { - $base = substr($ticker->symbol, -3, 3); - // XXXBTC XXXETH BTCUSDT (no separator!) - if ($base != 'BTC') continue; - $symbol = substr($ticker->symbol, 0, strlen($ticker->symbol)-3); - updateRawCoin('binance', $symbol); - } - } - } - - if (!exchange_get('gateio', 'disabled')) { - $json = gateio_api_query('marketlist'); - $list = arraySafeVal($json,'data'); - if(!empty($list)) - { - dborun("UPDATE markets SET deleted=true WHERE name='gateio'"); - foreach($list as $item) { - if ($item['curr_b'] != 'BTC') - continue; - $symbol = trim(strtoupper($item['symbol'])); - $name = trim($item['name']); - updateRawCoin('gateio', $symbol, $name); - } - } - } - - if (!exchange_get('nova', 'disabled')) { - $list = nova_api_query('markets'); - if(is_object($list) && !empty($list->markets)) - { - dborun("UPDATE markets SET deleted=true WHERE name='nova'"); - foreach($list->markets as $item) { - if ($item->basecurrency != 'BTC') - continue; - $symbol = strtoupper($item->currency); - updateRawCoin('nova', $symbol); - //debuglog("nova: $symbol"); - } - } - } - - if (!exchange_get('stocksexchange', 'disabled')) { - $list = stocksexchange_api_query('markets'); - if(is_array($list)) - { - dborun("UPDATE markets SET deleted=true WHERE name='stocksexchange'"); - foreach($list as $item) { - if ($item->partner != 'BTC') - continue; - if ($item->active == false) - continue; - $symbol = strtoupper($item->currency); - $name = trim($item->currency_long); - updateRawCoin('stocksexchange', $symbol, $name); - } - } - } - - if (!exchange_get('empoex', 'disabled')) { - $list = empoex_api_query('marketinfo'); - if(is_array($list)) - { - dborun("UPDATE markets SET deleted=true WHERE name='empoex'"); - foreach($list as $item) { - $e = explode('-', $item->pairname); - $base = strtoupper($e[1]); - if ($base != 'BTC') - continue; - $symbol = strtoupper($e[0]); - updateRawCoin('empoex', $symbol); - } - } - } - - if (!exchange_get('kucoin', 'disabled')) { - $list = kucoin_api_query('market/open/coins'); - if(is_object($list) && isset($list->data) && !empty($list->data)) - { - dborun("UPDATE markets SET deleted=true WHERE name='kucoin'"); - foreach($list->data as $item) { - $symbol = $item->coin; - $name = $item->name; - if (strpos($item->withdrawRemark,'Ethereum')) continue; - updateRawCoin('kucoin', $symbol, $name); - } - } - } - - if (!exchange_get('livecoin', 'disabled')) { - $list = livecoin_api_query('exchange/ticker'); - if(is_array($list)) - { - dborun("UPDATE markets SET deleted=true WHERE name='livecoin'"); - foreach($list as $item) { - $e = explode('/', $item->symbol); - $base = strtoupper($e[1]); - if ($base != 'BTC') - continue; - $symbol = strtoupper($e[0]); - updateRawCoin('livecoin', $symbol); - } - } - } - - if (!exchange_get('shapeshift', 'disabled')) { - $list = shapeshift_api_query('getcoins'); - if(is_array($list) && !empty($list)) - { - dborun("UPDATE markets SET deleted=true WHERE name='shapeshift'"); - foreach($list as $item) { - $status = $item['status']; - if ($status != 'available') continue; - $symbol = strtoupper($item['symbol']); - $name = trim($item['name']); - updateRawCoin('shapeshift', $symbol, $name); - //debuglog("shapeshift: $symbol $name"); - } - } - } - - if (!exchange_get('tradesatoshi', 'disabled')) { - $data = tradesatoshi_api_query('getcurrencies'); - if(is_object($data) && !empty($data->result)) - { - dborun("UPDATE markets SET deleted=true WHERE name='tradesatoshi'"); - foreach($data->result as $item) { - $symbol = $item->currency; - $name = trim($item->currencyLong); - updateRawCoin('tradesatoshi', $symbol, $name); - } - } - } - - ////////////////////////////////////////////////////////// - - $markets = dbocolumn("SELECT DISTINCT name FROM markets"); - foreach ($markets as $exchange) { - if (exchange_get($exchange, 'disabled')) { - $res = dborun("UPDATE markets SET disabled=8 WHERE name='$exchange'"); - if(!$res) continue; - $coins = getdbolist('db_coins', "id IN (SELECT coinid FROM markets WHERE name='$exchange')"); - foreach($coins as $coin) { - // allow to track a single market on a disabled exchange (dev test) - if (market_get($exchange, $coin->getOfficialSymbol(), 'disabled', 1) == 0) { - $res -= dborun("UPDATE markets SET disabled=0 WHERE name='$exchange' AND coinid={$coin->id}"); - } - } - debuglog("$exchange: $res markets disabled from db settings"); - } else { - $res = dborun("UPDATE markets SET disabled=0 WHERE name='$exchange' AND disabled=8"); - if($res) debuglog("$exchange: $res markets re-enabled from db settings"); - } - } - - dborun("DELETE FROM markets WHERE deleted"); - - $list = getdbolist('db_coins', "not enable and not installed and id not in (select distinct coinid from markets)"); - foreach($list as $coin) - { - if ($coin->visible) - debuglog("{$coin->symbol} is no longer active"); - // todo: proper cleanup in all tables (like "yiimp coin SYM delete") - // if ($coin->symbol != 'BTC') - // $coin->delete(); - } + // debuglog(__FUNCTION__); + + exchange_set_default('alcurex', 'disabled', true); + exchange_set_default('binance', 'disabled', true); + exchange_set_default('empoex', 'disabled', true); + exchange_set_default('coinbene', 'disabled', true); + exchange_set_default('coinexchange', 'disabled', true); + exchange_set_default('coinsmarkets', 'disabled', true); + exchange_set_default('escodex', 'disabled', true); + exchange_set_default('gateio', 'disabled', true); + exchange_set_default('jubi', 'disabled', true); + exchange_set_default('nova', 'disabled', true); + exchange_set_default('stocksexchange', 'disabled', true); + exchange_set_default('tradesatoshi', 'disabled', true); + + settings_prefetch_all(); + + if (!exchange_get('bittrex', 'disabled')) { + $list = bittrex_api_query('public/getcurrencies'); + if (isset($list->result) && !empty($list->result)) { + dborun("UPDATE markets SET deleted=true WHERE name='bittrex'"); + foreach ($list->result as $currency) { + if ($currency->Currency == 'BTC') { + exchange_set('bittrex', 'withdraw_fee_btc', $currency->TxFee); + continue; + } + updateRawCoin('bittrex', $currency->Currency, $currency->CurrencyLong); + } + } + } + + if (!exchange_get('bitz', 'disabled')) { + $list = bitz_api_query('tickerall'); + if (!empty($list)) { + dborun("UPDATE markets SET deleted=true WHERE name='bitz'"); + foreach ($list as $c => $ticker) { + $e = explode('_', $c); + if (strtoupper($e[1]) !== 'BTC') + continue; + $symbol = strtoupper($e[0]); + updateRawCoin('bitz', $symbol); + } + } + } + + if (!exchange_get('bleutrade', 'disabled')) { + $list = bleutrade_api_query('public/getcurrencies'); + if (isset($list->result) && !empty($list->result)) { + dborun("UPDATE markets SET deleted=true WHERE name='bleutrade'"); + foreach ($list->result as $currency) { + if ($currency->Currency == 'BTC') { + exchange_set('bleutrade', 'withdraw_fee_btc', $currency->TxFee); + continue; + } + updateRawCoin('bleutrade', $currency->Currency, $currency->CurrencyLong); + } + } + } + + if (!exchange_get('coinbene', 'disabled')) { + $data = coinbene_api_query('market/symbol'); + $list = objSafeVal($data, 'symbol'); + if (is_array($list) && !empty($list)) { + dborun("UPDATE markets SET deleted=true WHERE name='coinbene'"); + foreach ($list as $ticker) { + if ($ticker->quoteAsset != 'BTC') + continue; + $symbol = $ticker->baseAsset; + updateRawCoin('coinbene', $symbol); + } + } + } + + if (!exchange_get('crex24', 'disabled')) { + $list = crex24_api_query('currencies'); + if (is_array($list) && !empty($list)) { + dborun("UPDATE markets SET deleted=true WHERE name='crex24'"); + foreach ($list as $currency) { + $symbol = objSafeVal($currency, 'symbol'); + $name = objSafeVal($currency, 'name'); + if ($currency->isFiat || $currency->isDelisted) + continue; + updateRawCoin('crex24', $symbol, $name); + } + } + } + + if (!exchange_get('poloniex', 'disabled')) { + $poloniex = new poloniex; + $tickers = $poloniex->get_currencies(); + if (!$tickers) + $tickers = array(); + else + dborun("UPDATE markets SET deleted=true WHERE name='poloniex'"); + foreach ($tickers as $symbol => $ticker) { + if (arraySafeVal($ticker, 'disabled')) + continue; + if (arraySafeVal($ticker, 'delisted')) + continue; + updateRawCoin('poloniex', $symbol); + } + } + + if (!exchange_get('c-cex', 'disabled')) { + $ccex = new CcexAPI; + $list = $ccex->getPairs(); + if ($list) { + sleep(1); + $names = $ccex->getCoinNames(); + + dborun("UPDATE markets SET deleted=true WHERE name='c-cex'"); + foreach ($list as $item) { + $e = explode('-', $item); + $symbol = strtoupper($e[0]); + + updateRawCoin('c-cex', $symbol, arraySafeVal($names, $e[0], 'unknown')); + } + } + } + + if (!exchange_get('yobit', 'disabled')) { + $res = yobit_api_query('info'); + if ($res) { + dborun("UPDATE markets SET deleted=true WHERE name='yobit'"); + foreach ($res->pairs as $i => $item) { + $e = explode('_', $i); + $symbol = strtoupper($e[0]); + updateRawCoin('yobit', $symbol); + } + } + } + + if (!exchange_get('coinexchange', 'disabled')) { + $list = coinexchange_api_query('getmarkets'); + if (isset($list->result) && !empty($list->result)) { + dborun("UPDATE markets SET deleted=true WHERE name='coinexchange'"); + foreach ($list->result as $item) { + if ($item->BaseCurrencyCode != 'BTC') + continue; + $symbol = $item->MarketAssetCode; + $label = objSafeVal($item, 'MarketAssetName'); + updateRawCoin('coinexchange', $symbol, $label); + } + } + } + + if (!exchange_get('coinsmarkets', 'disabled')) { + $list = coinsmarkets_api_query('apicoin'); + if (!empty($list) && is_array($list)) { + dborun("UPDATE markets SET deleted=true WHERE name='coinsmarkets'"); + foreach ($list as $pair => $data) { + $e = explode('_', $pair); + if ($e[0] != 'BTC') + continue; + $symbol = strtoupper($e[1]); + updateRawCoin('coinsmarkets', $symbol); + } + } + } + + if (!exchange_get('cryptopia', 'disabled')) { + $list = cryptopia_api_query('GetMarkets'); + if (isset($list->Data)) { + dborun("UPDATE markets SET deleted=true WHERE name='cryptopia'"); + foreach ($list->Data as $item) { + $e = explode('/', $item->Label); + if (strtoupper($e[1]) !== 'BTC') + continue; + $symbol = strtoupper($e[0]); + updateRawCoin('cryptopia', $symbol); + } + } + } + + if (!exchange_get('cryptobridge', 'disabled')) { + $list = cryptobridge_api_query('ticker'); + if (is_array($list) && !empty($list)) { + dborun("UPDATE markets SET deleted=true WHERE name='cryptobridge'"); + foreach ($list as $ticker) { + $e = explode('_', $ticker->id); + if (strtoupper($e[1]) !== 'BTC') + continue; + $symbol = strtoupper($e[0]); + updateRawCoin('cryptobridge', $symbol); + } + } + } + + if (!exchange_get('escodex', 'disabled')) { + $list = escodex_api_query('ticker'); + if (is_array($list) && !empty($list)) { + dborun("UPDATE markets SET deleted=true WHERE name='escodex'"); + foreach ($list as $ticker) { + #debuglog (json_encode($ticker)); + if (strtoupper($ticker->base) !== 'BTC') + continue; + $symbol = strtoupper($ticker->quote); + updateRawCoin('escodex', $symbol); + } + } + } + + if (!exchange_get('hitbtc', 'disabled')) { + $list = hitbtc_api_query('symbols'); + if (is_object($list) && isset($list->symbols) && is_array($list->symbols)) { + dborun("UPDATE markets SET deleted=true WHERE name='hitbtc'"); + foreach ($list->symbols as $data) { + $base = strtoupper($data->currency); + if ($base != 'BTC') + continue; + $symbol = strtoupper($data->commodity); + updateRawCoin('hitbtc', $symbol); + } + } + } + + if (!exchange_get('kraken', 'disabled')) { + $list = kraken_api_query('AssetPairs'); + if (is_array($list)) { + dborun("UPDATE markets SET deleted=true WHERE name='kraken'"); + foreach ($list as $pair => $item) { + $pairs = explode('-', $pair); + $base = reset($pairs); + $symbol = end($pairs); + if ($symbol == 'BTC' || $base != 'BTC') + continue; + if (in_array($symbol, array( + 'GBP', + 'CAD', + 'EUR', + 'USD', + 'JPY' + ))) + continue; + if (strpos($symbol, '.d') !== false) + continue; + $symbol = strtoupper($symbol); + updateRawCoin('kraken', $symbol); + } + } + } + + if (!exchange_get('alcurex', 'disabled')) { + $list = alcurex_api_query('market', '?info=on'); + if (is_object($list) && isset($list->MARKETS)) { + dborun("UPDATE markets SET deleted=true WHERE name='alcurex'"); + foreach ($list->MARKETS as $item) { + $e = explode('_', $item->Pair); + $symbol = strtoupper($e[0]); + updateRawCoin('alcurex', $symbol); + } + } + } + + if (!exchange_get('binance', 'disabled')) { + $list = binance_api_query('ticker/allBookTickers'); + if (is_array($list)) { + dborun("UPDATE markets SET deleted=true WHERE name='binance'"); + foreach ($list as $ticker) { + $base = substr($ticker->symbol, -3, 3); + // XXXBTC XXXETH BTCUSDT (no separator!) + if ($base != 'BTC') + continue; + $symbol = substr($ticker->symbol, 0, strlen($ticker->symbol) - 3); + updateRawCoin('binance', $symbol); + } + } + } + + if (!exchange_get('gateio', 'disabled')) { + $json = gateio_api_query('marketlist'); + $list = arraySafeVal($json, 'data'); + if (!empty($list)) { + dborun("UPDATE markets SET deleted=true WHERE name='gateio'"); + foreach ($list as $item) { + if ($item['curr_b'] != 'BTC') + continue; + $symbol = trim(strtoupper($item['symbol'])); + $name = trim($item['name']); + updateRawCoin('gateio', $symbol, $name); + } + } + } + + if (!exchange_get('nova', 'disabled')) { + $list = nova_api_query('markets'); + if (is_object($list) && !empty($list->markets)) { + dborun("UPDATE markets SET deleted=true WHERE name='nova'"); + foreach ($list->markets as $item) { + if ($item->basecurrency != 'BTC') + continue; + $symbol = strtoupper($item->currency); + updateRawCoin('nova', $symbol); + //debuglog("nova: $symbol"); + } + } + } + + if (!exchange_get('stocksexchange', 'disabled')) { + $list = stocksexchange_api_query('markets'); + if (is_array($list)) { + dborun("UPDATE markets SET deleted=true WHERE name='stocksexchange'"); + foreach ($list as $item) { + if ($item->partner != 'BTC') + continue; + if ($item->active == false) + continue; + $symbol = strtoupper($item->currency); + $name = trim($item->currency_long); + updateRawCoin('stocksexchange', $symbol, $name); + } + } + } + + if (!exchange_get('empoex', 'disabled')) { + $list = empoex_api_query('marketinfo'); + if (is_array($list)) { + dborun("UPDATE markets SET deleted=true WHERE name='empoex'"); + foreach ($list as $item) { + $e = explode('-', $item->pairname); + $base = strtoupper($e[1]); + if ($base != 'BTC') + continue; + $symbol = strtoupper($e[0]); + updateRawCoin('empoex', $symbol); + } + } + } + + if (!exchange_get('kucoin', 'disabled')) { + $list = kucoin_api_query('currencies'); + if (kucoin_result_valid($list) && !empty($list->data)) { + dborun("UPDATE markets SET deleted=true WHERE name='kucoin'"); + foreach ($list->data as $item) { + $symbol = $item->name; + $name = $item->fullName; + updateRawCoin('kucoin', $symbol, $name); + } + } + } + + if (!exchange_get('livecoin', 'disabled')) { + $list = livecoin_api_query('exchange/ticker'); + if (is_array($list)) { + dborun("UPDATE markets SET deleted=true WHERE name='livecoin'"); + foreach ($list as $item) { + $e = explode('/', $item->symbol); + $base = strtoupper($e[1]); + if ($base != 'BTC') + continue; + $symbol = strtoupper($e[0]); + updateRawCoin('livecoin', $symbol); + } + } + } + + if (!exchange_get('shapeshift', 'disabled')) { + $list = shapeshift_api_query('getcoins'); + if (is_array($list) && !empty($list)) { + dborun("UPDATE markets SET deleted=true WHERE name='shapeshift'"); + foreach ($list as $item) { + $status = $item['status']; + if ($status != 'available') + continue; + $symbol = strtoupper($item['symbol']); + $name = trim($item['name']); + updateRawCoin('shapeshift', $symbol, $name); + //debuglog("shapeshift: $symbol $name"); + } + } + } + + if (!exchange_get('tradesatoshi', 'disabled')) { + $data = tradesatoshi_api_query('getcurrencies'); + if (is_object($data) && !empty($data->result)) { + dborun("UPDATE markets SET deleted=true WHERE name='tradesatoshi'"); + foreach ($data->result as $item) { + $symbol = $item->currency; + $name = trim($item->currencyLong); + updateRawCoin('tradesatoshi', $symbol, $name); + } + } + } + + ////////////////////////////////////////////////////////// + + $markets = dbocolumn("SELECT DISTINCT name FROM markets"); + foreach ($markets as $exchange) { + if (exchange_get($exchange, 'disabled')) { + $res = dborun("UPDATE markets SET disabled=8 WHERE name='$exchange'"); + if (!$res) + continue; + $coins = getdbolist('db_coins', "id IN (SELECT coinid FROM markets WHERE name='$exchange')"); + foreach ($coins as $coin) { + // allow to track a single market on a disabled exchange (dev test) + if (market_get($exchange, $coin->getOfficialSymbol(), 'disabled', 1) == 0) { + $res -= dborun("UPDATE markets SET disabled=0 WHERE name='$exchange' AND coinid={$coin->id}"); + } + } + debuglog("$exchange: $res markets disabled from db settings"); + } else { + $res = dborun("UPDATE markets SET disabled=0 WHERE name='$exchange' AND disabled=8"); + if ($res) + debuglog("$exchange: $res markets re-enabled from db settings"); + } + } + + dborun("DELETE FROM markets WHERE deleted"); + + $list = getdbolist('db_coins', "not enable and not installed and id not in (select distinct coinid from markets)"); + foreach ($list as $coin) { + if ($coin->visible) + debuglog("{$coin->symbol} is no longer active"); + // todo: proper cleanup in all tables (like "yiimp coin SYM delete") + // if ($coin->symbol != 'BTC') + // $coin->delete(); + } } -function updateRawCoin($marketname, $symbol, $name='unknown') +function updateRawCoin($marketname, $symbol, $name = 'unknown') { - if($symbol == 'BTC') return; - - $coin = getdbosql('db_coins', "symbol=:symbol", array(':symbol'=>$symbol)); - if(!$coin && YAAMP_CREATE_NEW_COINS) - { - $algo = ''; - if ($marketname == 'cryptopia') { - // get coin label and algo (different api) - $labels = cryptopia_api_query('GetCurrencies'); - if (is_object($labels) && !empty($labels->Data)) { - foreach ($labels->Data as $coin) { - if ($coin->Symbol == $symbol) { - $name = $coin->Name; - $algo = strtolower($coin->Algorithm); - if ($algo == 'scrypt') $algo = ''; // cryptopia default generally wrong - break; - } - } - } - } - - if (in_array($marketname, array('nova','askcoin','binance','bitz','coinexchange','coinsmarkets','cryptobridge','hitbtc'))) { - // don't polute too much the db with new coins, its better from exchanges with labels - return; - } - - // some other to ignore... - if (in_array($marketname, array('crex24','escodex','yobit','coinbene','kucoin','tradesatoshi'))) - return; - - if (market_get($marketname, $symbol, "disabled")) { - return; - } - - debuglog("new coin $marketname $symbol $name"); - - $coin = new db_coins; - $coin->txmessage = true; - $coin->hassubmitblock = true; - $coin->name = $name; - $coin->algo = $algo; - $coin->symbol = $symbol; - $coin->created = time(); - $coin->save(); - - $url = getMarketUrl($coin, $marketname); - if (YAAMP_NOTIFY_NEW_COINS) - mail(YAAMP_ADMIN_EMAIL, "New coin $symbol", "new coin $symbol ($name) on $marketname\r\n\r\n$url"); - sleep(30); - } - - else if($coin && $coin->name == 'unknown' && $name != 'unknown') - { - $coin->name = $name; - $coin->save(); - } - - $list = getdbolist('db_coins', "symbol=:symbol or symbol2=:symbol", array(':symbol'=>$symbol)); - foreach($list as $coin) - { - $market = getdbosql('db_markets', "coinid=$coin->id and name='$marketname'"); - if(!$market) - { - $market = new db_markets; - $market->coinid = $coin->id; - $market->name = $marketname; - } - - $market->deleted = false; - $market->save(); - } + if ($symbol == 'BTC') + return; + + $coin = getdbosql('db_coins', "symbol=:symbol", array( + ':symbol' => $symbol + )); + if (!$coin && YAAMP_CREATE_NEW_COINS) { + $algo = ''; + if ($marketname == 'cryptopia') { + // get coin label and algo (different api) + $labels = cryptopia_api_query('GetCurrencies'); + if (is_object($labels) && !empty($labels->Data)) { + foreach ($labels->Data as $coin) { + if ($coin->Symbol == $symbol) { + $name = $coin->Name; + $algo = strtolower($coin->Algorithm); + if ($algo == 'scrypt') + $algo = ''; // cryptopia default generally wrong + break; + } + } + } + } + + if (in_array($marketname, array( + 'nova', + 'askcoin', + 'binance', + 'bitz', + 'coinexchange', + 'coinsmarkets', + 'cryptobridge', + 'hitbtc' + ))) { + // don't polute too much the db with new coins, its better from exchanges with labels + return; + } + + // some other to ignore... + if (in_array($marketname, array( + 'crex24', + 'escodex', + 'yobit', + 'coinbene', + 'kucoin', + 'tradesatoshi' + ))) + return; + + if (market_get($marketname, $symbol, "disabled")) { + return; + } + + debuglog("new coin $marketname $symbol $name"); + + $coin = new db_coins; + $coin->txmessage = true; + $coin->hassubmitblock = true; + $coin->name = $name; + $coin->algo = $algo; + $coin->symbol = $symbol; + $coin->created = time(); + $coin->save(); + + $url = getMarketUrl($coin, $marketname); + if (YAAMP_NOTIFY_NEW_COINS) + mail(YAAMP_ADMIN_EMAIL, "New coin $symbol", "new coin $symbol ($name) on $marketname\r\n\r\n$url"); + sleep(30); + } + + else if ($coin && $coin->name == 'unknown' && $name != 'unknown') { + $coin->name = $name; + $coin->save(); + } + + $list = getdbolist('db_coins', "symbol=:symbol or symbol2=:symbol", array( + ':symbol' => $symbol + )); + foreach ($list as $coin) { + $market = getdbosql('db_markets', "coinid=$coin->id and name='$marketname'"); + if (!$market) { + $market = new db_markets; + $market->coinid = $coin->id; + $market->name = $marketname; + } + + $market->deleted = false; + $market->save(); + } } - diff --git a/web/yaamp/core/backend/renting.php b/web/yaamp/core/backend/renting.php index a17ea016f..423cf914d 100644 --- a/web/yaamp/core/backend/renting.php +++ b/web/yaamp/core/backend/renting.php @@ -2,275 +2,296 @@ function BackendRentingUpdate() { -// debuglog(__FUNCTION__); - if(!YAAMP_RENTAL) - { - dborun("update jobs set active=false, ready=false"); - return; - } - - dborun("update jobs set active=false where not ready"); - foreach(yaamp_get_algos() as $algo) - { - $rent = dboscalar("select rent from hashrate where algo=:algo order by time desc limit 1", array(':algo'=>$algo)); - - dborun("update jobs set active=true where ready and price>$rent and algo=:algo", array(':algo'=>$algo)); - dborun("update jobs set active=false where active and price<$rent and algo=:algo", array(':algo'=>$algo)); - } - - $list = getdbolist('db_jobsubmits', "status=0"); - foreach($list as $submit) - { - $rent = dboscalar("select rent from hashrate where algo=:algo order by time desc limit 1", array(':algo'=>$submit->algo)); - $amount = $rent * $submit->difficulty / 20116.56761169; - - $factor = yaamp_algo_mBTC_factor($submit->algo); // 1000 for sha256 - $amount /= $factor; - - $submit->amount = $amount - $amount*YAAMP_FEES_RENTING/100; - $submit->status = 1; - $submit->save(); - - $job = getdbo('db_jobs', $submit->jobid); - if(!$job) - { - $submit->delete(); - continue; - } - - $renter = getdbo('db_renters', $job->renterid); - if(!$renter) - { - $job->delete(); - $submit->delete(); - continue; - } - - $renter->balance -= $amount; - $renter->spent += $amount; - - if($renter->balance <= 0.00001000) - { - debuglog("resetting balance to 0, $renter->balance, $renter->id, $renter->address"); - $renter->balance = 0; - dborun("update jobs set active=false, ready=false where renterid=$renter->id"); - } - - $renter->updated = time(); - $renter->save(); - } - -// debuglog(__FUNCTION__); + // debuglog(__FUNCTION__); + if (!YAAMP_RENTAL) { + dborun("update jobs set active=false, ready=false"); + return; + } + + dborun("update jobs set active=false where not ready"); + foreach (yaamp_get_algos() as $algo) { + $rent = dboscalar("select rent from hashrate where algo=:algo order by time desc limit 1", array( + ':algo' => $algo + )); + + dborun("update jobs set active=true where ready and price>$rent and algo=:algo", array( + ':algo' => $algo + )); + dborun("update jobs set active=false where active and price<$rent and algo=:algo", array( + ':algo' => $algo + )); + } + + $list = getdbolist('db_jobsubmits', "status=0"); + foreach ($list as $submit) { + $rent = dboscalar("select rent from hashrate where algo=:algo order by time desc limit 1", array( + ':algo' => $submit->algo + )); + $amount = $rent * $submit->difficulty / 20116.56761169; + + $factor = yaamp_algo_mBTC_factor($submit->algo); // 1000 for sha256 + $amount /= $factor; + + $submit->amount = $amount - $amount * YAAMP_FEES_RENTING / 100; + $submit->status = 1; + $submit->save(); + + $job = getdbo('db_jobs', $submit->jobid); + if (!$job) { + $submit->delete(); + continue; + } + + $renter = getdbo('db_renters', $job->renterid); + if (!$renter) { + $job->delete(); + $submit->delete(); + continue; + } + + $renter->balance -= $amount; + $renter->spent += $amount; + + if ($renter->balance <= 0.00001000) { + debuglog("resetting balance to 0, $renter->balance, $renter->id, $renter->address"); + $renter->balance = 0; + dborun("update jobs set active=false, ready=false where renterid=$renter->id"); + } + + $renter->updated = time(); + $renter->save(); + } + + // debuglog(__FUNCTION__); } ////////////////////////////////////////////////////////////////////////////////////////////////////////// function BackendRentingPayout() { -// debuglog(__FUNCTION__); - - $total_cleared = 0; - foreach(yaamp_get_algos() as $algo) - { - $delay = time() - 5*60; - dborun("delete from jobsubmits where status=2 and algo=:algo and time<$delay", array(':algo'=>$algo)); - - $amount = dboscalar("select sum(amount) from jobsubmits where status=1 and algo=:algo", array(':algo'=>$algo)); - if($amount < 0.00002000) continue; - - dborun("update jobsubmits set status=2 where status=1 and algo=:algo", array(':algo'=>$algo)); - $total_cleared += $amount; - - $block = new db_blocks; - $block->coin_id = 0; - $block->time = time(); - $block->amount = $amount; - $block->price = 1; - $block->algo = $algo; - $block->category = 'generate'; - $block->save(); - - $total_hash_power = dboscalar("SELECT sum(difficulty) FROM shares where valid and algo=:algo", array(':algo'=>$algo)); - if(!$total_hash_power) continue; - - $list = dbolist("SELECT userid, sum(difficulty) as total FROM shares where valid and algo=:algo GROUP BY userid", array(':algo'=>$algo)); - foreach($list as $item) - { - $hash_power = $item['total']; - if(!$hash_power) continue; - - $user = getdbo('db_accounts', $item['userid']); - if(!$user) continue; - - $earning = new db_earnings; - $earning->userid = $user->id; - $earning->coinid = 0; - $earning->blockid = $block->id; - $earning->create_time = time(); - $earning->price = 1; - $earning->status = 2; // cleared - - $earning->amount = $amount * $hash_power / $total_hash_power; - if(!$user->no_fees) $earning->amount = take_yaamp_fee($earning->amount, $algo); - if(!empty($user->donation)) { - $earning->amount = take_yaamp_fee($earning->amount, $algo, $user->donation); - if ($earning->amount <= 0) continue; - } - - $earning->save(); - - $refcoin = getdbo('db_coins', $user->coinid); - $value = $earning->amount / (($refcoin && $refcoin->price2)? $refcoin->price2: 1); - - // $value = yaamp_convert_amount_user($coin, $earning->amount, $user); - - $user->last_earning = time(); - $user->balance += $value; - $user->save(); - } - - $delay = time() - 5*60; - dborun("delete from shares where algo=:algo and time<$delay", array(':algo'=>$algo)); - } - - if($total_cleared>0) - debuglog("total cleared from rental $total_cleared BTC"); + // debuglog(__FUNCTION__); + + $total_cleared = 0; + foreach (yaamp_get_algos() as $algo) { + $delay = time() - 5 * 60; + dborun("delete from jobsubmits where status=2 and algo=:algo and time<$delay", array( + ':algo' => $algo + )); + + $amount = dboscalar("select sum(amount) from jobsubmits where status=1 and algo=:algo", array( + ':algo' => $algo + )); + if ($amount < 0.00002000) + continue; + + dborun("update jobsubmits set status=2 where status=1 and algo=:algo", array( + ':algo' => $algo + )); + $total_cleared += $amount; + + $block = new db_blocks; + $block->coin_id = 0; + $block->time = time(); + $block->amount = $amount; + $block->price = 1; + $block->algo = $algo; + $block->category = 'generate'; + $block->save(); + + $total_hash_power = dboscalar("SELECT sum(difficulty) FROM shares where valid and algo=:algo", array( + ':algo' => $algo + )); + if (!$total_hash_power) + continue; + + $list = dbolist("SELECT userid, sum(difficulty) as total FROM shares where valid and algo=:algo GROUP BY userid", array( + ':algo' => $algo + )); + foreach ($list as $item) { + $hash_power = $item['total']; + if (!$hash_power) + continue; + + $user = getdbo('db_accounts', $item['userid']); + if (!$user) + continue; + + $earning = new db_earnings; + $earning->userid = $user->id; + $earning->coinid = 0; + $earning->blockid = $block->id; + $earning->create_time = time(); + $earning->price = 1; + $earning->status = 2; // cleared + + $earning->amount = $amount * $hash_power / $total_hash_power; + if (!$user->no_fees) + $earning->amount = take_yaamp_fee($earning->amount, $algo); + if (!empty($user->donation)) { + $earning->amount = take_yaamp_fee($earning->amount, $algo, $user->donation); + if ($earning->amount <= 0) + continue; + } + + $earning->save(); + + $refcoin = getdbo('db_coins', $user->coinid); + $value = $earning->amount / (($refcoin && $refcoin->price2) ? $refcoin->price2 : 1); + + // $value = yaamp_convert_amount_user($coin, $earning->amount, $user); + + $user->last_earning = time(); + $user->balance += $value; + $user->save(); + } + + $delay = time() - 5 * 60; + dborun("delete from shares where algo=:algo and time<$delay", array( + ':algo' => $algo + )); + } + + if ($total_cleared > 0) + debuglog("total cleared from rental $total_cleared BTC"); } //////////////////////////////////////////////////////////////////////////////// function BackendUpdateDeposit() { -// debuglog(__FUNCTION__); + // debuglog(__FUNCTION__); - $btc = getdbosql('db_coins', "symbol='BTC'"); - if(!$btc) return; + $btc = getdbosql('db_coins', "symbol='BTC'"); + if (!$btc) + return; - $remote = new WalletRPC($btc); + $remote = new WalletRPC($btc); + + $info = $remote->getinfo(); + if (!$info) + return; + if (!isset($info['blocks'])) + return; - $info = $remote->getinfo(); - if(!$info) return; - if(!isset($info['blocks'])) return; + $hash = $remote->getblockhash(intval($info['blocks'])); + if (!$hash) + return; - $hash = $remote->getblockhash(intval($info['blocks'])); - if(!$hash) return; + $block = $remote->getblock($hash); + if (!$block) + return; - $block = $remote->getblock($hash); - if(!$block) return; + if (!isset($block['time'])) + return; + if ($block['time'] + 30 * 60 < time()) + return; - if(!isset($block['time'])) return; - if($block['time'] + 30*60 < time()) return; + $list = $remote->listaccounts(1); + foreach ($list as $r => $a) { + if ($a == 0) + continue; - $list = $remote->listaccounts(1); - foreach($list as $r=>$a) - { - if($a == 0) continue; + $b = preg_match('/renter-prod-([0-9]+)/', $r, $m); + if (!$b) + continue; - $b = preg_match('/renter-prod-([0-9]+)/', $r, $m); - if(!$b) continue; + $renter = getdbo('db_renters', $m[1]); + if (!$renter) + continue; - $renter = getdbo('db_renters', $m[1]); - if(!$renter) continue; + $ts = $remote->listtransactions(yaamp_renter_account($renter), 1); + if (!$ts || !isset($ts[0])) + continue; - $ts = $remote->listtransactions(yaamp_renter_account($renter), 1); - if(!$ts || !isset($ts[0])) continue; + $moved = $remote->move(yaamp_renter_account($renter), '', $a); + if (!$moved) + continue; - $moved = $remote->move(yaamp_renter_account($renter), '', $a); - if(!$moved) continue; + debuglog("deposit $renter->id $renter->address, $a"); - debuglog("deposit $renter->id $renter->address, $a"); + $rentertx = new db_rentertxs; + $rentertx->renterid = $renter->id; + $rentertx->time = time(); + $rentertx->amount = $a; + $rentertx->type = 'deposit'; + $rentertx->tx = isset($ts[0]['txid']) ? $ts[0]['txid'] : ''; + $rentertx->save(); - $rentertx = new db_rentertxs; - $rentertx->renterid = $renter->id; - $rentertx->time = time(); - $rentertx->amount = $a; - $rentertx->type = 'deposit'; - $rentertx->tx = isset($ts[0]['txid'])? $ts[0]['txid']: ''; - $rentertx->save(); + $renter->unconfirmed = 0; + $renter->balance += $a; + $renter->updated = time(); + $renter->save(); + } - $renter->unconfirmed = 0; - $renter->balance += $a; - $renter->updated = time(); - $renter->save(); - } + $list = $remote->listaccounts(0); + foreach ($list as $r => $a) { + if ($a == 0) + continue; - $list = $remote->listaccounts(0); - foreach($list as $r=>$a) - { - if($a == 0) continue; + $b = preg_match('/renter-prod-([0-9]+)/', $r, $m); + if (!$b) + continue; - $b = preg_match('/renter-prod-([0-9]+)/', $r, $m); - if(!$b) continue; + $renter = getdbo('db_renters', $m[1]); + if (!$renter) + continue; - $renter = getdbo('db_renters', $m[1]); - if(!$renter) continue; + debuglog("unconfirmed $renter->id $renter->address, $a"); - debuglog("unconfirmed $renter->id $renter->address, $a"); + $renter->unconfirmed = $a; + $renter->updated = time(); + $renter->save(); + } - $renter->unconfirmed = $a; - $renter->updated = time(); - $renter->save(); - } + ///////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////// + $received1 = $remote->getbalance('bittrex', 1); //nicehash payments + if ($received1 > 0) { + $moved = $remote->move('bittrex', '', $received1); + debuglog("moved from bittrex $received1"); - $received1 = $remote->getbalance('bittrex', 1); //nicehash payments - if($received1>0) - { - $moved = $remote->move('bittrex', '', $received1); - debuglog("moved from bittrex $received1"); + dborun("update renters set balance=balance+$received1 where id=7"); + dborun("update renters set custom_start=custom_start+$received1 where id=7"); + } - dborun("update renters set balance=balance+$received1 where id=7"); - dborun("update renters set custom_start=custom_start+$received1 where id=7"); - } + ///////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////// + $fees = YAAMP_TXFEE_RENTING_WD; // 0.002 - $fees = YAAMP_TXFEE_RENTING_WD; // 0.002 + $list = getdbolist('db_rentertxs', "type='withdraw' and tx='scheduled'"); + foreach ($list as $tx) { + $renter = getdbo('db_renters', $tx->renterid); + if (!$renter) + continue; - $list = getdbolist('db_rentertxs', "type='withdraw' and tx='scheduled'"); - foreach($list as $tx) - { - $renter = getdbo('db_renters', $tx->renterid); - if(!$renter) continue; + // debuglog("$renter->balance < $tx->amount + $fees"); + $tx->amount = bitcoinvaluetoa(min($tx->amount, $renter->balance - $fees)); + if ($tx->amount < $fees * 2) { + $tx->tx = 'failed'; + $tx->save(); -// debuglog("$renter->balance < $tx->amount + $fees"); - $tx->amount = bitcoinvaluetoa(min($tx->amount, $renter->balance-$fees)); - if($tx->amount < $fees*2) - { - $tx->tx = 'failed'; - $tx->save(); + continue; + } - continue; - } + debuglog("withdraw send $renter->id $renter->address sendtoaddress($tx->address, $tx->amount)"); + $tx->tx = $remote->sendtoaddress($tx->address, round($tx->amount, 8)); - debuglog("withdraw send $renter->id $renter->address sendtoaddress($tx->address, $tx->amount)"); - $tx->tx = $remote->sendtoaddress($tx->address, round($tx->amount, 8)); + if (!$tx->tx) { + $tx->tx = 'failed'; + $tx->save(); - if(!$tx->tx) - { - $tx->tx = 'failed'; - $tx->save(); + continue; + } - continue; - } + $renter->balance -= $tx->amount + $fees; + $renter->balance = max($renter->balance, 0); - $renter->balance -= $tx->amount+$fees; - $renter->balance = max($renter->balance, 0); + dborun("update renters set balance=$renter->balance where id=$renter->id"); - dborun("update renters set balance=$renter->balance where id=$renter->id"); + $tx->save(); - $tx->save(); - - if($renter->balance <= 0.0001) - dborun("update jobs set active=false, ready=false where id=$renter->id"); - } + if ($renter->balance <= 0.0001) + dborun("update jobs set active=false, ready=false where id=$renter->id"); + } } - - - - - - - diff --git a/web/yaamp/core/backend/sell.php b/web/yaamp/core/backend/sell.php index 7fba09b3c..584e58def 100644 --- a/web/yaamp/core/backend/sell.php +++ b/web/yaamp/core/backend/sell.php @@ -4,124 +4,122 @@ function TradingSellCoins() { -// debuglog(__FUNCTION__); + // debuglog(__FUNCTION__); - $coins = getdbolist('db_coins', "enable and balance>0 and symbol!='BTC'"); - foreach($coins as $coin) sellCoinToExchange($coin); + $coins = getdbolist('db_coins', "enable and balance>0 and symbol!='BTC'"); + foreach ($coins as $coin) + sellCoinToExchange($coin); } function sellCoinToExchange($coin) { - if($coin->dontsell) return; - - $remote = new WalletRPC($coin); - - $info = $remote->getinfo(); - if(!$info || !$info['balance']) return false; - - if(!empty($coin->symbol2)) - { - $coin2 = getdbosql('db_coins', "symbol='$coin->symbol2'"); - if(!$coin2) return; - - $amount = $info['balance'] - $info['paytxfee']; - $amount *= 0.9; - -// debuglog("sending $amount $coin->symbol to main wallet"); - - $tx = $remote->sendtoaddress($coin2->master_wallet, $amount); -// if(!$tx) debuglog($remote->error); - - return; - } - - $market = getBestMarket($coin); - if(!$market) return; - - if($market->lastsent != null && $market->lastsent > $market->lasttraded) - { -// debuglog("*** not sending $coin->name to $market->name. last tx is late ***"); - return; - } - - $deposit_address = $market->deposit_address; - $marketname = $market->name; - - if(empty($deposit_address)) return false; - $reserved1 = dboscalar("select sum(balance) from accounts where coinid=$coin->id"); - $reserved2 = dboscalar("select sum(amount*price) from earnings - where status!=2 and userid in (select id from accounts where coinid=$coin->id)"); - - $reserved = ($reserved1 + $reserved2) * 10; - $amount = $info['balance'] - $info['paytxfee'] - $reserved; - -// if($reserved>0) -// { -// debuglog("$reserved1 $reserved2 out of {$info['balance']}"); -// debuglog("reserving $reserved $coin->symbol out of $coin->balance, available $amount"); -// } - - if($amount < $coin->reward/4) - { - // debuglog("not enough $coin->symbol to sell $amount < $coin->reward /4"); - return false; - } - - $deposit_info = $remote->validateaddress($deposit_address); - if(!$deposit_info || !isset($deposit_info['isvalid']) || !$deposit_info['isvalid']) - { - debuglog("sell invalid address $deposit_address"); - return; - } - - $amount = round($amount, 8); -// debuglog("sending $amount $coin->symbol to $marketname, $deposit_address"); - -// sleep(1); - - $tx = $remote->sendtoaddress($deposit_address, $amount); - if(!$tx) - { - // debuglog($remote->error); - - if($coin->symbol == 'DIME') - $amount = min($amount, 10000000); - else if($coin->symbol == 'CNOTE') - $amount = min($amount, 10000); - else if($coin->symbol == 'SRC') - $amount = min($amount, 500); - else - $amount = round($amount * 0.99, 8); - -// debuglog("sending $amount $coin->symbol to $deposit_address"); - sleep(1); - - $tx = $remote->sendtoaddress($deposit_address, $amount); - if(!$tx) - { - debuglog("sending $amount $coin->symbol to $deposit_address"); - debuglog($remote->error); - return; - } - } - - if($tx) - { - $market->lastsent = time(); - $market->save(); - } - - $exchange = new db_exchange; - $exchange->market = $marketname; - $exchange->coinid = $coin->id; - $exchange->send_time = time(); - $exchange->quantity = $amount; - $exchange->price_estimate = $coin->price; - $exchange->status = 'waiting'; - $exchange->tx = $tx; - $exchange->save(); - - return; + if ($coin->dontsell) + return; + + $remote = new WalletRPC($coin); + + $info = $remote->getinfo(); + if (!$info || !$info['balance']) + return false; + + if (!empty($coin->symbol2)) { + $coin2 = getdbosql('db_coins', "symbol='$coin->symbol2'"); + if (!$coin2) + return; + + $amount = $info['balance'] - $info['paytxfee']; + $amount *= 0.9; + + // debuglog("sending $amount $coin->symbol to main wallet"); + + $tx = $remote->sendtoaddress($coin2->master_wallet, $amount); + // if(!$tx) debuglog($remote->error); + + return; + } + + $market = getBestMarket($coin); + if (!$market) + return; + + if ($market->lastsent != null && $market->lastsent > $market->lasttraded) { + // mail(YAAMP_ADMIN_EMAIL, "Late Transaction", "A previous transaction for $coin->name to $market->name has not been recieved."); + // debuglog("*** not sending $coin->name to $market->name. last tx is late ***"); + return; + } + + $deposit_address = $market->deposit_address; + $marketname = $market->name; + + if (empty($deposit_address)) + return false; + $reserved1 = dboscalar("select sum(balance) from accounts where coinid=$coin->id"); + $reserved2 = dboscalar("select sum(amount*price) from earnings + where status!=2 and userid in (select id from accounts where coinid=$coin->id)"); + + $reserved = ($reserved1 + $reserved2) * 10; + $amount = $info['balance'] - $info['paytxfee'] - $reserved; + + // if($reserved>0) + // { + // debuglog("$reserved1 $reserved2 out of {$info['balance']}"); + // debuglog("reserving $reserved $coin->symbol out of $coin->balance, available $amount"); + // } + + if ($amount < $coin->reward / 4) { + // debuglog("not enough $coin->symbol to sell $amount < $coin->reward /4"); + return false; + } + + $deposit_info = $remote->validateaddress($deposit_address); + if (!$deposit_info || !isset($deposit_info['isvalid']) || !$deposit_info['isvalid']) { + debuglog("sell invalid address $deposit_address"); + return; + } + + $amount = round($amount, 8); + // debuglog("sending $amount $coin->symbol to $marketname, $deposit_address"); + + // sleep(1); + + $tx = $remote->sendtoaddress($deposit_address, $amount); + if (!$tx) { + // debuglog($remote->error); + + if ($coin->symbol == 'DIME') + $amount = min($amount, 10000000); + else if ($coin->symbol == 'CNOTE') + $amount = min($amount, 10000); + else if ($coin->symbol == 'SRC') + $amount = min($amount, 500); + else + $amount = round($amount * 0.99, 8); + + // debuglog("sending $amount $coin->symbol to $deposit_address"); + sleep(1); + + $tx = $remote->sendtoaddress($deposit_address, $amount); + if (!$tx) { + debuglog("sending $amount $coin->symbol to $deposit_address"); + debuglog($remote->error); + return; + } + } + + if ($tx) { + $market->lastsent = time(); + $market->save(); + } + + $exchange = new db_exchange; + $exchange->market = $marketname; + $exchange->coinid = $coin->id; + $exchange->send_time = time(); + $exchange->quantity = $amount; + $exchange->price_estimate = $coin->price; + $exchange->status = 'waiting'; + $exchange->tx = $tx; + $exchange->save(); + + return; } - - diff --git a/web/yaamp/core/backend/services.php b/web/yaamp/core/backend/services.php index 60dfbd398..fd15860cb 100644 --- a/web/yaamp/core/backend/services.php +++ b/web/yaamp/core/backend/services.php @@ -3,239 +3,231 @@ /* NiceHash Stuff */ function BackendUpdateServices() { -// debuglog(__FUNCTION__); - - if (YAAMP_USE_NICEHASH_API != true) - return; - - $table = array( - 0=>'scrypt', - 1=>'sha256', - 2=>'scryptn', - 3=>'x11', - 4=>'x13', - 5=>'keccak', - 6=>'x15', - 7=>'nist5', - 8=>'neoscrypt', - 9=>'lyra2', - 10=>'whirlx', - 11=>'qubit', - 12=>'quark', - // 13=>'Axiom', - 14=>'lyra2v2', // 14 = Lyra2REv2 - // 15=>'ScryptJaneNf16', // 15 = ScryptJaneNf16 - 16=>'blakecoin', // 16 = Blake256r8 - // 17=>'Blake256r14', - // 18=>'Blake256r8vnl', - // 19=>'Hodl', - // 20=>'DaggerHashimoto', - // 21=>'Decred', - // 22=>'CryptoNight', - 23=>'lbry', - 24=>'equihash', - // 25=>'Pascal', - 26=>'sib', // X11Gost - // 27=>'Sia', - 28=>'blake2s', - 29=>'skunk', - ); - - $res = fetch_url('https://api.nicehash.com/api?method=stats.global.current'); - if(!$res) return; - - $a = json_decode($res); - if(!$a || !isset($a->result)) return; - - foreach($a->result->stats as $stat) - { - if($stat->price <= 0) continue; - if(!isset($table[$stat->algo])) continue; - $algo = $table[$stat->algo]; - - $service = getdbosql('db_services', "name='Nicehash' and algo=:algo", array(':algo'=>$algo)); - if(!$service) - { - $service = new db_services; - $service->name = 'Nicehash'; - $service->algo = $algo; - } - - $service->price = $stat->price/1000; - $service->speed = $stat->speed*1000000000; - $service->save(); - - $list = getdbolist('db_jobs', "percent>0 and algo=:algo and (host='stratum.westhash.com' or host='stratum.nicehash.com')", array(':algo'=>$algo)); - foreach($list as $job) - { - $job->price = round($service->price*1000*(100-$job->percent)/100, 2); - $job->save(); - } - } - - $list = getdbolist('db_renters', "custom_address is not null and custom_server is not null"); - foreach($list as $renter) - { - $res = fetch_url("https://$renter->custom_server/api?method=stats.provider&addr=$renter->custom_address"); - if(!$res) continue; - - $renter->custom_balance = 0; - $renter->custom_accept = 0; - $renter->custom_reject = 0; - - $a = json_decode($res); - foreach($a->result->stats as $stat) - { - if(!isset($table[$stat->algo])) continue; - $algo = $table[$stat->algo]; - - $renter->custom_balance += $stat->balance; - $renter->custom_accept += $stat->accepted_speed*1000000000; - } - - $renter->save(); - } - - /////////////////////////////////////////////////////////////////////////// - - // renting from nicehash - if (YAAMP_USE_NICEHASH_API != true) - return; - - $apikey = NICEHASH_API_KEY; - $apiid = NICEHASH_API_ID; - - $deposit = NICEHASH_DEPOSIT; - $amount = NICEHASH_DEPOSIT_AMOUNT; - - $res = fetch_url("https://api.nicehash.com/api?method=balance&id=$apiid&key=$apikey"); - debuglog($res); - - $a = json_decode($res); - $balance = $a->result->balance_confirmed; - - foreach($table as $i=>$algo) - { - $nicehash = getdbosql('db_nicehash', "algo=:algo", array(':algo'=>$algo)); - if(!$nicehash) - { - $nicehash = new db_nicehash; - $nicehash->active = false; - $nicehash->algo = $algo; - } - - if(!$nicehash->active) - { - if($nicehash->orderid) - { - $res = fetch_url("https://api.nicehash.com/api?method=orders.remove&id=$apiid&key=$apikey&location=0&algo=$i&order=$nicehash->orderid"); - debuglog($res); - - $nicehash->orderid = null; - } - - $nicehash->btc = null; - $nicehash->price = null; - $nicehash->speed = null; - $nicehash->last_decrease = null; - - $nicehash->save(); - continue; - } - - $price = dboscalar("select price from hashrate where algo=:algo order by time desc limit 1", array(':algo'=>$algo)); - $minprice = $price*0.5; - $setprice = $price*0.7; - $maxprice = $price*0.9; - $cancelprice = $price*1.1; - - $res = fetch_url("https://api.nicehash.com/api?method=orders.get&my&id=$apiid&key=$apikey&location=0&algo=$i"); - if(!$res) break; - - $a = json_decode($res); - if(count($a->result->orders) == 0) - { - if($balance < $amount) continue; - $port = getAlgoPort($algo); - - $res = fetch_url("https://api.nicehash.com/api?method=orders.create&id=$apiid&key=$apikey&location=0&algo=$i&amount=$amount&price=$setprice&limit=0&pool_host=yaamp.com&pool_port=$port&pool_user=$deposit&pool_pass=xx"); - debuglog($res); - - $nicehash->last_decrease = time(); - $nicehash->save(); - - continue; - } - - $order = $a->result->orders[0]; - debuglog("$algo $order->price $minprice $setprice $maxprice $cancelprice"); - - $nicehash->orderid = $order->id; - $nicehash->btc = $order->btc_avail; - $nicehash->workers = $order->workers; - $nicehash->price = $order->price; - $nicehash->speed = $order->limit_speed; - $nicehash->accepted = $order->accepted_speed; + // debuglog(__FUNCTION__); + + if (YAAMP_USE_NICEHASH_API != true) + return; + + $table = array( + 0 => 'scrypt', + 1 => 'sha256', + 2 => 'scryptn', + 3 => 'x11', + 4 => 'x13', + 5 => 'keccak', + 6 => 'x15', + 7 => 'nist5', + 8 => 'neoscrypt', + 9 => 'lyra2', + 10 => 'whirlx', + 11 => 'qubit', + 12 => 'quark', + // 13=>'Axiom', + 14 => 'lyra2v2', // 14 = Lyra2REv2 + // 15=>'ScryptJaneNf16', // 15 = ScryptJaneNf16 + 16 => 'blakecoin', // 16 = Blake256r8 + // 17=>'Blake256r14', + // 18=>'Blake256r8vnl', + // 19=>'Hodl', + // 20=>'DaggerHashimoto', + // 21=>'Decred', + // 22=>'CryptoNight', + 23 => 'lbry', + 24 => 'equihash', + // 25=>'Pascal', + 26 => 'sib', // X11Gost + // 27=>'Sia', + 28 => 'blake2s', + 29 => 'skunk' + ); + + $res = fetch_url('https://api.nicehash.com/api?method=stats.global.current'); + if (!$res) + return; + + $a = json_decode($res); + if (!$a || !isset($a->result)) + return; + + foreach ($a->result->stats as $stat) { + if ($stat->price <= 0) + continue; + if (!isset($table[$stat->algo])) + continue; + $algo = $table[$stat->algo]; + + $service = getdbosql('db_services', "name='Nicehash' and algo=:algo", array( + ':algo' => $algo + )); + if (!$service) { + $service = new db_services; + $service->name = 'Nicehash'; + $service->algo = $algo; + } + + $service->price = $stat->price / 1000; + $service->speed = $stat->speed * 1000000000; + $service->save(); + + $list = getdbolist('db_jobs', "percent>0 and algo=:algo and (host='stratum.westhash.com' or host='stratum.nicehash.com')", array( + ':algo' => $algo + )); + foreach ($list as $job) { + $job->price = round($service->price * 1000 * (100 - $job->percent) / 100, 2); + $job->save(); + } + } + + $list = getdbolist('db_renters', "custom_address is not null and custom_server is not null"); + foreach ($list as $renter) { + $res = fetch_url("https://$renter->custom_server/api?method=stats.provider&addr=$renter->custom_address"); + if (!$res) + continue; + + $renter->custom_balance = 0; + $renter->custom_accept = 0; + $renter->custom_reject = 0; + + $a = json_decode($res); + foreach ($a->result->stats as $stat) { + if (!isset($table[$stat->algo])) + continue; + $algo = $table[$stat->algo]; + + $renter->custom_balance += $stat->balance; + $renter->custom_accept += $stat->accepted_speed * 1000000000; + } + + $renter->save(); + } + + /////////////////////////////////////////////////////////////////////////// + + // renting from nicehash + if (YAAMP_USE_NICEHASH_API != true) + return; + + $apikey = NICEHASH_API_KEY; + $apiid = NICEHASH_API_ID; + + $deposit = NICEHASH_DEPOSIT; + $amount = NICEHASH_DEPOSIT_AMOUNT; + + $res = fetch_url("https://api.nicehash.com/api?method=balance&id=$apiid&key=$apikey"); + debuglog($res); + + $a = json_decode($res); + $balance = $a->result->balance_confirmed; + + foreach ($table as $i => $algo) { + $nicehash = getdbosql('db_nicehash', "algo=:algo", array( + ':algo' => $algo + )); + if (!$nicehash) { + $nicehash = new db_nicehash; + $nicehash->active = false; + $nicehash->algo = $algo; + } + + if (!$nicehash->active) { + if ($nicehash->orderid) { + $res = fetch_url("https://api.nicehash.com/api?method=orders.remove&id=$apiid&key=$apikey&location=0&algo=$i&order=$nicehash->orderid"); + debuglog($res); + + $nicehash->orderid = null; + } + + $nicehash->btc = null; + $nicehash->price = null; + $nicehash->speed = null; + $nicehash->last_decrease = null; + + $nicehash->save(); + continue; + } + + $price = dboscalar("select price from hashrate where algo=:algo order by time desc limit 1", array( + ':algo' => $algo + )); + $minprice = $price * 0.5; + $setprice = $price * 0.7; + $maxprice = $price * 0.9; + $cancelprice = $price * 1.1; + + $res = fetch_url("https://api.nicehash.com/api?method=orders.get&my&id=$apiid&key=$apikey&location=0&algo=$i"); + if (!$res) + break; + + $a = json_decode($res); + if (count($a->result->orders) == 0) { + if ($balance < $amount) + continue; + $port = getAlgoPort($algo); - if($order->price > $cancelprice && $order->workers > 0) - { - debuglog("* cancel order $algo"); + $res = fetch_url("https://api.nicehash.com/api?method=orders.create&id=$apiid&key=$apikey&location=0&algo=$i&amount=$amount&price=$setprice&limit=0&pool_host=yaamp.com&pool_port=$port&pool_user=$deposit&pool_pass=xx"); + debuglog($res); + + $nicehash->last_decrease = time(); + $nicehash->save(); + + continue; + } - $res = fetch_url("https://api.nicehash.com/api?method=orders.remove&id=$apiid&key=$apikey&location=0&algo=$i&order=$order->id"); - debuglog($res); - } + $order = $a->result->orders[0]; + debuglog("$algo $order->price $minprice $setprice $maxprice $cancelprice"); - else if($order->price > $maxprice && $order->limit_speed == 0) - { - debuglog("* decrease speed $algo"); + $nicehash->orderid = $order->id; + $nicehash->btc = $order->btc_avail; + $nicehash->workers = $order->workers; + $nicehash->price = $order->price; + $nicehash->speed = $order->limit_speed; + $nicehash->accepted = $order->accepted_speed; - $res = fetch_url("https://api.nicehash.com/api?method=orders.set.limit&id=$apiid&key=$apikey&location=0&algo=$i&order=$order->id&limit=0.05"); - debuglog($res); - } + if ($order->price > $cancelprice && $order->workers > 0) { + debuglog("* cancel order $algo"); - else if($order->price > $maxprice && $nicehash->last_decrease+10*60 < time()) - { - debuglog("* decrease price $algo"); + $res = fetch_url("https://api.nicehash.com/api?method=orders.remove&id=$apiid&key=$apikey&location=0&algo=$i&order=$order->id"); + debuglog($res); + } - $res = fetch_url("https://api.nicehash.com/api?method=orders.set.price.decrease&id=$apiid&key=$apikey&location=0&algo=$i&order=$order->id"); - debuglog($res); + else if ($order->price > $maxprice && $order->limit_speed == 0) { + debuglog("* decrease speed $algo"); - $nicehash->last_decrease = time(); - } - - else if($order->price < $minprice && $order->workers <= 0) - { - debuglog("* increase price $algo"); - - $res = fetch_url("https://api.nicehash.com/api?method=orders.set.price&id=$apiid&key=$apikey&algo=$i&location=0&order=$order->id&price=$setprice"); - debuglog($res); - } - - else if($order->price < $maxprice && $order->limit_speed == 0.05) - { - debuglog("* increase speed $algo"); - - $res = fetch_url("https://api.nicehash.com/api?method=orders.set.limit&id=$apiid&key=$apikey&location=0&algo=$i&order=$order->id&limit=0"); - debuglog($res); - } - - else if($order->btc_avail < 0.00075000) - { - debuglog("* refilling order $order->id"); + $res = fetch_url("https://api.nicehash.com/api?method=orders.set.limit&id=$apiid&key=$apikey&location=0&algo=$i&order=$order->id&limit=0.05"); + debuglog($res); + } - $res = fetch_url("https://api.nicehash.com/api?method=orders.refill&id=$apiid&key=$apikey&location=0&algo=$i&order=$order->id&amount=0.01"); - debuglog($res); - } + else if ($order->price > $maxprice && $nicehash->last_decrease + 10 * 60 < time()) { + debuglog("* decrease price $algo"); - $nicehash->save(); - } + $res = fetch_url("https://api.nicehash.com/api?method=orders.set.price.decrease&id=$apiid&key=$apikey&location=0&algo=$i&order=$order->id"); + debuglog($res); -} + $nicehash->last_decrease = time(); + } + else if ($order->price < $minprice && $order->workers <= 0) { + debuglog("* increase price $algo"); + $res = fetch_url("https://api.nicehash.com/api?method=orders.set.price&id=$apiid&key=$apikey&algo=$i&location=0&order=$order->id&price=$setprice"); + debuglog($res); + } + else if ($order->price < $maxprice && $order->limit_speed == 0.05) { + debuglog("* increase speed $algo"); + $res = fetch_url("https://api.nicehash.com/api?method=orders.set.limit&id=$apiid&key=$apikey&location=0&algo=$i&order=$order->id&limit=0"); + debuglog($res); + } + else if ($order->btc_avail < 0.00075000) { + debuglog("* refilling order $order->id"); + $res = fetch_url("https://api.nicehash.com/api?method=orders.refill&id=$apiid&key=$apikey&location=0&algo=$i&order=$order->id&amount=0.01"); + debuglog($res); + } + $nicehash->save(); + } +} diff --git a/web/yaamp/core/backend/stats.php b/web/yaamp/core/backend/stats.php index 4d607cfc4..440e7cd2b 100644 --- a/web/yaamp/core/backend/stats.php +++ b/web/yaamp/core/backend/stats.php @@ -2,356 +2,375 @@ function BackendStatsUpdate() { -// debuglog(__FUNCTION__); -// $t1xx = microtime(true); - - $t = time()-2*60; - $idleing = array(); - - $list = getdbolist('db_stratums', "time<$t"); - foreach($list as $stratum) { - $idleing[$stratum->algo] = $stratum->algo; - } - - if(!empty($idleing)) { - //noisy... - //debuglog("stratum restarted: ".implode(', ',$idleing)); - //send_email_alert('stratums', "stratum restart", "stratum restart: ".implode(', ',$idleing)); - } - - dborun("DELETE FROM stratums WHERE time<$t"); - dborun("DELETE FROM workers WHERE pid NOT IN (SELECT pid FROM stratums)"); - - // todo: cleanup could be done once per day or week... - dborun("DELETE FROM hashstats WHERE IFNULL(hashrate,0) = 0 AND IFNULL(earnings,0) = 0"); - - ////////////////////////////////////////////////////////////////////////////////////////////////////// - // long term stats - - $tm = floor(time()/60/60)*60*60; - foreach(yaamp_get_algos() as $algo) - { - $pool_rate = yaamp_pool_rate($algo); - - $stats = getdbosql('db_hashstats', "time=$tm and algo=:algo", array(':algo'=>$algo)); - if(!$stats) - { - $stats = new db_hashstats; - $stats->time = $tm; - $stats->hashrate = $pool_rate; - $stats->algo = $algo; - $stats->earnings = null; - } - else - { - $percent = 1; - $stats->hashrate = round(($stats->hashrate*(100-$percent) + $pool_rate*$percent) / 100); - } - - $earnings = bitcoinvaluetoa(dboscalar( - "SELECT SUM(amount*price) FROM blocks WHERE algo=:algo AND time>$tm AND category!='orphan'", - array(':algo'=>$algo) - )); - - if (bitcoinvaluetoa($stats->earnings) != $earnings) { - debuglog("$algo earnings: $earnings BTC"); - $stats->earnings = $earnings; - } - - if (floatval($earnings) || $stats->hashrate) - $stats->save(); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // short term stats - - $step = 15; - $tm = floor(time()/$step/60)*$step*60; - - foreach(yaamp_get_algos() as $algo) - { - $stats = getdbosql('db_hashrate', "time=$tm and algo=:algo", array(':algo'=>$algo)); - if(!$stats) - { - $stats = new db_hashrate; - $stats->time = $tm; - $stats->hashrate = dboscalar("select hashrate from hashrate where algo=:algo order by time desc limit 1", array(':algo'=>$algo)); - $stats->hashrate_bad = 0; //dboscalar("select hashrate_bad from hashrate where algo=:algo order by time desc limit 1", array(':algo'=>$algo)); - $stats->price = dboscalar("select price from hashrate where algo=:algo order by time desc limit 1", array(':algo'=>$algo)); - $stats->rent = dboscalar("select rent from hashrate where algo=:algo order by time desc limit 1", array(':algo'=>$algo)); - $stats->algo = $algo; - } - - $pool_rate = yaamp_pool_rate($algo); - $stats->hashrate = $pool_rate; //round(($stats->hashrate*(100-$percent) + $pool_rate*$percent) / 100); - - $pool_rate_bad = yaamp_pool_rate_bad($algo); - $stats->hashrate_bad = $pool_rate_bad; //round(($stats->hashrate_bad*(100-$percent) + $pool_rate_bad*$percent) / 100); - - if($stats->hashrate < 1000) $stats->hashrate = 0; - - $t1 = time() - 5*60; - $total_rentable = dboscalar("select sum(difficulty) from shares where valid and extranonce1 and algo=:algo and time>$t1", array(':algo'=>$algo)); - $total_diff = dboscalar("select sum(difficulty) from shares where valid and algo=:algo and time>$t1", array(':algo'=>$algo)); - $total_rented = 0; - - if(!$total_diff) - { - $t1 = time() - 15*60; - $total_diff = dboscalar("select sum(difficulty) from shares where valid and algo=:algo and time>$t1", array(':algo'=>$algo)); - } - - if($total_diff > 0) - { - $price = 0; - $rent = 0; - - $list = dbolist("select coinid, sum(difficulty) as d from shares where valid and algo=:algo and time>$t1 group by coinid", array(':algo'=>$algo)); - foreach($list as $item) - { - if($item['coinid'] == 0) - { - if(!$total_rentable) continue; - $total_rented = $item['d']; - - $price += $stats->rent * $item['d'] / $total_diff; - $rent += $stats->rent * $item['d'] / $total_rentable; - } - else - { - $coin = getdbo('db_coins', $item['coinid']); - if(!$coin) continue; - - $btcghd = yaamp_profitability($coin); - - $price += $btcghd * $item['d'] / $total_diff; - $rent += $btcghd * $item['d'] / $total_diff; - } - } - - $percent = 33; - $rent = max($price, ($stats->rent*(100-$percent) + $rent*$percent) / 100); - - $target = yaamp_hashrate_constant($algo); - $interval = yaamp_hashrate_step(); - - $aa = $total_rentable * $target / $interval / 1000; - $bb = dboscalar("select sum(speed) from jobs where active and ready and price>$rent and algo=:algo", array(':algo'=>$algo)); - - if($total_rented*1.3 < $total_rentable || $bb > $aa) - $rent += $price*YAAMP_FEES_RENTING/100; - - else - $rent -= $price*YAAMP_FEES_RENTING/100; - - $stats->price = $price; - $stats->rent = $rent; - } - - else - { - $coin = getdbosql('db_coins', "enable and auto_ready and algo=:algo order by index_avg desc", array(':algo'=>$algo)); - if($coin) - { - $btcghd = yaamp_profitability($coin); - $stats->price = $btcghd; - $stats->rent = $stats->price + $stats->price * YAAMP_FEES_RENTING / 100; - } - } - - if(YAAMP_LIMIT_ESTIMATE) - { - $t1 = time() - 24*60*60; - $avg = dboscalar("select avg(price) from hashrate where time>$t1 and algo=:algo", array(':algo'=>$algo)); - if($avg) $stats->price = min($stats->price, $avg*1.5); - } - - $stats->difficulty = dboscalar("select sum(difficulty) from coins where enable and auto_ready and algo=:algo", array(':algo'=>$algo)); - $stats->save(); - } - - ////////////////////////////////////////////////////////////// - - $step = 15; - $tm = floor(time()/$step/60)*$step*60; - - $btc = getdbosql('db_coins', "symbol='BTC'"); - if (!$btc) $btc = json_decode('{"id": 6, "balance": 0}'); + // debuglog(__FUNCTION__); + // $t1xx = microtime(true); + + $t = time() - 2 * 60; + $idleing = array(); + + $list = getdbolist('db_stratums', "time<$t"); + foreach ($list as $stratum) { + $idleing[$stratum->algo] = $stratum->algo; + } + + if (!empty($idleing)) { + //noisy... + //debuglog("stratum restarted: ".implode(', ',$idleing)); + //send_email_alert('stratums', "stratum restart", "stratum restart: ".implode(', ',$idleing)); + } + + dborun("DELETE FROM stratums WHERE time<$t"); + dborun("DELETE FROM workers WHERE pid NOT IN (SELECT pid FROM stratums)"); + + // todo: cleanup could be done once per day or week... + dborun("DELETE FROM hashstats WHERE IFNULL(hashrate,0) = 0 AND IFNULL(earnings,0) = 0"); + + ////////////////////////////////////////////////////////////////////////////////////////////////////// + // long term stats + + $tm = floor(time() / 60 / 60) * 60 * 60; + foreach (yaamp_get_algos() as $algo) { + $pool_rate = yaamp_pool_rate($algo); + + $stats = getdbosql('db_hashstats', "time=$tm and algo=:algo", array( + ':algo' => $algo + )); + if (!$stats) { + $stats = new db_hashstats; + $stats->time = $tm; + $stats->hashrate = $pool_rate; + $stats->algo = $algo; + $stats->earnings = null; + } else { + $percent = 1; + $stats->hashrate = round(($stats->hashrate * (100 - $percent) + $pool_rate * $percent) / 100); + } + + $earnings = bitcoinvaluetoa(dboscalar("SELECT SUM(amount*price) FROM blocks WHERE algo=:algo AND time>$tm AND category!='orphan'", array( + ':algo' => $algo + ))); + + if (bitcoinvaluetoa($stats->earnings) != $earnings) { + debuglog("$algo earnings: $earnings BTC"); + $stats->earnings = $earnings; + } + + if (floatval($earnings) || $stats->hashrate) + $stats->save(); + } + + //////////////////////////////////////////////////////////////////////////////////////////////////// + // short term stats + + $step = 15; + $tm = floor(time() / $step / 60) * $step * 60; + + foreach (yaamp_get_algos() as $algo) { + $stats = getdbosql('db_hashrate', "time=$tm and algo=:algo", array( + ':algo' => $algo + )); + if (!$stats) { + $stats = new db_hashrate; + $stats->time = $tm; + $stats->hashrate = dboscalar("select hashrate from hashrate where algo=:algo order by time desc limit 1", array( + ':algo' => $algo + )); + $stats->hashrate_bad = 0; //dboscalar("select hashrate_bad from hashrate where algo=:algo order by time desc limit 1", array(':algo'=>$algo)); + $stats->price = dboscalar("select price from hashrate where algo=:algo order by time desc limit 1", array( + ':algo' => $algo + )); + $stats->rent = dboscalar("select rent from hashrate where algo=:algo order by time desc limit 1", array( + ':algo' => $algo + )); + $stats->algo = $algo; + } + + $pool_rate = yaamp_pool_rate($algo); + $stats->hashrate = $pool_rate; //round(($stats->hashrate*(100-$percent) + $pool_rate*$percent) / 100); + + $pool_rate_bad = yaamp_pool_rate_bad($algo); + $stats->hashrate_bad = $pool_rate_bad; //round(($stats->hashrate_bad*(100-$percent) + $pool_rate_bad*$percent) / 100); + + if ($stats->hashrate < 1000) + $stats->hashrate = 0; + + $t1 = time() - 5 * 60; + $total_rentable = dboscalar("select sum(difficulty) from shares where valid and extranonce1 and algo=:algo and time>$t1", array( + ':algo' => $algo + )); + $total_diff = dboscalar("select sum(difficulty) from shares where valid and algo=:algo and time>$t1", array( + ':algo' => $algo + )); + $total_rented = 0; + + if (!$total_diff) { + $t1 = time() - 15 * 60; + $total_diff = dboscalar("select sum(difficulty) from shares where valid and algo=:algo and time>$t1", array( + ':algo' => $algo + )); + } + + if ($total_diff > 0) { + $price = 0; + $rent = 0; + + $list = dbolist("select coinid, sum(difficulty) as d from shares where valid and algo=:algo and time>$t1 group by coinid", array( + ':algo' => $algo + )); + foreach ($list as $item) { + if ($item['coinid'] == 0) { + if (!$total_rentable) + continue; + $total_rented = $item['d']; + + $price += $stats->rent * $item['d'] / $total_diff; + $rent += $stats->rent * $item['d'] / $total_rentable; + } else { + $coin = getdbo('db_coins', $item['coinid']); + if (!$coin) + continue; + + $btcghd = yaamp_profitability($coin); + + $price += $btcghd * $item['d'] / $total_diff; + $rent += $btcghd * $item['d'] / $total_diff; + } + } + + $percent = 33; + $rent = max($price, ($stats->rent * (100 - $percent) + $rent * $percent) / 100); + + $target = yaamp_hashrate_constant($algo); + $interval = yaamp_hashrate_step(); + + $aa = $total_rentable * $target / $interval / 1000; + $bb = dboscalar("select sum(speed) from jobs where active and ready and price>$rent and algo=:algo", array( + ':algo' => $algo + )); + + if ($total_rented * 1.3 < $total_rentable || $bb > $aa) + $rent += $price * YAAMP_FEES_RENTING / 100; + + else + $rent -= $price * YAAMP_FEES_RENTING / 100; + + $stats->price = $price; + $stats->rent = $rent; + } + + else { + $coin = getdbosql('db_coins', "enable and auto_ready and algo=:algo order by index_avg desc", array( + ':algo' => $algo + )); + if ($coin) { + $btcghd = yaamp_profitability($coin); + $stats->price = $btcghd; + $stats->rent = $stats->price + $stats->price * YAAMP_FEES_RENTING / 100; + } + } + + if (YAAMP_LIMIT_ESTIMATE) { + $t1 = time() - 24 * 60 * 60; + $avg = dboscalar("select avg(price) from hashrate where time>$t1 and algo=:algo", array( + ':algo' => $algo + )); + if ($avg) + $stats->price = min($stats->price, $avg * 1.5); + } + + $stats->difficulty = dboscalar("select sum(difficulty) from coins where enable and auto_ready and algo=:algo", array( + ':algo' => $algo + )); + $stats->save(); + } + + ////////////////////////////////////////////////////////////// + + $step = 15; + $tm = floor(time() / $step / 60) * $step * 60; + + $btc = getdbosql('db_coins', "symbol='BTC'"); + if (!$btc) + $btc = json_decode('{"id": 6, "balance": 0}'); + + $topay = dboscalar("select sum(balance) from accounts where coinid=$btc->id"); //here: take other currencies too + $margin = $btc->balance - $topay; + + $balances = dboscalar("select sum(balance) from balances"); + $onsell = dboscalar("select sum(amount*bid) from orders"); + + $immature = dboscalar("select sum(amount*price) from earnings where status=0"); + $confirmed = dboscalar("select sum(amount*price) from earnings where status=1"); + + $wallets = dboscalar("select sum(balance*price) from coins where enable and symbol!='BTC'"); + $renters = dboscalar("select sum(balance) from renters"); + + $mints = dboscalar("select sum(mint*price) from coins where enable"); + $off = $mints - $immature; + + // debuglog("mint $mints $immature $off"); + + $total_profit = $btc->balance + $balances + $onsell + $wallets - $topay - $renters; + + $stats = getdbosql('db_stats', "time=$tm"); + if (!$stats) { + $stats = new db_stats; + $stats->time = $tm; + } + + $stats->profit = $total_profit; + $stats->wallet = $btc->balance; + $stats->wallets = $wallets; - $topay = dboscalar("select sum(balance) from accounts where coinid=$btc->id"); //here: take other currencies too - $margin = $btc->balance - $topay; + $stats->margin = $margin; + $stats->balances = $balances; + $stats->onsell = $onsell; - $balances = dboscalar("select sum(balance) from balances"); - $onsell = dboscalar("select sum(amount*bid) from orders"); + $stats->immature = $immature; + $stats->waiting = $confirmed; + $stats->renters = $renters; - $immature = dboscalar("select sum(amount*price) from earnings where status=0"); - $confirmed = dboscalar("select sum(amount*price) from earnings where status=1"); + $stats->save(); - $wallets = dboscalar("select sum(balance*price) from coins where enable and symbol!='BTC'"); - $renters = dboscalar("select sum(balance) from renters"); + ///////////////////////////////////////////////////////////////////////////// - $mints = dboscalar("select sum(mint*price) from coins where enable"); - $off = $mints-$immature; - -// debuglog("mint $mints $immature $off"); + foreach (yaamp_get_algos() as $algo) { + $factor = yaamp_get_algo_norm($algo); - $total_profit = $btc->balance + $balances + $onsell + $wallets - $topay - $renters; - - $stats = getdbosql('db_stats', "time=$tm"); - if(!$stats) - { - $stats = new db_stats; - $stats->time = $tm; - } + $dbalgo = getdbosql('db_algos', "name='$algo'"); + if (!$dbalgo) { + $dbalgo = new db_algos; + $dbalgo->name = $algo; + } - $stats->profit = $total_profit; - $stats->wallet = $btc->balance; - $stats->wallets = $wallets; + $dbalgo->profit = dboscalar("select price from hashrate where algo=:algo order by time desc limit 1", array( + ':algo' => $algo + )); + $dbalgo->rent = dboscalar("select rent from hashrate where algo=:algo order by time desc limit 1", array( + ':algo' => $algo + )); - $stats->margin = $margin; - $stats->balances = $balances; - $stats->onsell = $onsell; + $dbalgo->factor = $factor; + $dbalgo->save(); + } - $stats->immature = $immature; - $stats->waiting = $confirmed; - $stats->renters = $renters; - - $stats->save(); - - ///////////////////////////////////////////////////////////////////////////// - - foreach(yaamp_get_algos() as $algo) - { - $factor = yaamp_get_algo_norm($algo); - - $dbalgo = getdbosql('db_algos', "name='$algo'"); - if(!$dbalgo) - { - $dbalgo = new db_algos; - $dbalgo->name = $algo; - } - - $dbalgo->profit = dboscalar("select price from hashrate where algo=:algo order by time desc limit 1", array(':algo'=>$algo)); - $dbalgo->rent = dboscalar("select rent from hashrate where algo=:algo order by time desc limit 1", array(':algo'=>$algo)); - - $dbalgo->factor = $factor; - $dbalgo->save(); - } - -// $d1 = microtime(true) - $t1xx; -// controller()->memcache->add_monitoring_function(__METHOD__, $d1); + // $d1 = microtime(true) - $t1xx; + // controller()->memcache->add_monitoring_function(__METHOD__, $d1); } function BackendStatsUpdate2() { -// debuglog('----------------------------------'); -// debuglog(__FUNCTION__); - - //////////////////////////////////////////////////////////////////////////////////////////////////// - - $step = 15; - $tm = floor(time()/$step/60)*$step*60; - - $list = dbolist("select userid, algo from shares where time>$tm group by userid, algo"); - foreach($list as $item) - { - $stats = getdbosql('db_hashuser', "time=$tm and algo=:algo and userid=:userid", - array(':algo'=>$item['algo'], ':userid'=>$item['userid'])); - if(!$stats) - { - $stats = new db_hashuser; - $stats->userid = $item['userid']; - $stats->time = $tm; - $stats->hashrate = dboscalar("select hashrate from hashuser where algo=:algo and userid=:userid order by time desc limit 1", - array(':algo'=>$item['algo'], ':userid'=>$item['userid'])); - $stats->hashrate_bad = 0; - $stats->algo = $item['algo']; - } - - $percent = 20; - $user_rate = yaamp_user_rate($item['userid'], $item['algo']); - - $stats->hashrate = round(($stats->hashrate*(100-$percent) + $user_rate*$percent) / 100); - if($stats->hashrate < 1000) $stats->hashrate = 0; - - $user_rate_bad = yaamp_user_rate_bad($item['userid'], $item['algo']); - - $stats->hashrate_bad = round(($stats->hashrate_bad*(100-$percent) + $user_rate_bad*$percent) / 100); - if($stats->hashrate_bad < 1000) $stats->hashrate_bad = 0; - - $stats->save(); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - - $step = 15; - $tm = floor(time()/$step/60)*$step*60; + // debuglog('----------------------------------'); + // debuglog(__FUNCTION__); + + //////////////////////////////////////////////////////////////////////////////////////////////////// + + $step = 15; + $tm = floor(time() / $step / 60) * $step * 60; + + $list = dbolist("select userid, algo from shares where time>$tm group by userid, algo"); + foreach ($list as $item) { + $stats = getdbosql('db_hashuser', "time=$tm and algo=:algo and userid=:userid", array( + ':algo' => $item['algo'], + ':userid' => $item['userid'] + )); + if (!$stats) { + $stats = new db_hashuser; + $stats->userid = $item['userid']; + $stats->time = $tm; + $stats->hashrate = dboscalar("select hashrate from hashuser where algo=:algo and userid=:userid order by time desc limit 1", array( + ':algo' => $item['algo'], + ':userid' => $item['userid'] + )); + $stats->hashrate_bad = 0; + $stats->algo = $item['algo']; + } + + $percent = 20; + $user_rate = yaamp_user_rate($item['userid'], $item['algo']); + + $stats->hashrate = round(($stats->hashrate * (100 - $percent) + $user_rate * $percent) / 100); + if ($stats->hashrate < 1000) + $stats->hashrate = 0; + + $user_rate_bad = yaamp_user_rate_bad($item['userid'], $item['algo']); + + $stats->hashrate_bad = round(($stats->hashrate_bad * (100 - $percent) + $user_rate_bad * $percent) / 100); + if ($stats->hashrate_bad < 1000) + $stats->hashrate_bad = 0; + + $stats->save(); + } + + //////////////////////////////////////////////////////////////////////////////////////////////////// + + $step = 15; + $tm = floor(time() / $step / 60) * $step * 60; + + $list = dbolist("select distinct jobid from jobsubmits where time>$tm"); + foreach ($list as $item) { + $jobid = $item['jobid']; + + $stats = getdbosql('db_hashrenter', "time=$tm and jobid=$jobid"); + if (!$stats) { + $stats = new db_hashrenter; + // $stats->renterid = ; + $stats->jobid = $item['jobid']; + $stats->time = $tm; + $stats->hashrate = dboscalar("select hashrate from hashrenter where jobid=:jobid order by time desc limit 1", array( + ':jobid' => $jobid + )); + $stats->hashrate_bad = 0; //dboscalar("select hashrate_bad from hashrenter where jobid=$jobid order by time desc limit 1"); + } + + $percent = 20; + $job_rate = yaamp_job_rate($jobid); + + $stats->hashrate = round(($stats->hashrate * (100 - $percent) + $job_rate * $percent) / 100); + if ($stats->hashrate < 1000) + $stats->hashrate = 0; + + $job_rate_bad = yaamp_job_rate_bad($jobid); + + $stats->hashrate_bad = round(($stats->hashrate_bad * (100 - $percent) + $job_rate_bad * $percent) / 100); + if ($stats->hashrate_bad < 1000) + $stats->hashrate_bad = 0; + + $stats->save(); + } + + //////////////////////////////////////////////////////////////////////////////////////////////////// + + $tm = floor(time() / $step / 60) * $step * 60; + $d = time() - 24 * 60 * 60; + + $list = getdbolist('db_accounts', "balance>0 OR last_earning>$d"); + foreach ($list as $user) { + $stats = getdbosql('db_balanceuser', "time=$tm and userid=$user->id"); + if (!$stats) { + $stats = new db_balanceuser; + $stats->userid = $user->id; + $stats->time = $tm; + } + + // $refcoin = getdbo('db_coins', $user->coinid); + // if(!$refcoin) $refcoin = getdbosql('db_coins', "symbol='BTC'"); + // if(!$refcoin->price || !$refcoin->price2) continue; + + // $pending1 = dboscalar("select sum(amount*price) from earnings where coinid=$refcoin->id and status!=2 and userid=$user->id"); + // $pending2 = dboscalar("select sum(amount*price) from earnings where coinid!=$refcoin->id and status!=2 and userid=$user->id"); + + $stats->pending = yaamp_convert_earnings_user($user, "status!=2"); + $stats->pending = bitcoinvaluetoa($stats->pending); - $list = dbolist("select distinct jobid from jobsubmits where time>$tm"); - foreach($list as $item) - { - $jobid = $item['jobid']; - - $stats = getdbosql('db_hashrenter', "time=$tm and jobid=$jobid"); - if(!$stats) - { - $stats = new db_hashrenter; - // $stats->renterid = ; - $stats->jobid = $item['jobid']; - $stats->time = $tm; - $stats->hashrate = dboscalar("select hashrate from hashrenter where jobid=:jobid order by time desc limit 1", array(':jobid'=>$jobid)); - $stats->hashrate_bad = 0; //dboscalar("select hashrate_bad from hashrenter where jobid=$jobid order by time desc limit 1"); - } - - $percent = 20; - $job_rate = yaamp_job_rate($jobid); - - $stats->hashrate = round(($stats->hashrate*(100-$percent) + $job_rate*$percent) / 100); - if($stats->hashrate < 1000) $stats->hashrate = 0; - - $job_rate_bad = yaamp_job_rate_bad($jobid); - - $stats->hashrate_bad = round(($stats->hashrate_bad*(100-$percent) + $job_rate_bad*$percent) / 100); - if($stats->hashrate_bad < 1000) $stats->hashrate_bad = 0; - - $stats->save(); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - - $tm = floor(time()/$step/60)*$step*60; - $d = time()-24*60*60; - - $list = getdbolist('db_accounts', "balance>0 OR last_earning>$d"); - foreach($list as $user) - { - $stats = getdbosql('db_balanceuser', "time=$tm and userid=$user->id"); - if(!$stats) - { - $stats = new db_balanceuser; - $stats->userid = $user->id; - $stats->time = $tm; - } - -// $refcoin = getdbo('db_coins', $user->coinid); -// if(!$refcoin) $refcoin = getdbosql('db_coins', "symbol='BTC'"); -// if(!$refcoin->price || !$refcoin->price2) continue; - -// $pending1 = dboscalar("select sum(amount*price) from earnings where coinid=$refcoin->id and status!=2 and userid=$user->id"); -// $pending2 = dboscalar("select sum(amount*price) from earnings where coinid!=$refcoin->id and status!=2 and userid=$user->id"); - - $stats->pending = yaamp_convert_earnings_user($user, "status!=2"); - $stats->pending = bitcoinvaluetoa($stats->pending); - - $stats->balance = $user->balance; - $stats->save(); - - $id = dboscalar("select id from earnings where userid=$user->id order by id desc limit 100, 1"); - if($id) dborun("delete from earnings where status=2 and userid=$user->id and id<$id"); - } + $stats->balance = $user->balance; + $stats->save(); + + $id = dboscalar("select id from earnings where userid=$user->id order by id desc limit 100, 1"); + if ($id) + dborun("delete from earnings where status=2 and userid=$user->id and id<$id"); + } } - - diff --git a/web/yaamp/core/backend/system.php b/web/yaamp/core/backend/system.php index b70da2ce9..fae92d6ce 100644 --- a/web/yaamp/core/backend/system.php +++ b/web/yaamp/core/backend/system.php @@ -2,354 +2,356 @@ function BackendDoBackup() { - $d = date('Y-m-d-H', time()); - $filename = "/root/backup/yaamp-$d.sql"; - - if (is_readable("/usr/bin/xz")) { - $ziptool = "xz --threads=4"; $ext = ".xz"; - } else { - $ziptool = "gzip"; $ext = ".gz"; - } - - include_once("/etc/yiimp/keys.php"); - - $host = YAAMP_DBHOST; - $db = YAAMP_DBNAME; - - $user = YIIMP_MYSQLDUMP_USER; - $pass = YIIMP_MYSQLDUMP_PASS; - - if (1) { - // faster on huge databases if the disk is fast (nvme), reduce the db lock time - system("mysqldump -h $host -u$user -p$pass --skip-extended-insert $db > $filename"); - shell_exec("$ziptool $filename &"); // compress then the .sql in background (db is no more locked) - } else { - // previous method (ok on small pools) - system("mysqldump -h $host -u$user -p$pass --skip-extended-insert $db | $ziptool > $filename$ext"); - } + $d = date('Y-m-d-H', time()); + $filename = "/root/backup/yaamp-$d.sql"; + + if (is_readable("/usr/bin/xz")) { + $ziptool = "xz --threads=4"; + $ext = ".xz"; + } else { + $ziptool = "gzip"; + $ext = ".gz"; + } + + include_once("/etc/yiimp/keys.php"); + + $host = YAAMP_DBHOST; + $db = YAAMP_DBNAME; + + $user = YIIMP_MYSQLDUMP_USER; + $pass = YIIMP_MYSQLDUMP_PASS; + + $d = date('Y-m-d-H', time()); + $filename = YIIMP_MYSQLDUMP_PATH . DIRECTORY_SEPARATOR . "$db-$d.sql"; + + if (1) { + // faster on huge databases if the disk is fast (nvme), reduce the db lock time + system("mysqldump -h $host -u$user -p$pass --skip-extended-insert $db > $filename"); + shell_exec("$ziptool $filename &"); // compress then the .sql in background (db is no more locked) + } else { + // previous method (ok on small pools) + system("mysqldump -h $host -u$user -p$pass --skip-extended-insert $db | $ziptool > $filename$ext"); + } } function BackendQuickClean() { - $coins = getdbolist('db_coins', "installed"); + $coins = getdbolist('db_coins', "installed"); - foreach($coins as $coin) - { - $delay = time() - 7*24*60*60; + foreach ($coins as $coin) { + $delay = time() - 7 * 24 * 60 * 60; - $id = dboscalar("select id from blocks where coin_id=$coin->id and time<$delay and - id not in (select blockid from earnings where coinid=$coin->id) - order by id desc limit 200, 1"); + $id = dboscalar("select id from blocks where coin_id=$coin->id and time<$delay and + id not in (select blockid from earnings where coinid=$coin->id) + order by id desc limit 200, 1"); - if($id) dborun("delete from blocks where coin_id=$coin->id and time<$delay and - id not in (select blockid from earnings where coinid=$coin->id) and id<$id"); - } + if ($id) + dborun("delete from blocks where coin_id=$coin->id and time<$delay and + id not in (select blockid from earnings where coinid=$coin->id) and id<$id"); + } - dborun("delete from earnings where blockid in (select id from blocks where category='orphan')"); - dborun("delete from earnings where blockid not in (select id from blocks)"); - dborun("UPDATE blocks SET amount=0 WHERE category='orphan' AND amount>0"); + dborun("delete from earnings where blockid in (select id from blocks where category='orphan')"); + dborun("delete from earnings where blockid not in (select id from blocks)"); + dborun("UPDATE blocks SET amount=0 WHERE category='orphan' AND amount>0"); } -function marketHistoryPrune($symbol="") +function marketHistoryPrune($symbol = "") { - $delay2M = settings_get("history_prune_delay", time() - 61*24*60*60); // 2 months - dborun("DELETE FROM market_history WHERE time < ".intval($delay2M)); - - // Prune records older than 1 week, one max per hour - $delay7D = time() - 7*24*60*60; - $sqlFilter = (!empty($symbol)) ? "AND C.symbol='$symbol'" : ''; - $prune = dbolist("SELECT idcoin, idmarket, - AVG(MH.price) AS price, AVG(MH.price2) AS price2, MAX(MH.balance) AS balance, - MIN(MH.id) AS firstid, COUNT(MH.id) AS nbrecords, (MH.time DIV 3600) AS ival - FROM market_history MH - INNER JOIN coins C ON C.id = MH.idcoin - WHERE MH.time < $delay7D $sqlFilter - GROUP BY MH.idcoin, MH.idmarket, ival - HAVING nbrecords > 1"); - - $nbDel = 0; $nbUpd = 0; - foreach ($prune as $row) { - if (empty($row['idmarket'])) - $sqlFilter = "idcoin=:idcoin AND idmarket IS NULL"; - else - $sqlFilter = "idcoin=:idcoin AND idmarket=".intval($row['idmarket']); - - $nbDel += dborun("DELETE FROM market_history WHERE $sqlFilter AND id != :firstid - AND (time DIV 3600) = :interval", array( - ':idcoin' => $row['idcoin'], - ':interval'=> $row['ival'], - ':firstid' => $row['firstid'], - )); - - $nbUpd += dborun("UPDATE market_history SET time=:interval, - balance=:balance, price=:price, price2=:price2 - WHERE id=:firstid", array( - ':interval' => (3600 * $row['ival']), - ':balance' => $row['balance'], - ':price' => $row['price'], ':price2' => $row['price2'], - ':firstid' => $row['firstid'], - )); - } - if ($nbDel) debuglog("history: $nbDel records pruned, $nbUpd updated $symbol"); + $delay2M = settings_get("history_prune_delay", time() - 61 * 24 * 60 * 60); // 2 months + dborun("DELETE FROM market_history WHERE time < " . intval($delay2M)); + + // Prune records older than 1 week, one max per hour + $delay7D = time() - 7 * 24 * 60 * 60; + $sqlFilter = (!empty($symbol)) ? "AND C.symbol='$symbol'" : ''; + $prune = dbolist("SELECT idcoin, idmarket, + AVG(MH.price) AS price, AVG(MH.price2) AS price2, MAX(MH.balance) AS balance, + MIN(MH.id) AS firstid, COUNT(MH.id) AS nbrecords, (MH.time DIV 3600) AS ival + FROM market_history MH + INNER JOIN coins C ON C.id = MH.idcoin + WHERE MH.time < $delay7D $sqlFilter + GROUP BY MH.idcoin, MH.idmarket, ival + HAVING nbrecords > 1"); + + $nbDel = 0; + $nbUpd = 0; + foreach ($prune as $row) { + if (empty($row['idmarket'])) + $sqlFilter = "idcoin=:idcoin AND idmarket IS NULL"; + else + $sqlFilter = "idcoin=:idcoin AND idmarket=" . intval($row['idmarket']); + + $nbDel += dborun("DELETE FROM market_history WHERE $sqlFilter AND id != :firstid + AND (time DIV 3600) = :interval", array( + ':idcoin' => $row['idcoin'], + ':interval' => $row['ival'], + ':firstid' => $row['firstid'] + )); + + $nbUpd += dborun("UPDATE market_history SET time=:interval, + balance=:balance, price=:price, price2=:price2 + WHERE id=:firstid", array( + ':interval' => (3600 * $row['ival']), + ':balance' => $row['balance'], + ':price' => $row['price'], + ':price2' => $row['price2'], + ':firstid' => $row['firstid'] + )); + } + if ($nbDel) + debuglog("history: $nbDel records pruned, $nbUpd updated $symbol"); } function consolidateOldShares() { - $delay = time() - 24*60*60; // drop invalid shares not used anymore (24h graph only) - dborun("DELETE FROM shares WHERE time < $delay AND valid = 0"); - - $t1 = time() - 48*3600; - $list = dbolist("SELECT coinid, userid, workerid, algo, AVG(time) AS time, SUM(difficulty) AS difficulty, AVG(share_diff) AS share_diff ". - "FROM shares WHERE valid AND time < $t1 AND pid > 0 ". - "GROUP BY coinid, userid, workerid, algo ORDER BY coinid, userid"); - $pruned = 0; - foreach ($list as $row) { - $share = new db_shares; - $share->isNewRecord = true; - $share->coinid = $row['coinid']; - $share->userid = $row['userid']; - $share->workerid = $row['workerid']; - $share->algo = $row['algo']; - $share->time = (int) $row['time']; - $share->difficulty = $row['difficulty']; - $share->share_diff = $row['share_diff']; - $share->valid = 1; - $share->pid = 0; - if ($share->save()) { - $pruned += dborun("DELETE FROM shares WHERE userid=:userid AND coinid=:coinid AND workerid=:worker AND pid > 0 AND time < $t1", array( - ':userid' => $row['userid'], - ':coinid' => $row['coinid'], - ':worker' => $row['workerid'], - )); - } - } - if ($pruned) { - debuglog("$pruned old shares records were consolidated"); - } - return $pruned; + $delay = time() - 24 * 60 * 60; // drop invalid shares not used anymore (24h graph only) + dborun("DELETE FROM shares WHERE time < $delay AND valid = 0"); + + $t1 = time() - 48 * 3600; + $list = dbolist("SELECT coinid, userid, workerid, algo, AVG(time) AS time, SUM(difficulty) AS difficulty, AVG(share_diff) AS share_diff " . "FROM shares WHERE valid AND time < $t1 AND pid > 0 " . "GROUP BY coinid, userid, workerid, algo ORDER BY coinid, userid"); + $pruned = 0; + foreach ($list as $row) { + $share = new db_shares; + $share->isNewRecord = true; + $share->coinid = $row['coinid']; + $share->userid = $row['userid']; + $share->workerid = $row['workerid']; + $share->algo = $row['algo']; + $share->time = (int) $row['time']; + $share->difficulty = $row['difficulty']; + $share->share_diff = $row['share_diff']; + $share->valid = 1; + $share->pid = 0; + if ($share->save()) { + $pruned += dborun("DELETE FROM shares WHERE userid=:userid AND coinid=:coinid AND workerid=:worker AND pid > 0 AND time < $t1", array( + ':userid' => $row['userid'], + ':coinid' => $row['coinid'], + ':worker' => $row['workerid'] + )); + } + } + if ($pruned) { + debuglog("$pruned old shares records were consolidated"); + } + return $pruned; } function BackendCleanDatabase() { - marketHistoryPrune(); - - $delay = time() - 60*24*60*60; - dborun("DELETE from blocks where time<$delay"); - dborun("delete from hashstats where time<$delay"); - dborun("delete from payouts where time<$delay"); - dborun("delete from rentertxs where time<$delay"); - dborun("DELETE FROM shares WHERE time<$delay"); - - $delay = time() - 2*24*60*60; - dborun("delete from stats where time<$delay"); - dborun("delete from hashrate where time<$delay"); - dborun("delete from hashuser where time<$delay"); - dborun("delete from hashrenter where time<$delay"); - dborun("delete from balanceuser where time<$delay"); - dborun("delete from exchange where send_time<$delay"); - dborun("DELETE FROM shares WHERE time<$delay AND coinid NOT IN (select id from coins)"); - - consolidateOldShares(); - - $delay = time() - 12*60*60; - dborun("delete from earnings where status=2 and mature_time<$delay"); + marketHistoryPrune(); + + $delay = time() - 60 * 24 * 60 * 60; + dborun("DELETE from blocks where time<$delay"); + dborun("delete from hashstats where time<$delay"); + dborun("delete from payouts where time<$delay"); + dborun("delete from rentertxs where time<$delay"); + dborun("DELETE FROM shares WHERE time<$delay"); + + $delay = time() - 2 * 24 * 60 * 60; + dborun("delete from stats where time<$delay"); + dborun("delete from hashrate where time<$delay"); + dborun("delete from hashuser where time<$delay"); + dborun("delete from hashrenter where time<$delay"); + dborun("delete from balanceuser where time<$delay"); + dborun("delete from exchange where send_time<$delay"); + dborun("DELETE FROM shares WHERE time<$delay AND coinid NOT IN (select id from coins)"); + + consolidateOldShares(); + + $delay = time() - 12 * 60 * 60; + dborun("delete from earnings where status=2 and mature_time<$delay"); } function BackendOptimizeTables() { - $list = dbolist("show tables"); - foreach($list as $item) - { - $tablename = $item['Tables_in_yaamp']; - dbolist("optimize table $tablename"); - - sleep(1); - } + $list = dbolist("show tables"); + foreach ($list as $item) { + $tablename = $item['Tables_in_yaamp']; + dbolist("optimize table $tablename"); + + sleep(1); + } } function BackendProcessList() { - $list = dbolist("show processlist"); - foreach($list as $item) - { - $conn = getdbo('db_connections', $item['Id']); - if(!$conn) - { - $conn = new db_connections; - $conn->id = $item['Id']; - $conn->user = $item['User']; - $conn->host = $item['Host']; - $conn->db = $item['db']; - $conn->created = time(); - } - - $conn->idle = $item['Time']; - $conn->last = time(); - - $conn->save(); - } - - $delay = time() - 5*60; - dborun("delete from connections where last<$delay"); + $list = dbolist("show processlist"); + foreach ($list as $item) { + $conn = getdbo('db_connections', $item['Id']); + if (!$conn) { + $conn = new db_connections; + $conn->id = $item['Id']; + $conn->user = $item['User']; + $conn->host = $item['Host']; + $conn->db = $item['db']; + $conn->created = time(); + } + + $conn->idle = $item['Time']; + $conn->last = time(); + + $conn->save(); + } + + $delay = time() - 5 * 60; + dborun("delete from connections where last<$delay"); } function BackendRunCoinActions() { -// debuglog(__FUNCTION__); + // debuglog(__FUNCTION__); -// $hostname = exec("hostname"); -// $server = getdbosql('db_servers', "name='$hostname'"); -// if(!$server) -// { -// $server = new db_servers; -// $server->name = $hostname; -// } + // $hostname = exec("hostname"); + // $server = getdbosql('db_servers', "name='$hostname'"); + // if(!$server) + // { + // $server = new db_servers; + // $server->name = $hostname; + // } -// $server->uptime = exec("uptime"); -// $server->save(); + // $server->uptime = exec("uptime"); + // $server->save(); - ////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////// -// if($hostname == 'yaamp') -// { -// $mining = getdbosql('db_mining'); -// exec("pgrep stratum", $ids, $ret); + // if($hostname == 'yaamp') + // { + // $mining = getdbosql('db_mining'); + // exec("pgrep stratum", $ids, $ret); -// $mining->stratumids = implode(',', $ids); -// $mining->save(); -// } + // $mining->stratumids = implode(',', $ids); + // $mining->save(); + // } - ///////////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////////////// -// $coins = getdbolist('db_coins'); -// foreach($coins as $coin) -// { -// if(empty($coin->action) || empty($coin->program) || empty($coin->conf_folder)) continue; -// $hostname = exec("hostname"); -// if($hostname != $coin->rpchost) continue; -// switch($coin->action) -// { -// case 1: -// debuglog("starting $coin->program"); + // $coins = getdbolist('db_coins'); + // foreach($coins as $coin) + // { + // if(empty($coin->action) || empty($coin->program) || empty($coin->conf_folder)) continue; + // $hostname = exec("hostname"); + // if($hostname != $coin->rpchost) continue; + // switch($coin->action) + // { + // case 1: + // debuglog("starting $coin->program"); -// $debugfile = YAAMP_WALLETS."/$coin->conf_folder/debug.log"; -// @unlink($debugfile); + // $debugfile = YAAMP_WALLETS."/$coin->conf_folder/debug.log"; + // @unlink($debugfile); -// exec(YAAMP_BIN."/run-background.sh ".YAAMP_BIN."/$coin->program"); -// $coin->enable = true; -// break; + // exec(YAAMP_BIN."/run-background.sh ".YAAMP_BIN."/$coin->program"); + // $coin->enable = true; + // break; -// case 2: -// debuglog("stopping $coin->program"); -// exec(YAAMP_BIN."/$coin->program stop"); -// break; + // case 2: + // debuglog("stopping $coin->program"); + // exec(YAAMP_BIN."/$coin->program stop"); + // break; -// case 4: -// debuglog("restarting $coin->program"); -// exec(YAAMP_BIN."/$coin->program stop"); -// sleep(10); + // case 4: + // debuglog("restarting $coin->program"); + // exec(YAAMP_BIN."/$coin->program stop"); + // sleep(10); -// $debugfile = YAAMP_WALLETS."/$coin->conf_folder/debug.log"; -// @unlink($debugfile); + // $debugfile = YAAMP_WALLETS."/$coin->conf_folder/debug.log"; + // @unlink($debugfile); -// exec(YAAMP_BIN."/run-background.sh ".YAAMP_BIN."/$coin->program"); -// $coin->enable = true; -// break; + // exec(YAAMP_BIN."/run-background.sh ".YAAMP_BIN."/$coin->program"); + // $coin->enable = true; + // break; -// case 3: -// debuglog("reset blockchain $coin->conf_folder"); -// $folder = YAAMP_WALLETS."/$coin->conf_folder"; + // case 3: + // debuglog("reset blockchain $coin->conf_folder"); + // $folder = YAAMP_WALLETS."/$coin->conf_folder"; -// // exec("rm {$folder}/blk*.dat"); -// exec("rm -fr {$folder}/database"); -// break; + // // exec("rm {$folder}/blk*.dat"); + // exec("rm -fr {$folder}/database"); + // break; -// case 5: -// $t = time(); -// $coin->rpcport = $coin->id*2+10240; -// $coin->rpcuser = 'yaamprpc'; -// $coin->rpcpasswd = md5("$t.$coin->id"); -// $coin->save(); + // case 5: + // $t = time(); + // $coin->rpcport = $coin->id*2+10240; + // $coin->rpcuser = 'yaamprpc'; + // $coin->rpcpasswd = md5("$t.$coin->id"); + // $coin->save(); -// $configfile = YAAMP_WALLETS."/$coin->conf_folder/".substr($coin->conf_folder, 1).".conf"; -// debuglog("make config $configfile"); + // $configfile = YAAMP_WALLETS."/$coin->conf_folder/".substr($coin->conf_folder, 1).".conf"; + // debuglog("make config $configfile"); -// $stratum_port = 3433; + // $stratum_port = 3433; -// if($coin->algo == 'sha256') -// $stratum_port = 3333; + // if($coin->algo == 'sha256') + // $stratum_port = 3333; -// else if($coin->algo == 'scrypt') -// $stratum_port = 3433; + // else if($coin->algo == 'scrypt') + // $stratum_port = 3433; -// else if($coin->algo == 'x11') -// $stratum_port = 3533; + // else if($coin->algo == 'x11') + // $stratum_port = 3533; -// else if($coin->algo == 'x13') -// $stratum_port = 3633; + // else if($coin->algo == 'x13') + // $stratum_port = 3633; -// else if($coin->algo == 'x14') -// $stratum_port = 3933; + // else if($coin->algo == 'x14') + // $stratum_port = 3933; -// else if($coin->algo == 'x15') -// $stratum_port = 3733; + // else if($coin->algo == 'x15') + // $stratum_port = 3733; -// else if($coin->algo == 'nist5') -// $stratum_port = 3833; + // else if($coin->algo == 'nist5') + // $stratum_port = 3833; -// else if($coin->algo == 'quark') -// $stratum_port = 4033; + // else if($coin->algo == 'quark') + // $stratum_port = 4033; -// else if($coin->algo == 'fresh') -// $stratum_port = 4133; + // else if($coin->algo == 'fresh') + // $stratum_port = 4133; -// else if($coin->algo == 'neoscrypt') -// $stratum_port = 4233; + // else if($coin->algo == 'neoscrypt') + // $stratum_port = 4233; -// else if($coin->algo == 'scryptn') -// $stratum_port = 4333; + // else if($coin->algo == 'scryptn') + // $stratum_port = 4333; -// else if($coin->algo == 'lyra2') -// $stratum_port = 4433; + // else if($coin->algo == 'lyra2') + // $stratum_port = 4433; -// else if($coin->algo == 'blake') -// $stratum_port = 4533; + // else if($coin->algo == 'blake') + // $stratum_port = 4533; -// // else if($coin->algo == 'keccak') -// // $stratum_port = 3933; + // // else if($coin->algo == 'keccak') + // // $stratum_port = 3933; -// $data = "server=1\ndeamon=1\ngen=0\nrpcuser=$coin->rpcuser\nrpcpassword=$coin->rpcpasswd\nrpcport=$coin->rpcport\nrpcallowip=10.*.*.*\nblocknotify=".YAAMP_BIN."/blocknotify.sh --host yaamp --port $stratum_port --id $coin->id --block %s --password tu8tu5\n"; -// file_put_contents($configfile, $data); + // $data = "server=1\ndeamon=1\ngen=0\nrpcuser=$coin->rpcuser\nrpcpassword=$coin->rpcpasswd\nrpcport=$coin->rpcport\nrpcallowip=10.*.*.*\nblocknotify=".YAAMP_BIN."/blocknotify.sh --host yaamp --port $stratum_port --id $coin->id --block %s --password tu8tu5\n"; + // file_put_contents($configfile, $data); -// debuglog("starting $coin->program"); + // debuglog("starting $coin->program"); -// $debugfile = YAAMP_WALLETS."/$coin->conf_folder/debug.log"; -// @unlink($debugfile); + // $debugfile = YAAMP_WALLETS."/$coin->conf_folder/debug.log"; + // @unlink($debugfile); -// exec(YAAMP_BIN."/run-background.sh ".YAAMP_BIN."/$coin->program"); -// $coin->enable = true; + // exec(YAAMP_BIN."/run-background.sh ".YAAMP_BIN."/$coin->program"); + // $coin->enable = true; -// break; -// } + // break; + // } -// $coin->action = null; -// $coin->save(); -// } + // $coin->action = null; + // $coin->save(); + // } -// $filename = '/root/stratum/stratum.log'; -// $filesize = filesize($filename); + // $filename = '/root/stratum/stratum.log'; + // $filesize = filesize($filename); -// $oldsize = controller()->memcache->get('stratum_log_size'); -// if($oldsize == $filesize) return; + // $oldsize = controller()->memcache->get('stratum_log_size'); + // if($oldsize == $filesize) return; -// $file = fopen($filename, $r); -// if(!$file) return; + // $file = fopen($filename, $r); + // if(!$file) return; -// fseek($file, $oldsize); -// $data = fread($file, $filesize-$oldsize); -// fclose($file); + // fseek($file, $oldsize); + // $data = fread($file, $filesize-$oldsize); + // fclose($file); -// controller()->memcache->set('stratum_log_size', $filesize); -// system("echo \"$data\" | mail -s \"yiimp server\" ".YAAMP_ADMIN_EMAIL); + // controller()->memcache->set('stratum_log_size', $filesize); + // system("echo \"$data\" | mail -s \"yiimp server\" ".YAAMP_ADMIN_EMAIL); } - diff --git a/web/yaamp/core/backend/users.php b/web/yaamp/core/backend/users.php index 443443d10..11499d358 100644 --- a/web/yaamp/core/backend/users.php +++ b/web/yaamp/core/backend/users.php @@ -2,103 +2,97 @@ function BackendUsersUpdate() { - $t1 = microtime(true); - - $list = getdbolist('db_accounts', "coinid IS NULL OR IFNULL(coinsymbol,'') != ''"); - foreach($list as $user) - { - $old_usercoinid = $user->coinid; - // debuglog("testing user $user->username, $user->coinsymbol"); - if(!empty($user->coinsymbol)) - { - $coin = getdbosql('db_coins', "symbol=:symbol", array(':symbol'=>$user->coinsymbol)); - $user->coinsymbol = ''; - - if($coin) - { - if($user->coinid == $coin->id) - { - $user->save(); - continue; - } - - $remote = new WalletRPC($coin); - - $b = $remote->validateaddress($user->username); - if(arraySafeVal($b,'isvalid')) - { - $old_balance = $user->balance; - if($user->balance > 0) - { - $coinref = getdbo('db_coins', $user->coinid); - if(!$coinref) { - if (YAAMP_ALLOW_EXCHANGE) - $coinref = getdbosql('db_coins', "symbol='BTC'"); - else - continue; - } - - $user->balance = $user->balance * $coinref->price / $coin->price; - } - - $user->coinid = $coin->id; - $user->save(); - - debuglog("{$user->username} converted to {$user->balance} {$coin->symbol} (old: $old_balance)"); - continue; - } - } - } - - $user->coinid = 0; - - $order = YAAMP_ALLOW_EXCHANGE ? "difficulty" : "id"; - $coins = getdbolist('db_coins', "enable ORDER BY $order DESC"); - foreach($coins as $coin) - { - $remote = new WalletRPC($coin); - - $b = $remote->validateaddress($user->username); - if(!arraySafeVal($b,'isvalid')) continue; - - if ($old_usercoinid && $old_usercoinid != $coin->id) { - debuglog("{$user->username} set to {$coin->symbol}, balance {$user->balance} reset to 0"); - $user->balance = 0; - } - $user->coinid = $coin->id; - break; - } - - if (empty($user->coinid)) { - debuglog("{$user->hostaddr} - {$user->username} is an unknown address!"); - } - - $user->save(); - } - -// $delay=time()-60*60; -// $list = dborun("UPDATE coins SET dontsell=1 WHERE id in (SELECT coinid FROM accounts WHERE balance>0 OR last_earning>$delay GROUP BY coinid)"); -// $list = dborun("UPDATE coins SET dontsell=0 WHERE id not in (SELECT coinid FROM accounts WHERE balance>0 OR last_earning>$delay GROUP BY coinid)"); - - -// $list = getdbolist('db_workers', "dns is null"); -// foreach($list as $worker) -// { -// $worker->dns = $worker->ip; -// $res = system("resolveip $worker->ip"); - -// if($res) -// { -// $a = explode(' ', $res); -// if($a && isset($a[5])) -// $worker->dns = $a[5]; -// } - -// $worker->save(); -// } - - $d1 = microtime(true) - $t1; - controller()->memcache->add_monitoring_function(__METHOD__, $d1); + $t1 = microtime(true); + + $list = getdbolist('db_accounts', "coinid IS NULL OR IFNULL(coinsymbol,'') != ''"); + foreach ($list as $user) { + $old_usercoinid = $user->coinid; + // debuglog("testing user $user->username, $user->coinsymbol"); + if (!empty($user->coinsymbol)) { + $coin = getdbosql('db_coins', "symbol=:symbol", array( + ':symbol' => $user->coinsymbol + )); + $user->coinsymbol = ''; + + if ($coin) { + if ($user->coinid == $coin->id) { + $user->save(); + continue; + } + + $remote = new WalletRPC($coin); + + $b = $remote->validateaddress($user->username); + if (arraySafeVal($b, 'isvalid')) { + $old_balance = $user->balance; + if ($user->balance > 0) { + $coinref = getdbo('db_coins', $user->coinid); + if (!$coinref) { + if (YAAMP_ALLOW_EXCHANGE) + $coinref = getdbosql('db_coins', "symbol='BTC'"); + else + continue; + } + + $user->balance = $user->balance * $coinref->price / $coin->price; + } + + $user->coinid = $coin->id; + $user->save(); + + debuglog("{$user->username} converted to {$user->balance} {$coin->symbol} (old: $old_balance)"); + continue; + } + } + } + + $user->coinid = 0; + + $order = YAAMP_ALLOW_EXCHANGE ? "difficulty" : "id"; + $coins = getdbolist('db_coins', "enable ORDER BY $order DESC"); + foreach ($coins as $coin) { + $remote = new WalletRPC($coin); + + $b = $remote->validateaddress($user->username); + if (!arraySafeVal($b, 'isvalid')) + continue; + + if ($old_usercoinid && $old_usercoinid != $coin->id) { + debuglog("{$user->username} set to {$coin->symbol}, balance {$user->balance} reset to 0"); + $user->balance = 0; + } + $user->coinid = $coin->id; + break; + } + + if (empty($user->coinid)) { + debuglog("{$user->hostaddr} - {$user->username} is an unknown address!"); + } + + $user->save(); + } + + // $delay=time()-60*60; + // $list = dborun("UPDATE coins SET dontsell=1 WHERE id in (SELECT coinid FROM accounts WHERE balance>0 OR last_earning>$delay GROUP BY coinid)"); + // $list = dborun("UPDATE coins SET dontsell=0 WHERE id not in (SELECT coinid FROM accounts WHERE balance>0 OR last_earning>$delay GROUP BY coinid)"); + + + // $list = getdbolist('db_workers', "dns is null"); + // foreach($list as $worker) + // { + // $worker->dns = $worker->ip; + // $res = system("resolveip $worker->ip"); + + // if($res) + // { + // $a = explode(' ', $res); + // if($a && isset($a[5])) + // $worker->dns = $a[5]; + // } + + // $worker->save(); + // } + + $d1 = microtime(true) - $t1; + controller()->memcache->add_monitoring_function(__METHOD__, $d1); } - - diff --git a/web/yaamp/core/common/libUtil.php b/web/yaamp/core/common/libUtil.php index bf3b051c3..450ee9069 100644 --- a/web/yaamp/core/common/libUtil.php +++ b/web/yaamp/core/common/libUtil.php @@ -1,174 +1,183 @@ = 1) $text = $text.' ====================='; - error_log("$t, $d - $text"); + if ($d >= 1) $text = $text . ' ====================='; + error_log("$t, $d - $text"); - $global_lastlog = $t; + $global_lastlog = $t; } // - -function LimitRequest($name, $limit=1) +function LimitRequest($name, $limit = 1) { - $t = controller()->memcache->get("yaamp-timestamp-$name-{$_SERVER['REMOTE_ADDR']}"); - $a = controller()->memcache->get("yaamp-average-$name-{$_SERVER['REMOTE_ADDR']}"); - - if(!$a || !$t) $a = $limit; - - else - { - $p = 33; - $a = ($a * (100-$p) + (microtime(true)-$t) * $p) / 100; - } - - if($a < $limit) return false; - - controller()->memcache->set("yaamp-timestamp-$name-{$_SERVER['REMOTE_ADDR']}", microtime(true), 300); - controller()->memcache->set("yaamp-average-$name-{$_SERVER['REMOTE_ADDR']}", $a, 300); - - return true; + $t = controller() + ->memcache + ->get("yaamp-timestamp-$name-{$_SERVER['REMOTE_ADDR']}"); + $a = controller() + ->memcache + ->get("yaamp-average-$name-{$_SERVER['REMOTE_ADDR']}"); + + if (!$a || !$t) $a = $limit; + + else + { + $p = 33; + $a = ($a * (100 - $p) + (microtime(true) - $t) * $p) / 100; + } + + if ($a < $limit) return false; + + controller() + ->memcache + ->set("yaamp-timestamp-$name-{$_SERVER['REMOTE_ADDR']}", microtime(true) , 300); + controller() + ->memcache + ->set("yaamp-average-$name-{$_SERVER['REMOTE_ADDR']}", $a, 300); + + return true; } function getuserparam($address) { - if(empty($address)) return null; + if (empty($address)) return null; - $address = trim(substr($address, 0, 35)); - $user = getdbosql('db_accounts', "username=:ad", array(':ad'=>$address)); + $address = trim(substr($address, 0, 98)); + $user = getdbosql('db_accounts', "username=:ad", array( + ':ad' => $address + )); - return $user; + return $user; } function getrenterparam($address) { - if(empty($address)) return null; + if (empty($address)) return null; - $address = trim(substr($address, 0, 35)); - $renter = getdbosql('db_renters', "address=:ad", array(':ad'=>$address)); + $address = trim(substr($address, 0, 98)); + $renter = getdbosql('db_renters', "address=:ad", array( + ':ad' => $address + )); - return $renter; + return $renter; } /////////////////////////////////////////////////////////// - function GetSSModulePath($name) { - $result = findfile('yaamp/models', "/\/{$name}.php/"); - if(!$result) - $result = findfile('yaamp/modules', "/\/{$name}.php/"); + $result = findfile('yaamp/models', "/\/{$name}.php/"); + if (!$result) $result = findfile('yaamp/modules', "/\/{$name}.php/"); -// debuglog($result); - return $result; + // debuglog($result); + return $result; } function findfile($path, $pattern) { - $result = null; - - $path = rtrim(str_replace("\\", "/", $path), '/') . '/*'; - foreach(glob($path) as $fullname) - { - if(is_dir($fullname)) - { - $result = findfile($fullname, $pattern); - if($result) break; - } - - else if(preg_match($pattern, $fullname)) - { - $result = $fullname; - break; - } - } - - return $result; + $result = null; + + $path = rtrim(str_replace("\\", "/", $path) , '/') . '/*'; + foreach (glob($path) as $fullname) + { + if (is_dir($fullname)) + { + $result = findfile($fullname, $pattern); + if ($result) break; + } + + else if (preg_match($pattern, $fullname)) + { + $result = $fullname; + break; + } + } + + return $result; } -function mydump($obj, $level=2) +function mydump($obj, $level = 2) { - CVarDumper::dump($obj, $level, true); - echo "
"; + CVarDumper::dump($obj, $level, true); + echo "
"; } -function mydumperror($obj, $level=2) +function mydumperror($obj, $level = 2) { - CVarDumper::dumperror($obj, $level); + CVarDumper::dumperror($obj, $level); } -function debuglog($string, $level=2) +function debuglog($string, $level = 2) { - if(is_object($string)) - { - mydumperror($string, $level); - return; - } - - if(is_array($string)) - { - mydumperror($string, $level); - return; - } - - $now = now(); - if(!is_dir(YAAMP_LOGS)) mkdir(YAAMP_LOGS); - error_log("[$now] $string\n", 3, YAAMP_LOGS."/debug.log"); + if (is_object($string)) + { + mydumperror($string, $level); + return; + } + + if (is_array($string)) + { + mydumperror($string, $level); + return; + } + + $now = now(); + if (!is_dir(YAAMP_LOGS)) mkdir(YAAMP_LOGS); + error_log("[$now] $string\n", 3, YAAMP_LOGS . "/debug.log"); } -function echolog($string, $level=2) +function echolog($string, $level = 2) { - $now = now(); - echo "[$now] $string\n"; + $now = now(); + echo "[$now] $string\n"; } function rentallog($string) { - $now = now(); - if(!is_dir(YAAMP_LOGS)) mkdir(YAAMP_LOGS); - error_log("[$now] $string\n", 3, YAAMP_LOGS."/rental.log"); + $now = now(); + if (!is_dir(YAAMP_LOGS)) mkdir(YAAMP_LOGS); + error_log("[$now] $string\n", 3, YAAMP_LOGS . "/rental.log"); - debuglog($string); + debuglog($string); } ///////////////////////////////////////////////////////////////////////////////////////// - function xmltoarray($xmlcontent) { - $xml = simplexml_load_string($xmlcontent); - $json = json_encode($xml); - $array = json_decode($json, true); + $xml = simplexml_load_string($xmlcontent); + $json = json_encode($xml); + $array = json_decode($json, true); - return $array; + return $array; } function XssFilter($data) { - $data = str_replace(">", "", $data); - $data = str_replace("<", "", $data); - $data = str_replace("'", "", $data); - $data = str_replace('"', "", $data); -// $data = str_replace(".", "", $data); - $data = str_replace("\\", "", $data); - $data = str_replace("&", "", $data); - $data = str_replace(";", "", $data); - -// mydump($data); die; - return $data; + $data = str_replace(">", "", $data); + $data = str_replace("<", "", $data); + $data = str_replace("'", "", $data); + $data = str_replace('"', "", $data); + // $data = str_replace(".", "", $data); + $data = str_replace("\\", "", $data); + $data = str_replace("&", "", $data); + $data = str_replace(";", "", $data); + + // mydump($data); die; + return $data; } -function showDatetimePicker($model, $attribute, $options='') +function showDatetimePicker($model, $attribute, $options = '') { - $name = "{$model->tableSchema->name}[{$attribute}]"; - $id = "{$model->tableSchema->name}_{$attribute}"; + $name = "{$model + ->tableSchema->name}[{$attribute}]"; + $id = "{$model + ->tableSchema->name}_{$attribute}"; - echo ""; - echo ""; } -function showDatetimePicker2($name, $value, $options='', $callback='null') +function showDatetimePicker2($name, $value, $options = '', $callback = 'null') { - $id = $name; - echo ""; - if(empty($value)) $value = $name; - echo ""; + if (empty($value)) $value = $name; + echo ""; } function showSubmitButton($name) { - echo "
"; - echo CUFHtml::submitButton($name, array('id'=>'btnSubmit')); - echo "
"; - echo ""; + echo "
"; + echo CUFHtml::submitButton($name, array( + 'id' => 'btnSubmit' + )); + echo "
"; + echo ""; } function InitMenuTabs($tabname) { - JavascriptReady("$('$tabname').tabs({ select: function(event, ui){ + JavascriptReady("$('$tabname').tabs({ select: function(event, ui){ window.location.replace(ui.tab.hash); return true;}});"); } function fetch_url($url) { -// debuglog("fetch_url($url)"); - $buffer = ''; + // debuglog("fetch_url($url)"); + $buffer = ''; - $file = @fopen($url, "r"); - if(!$file) return null; + $file = @fopen($url, "r"); + if (!$file) return null; - while(!feof($file)) - { - $line = fgets($file, 1024); - $buffer .= $line; - } + while (!feof($file)) + { + $line = fgets($file, 1024); + $buffer .= $line; + } - fclose($file); - return $buffer; + fclose($file); + return $buffer; } function gettempfile($ext) { - $phpsessid = session_id(); - $random = mt_rand(); + $phpsessid = session_id(); + $random = mt_rand(); - $filename = SANSSPACE_TEMP."\\{$phpsessid}-{$random}{$ext}"; - return $filename; + $filename = SANSSPACE_TEMP . "\\{$phpsessid}-{$random}{$ext}"; + return $filename; } function make_bitly_url($url, $format = 'xml', $version = '2.0.1') { - $login = 'o_1uu6u4g2h4'; - $appkey = 'R_433ebafeb24374d6c183c0fcbcc01575'; - - $bitly = 'http://api.bit.ly/shorten?version='.$version.'&longUrl='.urlencode($url).'&login='.$login.'&apiKey='.$appkey.'&format='.$format; - $response = file_get_contents($bitly); -// debuglog($response); - - if(strtolower($format) == 'json') - { - $json = @json_decode($response,true); - return $json['results'][$url]['shortUrl']; - } - else //xml - { - $xml = simplexml_load_string($response); - return 'bit.ly/'.$xml->results->nodeKeyVal->hash; - } + $login = 'o_1uu6u4g2h4'; + $appkey = 'R_433ebafeb24374d6c183c0fcbcc01575'; + + $bitly = 'http://api.bit.ly/shorten?version=' . $version . '&longUrl=' . urlencode($url) . '&login=' . $login . '&apiKey=' . $appkey . '&format=' . $format; + $response = file_get_contents($bitly); + // debuglog($response); + if (strtolower($format) == 'json') + { + $json = @json_decode($response, true); + return $json['results'][$url]['shortUrl']; + } + else + //xml + + { + $xml = simplexml_load_string($response); + return 'bit.ly/' . $xml + ->results + ->nodeKeyVal->hash; + } } function resolveShortURL($url1) { - $ch = curl_init("$url1"); + $ch = curl_init("$url1"); - curl_setopt($ch, CURLOPT_HEADER, true); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_ENCODING , "deflate,gzip"); + curl_setopt($ch, CURLOPT_HEADER, true); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_ENCODING, "deflate,gzip"); - $http_data = curl_exec($ch); - $curl_info = curl_getinfo($ch); - $headers = substr($http_data, 0, $curl_info["header_size"]); + $http_data = curl_exec($ch); + $curl_info = curl_getinfo($ch); + $headers = substr($http_data, 0, $curl_info["header_size"]); - preg_match("!\r\n(?:Location|URI): *(.*?) *\r\n!", $headers, $matches); - $url = $matches[1]; + preg_match("!\r\n(?:Location|URI): *(.*?) *\r\n!", $headers, $matches); + $url = $matches[1]; -// debuglog(" short $url1 -> $url"); - return empty($url)? $url1: $url; + // debuglog(" short $url1 -> $url"); + return empty($url) ? $url1 : $url; } function is_short_url($url) { - // 1. Overall URL length - May be a max of 30 charecters - if (strlen($url) > 30) return false; + // 1. Overall URL length - May be a max of 30 charecters + if (strlen($url) > 30) return false; - $parts = parse_url($url); + $parts = parse_url($url); - // No query string & no fragment - if ($parts["query"] || $parts["fragment"]) return false; + // No query string & no fragment + if ($parts["query"] || $parts["fragment"]) return false; - $path = $parts["path"]; - $pathParts = explode("/", $path); + $path = $parts["path"]; + $pathParts = explode("/", $path); - // 3. Number of '/' after protocol (http://) - Max 2 - if (count($pathParts) > 2) return false; + // 3. Number of '/' after protocol (http://) - Max 2 + if (count($pathParts) > 2) return false; - // 2. URL length after last '/' - May be a max of 10 characters - $lastPath = array_pop($pathParts); - if (strlen($lastPath) > 12) return false; + // 2. URL length after last '/' - May be a max of 10 characters + $lastPath = array_pop($pathParts); + if (strlen($lastPath) > 12) return false; - // 4. Max length of host - if (strlen($parts["host"]) > 10) return false; + // 4. Max length of host + if (strlen($parts["host"]) > 10) return false; - return true; + return true; } diff --git a/web/yaamp/core/common/libdbo.php b/web/yaamp/core/common/libdbo.php index f74d331b9..b4d238706 100644 --- a/web/yaamp/core/common/libdbo.php +++ b/web/yaamp/core/common/libdbo.php @@ -1,104 +1,106 @@ getTableSchema(); + $record = CActiveRecord::model($class); + $table = $record->getTableSchema(); + + $sql = "$table->primaryKey=:db_key"; + return $record->find($sql, array( + ':db_key' => $id + )); - $sql = "$table->primaryKey=:db_key"; - return $record->find($sql, array(':db_key'=>$id)); + // return $record->findByPk($id); -// return $record->findByPk($id); } -function getdbosql($class, $sql='1', $params=array()) +function getdbosql($class, $sql = '1', $params = array()) { -// debuglog("$class, $sql"); - return CActiveRecord::model($class)->find($sql, $params); + // debuglog("$class, $sql"); + return CActiveRecord::model($class)->find($sql, $params); } -function getdbolist($class, $sql='1', $params=array()) +function getdbolist($class, $sql = '1', $params = array()) { -// debuglog("sql $sql"); - return CActiveRecord::model($class)->findAll($sql, $params); + // debuglog("sql $sql"); + return CActiveRecord::model($class)->findAll($sql, $params); } -function getdbocount($class, $sql='1', $params=array()) +function getdbocount($class, $sql = '1', $params = array()) { -// debuglog("sql $sql"); - return CActiveRecord::model($class)->count($sql, $params); + // debuglog("sql $sql"); + return CActiveRecord::model($class)->count($sql, $params); } -function dborun($sql, $params=array()) +function dborun($sql, $params = array()) { - $command = app()->db->createCommand($sql); + $command = app() + ->db + ->createCommand($sql); - foreach($params as $name=>$value) - $command->bindValue($name, $value); + foreach ($params as $name => $value) $command->bindValue($name, $value); - return $command->execute(); + return $command->execute(); } -function dboscalar($sql, $params=array()) +function dboscalar($sql, $params = array()) { - $command = app()->db->createCommand($sql); + $command = app() + ->db + ->createCommand($sql); - foreach($params as $name=>$value) - $command->bindValue($name, $value); + foreach ($params as $name => $value) $command->bindValue($name, $value); - return $command->queryScalar(); + return $command->queryScalar(); } -function dborow($sql, $params=array()) +function dborow($sql, $params = array()) { - $command = app()->db->createCommand($sql); + $command = app() + ->db + ->createCommand($sql); - foreach($params as $name=>$value) - $command->bindValue($name, $value); + foreach ($params as $name => $value) $command->bindValue($name, $value); - return $command->queryRow(); + return $command->queryRow(); } -function dbocolumn($sql, $params=array()) +function dbocolumn($sql, $params = array()) { - $command = app()->db->createCommand($sql); + $command = app() + ->db + ->createCommand($sql); - foreach($params as $name=>$value) - $command->bindValue($name, $value); + foreach ($params as $name => $value) $command->bindValue($name, $value); - return $command->queryColumn(); + return $command->queryColumn(); } -function dbolist($sql, $params=array()) +function dbolist($sql, $params = array()) { - $command = app()->db->createCommand($sql); + $command = app() + ->db + ->createCommand($sql); - foreach($params as $name=>$value) - $command->bindValue($name, $value); + foreach ($params as $name => $value) $command->bindValue($name, $value); - return $command->queryAll(); + return $command->queryAll(); } function getdbolistWith($model, $with, $criteria) { - return CActiveRecord::model($model)->with($with)->findAll($criteria); + return CActiveRecord::model($model)->with($with)->findAll($criteria); } -function sqlQuote($value, $querytype='') +function sqlQuote($value, $querytype = '') { - $db = app()->db; - $quoted = $value; - - if ($querytype == '') - $quoted = $db->quoteValue($value); - elseif ($querytype == 'beginWith') - $quoted = $db->quoteValue($value.'%'); - elseif ($querytype == 'endWith') - $quoted = $db->quoteValue('%'.$value); - elseif ($querytype == 'contains') - $quoted = $db->quoteValue('%'.$value.'%'); - - return $quoted; + $db = app()->db; + $quoted = $value; + + if ($querytype == '') $quoted = $db->quoteValue($value); + elseif ($querytype == 'beginWith') $quoted = $db->quoteValue($value . '%'); + elseif ($querytype == 'endWith') $quoted = $db->quoteValue('%' . $value); + elseif ($querytype == 'contains') $quoted = $db->quoteValue('%' . $value . '%'); + + return $quoted; } diff --git a/web/yaamp/core/common/system.php b/web/yaamp/core/common/system.php index a666673ff..9a14d467f 100644 --- a/web/yaamp/core/common/system.php +++ b/web/yaamp/core/common/system.php @@ -1,66 +1,66 @@ memcache->get("last_email_sent_$name"); - if($last + $t*60 > time()) return; + // debuglog(__FUNCTION__); + $last = controller() + ->memcache + ->get("last_email_sent_$name"); + if ($last + $t * 60 > time()) return; - debuglog("mail('".YAAMP_ADMIN_EMAIL."', $title, ...)"); + debuglog("mail('" . YAAMP_ADMIN_EMAIL . "', $title, ...)"); - $b = mail(YAAMP_ADMIN_EMAIL, $title, $message); - if(!$b) debuglog('error sending email'); + $b = mail(YAAMP_ADMIN_EMAIL, $title, $message); + if (!$b) debuglog('error sending email'); - controller()->memcache->set("last_email_sent_$name", time()); + controller() + ->memcache + ->set("last_email_sent_$name", time()); } function dos_filesize($fn) { - return exec('FOR %A IN ("'.$fn.'") DO @ECHO %~zA'); + return exec('FOR %A IN ("' . $fn . '") DO @ECHO %~zA'); } ////////////////////////////////////////////////////////////// - function GetCpuLoad() { - $wmi = new COM("Winmgmts://"); - $result = $wmi->execquery("SELECT LoadPercentage FROM Win32_Processor"); + $wmi = new COM("Winmgmts://"); + $result = $wmi->execquery("SELECT LoadPercentage FROM Win32_Processor"); - $cpu_num = 0; - $load_total = 0; + $cpu_num = 0; + $load_total = 0; - foreach($result as $cpu) - { - $cpu_num++; - $load_total += $cpu->loadpercentage; - } + foreach ($result as $cpu) + { + $cpu_num++; + $load_total += $cpu->loadpercentage; + } - $load = round($load_total/$cpu_num); - return $load; + $load = round($load_total / $cpu_num); + return $load; } function GetNetworkLoad() { - $wmi = new COM("Winmgmts://"); - $allnets = $wmi->execquery("Select BytesTotalPersec From Win32_PerfFormattedData_Tcpip_NetworkInterface where BytesTotalPersec>1"); + $wmi = new COM("Winmgmts://"); + $allnets = $wmi->execquery("Select BytesTotalPersec From Win32_PerfFormattedData_Tcpip_NetworkInterface where BytesTotalPersec>1"); - $totalbps = 0; - foreach($allnets as $network) - { - $bps = $network->BytesTotalPersec*8; - $totalbps += $bps; - } + $totalbps = 0; + foreach ($allnets as $network) + { + $bps = $network->BytesTotalPersec * 8; + $totalbps += $bps; + } - return $totalbps; + return $totalbps; } function getclientip() { - if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) - return $_SERVER['HTTP_X_FORWARDED_FOR']; + if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) return $_SERVER['HTTP_X_FORWARDED_FOR']; - return $_SERVER['REMOTE_ADDR']; + return $_SERVER['REMOTE_ADDR']; } /** @@ -70,36 +70,36 @@ function getclientip() */ function get_ip_address() { - // check for shared internet/ISP IP - if (!empty($_SERVER['HTTP_CLIENT_IP']) && validate_ip($_SERVER['HTTP_CLIENT_IP'])) { - return $_SERVER['HTTP_CLIENT_IP']; - } - - // check for IPs passing through proxies - if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { - // check if multiple ips exist in var - if (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',') !== false) { - $iplist = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); - foreach ($iplist as $ip) { - if (validate_ip($ip)) - return $ip; - } - } else { - if (validate_ip($_SERVER['HTTP_X_FORWARDED_FOR'])) - return $_SERVER['HTTP_X_FORWARDED_FOR']; - } - } - if (!empty($_SERVER['HTTP_X_FORWARDED']) && validate_ip($_SERVER['HTTP_X_FORWARDED'])) - return $_SERVER['HTTP_X_FORWARDED']; - if (!empty($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']) && validate_ip($_SERVER['HTTP_X_CLUSTER_CLIENT_IP'])) - return $_SERVER['HTTP_X_CLUSTER_CLIENT_IP']; - if (!empty($_SERVER['HTTP_FORWARDED_FOR']) && validate_ip($_SERVER['HTTP_FORWARDED_FOR'])) - return $_SERVER['HTTP_FORWARDED_FOR']; - if (!empty($_SERVER['HTTP_FORWARDED']) && validate_ip($_SERVER['HTTP_FORWARDED'])) - return $_SERVER['HTTP_FORWARDED']; - - // return unreliable ip since all else failed - return $_SERVER['REMOTE_ADDR']; + // check for shared internet/ISP IP + if (!empty($_SERVER['HTTP_CLIENT_IP']) && validate_ip($_SERVER['HTTP_CLIENT_IP'])) + { + return $_SERVER['HTTP_CLIENT_IP']; + } + + // check for IPs passing through proxies + if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) + { + // check if multiple ips exist in var + if (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',') !== false) + { + $iplist = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); + foreach ($iplist as $ip) + { + if (validate_ip($ip)) return $ip; + } + } + else + { + if (validate_ip($_SERVER['HTTP_X_FORWARDED_FOR'])) return $_SERVER['HTTP_X_FORWARDED_FOR']; + } + } + if (!empty($_SERVER['HTTP_X_FORWARDED']) && validate_ip($_SERVER['HTTP_X_FORWARDED'])) return $_SERVER['HTTP_X_FORWARDED']; + if (!empty($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']) && validate_ip($_SERVER['HTTP_X_CLUSTER_CLIENT_IP'])) return $_SERVER['HTTP_X_CLUSTER_CLIENT_IP']; + if (!empty($_SERVER['HTTP_FORWARDED_FOR']) && validate_ip($_SERVER['HTTP_FORWARDED_FOR'])) return $_SERVER['HTTP_FORWARDED_FOR']; + if (!empty($_SERVER['HTTP_FORWARDED']) && validate_ip($_SERVER['HTTP_FORWARDED'])) return $_SERVER['HTTP_FORWARDED']; + + // return unreliable ip since all else failed + return $_SERVER['REMOTE_ADDR']; } /** @@ -108,28 +108,27 @@ function get_ip_address() */ function validate_ip($ip) { - if (strtolower($ip) === 'unknown') - return false; - - // generate ipv4 network address - $ip = ip2long($ip); - - // if the ip is set and not equivalent to 255.255.255.255 - if ($ip !== false && $ip !== -1) { - // make sure to get unsigned long representation of ip - // due to discrepancies between 32 and 64 bit OSes and - // signed numbers (ints default to signed in PHP) - $ip = sprintf('%u', $ip); - // do private network range checking - if ($ip >= 0 && $ip <= 50331647) return false; - if ($ip >= 167772160 && $ip <= 184549375) return false; - if ($ip >= 2130706432 && $ip <= 2147483647) return false; - if ($ip >= 2851995648 && $ip <= 2852061183) return false; - if ($ip >= 2886729728 && $ip <= 2887778303) return false; - if ($ip >= 3221225984 && $ip <= 3221226239) return false; - if ($ip >= 3232235520 && $ip <= 3232301055) return false; - if ($ip >= 4294967040) return false; - } - return true; + if (strtolower($ip) === 'unknown') return false; + + // generate ipv4 network address + $ip = ip2long($ip); + + // if the ip is set and not equivalent to 255.255.255.255 + if ($ip !== false && $ip !== - 1) + { + // make sure to get unsigned long representation of ip + // due to discrepancies between 32 and 64 bit OSes and + // signed numbers (ints default to signed in PHP) + $ip = sprintf('%u', $ip); + // do private network range checking + if ($ip >= 0 && $ip <= 50331647) return false; + if ($ip >= 167772160 && $ip <= 184549375) return false; + if ($ip >= 2130706432 && $ip <= 2147483647) return false; + if ($ip >= 2851995648 && $ip <= 2852061183) return false; + if ($ip >= 2886729728 && $ip <= 2887778303) return false; + if ($ip >= 3221225984 && $ip <= 3221226239) return false; + if ($ip >= 3232235520 && $ip <= 3232301055) return false; + if ($ip >= 4294967040) return false; + } + return true; } - diff --git a/web/yaamp/core/common/util.php b/web/yaamp/core/common/util.php index 999d89748..f56160682 100644 --- a/web/yaamp/core/common/util.php +++ b/web/yaamp/core/common/util.php @@ -1,369 +1,370 @@ getController(); + return app()->getController(); } function cache() { - if (app() instanceof CConsoleApplication) - return app()->cache; + if (app() instanceof CConsoleApplication) return app()->cache; - return app()->getController()->memcache; + return app() + ->getController()->memcache; } -function objSafeVal($obj,$key,$default=NULL) +function objSafeVal($obj, $key, $default = NULL) { - if (is_object($obj) && property_exists($obj,$key)) - return $obj->$key; - elseif (is_array($obj)) - return arraySafeVal($obj,$key,$default); - return $default; + if (is_object($obj) && property_exists($obj, $key)) return $obj->$key; + elseif (is_array($obj)) return arraySafeVal($obj, $key, $default); + return $default; } -function arraySafeVal($arr,$key,$default=NULL) +function arraySafeVal($arr, $key, $default = NULL) { - if (is_array($arr) && isset($arr[$key])) - return $arr[$key]; - elseif (is_object($arr)) - return objSafeVal($arr,$key,$default); - return $default; + if (is_array($arr) && isset($arr[$key])) return $arr[$key]; + elseif (is_object($arr)) return objSafeVal($arr, $key, $default); + return $default; } -function getparam($p,$default='') +function getparam($p, $default = '') { - return isset($_REQUEST[$p]) ? $_REQUEST[$p] : $default; + return isset($_REQUEST[$p]) ? $_REQUEST[$p] : $default; } -function gethexparam($p,$default='') +function gethexparam($p, $default = '') { - $str = getparam($p, NULL); - $hex = (is_string($str) && ctype_xdigit($str)) ? $str : $default; - return $hex; + $str = getparam($p, NULL); + $hex = (is_string($str) && ctype_xdigit($str)) ? $str : $default; + return $hex; } -function getiparam($p,$default=0) +function getiparam($p, $default = 0) { - // workaround for yii default /route/ .... - if ($p == 'id') { - $id = isset($_REQUEST[$p]) ? $_REQUEST[$p] : $default; - if (!$id) { - $url = explode('/', $_SERVER['REQUEST_URI']); - $id = array_pop($url); - } - return (int) $id; - } - return isset($_REQUEST[$p]) ? intval($_REQUEST[$p]) : $default; + // workaround for yii default /route/ .... + if ($p == 'id') + { + $id = isset($_REQUEST[$p]) ? $_REQUEST[$p] : $default; + if (!$id) + { + $url = explode('/', $_SERVER['REQUEST_URI']); + $id = array_pop($url); + } + return (int)$id; + } + return isset($_REQUEST[$p]) ? intval($_REQUEST[$p]) : $default; } function getalgoparam() { - $algo = strip_tags(substr(getparam('algo'), 0, 32)); - return $algo; + $algo = strip_tags(substr(getparam('algo') , 0, 32)); + return $algo; } ////////////////////////////////////////////////////// - function downloadFile($url, &$size) { - $data = file_get_contents($url); - $tempname = gettempfile('.ext'); + $data = file_get_contents($url); + $tempname = gettempfile('.ext'); - file_put_contents($tempname, $data); - $size = dos_filesize($tempname); + file_put_contents($tempname, $data); + $size = dos_filesize($tempname); - unlink($tempname); - return $data; + unlink($tempname); + return $data; } function getServerName() { - if(strpos($_SERVER['SERVER_NAME'], ':')) - return substr($_SERVER['SERVER_NAME'], 0, strpos($_SERVER['SERVER_NAME'], ':')); + if (strpos($_SERVER['SERVER_NAME'], ':')) return substr($_SERVER['SERVER_NAME'], 0, strpos($_SERVER['SERVER_NAME'], ':')); - return $_SERVER['SERVER_NAME']; + return $_SERVER['SERVER_NAME']; } function getFullServerName() { - if(isset($_SERVER['HTTPS']) && !strcasecmp($_SERVER['HTTPS'], 'on')) - $protocol = 'https'; - else - $protocol = 'http'; + if (isset($_SERVER['HTTPS']) && !strcasecmp($_SERVER['HTTPS'], 'on')) $protocol = 'https'; + else $protocol = 'http'; - return $protocol.'://'.$_SERVER['HTTP_HOST']; + return $protocol . '://' . $_SERVER['HTTP_HOST']; } /////////////////// - function getClientPlatform() { - $agent = $_SERVER['HTTP_USER_AGENT']; - $bname = 'Unknown'; - $platform = 'Unknown'; - $version= ""; + $agent = $_SERVER['HTTP_USER_AGENT']; + $bname = 'Unknown'; + $platform = 'Unknown'; + $version = ""; - if(preg_match('/ipad/i', $agent)) - $platform = 'Ipad'; + if (preg_match('/ipad/i', $agent)) $platform = 'Ipad'; - else if(preg_match('/iphone/i', $agent)) - $platform = 'Iphone'; + else if (preg_match('/iphone/i', $agent)) $platform = 'Iphone'; - else if(preg_match('/android/i', $agent)) - $platform = 'Android'; + else if (preg_match('/android/i', $agent)) $platform = 'Android'; - else if(preg_match('/linux/i', $agent)) - $platform = 'Linux'; + else if (preg_match('/linux/i', $agent)) $platform = 'Linux'; - elseif(preg_match('/macintosh|mac os x/i', $agent)) - $platform = 'Mac'; + elseif (preg_match('/macintosh|mac os x/i', $agent)) $platform = 'Mac'; - elseif(preg_match('/windows|win32/i', $agent)) - $platform = 'Windows'; + elseif (preg_match('/windows|win32/i', $agent)) $platform = 'Windows'; ////////////////////////////////////////////////////////////////////// - - if(preg_match('/MSIE/i',$agent) && !preg_match('/Opera/i',$agent)) + if (preg_match('/MSIE/i', $agent) && !preg_match('/Opera/i', $agent)) { $bname = 'Internet Explorer'; $ub = "MSIE"; } - elseif(preg_match('/Firefox/i',$agent)) + elseif (preg_match('/Firefox/i', $agent)) { $bname = 'Firefox'; $ub = "Firefox"; } - elseif(preg_match('/Chrome/i',$agent)) + elseif (preg_match('/Chrome/i', $agent)) { $bname = 'Chrome'; $ub = "Chrome"; } - elseif(preg_match('/Safari/i',$agent)) + elseif (preg_match('/Safari/i', $agent)) { $bname = 'Safari'; $ub = "Safari"; } - elseif(preg_match('/Opera/i',$agent)) + elseif (preg_match('/Opera/i', $agent)) { $bname = 'Opera'; $ub = "Opera"; } - elseif(preg_match('/Netscape/i',$agent)) + elseif (preg_match('/Netscape/i', $agent)) { $bname = 'Netscape'; $ub = "Netscape"; } // finally get the correct version number - $known = array('Version', $ub, 'other'); - $pattern = '#(?' . join('|', $known) . ')[/ ]+(?[0-9.|a-zA-Z.]*)#'; + $known = array( + 'Version', + $ub, + 'other' + ); + $pattern = '#(?' . join('|', $known) . ')[/ ]+(?[0-9.|a-zA-Z.]*)#'; - preg_match_all($pattern, $agent, $matches); + preg_match_all($pattern, $agent, $matches); // see how many we have $i = count($matches['browser']); - if ($i != 1) { + if ($i != 1) + { //we will have two since we are not using 'other' argument yet //see if version is before or after the name - if (strripos($agent,"Version") < strripos($agent,$ub)){ - $version= $matches['version'][0]; + if (strripos($agent, "Version") < strripos($agent, $ub)) + { + $version = $matches['version'][0]; } - else { - $version= $matches['version'][1]; + else + { + $version = $matches['version'][1]; } } - else { - $version= $matches['version'][0]; + else + { + $version = $matches['version'][0]; } // check if we have a number - if ($version==null || $version=="") {$version="?";} + if ($version == null || $version == "") + { + $version = "?"; + } return "$platform, $bname $version"; } function IsMobileDevice() { - $agent = $_SERVER['HTTP_USER_AGENT']; + $agent = $_SERVER['HTTP_USER_AGENT']; - return preg_match('/ipad/i', $agent) || - preg_match('/iphone/i', $agent) || - preg_match('/android/i', $agent); + return preg_match('/ipad/i', $agent) || preg_match('/iphone/i', $agent) || preg_match('/android/i', $agent); } -function file_get_contents_curl($url, $user=null) +function file_get_contents_curl($url, $user = null) { - $ch = curl_init($url); - - if($user) - { - $a = explode(',', $user->access_token); - $oauth_token = $a[0]; - $oauth_token_secret = $a[1]; - - $oauth = array( - 'oauth_consumer_key' => CONSUMER_KEY, - 'oauth_nonce' => md5(microtime().mt_rand()), - 'oauth_signature_method' => 'HMAC-SHA1', - 'oauth_timestamp' => time(), - 'oauth_token' => $oauth_token, - 'oauth_version' => '1.0'); - - $base_info = buildBaseString($url, 'POST', $oauth); - $composite_key = rawurlencode(CONSUMER_SECRET).'&'.rawurlencode($oauth_token_secret); - $oauth['oauth_signature'] = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true)); - $header = buildAuthorizationHeader($oauth); - - // debuglog($header); - curl_setopt($ch, CURLOPT_HTTPHEADER, array($header)); - } - - $maxallowed = 64*1024; - $totalread = 0; - $data = ''; - - $callback = function($ch, $text) use(&$data, &$maxallowed, &$totalread) - { - $data .= $text; - $count = strlen($text); - $totalread += $count; - - if($totalread >= $maxallowed || stristr($data, '')) - return 0; - - return $count; - }; - - curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; Tweetshow 2.1)'); - curl_setopt($ch, CURLOPT_HEADER, 0); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20); - curl_setopt($ch, CURLOPT_TIMEOUT, 20); - curl_setopt($ch, CURLOPT_ENCODING , "deflate,gzip"); - curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($ch, CURLOPT_WRITEFUNCTION, $callback); - - curl_exec($ch); - curl_close($ch); - -// debuglog(" total read $totalread, ".strlen($data)); - return $data; + $ch = curl_init($url); + + if ($user) + { + $a = explode(',', $user->access_token); + $oauth_token = $a[0]; + $oauth_token_secret = $a[1]; + + $oauth = array( + 'oauth_consumer_key' => CONSUMER_KEY, + 'oauth_nonce' => md5(microtime() . mt_rand()) , + 'oauth_signature_method' => 'HMAC-SHA1', + 'oauth_timestamp' => time() , + 'oauth_token' => $oauth_token, + 'oauth_version' => '1.0' + ); + + $base_info = buildBaseString($url, 'POST', $oauth); + $composite_key = rawurlencode(CONSUMER_SECRET) . '&' . rawurlencode($oauth_token_secret); + $oauth['oauth_signature'] = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true)); + $header = buildAuthorizationHeader($oauth); + + // debuglog($header); + curl_setopt($ch, CURLOPT_HTTPHEADER, array( + $header + )); + } + + $maxallowed = 64 * 1024; + $totalread = 0; + $data = ''; + + $callback = function ($ch, $text) use (&$data, &$maxallowed, &$totalread) + { + $data .= $text; + $count = strlen($text); + $totalread += $count; + + if ($totalread >= $maxallowed || stristr($data, '')) return 0; + + return $count; + }; + + curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; Tweetshow 2.1)'); + curl_setopt($ch, CURLOPT_HEADER, 0); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20); + curl_setopt($ch, CURLOPT_TIMEOUT, 20); + curl_setopt($ch, CURLOPT_ENCODING, "deflate,gzip"); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_WRITEFUNCTION, $callback); + + curl_exec($ch); + curl_close($ch); + + // debuglog(" total read $totalread, ".strlen($data)); + return $data; } function force_wordbreak($text, $max) { - $last = 0; - for($i=0; $i $max) - { - $text = substr_replace($text, ' ', $i, 0); - $i++; - $last = $i; - } - } - - return $text; -} + $last = 0; + for ($i = 0;$i < strlen($text);$i++) + { + if ($text[$i] == ' ') $last = $i; + else if ($i - $last > $max) + { + $text = substr_replace($text, ' ', $i, 0); + $i++; + $last = $i; + } + } -///////////////////////////////////////////////////////////////////////// + return $text; +} +///////////////////////////////////////////////////////////////////////// function adjust_background_color($color) { - sscanf($color, "%x", $rgb); - $r = ($rgb >> 16) & 0xFF; - $g = ($rgb >> 8) & 0xFF; - $b = $rgb & 0xFF; - $limit1 = 0xf4; - if($r < $limit1) $r = $limit1-($limit1 - $r)/16; - if($g < $limit1) $g = $limit1-($limit1 - $g)/16; - if($b < $limit1) $b = $limit1-($limit1 - $b)/32; - $color1 = ($r << 16) + ($g << 8) + $b; - $color1 = sprintf("%x", $color1); - return $color1; + sscanf($color, "%x", $rgb); + $r = ($rgb >> 16) & 0xFF; + $g = ($rgb >> 8) & 0xFF; + $b = $rgb & 0xFF; + $limit1 = 0xf4; + if ($r < $limit1) $r = $limit1 - ($limit1 - $r) / 16; + if ($g < $limit1) $g = $limit1 - ($limit1 - $g) / 16; + if ($b < $limit1) $b = $limit1 - ($limit1 - $b) / 32; + $color1 = ($r << 16) + ($g << 8) + $b; + $color1 = sprintf("%x", $color1); + return $color1; } function adjust_foreground_color($color) { - sscanf($color, "%x", $rgb); - $r = ($rgb >> 16) & 0xFF; - $g = ($rgb >> 8) & 0xFF; - $b = $rgb & 0xFF; - $limit2 = 0x33; - if($r > $limit2) $r = $limit2; - if($g > $limit2) $g = $limit2; - if($b > $limit2) $b = $limit2; - $color2 = ($r << 16) + ($g << 8) + $b; - $color2 = sprintf("%x", $color2); - return $color2; + sscanf($color, "%x", $rgb); + $r = ($rgb >> 16) & 0xFF; + $g = ($rgb >> 8) & 0xFF; + $b = $rgb & 0xFF; + $limit2 = 0x33; + if ($r > $limit2) $r = $limit2; + if ($g > $limit2) $g = $limit2; + if ($b > $limit2) $b = $limit2; + $color2 = ($r << 16) + ($g << 8) + $b; + $color2 = sprintf("%x", $color2); + return $color2; } function changeColor($user) { - if(!$user) return; + if (!$user) return; - $color = $user->profile_background_color; - sscanf($color, "%x", $rgb); + $color = $user->profile_background_color; + sscanf($color, "%x", $rgb); - $r = ($rgb >> 16) & 0xFF; - $g = ($rgb >> 8) & 0xFF; - $b = $rgb & 0xFF; + $r = ($rgb >> 16) & 0xFF; + $g = ($rgb >> 8) & 0xFF; + $b = $rgb & 0xFF; - $r = $r * 5/6; - $g = $g * 5/6; - $b = $b * 5/6; + $r = $r * 5 / 6; + $g = $g * 5 / 6; + $b = $b * 5 / 6; - $color2 = ($r << 16) + ($g << 8) + $b; - $color2 = sprintf("%x", $color2); + $color2 = ($r << 16) + ($g << 8) + $b; + $color2 = sprintf("%x", $color2); - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; } class RecursiveDOMIterator implements RecursiveIterator { - protected $_position; - protected $_nodeList; - public function __construct(DOMNode $domNode) - { - $this->_position = 0; - $this->_nodeList = $domNode->childNodes; - } - public function getChildren() { return new self($this->current()); } - public function key() { return $this->_position; } - public function next() { $this->_position++; } - public function rewind() { $this->_position = 0; } - public function valid() - { - return $this->_position < $this->_nodeList->length; - } - public function hasChildren() - { - return $this->current()->hasChildNodes(); - } - public function current() - { - return $this->_nodeList->item($this->_position); - } + protected $_position; + protected $_nodeList; + public function __construct(DOMNode $domNode) + { + $this->_position = 0; + $this->_nodeList = $domNode->childNodes; + } + public function getChildren() + { + return new self($this->current()); + } + public function key() + { + return $this->_position; + } + public function next() + { + $this->_position++; + } + public function rewind() + { + $this->_position = 0; + } + public function valid() + { + return $this->_position < $this + ->_nodeList->length; + } + public function hasChildren() + { + return $this->current() + ->hasChildNodes(); + } + public function current() + { + return $this + ->_nodeList + ->item($this->_position); + } } - - - - - - - diff --git a/web/yaamp/core/exchange/bitfinex.php b/web/yaamp/core/exchange/bitfinex.php new file mode 100644 index 000000000..474c5b42e --- /dev/null +++ b/web/yaamp/core/exchange/bitfinex.php @@ -0,0 +1,24 @@ +url = $this->base_url; + try { + if (is_array($options)) + { + foreach ($options as $option => $value) + { + $this->$option = $value; + } + } + else + { + return false; + } + } + catch (PDOException $e) { + throw new Exception($e->getMessage()); + } + } + /** + * Obtain single quoted price data + * @param symbol required string + * @return array + */ + public function ticker(array $parms){ + $sendData = $this->getData($parms); + $url = $this->url.'/Market/ticker?'.http_build_query($sendData); + return $this->httpRequest($url); + } + /** + * Obtain K-line data + * @param symbol required string + * @param resolution required string + * @param size optional int + * @param to optional int + * @return array + */ + public function kline(array $parms){ + $sendData = $this->getData($parms); + $url = $this->url.'/Market/kline?'.http_build_query($sendData); + return $this->httpRequest($url); + } + /** + * Obtain deep data + * @param symbol required string + * @return array + */ + public function depth(array $parms){ + $sendData = $this->getData($parms); + $url = $this->url.'/Market/depth?'.http_build_query($sendData); + return $this->httpRequest($url); + } + /** + * Obtain filled orders + * @param symbol required string + * @return array + */ + public function order(array $parms){ + $sendData = $this->getData($parms); + $url = $this->url.'/Market/order?'.http_build_query($sendData); + return $this->httpRequest($url); + } + /** + * Obtain all quoted price data + * @param symbols optional string + * @return array + */ + public function tickerall(array $parms){ + $sendData = $this->getData($parms); + $url = $this->url.'/Market/tickerall?'.http_build_query($sendData); + return $this->httpRequest($url); + } + /** + * Obtain trading pairs + * @param symbols optional string + * @return array + */ + public function symbolList(array $parms){ + $sendData = $this->getData($parms); + $url = $this->url.'/Market/symbolList?'.http_build_query($sendData); + return $this->httpRequest($url); + } + /** + * Obtain exchange rate for current legal currency + * @param symbols optional string + * @return array + */ + public function currencyRate(array $parms){ + $sendData = $this->getData($parms); + $url = $this->url.'/Market/currencyRate?'.http_build_query($sendData); + return $this->httpRequest($url); + } + /** + * Obtain exchange rate for digital currency and legal currency + * @param coins optional string + * @return array + */ + public function currencyCoinRate(array $parms){ + $sendData = $this->getData($parms); + $url = $this->url.'/Market/currencyCoinRate?'.http_build_query($sendData); + return $this->httpRequest($url); + } + /** + * Obtain exchange rate for corresponding currency + * @param coins optional string + * @return array + */ + public function coinRate(array $parms){ + $sendData = $this->getData($parms); + $url = $this->url.'/Market/coinRate?'.http_build_query($sendData); + return $this->httpRequest($url); + } + /** + * Obtain personal asset info + * @return array + */ + public function getUserAssets(){ + $sendData = $this->getData(); + $url = $this->url.'/Assets/getUserAssets'; + return $this->httpRequest($url,$sendData); + } + /** + * Submit orders + * @param symbol required eth_btc + * @param number required float + * @param price required float + * @param type required int + * @return array + */ + public function addEntrustSheet(array $parms) + { + $parms['tradePwd'] = $this->tradePwd; + $sendData = $this->getData($parms); + $url = $this->url.'/Trade/addEntrustSheet'; + return $this->httpRequest($url,$sendData); + } + /** + * Cancel single order + * @param entrustSheetId required string 787945820 + * @return array + */ + public function cancelEntrustSheet(array $parms){ + $sendData = $this->getData($parms); + $url = $this->url.'/Trade/cancelEntrustSheet'; + return $this->httpRequest($url,$sendData); + } + /** + * Cancel batch orders + * @param ids required string '787945739,787945820' + * @return array + */ + public function cancelAllEntrustSheet(array $parms){ + $sendData = $this->getData($parms); + $url = $this->url.'/Trade/cancelAllEntrustSheet'; + return $this->httpRequest($url,$sendData); + } + /** + * Obtain order details + * @param entrustSheetId required string 787945820 + * @return array + */ + public function getEntrustSheetInfo(array $parms){ + $sendData = $this->getData($parms); + $url = $this->url.'/Trade/getEntrustSheetInfo'; + return $this->httpRequest($url,$sendData); + } + /** + * Obtain current order details + * @param pageSize optional int + * @param page optional int + * @param coinForm required eth + * @param coinTo required btc + * @param startTime optional timestamp + * @param endTime optional timestamp + * @return array + */ + public function getUserNowEntrustSheet(array $parms){ + $sendData = $this->getData($parms); + $url = $this->url.'/Trade/getUserNowEntrustSheet'; + return $this->httpRequest($url,$sendData); + } + /** + * Obtain past order details + * @param pageSize optional int + * @param page optional int + * @param coinForm required eth + * @param coinTo required btc + * @param startTime optional timestamp + * @param endTime optional timestamp + * @return array + */ + public function getUserHistoryEntrustSheet(array $parms){ + $sendData = $this->getData($parms); + $url = $this->url.'/Trade/getUserHistoryEntrustSheet'; + return $this->httpRequest($url,$sendData); + } + protected function getData($data = null){ + $baseArr = array( + 'timeStamp' => time(), + 'nonce' => $this->getRandomString(6), + 'apiKey' => $this->apiKey, + ); + if(isset($data)){ + $sendData = array_merge($baseArr,$data); + }else{ + $sendData = $baseArr; + } + $sendData['sign'] = $this->getSign($sendData); + return $sendData; + } + protected function getSign($data) + { + ksort($data); + $dataStr = ''; + foreach ($data as $k => $v) + { + $dataStr .= $k.'='.$v."&"; + } + return md5(trim($dataStr,"&").$this->secretKey); + } + protected function getRandomString($len, $chars=null) + { + if (is_null($chars)){ + $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + } + for ($i = 0, $str = '', $lc = strlen($chars)-1; $i < $len; $i++){ + $str .= $chars[mt_rand(0, $lc)]; + } + return $str; + } + protected function httpRequest($url,$data = null){ + $curl = curl_init(); + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); + if(!empty($data)){ + curl_setopt($curl,CURLOPT_POST,1); + curl_setopt($curl,CURLOPT_POSTFIELDS,$data); + } + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + $output = curl_exec($curl); + curl_close($curl); + return $output; + } +} diff --git a/web/yaamp/core/exchange/cryptohub.php b/web/yaamp/core/exchange/cryptohub.php new file mode 100644 index 000000000..611172474 --- /dev/null +++ b/web/yaamp/core/exchange/cryptohub.php @@ -0,0 +1,68 @@ +$symbol)); + if(!$coin) return false; + $pair = $symbol; + $market = getdbosql('db_markets', "coinid={$coin->id} AND name='$exchange'"); + if(!$market) return false; + + } else if (is_object($market)) { + + $coin = getdbo('db_coins', $market->coinid); + if(!$coin) return false; + $symbol = $coin->getOfficialSymbol(); + $pair = $symbol; + if (!empty($market->base_coin)) $pair = $market->base_coin.'_'.$symbol; + } + + $t1 = microtime(true); + $ticker = cryptohub_api_query("market/ticker",$pair); + if(!$ticker || empty($ticker)) return false; + $ticker = array_pop($ticker); + if(arraySafeVal($ticker,'highestBid') === NULL) { + debuglog("$exchange: invalid data received for $pair ticker"); + return false; + } + + $price2 = ((double) $ticker['highestBid'] + $ticker['lowestAsk']) / 2; + $market->price2 = AverageIncrement($market->price2, $price2); + $market->price = AverageIncrement($market->price, (double) $ticker['highestBid']); + if ($ticker['lowestAsk'] < $market->price) $market->price = $ticker['lowestAsk']; + $market->pricetime = time(); + $market->save(); + + $apims = round((microtime(true) - $t1)*1000,3); + user()->setFlash('message', "$exchange $symbol price updated in $apims ms"); + + return true; +} diff --git a/web/yaamp/core/exchange/exchange.php b/web/yaamp/core/exchange/exchange.php index f1f55e62e..df83cb397 100644 --- a/web/yaamp/core/exchange/exchange.php +++ b/web/yaamp/core/exchange/exchange.php @@ -29,7 +29,6 @@ function strip_data($data) require_once("poloniex.php"); require_once("yobit.php"); require_once("shapeshift.php"); -require_once("bter.php"); require_once("empoex.php"); require_once("jubi.php"); require_once("alcurex.php"); @@ -91,8 +90,6 @@ function getMarketUrl($coin, $marketName) $url = "https://poloniex.com/exchange#{$lowbase}_{$lowsymbol}"; else if($market == 'bleutrade') $url = "https://bleutrade.com/exchange/{$symbol}/{$base}"; - else if($market == 'bter') - $url = "https://bter.com/trade/{$lowsymbol}_{$lowbase}"; else if($market == 'cexio') $url = "https://cex.io/trade/{$symbol}-{$base}"; else if($market == 'coinbene') @@ -124,9 +121,9 @@ function getMarketUrl($coin, $marketName) else if($market == 'hitbtc') $url = "https://hitbtc.com/exchange/{$symbol}-to-{$base}"; else if($market == 'kucoin') - $url = "https://www.kucoin.com/#/trade.pro/{$symbol}-{$base}"; + $url = "https://www.kucoin.com/trade/{$symbol}-{$base}"; else if($market == 'livecoin') - $url = "https://www.livecoin.net/trade/?currencyPair={$symbol}%2F{$base}"; + $url = "https://www.livecoin.net/en/trading/{$symbol}_{$base}"; else if($market == 'nova') $url = "https://novaexchange.com/market/{$base}_{$symbol}/"; else if($market == 'stocksexchange') diff --git a/web/yaamp/core/exchange/kucoin.php b/web/yaamp/core/exchange/kucoin.php index 743c86e2b..757379500 100644 --- a/web/yaamp/core/exchange/kucoin.php +++ b/web/yaamp/core/exchange/kucoin.php @@ -1,6 +1,6 @@ /wallet/address +// https://openapi-v2.kucoin.com/api/v1/deposit-addresses?currency= function kucoin_api_user($method, $params=NULL, $isPostMethod=false) { @@ -55,26 +55,33 @@ function kucoin_api_user($method, $params=NULL, $isPostMethod=false) if (!defined('EXCH_KUCOIN_SECRET')) define('EXCH_KUCOIN_SECRET', ''); if (empty(EXCH_KUCOIN_KEY) || empty(EXCH_KUCOIN_SECRET)) return false; + if (empty(EXCH_KUCOIN_PASSPHRASE)) return false; - $api_host = 'https://api.kucoin.com'; + $api_host = 'https://openapi-v2.kucoin.com'; $mt = explode(' ', microtime()); $nonce = $mt[1].substr($mt[0], 2, 3); - $url = $endpoint = "/v1/$method"; - $tosign = "$endpoint/$nonce/"; + $url = $endpoint = "/api/v1/$method"; if (empty($params)) $params = array(); $query = http_build_query($params); - if (strlen($query) && !$isPostMethod) { - $url .= '&'.$query; $query = ''; + $body = ""; + if ($isPostMethod) + $body = json_encode($params); + else if (strlen($query)) { + $body = '?'.$query; + $url .= $body; } - if ($isPostMethod) $post_data = $params; - $hmac = strtolower(hash_hmac('sha256', base64_encode($tosign.$query), EXCH_KUCOIN_SECRET)); + + $req = $isPostMethod ? "POST" : "GET"; + $tosign = "{$nonce}{$req}{$endpoint}{$body}"; + $hmac = hash_hmac('sha256', $tosign, EXCH_KUCOIN_SECRET, true); $headers = array( 'Content-Type: application/json;charset=UTF-8', 'KC-API-KEY: '.EXCH_KUCOIN_KEY, - 'KC-API-NONCE: '.$nonce, - 'KC-API-SIGNATURE: '.$hmac, + 'KC-API-PASSPHRASE: '.EXCH_KUCOIN_PASSPHRASE, + 'KC-API-TIMESTAMP: '.$nonce, + 'KC-API-SIGN: '.base64_encode($hmac), ); $ch = curl_init(); @@ -83,7 +90,7 @@ function kucoin_api_user($method, $params=NULL, $isPostMethod=false) curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); if ($isPostMethod) { curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); + curl_setopt($ch, CURLOPT_POSTFIELDS, $params); } curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); @@ -138,14 +145,14 @@ function kucoin_update_market($market) } $t1 = microtime(true); - $query = kucoin_api_query("$pair/open/tick"); + $query = kucoin_api_query('market/orderbook/level1','symbol='.$pair); if(!kucoin_result_valid($query)) return false; $ticker = $query->data; - $price2 = ((double) $ticker->buy + (double)$ticker->sell)/2; + $price2 = ((double) $ticker->bestBid + (double)$ticker->bestAsk)/2; $market->price2 = AverageIncrement($market->price2, $price2); - $market->price = AverageIncrement($market->price, $ticker->buy); - $market->pricetime = time(); + $market->price = AverageIncrement($market->price, $ticker->bestBid); + $market->pricetime = min(time(), 0 + $ticker->sequence); $market->save(); $apims = round((microtime(true) - $t1)*1000,3); diff --git a/web/yaamp/core/exchange/tradeogre.php b/web/yaamp/core/exchange/tradeogre.php new file mode 100644 index 000000000..d68248355 --- /dev/null +++ b/web/yaamp/core/exchange/tradeogre.php @@ -0,0 +1,55 @@ +Exchanges  Botnets  Users  @@ -14,48 +14,59 @@ function getAdminSideBarLinks() Payments  Big Miners  end; - return $links; + return $links; } // shared by wallet "tabs", to move in another php file... -function getAdminWalletLinks($coin, $info=NULL, $src='wallet') +function getAdminWalletLinks($coin, $info = NULL, $src = 'wallet') { - $html = CHtml::link("COIN PROPERTIES", '/site/update?id='.$coin->id); - if($info) { - $html .= ' || '.$coin->createExplorerLink("EXPLORER"); - $html .= ' || '.CHtml::link("PEERS", '/site/peers?id='.$coin->id); - if (YAAMP_ADMIN_WEBCONSOLE) - $html .= ' || '.CHtml::link("CONSOLE", '/site/console?id='.$coin->id); - $html .= ' || '.CHtml::link("TRIGGERS", '/site/triggers?id='.$coin->id); - if ($src != 'wallet') - $html .= ' || '.CHtml::link("{$coin->symbol}", '/site/coin?id='.$coin->id); - } - - if(!$info && $coin->enable) - $html .= '
'.CHtml::link("STOP COIND", '/site/stopcoin?id='.$coin->id); - - if($coin->auto_ready) - $html .= '
'.CHtml::link("UNSET AUTO", '/site/unsetauto?id='.$coin->id); - else - $html .= '
'.CHtml::link("SET AUTO", '/site/setauto?id='.$coin->id); - - $html .= '
'; - - if(!empty($coin->link_bitcointalk)) - $html .= CHtml::link('forum', $coin->link_bitcointalk, array('target'=>'_blank')).' '; - - if(!empty($coin->link_github)) - $html .= CHtml::link('git', $coin->link_github, array('target'=>'_blank')).' '; - - if(!empty($coin->link_site)) - $html .= CHtml::link('site', $coin->link_site, array('target'=>'_blank')).' '; - - if(!empty($coin->link_explorer)) - $html .= CHtml::link('chain', $coin->link_explorer, array('target'=>'_blank','title'=>'External Blockchain Explorer')).' '; - - $html .= CHtml::link('google', 'http://google.com/search?q='.urlencode($coin->name.' '.$coin->symbol.' bitcointalk'), array('target'=>'_blank')); - - return $html; + $html = CHtml::link("COIN PROPERTIES", '/site/update?id=' . $coin->id); + if ($info) { + $html .= ' || ' . $coin->createExplorerLink("EXPLORER"); + $html .= ' || ' . CHtml::link("PEERS", '/site/peers?id=' . $coin->id); + if (YAAMP_ADMIN_WEBCONSOLE) + $html .= ' || ' . CHtml::link("CONSOLE", '/site/console?id=' . $coin->id); + $html .= ' || ' . CHtml::link("TRIGGERS", '/site/triggers?id=' . $coin->id); + if ($src != 'wallet') + $html .= ' || ' . CHtml::link("{$coin->symbol}", '/site/coin?id=' . $coin->id); + } + + if (!$info && $coin->enable) + $html .= '
' . CHtml::link("STOP COIND", '/site/stopcoin?id=' . $coin->id); + + if ($coin->auto_ready) + $html .= '
' . CHtml::link("UNSET AUTO", '/site/unsetauto?id=' . $coin->id); + else + $html .= '
' . CHtml::link("SET AUTO", '/site/setauto?id=' . $coin->id); + + $html .= '
'; + + if (!empty($coin->link_bitcointalk)) + $html .= CHtml::link('forum', $coin->link_bitcointalk, array( + 'target' => '_blank' + )) . ' '; + + if (!empty($coin->link_github)) + $html .= CHtml::link('git', $coin->link_github, array( + 'target' => '_blank' + )) . ' '; + + if (!empty($coin->link_site)) + $html .= CHtml::link('site', $coin->link_site, array( + 'target' => '_blank' + )) . ' '; + + if (!empty($coin->link_explorer)) + $html .= CHtml::link('chain', $coin->link_explorer, array( + 'target' => '_blank', + 'title' => 'External Blockchain Explorer' + )) . ' '; + + $html .= CHtml::link('google', 'http://google.com/search?q=' . urlencode($coin->name . ' ' . $coin->symbol . ' bitcointalk'), array( + 'target' => '_blank' + )); + + return $html; } ///////////////////////////////////////////////////////////////////////////////////////////// @@ -63,28 +74,28 @@ function getAdminWalletLinks($coin, $info=NULL, $src='wallet') // Check if $IP is in $CIDR range function ipCIDRCheck($IP, $CIDR) { - list($net, $mask) = explode('/', $CIDR); + list($net, $mask) = explode('/', $CIDR); - $ip_net = ip2long($net); - $ip_mask = ~((1 << (32 - $mask)) - 1); + $ip_net = ip2long($net); + $ip_mask = ~((1 << (32 - $mask)) - 1); - $ip_ip = ip2long($IP); - $ip_ip_net = $ip_ip & $ip_mask; + $ip_ip = ip2long($IP); + $ip_ip_net = $ip_ip & $ip_mask; - return ($ip_ip_net === $ip_net); + return ($ip_ip_net === $ip_net); } function isAdminIP($ip) { - foreach(explode(',', YAAMP_ADMIN_IP) as $range) - { - if (strpos($range, '/')) { - if(ipCIDRCheck($ip, $range) === true) return true; - } else if ($range === $ip) { - return true; - } - } - return false; + foreach (explode(',', YAAMP_ADMIN_IP) as $range) { + if (strpos($range, '/')) { + if (ipCIDRCheck($ip, $range) === true) + return true; + } else if ($range === $ip) { + return true; + } + } + return false; } ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/web/yaamp/core/functions/yaamp.php b/web/yaamp/core/functions/yaamp.php index f604ca22d..a0811aeb3 100755 --- a/web/yaamp/core/functions/yaamp.php +++ b/web/yaamp/core/functions/yaamp.php @@ -2,629 +2,814 @@ function yaamp_get_algos() { - /* Toggle Site Algos Here */ - return array( - 'sha256', - 'sha256t', - 'sha256q', - 'scrypt', - 'scryptn', - 'allium', - 'argon2', - 'argon2d-dyn', - 'aergo', - 'bastion', - 'bitcore', - 'blake', - 'blakecoin', - 'blake2s', - 'blake2b', - 'decred', - 'deep', - 'exosis', - 'hmq1725', - 'keccak', - 'keccakc', - 'jha', - 'hex', - 'hsr', - 'lbry', - 'lbk3', - 'luffa', - 'lyra2', - 'lyra2v2', - 'lyra2z', - 'neoscrypt', - 'nist5', - 'penta', - 'polytimos', - 'quark', - 'qubit', - 'rainforest', - 'c11', - 'x11', - 'x11evo', - 'x12', - 'x13', - 'x14', - 'x15', - 'x16r', - 'x16s', - 'x17', - 'x22i', - 'xevan', - 'groestl', // dmd-gr -m 256 (deprecated) - 'dmd-gr', - 'myr-gr', - 'm7m', - 'phi', - 'phi2', - 'sib', - 'skein', - 'skein2', - 'skunk', - 'timetravel', - 'tribus', - 'a5a', - 'vanilla', - 'veltor', - 'velvet', - 'vitalium', - 'yescrypt', - 'yescryptR16', - 'yescryptR32', - 'whirlpool', - 'zr5', - ); + /* Toggle Site Algos Here */ + return array( + 'a5a', + 'aergo', + 'allium', + 'argon2', + 'argon2d-crds', + 'argon2d-dyn', + 'argon2m', + 'argon2d-uis', + 'balloon', + 'bastion', + 'bcd', + 'binarium-v1', + 'bitcore', + 'blake', + 'blake2b', + 'blake2s', + 'bmw512', + 'blakecoin', + 'c11', + 'decred', + 'deep', + 'dmd-gr', + 'exosis', + 'groestl', // dmd-gr -m 256 (deprecated) + 'geek', + 'hex', + 'hmq1725', + 'honeycomb', + 'hsr', + 'jha', + 'keccak', + 'keccakc', + 'lbk3', + 'lbry', + 'luffa', + 'lyra2', + 'lyra2v2', + 'lyra2v3', + 'lyra2vc0ban', + 'lyra2z', + 'lyra2zz', + 'lyra2z330', + 'm7m', + 'myr-gr', + 'neoscrypt', + 'nist5', + 'odo', + 'penta', + 'phi', + 'phi2', + 'phi1612', + 'polytimos', + 'quark', + 'qubit', + 'rainforest', + 'rfv2', + 'scrypt', + 'scryptn', + 'sha256', + 'sha256q', + 'sha256t', + 'sib', + 'skein', + 'skein2', + 'skunk', + 'sonoa', + 'timetravel', + 'tribus', + 'vanilla', + 'veltor', + 'velvet', + 'vitalium', + 'whirlpool', + 'x11', + 'x11evo', + 'x12', + 'x13', + 'x14', + 'x15', + 'x16r', + 'x16rv2', + 'x16rt', + 'x16s', + 'x17', + 'x18', + 'x20r', + 'x21s', + 'x22i', + 'x25x', + 'xevan', + 'yescrypt', + 'yescryptR8', + 'yescryptR16', + 'yescryptR32', + 'yespower', + 'yespowerR8', + 'yespowerR16', + 'yespowerR24', + 'yespowerR32', + 'zr5' + ); } // Used for graphs and 24h profit // GH/s for fast algos like sha256 function yaamp_algo_mBTC_factor($algo) { - switch($algo) { - case 'sha256': - case 'sha256t': - case 'sha256q': - case 'blake': - case 'blakecoin': - case 'blake2s': - case 'blake2b': - case 'decred': - case 'keccak': - case 'keccakc': - case 'lbry': - case 'vanilla': - return 1000; - default: - return 1; - } + switch ($algo) { + case 'sha256': + case 'sha256t': + case 'sha256q': + case 'blake': + case 'blakecoin': + case 'blake2s': + case 'blake2b': + case 'decred': + case 'keccak': + case 'keccakc': + case 'lbry': + case 'vanilla': + return 1000; + default: + return 1; + } } // mBTC coef per algo function yaamp_get_algo_norm($algo) { - global $configAlgoNormCoef; - if (isset($configAlgoNormCoef[$algo])) - return (float) $configAlgoNormCoef[$algo]; - - $a = array( - 'sha256' => 1.0, - 'scrypt' => 1.0, - 'scryptn' => 1.0, - 'x11' => 1.0, - 'x13' => 1.0, - 'argon2' => 1.0, - 'argon2d-dyn' => 1.0, - 'lyra2' => 1.0, - 'lyra2v2' => 1.0, - 'myr-gr' => 1.0, - 'nist5' => 1.0, - 'neoscrypt' => 1.0, - 'quark' => 1.0, - 'qubit' => 1.0, - 'skein' => 1.0, - 'blake' => 1.0, - 'keccak' => 1.0, - 'skein2' => 1.0, - 'velvet' => 1.0, - 'whirlpool' => 1.0, - 'yescrypt' => 1.0, - 'yescryptR16' => 1.0, - 'yescryptR32' => 1.0, - 'zr5' => 1.0, - ); - - if(!isset($a[$algo])) - return 1.0; - - return $a[$algo]; + global $configAlgoNormCoef; + if (isset($configAlgoNormCoef[$algo])) + return (float) $configAlgoNormCoef[$algo]; + + $a = array( + 'argon2' => 1.0, + 'argon2d-crds' => 1.0, + 'argon2d-dyn' => 1.0, + 'argon2m' => 1.0, + 'argon2d-uis' => 1.0, + 'blake' => 1.0, + 'keccak' => 1.0, + 'lyra2' => 1.0, + 'lyra2v2' => 1.0, + 'lyra2v3' => 1.0, + 'myr-gr' => 1.0, + 'neoscrypt' => 1.0, + 'nist5' => 1.0, + 'quark' => 1.0, + 'qubit' => 1.0, + 'scrypt' => 1.0, + 'scryptn' => 1.0, + 'sha256' => 1.0, + 'skein' => 1.0, + 'skein2' => 1.0, + 'velvet' => 1.0, + 'whirlpool' => 1.0, + 'x11' => 1.0, + 'x13' => 1.0, + 'yescrypt' => 1.0, + 'yescryptR8' => 1.0, + 'yescryptR16' => 1.0, + 'yescryptR32' => 1.0, + 'zr5' => 1.0 + ); + + if (!isset($a[$algo])) + return 1.0; + + return $a[$algo]; } function getAlgoColors($algo) { - $a = array( - 'sha256' => '#d0d0a0', - 'sha256t' => '#d0d0f0', - 'sha256q' => '#9696dd', - 'scrypt' => '#c0c0e0', - 'neoscrypt' => '#a0d0f0', - 'scryptn' => '#d0d0d0', - 'c11' => '#a0a0d0', - 'decred' => '#f0f0f0', - 'deep' => '#e0ffff', - 'x11' => '#f0f0a0', - 'x11evo' => '#c0f0c0', - 'x12' => '#ffe090', - 'x13' => '#ffd880', - 'x14' => '#f0c080', - 'x15' => '#f0b080', - 'x16r' => '#f0b080', - 'x16s' => '#f0b080', - 'x17' => '#f0b0a0', - 'x22i' => '#f0a090', - 'xevan' => '#f0b0a0', - 'allium' => '#80a0d0', - 'argon2' => '#e0d0e0', - 'argon2d-dyn' => '#e0d0e0', - 'aergo' => '#e0d0e0', - 'bastion' => '#e0b0b0', - 'blake' => '#f0f0f0', - 'blakecoin' => '#f0f0f0', - 'blake2b' => '#f2c81f', - 'exosis' => '#49CCFE', - 'groestl' => '#d0a0a0', - 'jha' => '#a0d0c0', - 'dmd-gr' => '#a0c0f0', - 'myr-gr' => '#a0c0f0', - 'hmq1725' => '#ffa0a0', - 'hsr' => '#aa70ff', - 'keccak' => '#c0f0c0', - 'keccakc' => '#c0f0c0', - 'hex' => '#c0f0c0', - 'lbry' => '#b0d0e0', - 'luffa' => '#a0c0c0', - 'm7m' => '#d0a0a0', - 'penta' => '#80c0c0', - 'nist5' => '#c0e0e0', - 'quark' => '#c0c0c0', - 'qubit' => '#d0a0f0', - 'rainforest' => '#d0f0a0', - 'lbk3' => '#809aef', - 'lyra2' => '#80a0f0', - 'lyra2v2' => '#80c0f0', - 'lyra2z' => '#80b0f0', - 'phi' => '#a0a0e0', - 'phi2' => '#a0a0e0', - 'polytimos' => '#dedefe', - 'sib' => '#a0a0c0', - 'skein' => '#80a0a0', - 'skein2' => '#c8a060', - 'timetravel' => '#f0b0d0', - 'bitcore' => '#f790c0', - 'skunk' => '#dedefe', - 'tribus' => '#c0d0d0', - 'a5a' => '#f0f0f0', - 'vanilla' => '#f0f0f0', - 'velvet' => '#aac0cc', - 'vitalium' => '#f0b0a0', - 'whirlpool' => '#d0e0e0', - 'yescrypt' => '#e0d0e0', - 'yescryptR16' => '#e2d0e2', - 'yescryptR32' => '#e2d0d2', - 'zr5' => '#d0b0d0', - - 'MN' => '#ffffff', // MasterNode Earnings - 'PoS' => '#ffffff' // Stake - ); - - if(!isset($a[$algo])) - return '#ffffff'; - - return $a[$algo]; + $a = array( + 'a5a' => '#f0f0f0', + 'aergo' => '#e0d0e0', + 'allium' => '#80a0d0', + 'argon2' => '#e0d0e0', + 'argon2d-crds' => '#e0d0e0', + 'argon2d-dyn' => '#e0d0e0', + 'argon2m' => '#e0d0e0', + 'argon2d-uis' => '#e0d0e0', + 'balloon' => '#e0b0b0', + 'bastion' => '#e0b0b0', + 'bcd' => '#ffd880', + 'binarium-v1' => '#f0f0f0', + 'bitcore' => '#f790c0', + 'blake' => '#f0f0f0', + 'blake2b' => '#f2c81f', + 'blakecoin' => '#f0f0f0', + 'bmw512' => '#f0f0f0', + 'cuckoo' => '#d0a0a0', + 'c11' => '#a0a0d0', + 'decred' => '#f0f0f0', + 'deep' => '#e0ffff', + 'dmd-gr' => '#a0c0f0', + 'exosis' => '#49CCFE', + 'geek' => '#d0a0a0', + 'groestl' => '#d0a0a0', + 'hex' => '#c0f0c0', + 'hmq1725' => '#ffa0a0', + 'honeycomb' => '#c0f0c0', + 'hsr' => '#aa70ff', + 'jha' => '#a0d0c0', + 'keccak' => '#c0f0c0', + 'keccakc' => '#c0f0c0', + 'lbk3' => '#809aef', + 'lbry' => '#b0d0e0', + 'luffa' => '#a0c0c0', + 'lyra2' => '#80a0f0', + 'lyra2v2' => '#80c0f0', + 'lyra2v3' => '#80a0f0', + 'lyra2z330' => '#80b0f0', + 'lyra2vc0ban' => '#80c0f0', + 'lyra2z' => '#80b0f0', + 'lyra2zz' => '#80b0f0', + 'm7m' => '#d0a0a0', + 'myr-gr' => '#a0c0f0', + 'neoscrypt' => '#a0d0f0', + 'nist5' => '#c0e0e0', + 'odocrypt' => '#c0f0c0', + 'penta' => '#80c0c0', + 'phi' => '#a0a0e0', + 'phi2' => '#a0a0e0', + 'phi1612' => '#a0a0e0', + 'polytimos' => '#dedefe', + 'quark' => '#c0c0c0', + 'qubit' => '#d0a0f0', + 'rainforest' => '#d0f0a0', + 'rfv2' => '#d0f0a0', + 'renesis' => '#f0b0a0', + 'scrypt' => '#c0c0e0', + 'scryptn' => '#d0d0d0', + 'sha256' => '#d0d0a0', + 'sha256q' => '#9696dd', + 'sha256t' => '#d0d0f0', + 'sib' => '#a0a0c0', + 'skein' => '#80a0a0', + 'skein2' => '#c8a060', + 'skunk' => '#dedefe', + 'sonoa' => '#dedefe', + 'timetravel' => '#f0b0d0', + 'tribus' => '#c0d0d0', + 'vanilla' => '#f0f0f0', + 'velvet' => '#aac0cc', + 'vitalium' => '#f0b0a0', + 'whirlpool' => '#d0e0e0', + 'x11' => '#f0f0a0', + 'x11evo' => '#c0f0c0', + 'x12' => '#ffe090', + 'x13' => '#ffd880', + 'x14' => '#f0c080', + 'x15' => '#f0b080', + 'x16r' => '#f0b080', + 'x16rv2' => '#f0b080', + 'x16rt' => '#f0b080', + 'x16s' => '#f0b080', + 'x17' => '#f0b0a0', + 'x18' => '#f0b0a0', + 'x20r' => '#f0b0a0', + 'x21s' => '#f0b0a0', + 'x22i' => '#f0a090', + 'x25x' => '#f0a090', + 'xevan' => '#f0b0a0', + 'yescrypt' => '#e0d0e0', + 'yescryptR8' => '#e0d0e0', + 'yescryptR16' => '#e2d0e2', + 'yescryptR32' => '#e2d0d2', + 'yespower' => '#e2d0d2', + 'yespowerR8' => '#e2d0d2', + 'yespowerR16' => '#e2d0d2', + 'yespowerR24' => '#e2d0d2', + 'yespowerR32' => '#e2d0d2', + 'zr5' => '#d0b0d0', + + 'MN' => '#ffffff', // MasterNode Earnings + 'PoS' => '#ffffff' // Stake + ); + + if (!isset($a[$algo])) + return '#ffffff'; + + return $a[$algo]; } function getAlgoPort($algo) { - $a = array( - 'sha256' => 3333, - 'sha256t' => 3339, - 'sha256q' => 3337, - 'lbry' => 3334, - 'scrypt' => 3433, - 'timetravel' => 3555, - 'bitcore' => 3556, - 'exosis' => 3557, - 'c11' => 3573, - 'deep' => 3535, - 'x11' => 3533, - 'x11evo' => 3553, - 'x12' => 3233, - 'x13' => 3633, - 'x15' => 3733, - 'x16r' => 3636, - 'x16s' => 3663, - 'x17' => 3737, - 'x22i' => 3223, - 'aergo' => 3691, - 'xevan' => 3739, - 'hmq1725' => 3747, - 'nist5' => 3833, - 'x14' => 3933, - 'quark' => 4033, - 'whirlpool' => 4133, - 'neoscrypt' => 4233, - 'argon2' => 4234, - 'argon2d-dyn' => 4239, - 'scryptn' => 4333, - 'allium' => 4443, - 'lbk3' => 5522, - 'lyra2' => 4433, - 'lyra2v2' => 4533, - 'lyra2z' => 4553, - 'jha' => 4633, - 'qubit' => 4733, - 'zr5' => 4833, - 'skein' => 4933, - 'sib' => 5033, - 'keccak' => 5133, - 'keccakc' => 5134, - 'hex' => 5135, - 'skein2' => 5233, - //'groestl' => 5333, - 'dmd-gr' => 5333, - 'myr-gr' => 5433, - 'zr5' => 5533, - // 5555 to 5683 reserved - 'blake' => 5733, - 'blakecoin' => 5743, - 'decred' => 3252, - 'vanilla' => 5755, - 'blake2s' => 5766, - 'blake2b' => 5777, - 'penta' => 5833, - 'rainforest' => 7443, - 'luffa' => 5933, - 'm7m' => 6033, - 'veltor' => 5034, - 'velvet' => 6133, - 'vitalium' => 3233, - 'yescrypt' => 6233, - 'yescryptR16' => 6333, - 'yescryptR32' => 6343, - 'bastion' => 6433, - 'hsr' => 7433, - 'phi' => 8333, - 'phi2' => 8332, - 'polytimos' => 8463, - 'skunk' => 8433, - 'tribus' => 8533, - 'a5a' => 8633, - ); - - global $configCustomPorts; - if(isset($configCustomPorts[$algo])) - return $configCustomPorts[$algo]; - - if(!isset($a[$algo])) - return 3033; - - return $a[$algo]; + $a = array( + 'a5a' => 8633, + 'aergo' => 3691, + 'allium' => 4443, + 'argon2' => 4235, + 'argon2d-crds' => 4238, + 'argon2d-dyn' => 4239, + 'argon2m' => 4234, + 'argon2d-uis' => 4240, + 'balloon' => 5100, + 'bastion' => 6433, + 'bcd' => 3643, + 'binarium-v1' => 6666, + 'bitcore' => 3556, + 'blake' => 5733, + 'blake2b' => 5777, + 'blake2s' => 5766, + 'blakecoin' => 5743, + 'bmw512' => 5787, + 'c11' => 3573, + 'decred' => 3252, + 'deep' => 3535, + 'dmd-gr' => 5333, + 'exosis' => 3557, + 'geek' => 3692, + 'hex' => 5135, + 'hmq1725' => 3747, + 'honeycomb' => 7777, + 'hsr' => 7433, + 'jha' => 4633, + 'keccak' => 5133, + 'keccakc' => 5134, + 'lbk3' => 5522, + 'lbry' => 3334, + 'luffa' => 5933, + 'lyra2' => 4432, + 'lyra2v2' => 4533, + 'lyra2v3' => 4433, + 'lyra2vc0ban' => 4563, + 'lyra2z' => 4553, + 'lyra2z330' => 4555, + 'lyra2zz' => 4556, + 'm7m' => 6033, + 'myr-gr' => 5433, + 'neoscrypt' => 4233, + 'odocrypt' => 7777, + 'nist5' => 3833, + 'penta' => 5833, + 'phi' => 8333, + 'phi2' => 8332, + 'phi1612' => 8334, + 'polytimos' => 8463, + 'quark' => 4033, + 'qubit' => 4733, + 'renesis' => 5252, + 'rainforest' => 7443, + 'rfv2' => 8443, + 'scrypt' => 3433, + 'scryptn' => 4333, + 'sha256' => 3333, + 'sha256q' => 3337, + 'sha256t' => 3339, + 'sib' => 5033, + 'skein' => 4933, + 'skein2' => 5233, + 'skunk' => 8433, + 'sonoa' => 8733, + 'timetravel' => 3555, + 'tribus' => 8533, + 'vanilla' => 5755, + 'veltor' => 5034, + 'velvet' => 6133, + 'vitalium' => 3233, + 'whirlpool' => 4133, + 'x11' => 3533, + 'x11evo' => 3553, + 'x12' => 3233, + 'x13' => 3633, + 'x14' => 3933, + 'x15' => 3733, + 'x16r' => 3636, + 'x16rv2' => 3637, + 'x16rt' => 7220, + 'x16s' => 3663, + 'x17' => 3737, + 'x18' => 3738, + 'x20r' => 4300, + 'x21s' => 3224, + 'x22i' => 3223, + 'x25x' => 5633, + 'xevan' => 3739, + 'yescrypt' => 6233, + 'yescryptR8' => 6353, + 'yescryptR16' => 6333, + 'yescryptR32' => 6343, + 'yespower' => 6234, + 'yespowerR8' => 6235, + 'yespowerR16' => 6236, + 'yespowerR24' => 6237, + 'yespowerR32' => 6238, + 'zr5' => 5533 + //'groestl' => 5333, + // 5555 to 5683 reserved + ); + + global $configCustomPorts; + if (isset($configCustomPorts[$algo])) + return $configCustomPorts[$algo]; + + if (!isset($a[$algo])) + return 3033; + + return $a[$algo]; } //////////////////////////////////////////////////////////////////////// function yaamp_fee($algo) { - $fee = controller()->memcache->get("yaamp_fee-$algo"); - if($fee && is_numeric($fee)) return (float) $fee; + $fee = controller()->memcache->get("yaamp_fee-$algo"); + if ($fee && is_numeric($fee)) + return (float) $fee; -/* $norm = yaamp_get_algo_norm($algo); - if($norm == 0) $norm = 1; + /* $norm = yaamp_get_algo_norm($algo); + if($norm == 0) $norm = 1; - $hashrate = getdbosql('db_hashrate', "algo=:algo order by time desc", array(':algo'=>$algo)); - if(!$hashrate || !$hashrate->difficulty) return 1; + $hashrate = getdbosql('db_hashrate', "algo=:algo order by time desc", array(':algo'=>$algo)); + if(!$hashrate || !$hashrate->difficulty) return 1; - $target = yaamp_hashrate_constant($algo); - $interval = yaamp_hashrate_step(); - $delay = time()-$interval; + $target = yaamp_hashrate_constant($algo); + $interval = yaamp_hashrate_step(); + $delay = time()-$interval; - $rate = controller()->memcache->get_database_scalar("yaamp_pool_rate_coinonly-$algo", - "select sum(difficulty) * $target / $interval / 1000 from shares where valid and time>$delay and algo=:algo and jobid=0", array(':algo'=>$algo)); + $rate = controller()->memcache->get_database_scalar("yaamp_pool_rate_coinonly-$algo", + "select sum(difficulty) * $target / $interval / 1000 from shares where valid and time>$delay and algo=:algo and jobid=0", array(':algo'=>$algo)); -// $fee = round(log($hashrate->hashrate * $norm / 1000000 / $hashrate->difficulty + 1), 1) + YAAMP_FEES_MINING; -// $fee = round(log($rate * $norm / 2000000 / $hashrate->difficulty + 1), 1) + YAAMP_FEES_MINING; -*/ - $fee = YAAMP_FEES_MINING; + // $fee = round(log($hashrate->hashrate * $norm / 1000000 / $hashrate->difficulty + 1), 1) + YAAMP_FEES_MINING; + // $fee = round(log($rate * $norm / 2000000 / $hashrate->difficulty + 1), 1) + YAAMP_FEES_MINING; + */ + $fee = YAAMP_FEES_MINING; - // local fees config - global $configFixedPoolFees; - if (isset($configFixedPoolFees[$algo])) { - $fee = (float) $configFixedPoolFees[$algo]; - } + // local fees config + global $configFixedPoolFees; + if (isset($configFixedPoolFees[$algo])) { + $fee = (float) $configFixedPoolFees[$algo]; + } - controller()->memcache->set("yaamp_fee-$algo", $fee); - return $fee; + controller()->memcache->set("yaamp_fee-$algo", $fee); + return $fee; } -function take_yaamp_fee($v, $algo, $percent=-1) +function take_yaamp_fee($v, $algo, $percent = -1) { - if ($percent == -1) $percent = yaamp_fee($algo); + if ($percent == -1) + $percent = yaamp_fee($algo); - return $v - ($v * $percent / 100.0); + return $v - ($v * $percent / 100.0); } -function yaamp_hashrate_constant($algo=null) +function yaamp_hashrate_constant($algo = null) { - return pow(2, 42); // 0x400 00000000 + return pow(2, 42); // 0x400 00000000 } function yaamp_hashrate_step() { - return 300; + return 300; } function yaamp_profitability($coin) { - if(!$coin->difficulty) return 0; - - $btcmhd = 20116.56761169 / $coin->difficulty * $coin->reward * $coin->price; - if(!$coin->auxpow && $coin->rpcencoding == 'POW') - { - $listaux = getdbolist('db_coins', "enable and visible and auto_ready and auxpow and algo='$coin->algo'"); - foreach($listaux as $aux) - { - if(!$aux->difficulty) continue; - - $btcmhdaux = 20116.56761169 / $aux->difficulty * $aux->reward * $aux->price; - $btcmhd += $btcmhdaux; - } - } - - $algo_unit_factor = yaamp_algo_mBTC_factor($coin->algo); - return $btcmhd * $algo_unit_factor; + if (!$coin->difficulty) + return 0; + + $btcmhd = 20116.56761169 / $coin->difficulty * $coin->reward * $coin->price; + if (!$coin->auxpow && $coin->rpcencoding == 'POW') { + $listaux = getdbolist('db_coins', "enable and visible and auto_ready and auxpow and algo='$coin->algo'"); + foreach ($listaux as $aux) { + if (!$aux->difficulty) + continue; + + $btcmhdaux = 20116.56761169 / $aux->difficulty * $aux->reward * $aux->price; + $btcmhd += $btcmhdaux; + } + } + + $algo_unit_factor = yaamp_algo_mBTC_factor($coin->algo); + return $btcmhd * $algo_unit_factor; } function yaamp_convert_amount_user($coin, $amount, $user) { - $refcoin = getdbo('db_coins', $user->coinid); - $value = 0.; - if (YAAMP_ALLOW_EXCHANGE) { - if(!$refcoin) $refcoin = getdbosql('db_coins', "symbol='BTC'"); - if(!$refcoin || $refcoin->price <= 0) return 0; - $value = $amount * $coin->price / $refcoin->price; - } else if ($coin->price && $refcoin && $refcoin->price > 0.) { - $value = $amount * $coin->price / $refcoin->price; - } else if ($coin->id == $user->coinid) { - $value = $amount; - } - return $value; + $refcoin = getdbo('db_coins', $user->coinid); + $value = 0.; + if (YAAMP_ALLOW_EXCHANGE) { + if (!$refcoin) + $refcoin = getdbosql('db_coins', "symbol='BTC'"); + if (!$refcoin || $refcoin->price <= 0) + return 0; + $value = $amount * $coin->price / $refcoin->price; + } else if ($coin->price && $refcoin && $refcoin->price > 0.) { + $value = $amount * $coin->price / $refcoin->price; + } else if ($coin->id == $user->coinid) { + $value = $amount; + } + return $value; } function yaamp_convert_earnings_user($user, $status) { - $refcoin = getdbo('db_coins', $user->coinid); - $value = 0.; - if (YAAMP_ALLOW_EXCHANGE) { - if(!$refcoin) $refcoin = getdbosql('db_coins', "symbol='BTC'"); - if(!$refcoin || $refcoin->price <= 0) return 0; - $value = dboscalar("SELECT sum(amount*price) FROM earnings WHERE $status AND userid={$user->id}"); - $value = $value / $refcoin->price; - } else if ($refcoin && $refcoin->price > 0.) { - $value = dboscalar("SELECT sum(amount*price) FROM earnings WHERE $status AND userid={$user->id}"); - $value = $value / $refcoin->price; - } else if ($user->coinid) { - $value = dboscalar("SELECT sum(amount) FROM earnings WHERE $status AND userid={$user->id} AND coinid=".$user->coinid); - } - return $value; + $refcoin = getdbo('db_coins', $user->coinid); + $value = 0.; + if (YAAMP_ALLOW_EXCHANGE) { + if (!$refcoin) + $refcoin = getdbosql('db_coins', "symbol='BTC'"); + if (!$refcoin || $refcoin->price <= 0) + return 0; + $value = dboscalar("SELECT sum(amount*price) FROM earnings WHERE $status AND userid={$user->id}"); + $value = $value / $refcoin->price; + } else if ($refcoin && $refcoin->price > 0.) { + $value = dboscalar("SELECT sum(amount*price) FROM earnings WHERE $status AND userid={$user->id}"); + $value = $value / $refcoin->price; + } else if ($user->coinid) { + $value = dboscalar("SELECT sum(amount) FROM earnings WHERE $status AND userid={$user->id} AND coinid=" . $user->coinid); + } + return $value; } -//////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////credits to Alexg for PHP code changes////////////////////////////////////////// -function yaamp_pool_rate($algo=null) +function yaamp_pool_rate($algo = null) { - if(!$algo) $algo = user()->getState('yaamp-algo'); + if (!$algo) + $algo = user()->getState('yaamp-algo'); - $target = yaamp_hashrate_constant($algo); - $interval = yaamp_hashrate_step(); - $delay = time()-$interval; + $target = yaamp_hashrate_constant($algo); + $interval = yaamp_hashrate_step(); + $delay = time() - $interval; - $rate = controller()->memcache->get_database_scalar("yaamp_pool_rate-$algo", - "SELECT (sum(difficulty) * $target / $interval / 1000) FROM shares WHERE valid AND time>$delay AND algo=:algo", array(':algo'=>$algo)); + $rate = controller()->memcache->get_database_scalar("yaamp_pool_rate-$algo", "SELECT (sum(difficulty) * $target / $interval / 1000) FROM shares WHERE valid AND time>$delay AND algo=:algo", array( + ':algo' => $algo + )); - return $rate; + return $rate; } -function yaamp_pool_rate_bad($algo=null) +function yaamp_pool_rate_bad($algo = null) { - if(!$algo) $algo = user()->getState('yaamp-algo'); + if (!$algo) + $algo = user()->getState('yaamp-algo'); - $target = yaamp_hashrate_constant($algo); - $interval = yaamp_hashrate_step(); - $delay = time()-$interval; + $rate = controller()->memcache->get("yaamp_pool_rate_bad-$algo"); + if ($rate === false) { - $rate = controller()->memcache->get_database_scalar("yaamp_pool_rate_bad-$algo", - "SELECT (sum(difficulty) * $target / $interval / 1000) FROM shares WHERE not valid AND time>$delay AND algo=:algo", array(':algo'=>$algo)); + $target = yaamp_hashrate_constant($algo); + $interval = yaamp_hashrate_step(); + $delay = time() - $interval; - return $rate; + $rate = dboscalar("SELECT sum(difficulty) FROM shares WHERE not valid AND time>$delay AND algo=:algo", array( + ':algo' => $algo + )); + $rate = $rate * $target / $interval / 1000; + $t = 30; + controller()->memcache->set("yaamp_pool_rate_bad-$algo", $rate, $t); + } + + return $rate; } -function yaamp_pool_rate_rentable($algo=null) +function yaamp_pool_rate_rentable($algo = null) { - if(!$algo) $algo = user()->getState('yaamp-algo'); + if (!$algo) + $algo = user()->getState('yaamp-algo'); + + $rate = controller()->memcache->get("yaamp_pool_rate_rentable-$algo"); + if ($rate === false) { - $target = yaamp_hashrate_constant($algo); - $interval = yaamp_hashrate_step(); - $delay = time()-$interval; + $target = yaamp_hashrate_constant($algo); + $interval = yaamp_hashrate_step(); + $delay = time() - $interval; - $rate = controller()->memcache->get_database_scalar("yaamp_pool_rate_rentable-$algo", - "SELECT (sum(difficulty) * $target / $interval / 1000) FROM shares WHERE valid AND extranonce1 AND time>$delay AND algo=:algo", array(':algo'=>$algo)); + $rate = dboscalar("SELECT sum(difficulty) FROM shares WHERE valid AND extranonce1 AND time>$delay AND algo=:algo", array( + ':algo' => $algo + )); + $rate = $rate * $target / $interval / 1000; + $t = 30; + controller()->memcache->set("yaamp_pool_rate_rentable-$algo", $rate, $t); + } - return $rate; + return $rate; } -function yaamp_user_rate($userid, $algo=null) +function yaamp_user_rate($userid, $algo = null) { - if(!$algo) $algo = user()->getState('yaamp-algo'); + if (!$algo) + $algo = user()->getState('yaamp-algo'); + + $rate = controller()->memcache->get("yaamp_user_rate-$userid-$algo"); + if ($rate === false) { - $target = yaamp_hashrate_constant($algo); - $interval = yaamp_hashrate_step(); - $delay = time()-$interval; + $target = yaamp_hashrate_constant($algo); + $interval = yaamp_hashrate_step(); + $delay = time() - $interval; - $rate = controller()->memcache->get_database_scalar("yaamp_user_rate-$userid-$algo", - "SELECT (sum(difficulty) * $target / $interval / 1000) FROM shares WHERE valid AND time>$delay AND userid=$userid AND algo=:algo", array(':algo'=>$algo)); + $rate = dboscalar("SELECT sum(difficulty) FROM shares WHERE valid AND time>$delay AND userid=$userid AND algo=:algo", array( + ':algo' => $algo + )); + $rate = $rate * $target / $interval / 1000; + $t = 30; + controller()->memcache->set("yaamp_user_rate-$userid-$algo", $rate, $t); + } - return $rate; + return $rate; } -function yaamp_user_rate_bad($userid, $algo=null) +function yaamp_user_rate_bad($userid, $algo = null) { - if(!$algo) $algo = user()->getState('yaamp-algo'); + if (!$algo) + $algo = user()->getState('yaamp-algo'); - $target = yaamp_hashrate_constant($algo); - $interval = yaamp_hashrate_step(); - $delay = time()-$interval; + $rate = controller()->memcache->get("yaamp_user_rate_bad-$userid-$algo"); + if ($rate === false) { - $diff = (double) controller()->memcache->get_database_scalar("yaamp_user_diff_avg-$userid-$algo", - "SELECT avg(difficulty) FROM shares WHERE valid AND time>$delay AND userid=$userid AND algo=:algo", array(':algo'=>$algo)); + $target = yaamp_hashrate_constant($algo); + $interval = yaamp_hashrate_step(); + $delay = time() - $interval; - $rate = controller()->memcache->get_database_scalar("yaamp_user_rate_bad-$userid-$algo", - "SELECT ((count(id) * $diff) * $target / $interval / 1000) FROM shares WHERE valid!=1 AND time>$delay AND userid=$userid AND algo=:algo", array(':algo'=>$algo)); + $diff = (double) controller()->memcache->get_database_scalar("yaamp_user_diff_avg-$userid-$algo", "SELECT avg(difficulty) FROM shares WHERE valid AND time>$delay AND userid=$userid AND algo=:algo", array( + ':algo' => $algo + )); - return $rate; + $rate = dboscalar("SELECT count(id) FROM shares WHERE valid!=1 AND time>$delay AND userid=$userid AND algo=:algo", array( + ':algo' => $algo + )); + $rate = $rate * $diff * $target / $interval / 1000; + $t = 30; + controller()->memcache->set("yaamp_user_rate_bad-$userid-$algo", $rate, $t); + } + + return $rate; } -function yaamp_worker_rate($workerid, $algo=null) +function yaamp_worker_rate($workerid, $algo = null) { - if(!$algo) $algo = user()->getState('yaamp-algo'); + if (!$algo) + $algo = user()->getState('yaamp-algo'); + + $rate = controller()->memcache->get("yaamp_worker_rate-$workerid-$algo"); + if ($rate === false) { - $target = yaamp_hashrate_constant($algo); - $interval = yaamp_hashrate_step(); - $delay = time()-$interval; + $target = yaamp_hashrate_constant($algo); + $interval = yaamp_hashrate_step(); + $delay = time() - $interval; - $rate = controller()->memcache->get_database_scalar("yaamp_worker_rate-$workerid-$algo", - "SELECT (sum(difficulty) * $target / $interval / 1000) FROM shares WHERE valid AND time>$delay AND workerid=".$workerid); + $rate = dboscalar("SELECT sum(difficulty) FROM shares WHERE valid AND time>$delay AND workerid=" . $workerid); + $rate = $rate * $target / $interval / 1000; + $t = 30; + controller()->memcache->set("yaamp_worker_rate-$workerid-$algo", $rate, $t); + } - return $rate; + return $rate; } -function yaamp_worker_rate_bad($workerid, $algo=null) +function yaamp_worker_rate_bad($workerid, $algo = null) { - if(!$algo) $algo = user()->getState('yaamp-algo'); + if (!$algo) + $algo = user()->getState('yaamp-algo'); + + $rate = controller()->memcache->get("yaamp_worker_rate_bad-$workerid-$algo"); + if ($rate === false) { - $target = yaamp_hashrate_constant($algo); - $interval = yaamp_hashrate_step(); - $delay = time()-$interval; + $target = yaamp_hashrate_constant($algo); + $interval = yaamp_hashrate_step(); + $delay = time() - $interval; - $diff = (double) controller()->memcache->get_database_scalar("yaamp_worker_diff_avg-$workerid-$algo", - "SELECT avg(difficulty) FROM shares WHERE valid AND time>$delay AND workerid=".$workerid); + $diff = (double) controller()->memcache->get_database_scalar("yaamp_worker_diff_avg-$workerid-$algo", "SELECT avg(difficulty) FROM shares WHERE valid AND time>$delay AND workerid=" . $workerid); - $rate = controller()->memcache->get_database_scalar("yaamp_worker_rate_bad-$workerid-$algo", - "SELECT ((count(id) * $diff) * $target / $interval / 1000) FROM shares WHERE valid!=1 AND time>$delay AND workerid=".$workerid); + $rate = dboscalar("SELECT count(id) FROM shares WHERE valid!=1 AND time>$delay AND workerid=" . $workerid); - return empty($rate)? 0: $rate; + $rate = $rate * $diff * $target / $interval / 1000; + $t = 30; + controller()->memcache->set("yaamp_worker_rate_bad-$workerid-$algo", $rate, $t); + } + + return empty($rate) ? 0 : $rate; } -function yaamp_worker_shares_bad($workerid, $algo=null) +function yaamp_worker_shares_bad($workerid, $algo = null) { - if(!$algo) $algo = user()->getState('yaamp-algo'); + if (!$algo) + $algo = user()->getState('yaamp-algo'); - $interval = yaamp_hashrate_step(); - $delay = time()-$interval; + $interval = yaamp_hashrate_step(); + $delay = time() - $interval; - $rate = (int) controller()->memcache->get_database_scalar("yaamp_worker_shares_bad-$workerid-$algo", - "SELECT count(id) FROM shares WHERE valid!=1 AND time>$delay AND workerid=".$workerid); + $rate = (int) controller()->memcache->get_database_scalar("yaamp_worker_shares_bad-$workerid-$algo", "SELECT count(id) FROM shares WHERE valid!=1 AND time>$delay AND workerid=" . $workerid); - return $rate; + return $rate; } function yaamp_coin_rate($coinid) { - $coin = getdbo('db_coins', $coinid); - if(!$coin || !$coin->enable) return 0; + $coin = getdbo('db_coins', $coinid); + if (!$coin || !$coin->enable) + return 0; + + $rate = controller()->memcache->get("yaamp_coin_rate-$coinid"); + if ($rate === false) { - $target = yaamp_hashrate_constant($coin->algo); - $interval = yaamp_hashrate_step(); - $delay = time()-$interval; + $target = yaamp_hashrate_constant($coin->algo); + $interval = yaamp_hashrate_step(); + $delay = time() - $interval; - $rate = controller()->memcache->get_database_scalar("yaamp_coin_rate-$coinid", - "SELECT (sum(difficulty) * $target / $interval / 1000) FROM shares WHERE valid AND time>$delay AND coinid=$coinid"); + $rate = dboscalar("SELECT sum(difficulty) FROM shares WHERE valid AND time>$delay AND coinid=$coinid"); + $rate = $rate * $target / $interval / 1000; + $t = 30; + controller()->memcache->set("yaamp_coin_rate-$coinid", $rate, $t); + } - return $rate; + return $rate; } -function yaamp_rented_rate($algo=null) +function yaamp_rented_rate($algo = null) { - if(!$algo) $algo = user()->getState('yaamp-algo'); + if (!$algo) + $algo = user()->getState('yaamp-algo'); + + $rate = controller()->memcache->get("yaamp_rented_rate-$algo"); + if ($rate === false) { - $target = yaamp_hashrate_constant($algo); - $interval = yaamp_hashrate_step(); - $delay = time()-$interval; + $target = yaamp_hashrate_constant($algo); + $interval = yaamp_hashrate_step(); + $delay = time() - $interval; - $rate = controller()->memcache->get_database_scalar("yaamp_rented_rate-$algo", - "SELECT (sum(difficulty) * $target / $interval / 1000) FROM shares WHERE time>$delay AND algo=:algo AND jobid!=0 AND valid", array(':algo'=>$algo)); + $rate = dboscalar("SELECT sum(difficulty) FROM shares WHERE time>$delay AND algo=:algo AND jobid!=0 AND valid", array( + ':algo' => $algo + )); + $rate = $rate * $target / $interval / 1000; + $t = 30; + controller()->memcache->set("yaamp_rented_rate-$algo", $rate, $t); + } - return $rate; + return $rate; } function yaamp_job_rate($jobid) { - $job = getdbo('db_jobs', $jobid); - if(!$job) return 0; + $job = getdbo('db_jobs', $jobid); + if (!$job) + return 0; - $target = yaamp_hashrate_constant($job->algo); - $interval = yaamp_hashrate_step(); - $delay = time()-$interval; + $rate = controller()->memcache->get("yaamp_job_rate-$jobid"); + if ($rate === false) { - $rate = controller()->memcache->get_database_scalar("yaamp_job_rate-$jobid", - "SELECT (sum(difficulty) * $target / $interval / 1000) FROM jobsubmits WHERE valid AND time>$delay AND jobid=".$jobid); - return $rate; + $target = yaamp_hashrate_constant($job->algo); + $interval = yaamp_hashrate_step(); + $delay = time() - $interval; + + $rate = dboscalar("SELECT sum(difficulty) FROM jobsubmits WHERE valid AND time>$delay AND jobid=" . $jobid); + $rate = $rate * $target / $interval / 1000; + $t = 30; + controller()->memcache->set("yaamp_job_rate-$jobid", $rate, $t); + } + + return $rate; } function yaamp_job_rate_bad($jobid) { - $job = getdbo('db_jobs', $jobid); - if(!$job) return 0; + $job = getdbo('db_jobs', $jobid); + if (!$job) + return 0; + + $rate = controller()->memcache->get("yaamp_job_rate_bad-$jobid"); + if ($rate === false) { - $target = yaamp_hashrate_constant($job->algo); - $interval = yaamp_hashrate_step(); - $delay = time()-$interval; + $target = yaamp_hashrate_constant($job->algo); + $interval = yaamp_hashrate_step(); + $delay = time() - $interval; - $diff = (double) controller()->memcache->get_database_scalar("yaamp_job_diff_avg-$jobid", - "SELECT avg(difficulty) FROM jobsubmits WHERE valid AND time>$delay AND jobid=".$jobid); + $diff = (double) controller()->memcache->get_database_scalar("yaamp_job_diff_avg-$jobid", "SELECT avg(difficulty) FROM jobsubmits WHERE valid AND time>$delay AND jobid=" . $jobid); - $rate = controller()->memcache->get_database_scalar("yaamp_job_rate_bad-$jobid", - "SELECT ((count(id) * $diff) * $target / $interval / 1000) FROM jobsubmits WHERE valid!=1 AND time>$delay AND jobid=".$jobid); + $rate = dboscalar("SELECT count(id) FROM jobsubmits WHERE valid!=1 AND time>$delay AND jobid=" . $jobid); + $rate = $rate * $diff * $target / $interval / 1000; + $t = 30; + controller()->memcache->set("yaamp_job_rate_bad-$jobid", $rate, $t); + } - return $rate; + return $rate; } ////////////////////////////////////////////////////////////////////////////////////////////////////// -function yaamp_pool_rate_pow($algo=null) +function yaamp_pool_rate_pow($algo = null) { - if(!$algo) $algo = user()->getState('yaamp-algo'); + if (!$algo) + $algo = user()->getState('yaamp-algo'); - $target = yaamp_hashrate_constant($algo); - $interval = yaamp_hashrate_step(); - $delay = time()-$interval; + $target = yaamp_hashrate_constant($algo); + $interval = yaamp_hashrate_step(); + $delay = time() - $interval; - $rate = controller()->memcache->get_database_scalar("yaamp_pool_rate_pow-$algo", - "SELECT sum(shares.difficulty) * $target / $interval / 1000 FROM shares, coins - WHERE shares.valid AND shares.time>$delay AND shares.algo=:algo AND - shares.coinid=coins.id AND coins.rpcencoding='POW'", array(':algo'=>$algo)); + $rate = controller()->memcache->get_database_scalar("yaamp_pool_rate_pow-$algo", "SELECT sum(shares.difficulty) * $target / $interval / 1000 FROM shares, coins + WHERE shares.valid AND shares.time>$delay AND shares.algo=:algo AND + shares.coinid=coins.id AND coins.rpcencoding='POW'", array( + ':algo' => $algo + )); - return $rate; + return $rate; } ///////////////////////////////////////////////////////////////////////////////////////////// function yaamp_renter_account($renter) { - if(YAAMP_PRODUCTION) - return "renter-prod-$renter->id"; - else - return "renter-dev-$renter->id"; + if (YAAMP_PRODUCTION) + return "renter-prod-$renter->id"; + else + return "renter-dev-$renter->id"; } ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/web/yaamp/core/trading/bitzv2_trading.php b/web/yaamp/core/trading/bitzv2_trading.php new file mode 100644 index 000000000..598f50da9 --- /dev/null +++ b/web/yaamp/core/trading/bitzv2_trading.php @@ -0,0 +1,47 @@ +getUserAssets())->data->info; + if (!is_array($data) || empty($data)) return; + $savebalance = getdbosql('db_balances', "name='$exchange'"); + foreach($data as $balance) + { + if ($balance->name == 'btc') { + if (is_object($savebalance)) { + $savebalance->balance = $balance->over; + $savebalance->onsell = $balance->lock; + $savebalance->save(); + } + continue; + } + if ($updatebalances) { + // store available balance in market table + $coins = getdbolist('db_coins', "symbol=:symbol OR symbol2=:symbol", + array(':symbol'=>strtoupper($balance->name)) + ); + if (empty($coins)) continue; + foreach ($coins as $coin) { + $market = getdbosql('db_markets', "coinid=:coinid AND name='$exchange'", array(':coinid'=>$coin->id)); + if (!$market) continue; + $market->balance = $balance->over; + $market->ontrade = $balance->lock; + $market->balancetime = time(); + $market->save(); + } + } + } + if (!YAAMP_ALLOW_EXCHANGE) return; + // real trading, todo.. +} diff --git a/web/yaamp/core/trading/cryptobridge_trading.php b/web/yaamp/core/trading/cryptobridge_trading.php new file mode 100644 index 000000000..48d936d57 --- /dev/null +++ b/web/yaamp/core/trading/cryptobridge_trading.php @@ -0,0 +1,75 @@ +balance = 0; + $savebalance->onsell = 0; + $savebalance->save(); + } + + foreach($balances as $asset => $balance) + { + $parts = explode('.', $asset); + $symbol = arraySafeVal($parts,1); + if (empty($symbol) || $parts[0] != 'BRIDGE') continue; + + if ($symbol == 'BTC') { + if (is_object($savebalance)) { + $savebalance->balance = arraySafeVal($balance,'balance',0); + $savebalance->onsell = arraySafeVal($balance,'orders',0); + $savebalance->save(); + } + continue; + } + + if ($updatebalances) { + // store available balance in market table + $coins = getdbolist('db_coins', "symbol=:symbol OR symbol2=:symbol", + array(':symbol'=>$symbol) + ); + if (empty($coins)) continue; + foreach ($coins as $coin) { + $market = getdbosql('db_markets', "coinid=:coinid AND name='$exchange'", array(':coinid'=>$coin->id)); + if (!$market) continue; + $market->balance = arraySafeVal($balance,'balance',0); + $market->ontrade = arraySafeVal($balance,'orders',0); + $market->balancetime = time(); + $market->save(); + } + } + } + + if (!YAAMP_ALLOW_EXCHANGE) return; + + // more could be done i guess +} diff --git a/web/yaamp/core/trading/kucoin_trading.php b/web/yaamp/core/trading/kucoin_trading.php index dd331823a..6b0389634 100644 --- a/web/yaamp/core/trading/kucoin_trading.php +++ b/web/yaamp/core/trading/kucoin_trading.php @@ -14,7 +14,7 @@ function doKuCoinTrading($quick=false) if (exchange_get($exchange, 'disabled')) return; - $data = kucoin_api_user('account/balance'); + $data = kucoin_api_user('accounts'); if (!kucoin_result_valid($data)) return; $savebalance = getdbosql('db_balances', "name='$exchange'"); @@ -22,19 +22,19 @@ function doKuCoinTrading($quick=false) if (is_array($data->data)) foreach($data->data as $balance) { - if ($balance->coinType == 'BTC') { + if ($balance->currency == 'BTC' && $balance->type == 'main') { if (is_object($savebalance)) { $savebalance->balance = $balance->balance; - $savebalance->onsell = $balance->freezeBalance; + $savebalance->onsell = $balance->holds; $savebalance->save(); } continue; } - if ($updatebalances) { + if ($updatebalances && $balance->type == 'main') { // store available balance in market table $coins = getdbolist('db_coins', "symbol=:symbol OR symbol2=:symbol", - array(':symbol'=>$balance->coinType) + array(':symbol'=>$balance->currency) ); if (empty($coins)) continue; foreach ($coins as $coin) { @@ -44,14 +44,14 @@ function doKuCoinTrading($quick=false) ); if (!$market) continue; $market->balance = $balance->balance; - $market->ontrade = $balance->freezeBalance; + $market->ontrade = $balance->holds; $market->balancetime = time(); $market->save(); $checked_today = cache()->get($exchange.'-deposit_address-check-'.$coin->symbol); if ($coin->installed && !$checked_today) { sleep(1); - $obj = kucoin_api_user("account/{$coin->symbol}/wallet/address"); + $obj = kucoin_api_user('deposit-addresses',array('currency'=>$coin->symbol)); if (!kucoin_result_valid($obj)) continue; $result = $obj->data; $deposit_address = objSafeVal($result,'address'); diff --git a/web/yaamp/core/trading/trading.php b/web/yaamp/core/trading/trading.php index 9d88b5083..f5da68140 100644 --- a/web/yaamp/core/trading/trading.php +++ b/web/yaamp/core/trading/trading.php @@ -3,13 +3,13 @@ require_once('binance_trading.php'); require_once('bittrex_trading.php'); require_once('bleutrade_trading.php'); -require_once('bter_trading.php'); require_once('c-cex_trading.php'); require_once('kraken_trading.php'); require_once('yobit_trading.php'); require_once('alcurex_trading.php'); require_once('coinsmarkets_trading.php'); require_once('crex24_trading.php'); +require_once('cryptobridge_trading.php'); require_once('cryptopia_trading.php'); require_once('hitbtc_trading.php'); require_once('kucoin_trading.php'); @@ -72,11 +72,6 @@ function runExchange($exchangeName=false) updateBinanceMarkets(); break; - case 'bter': - doBterTrading(true); - updateBterMarkets(); - break; - case 'crex24': doCrex24Trading(true); updateCrex24Markets(); @@ -88,6 +83,7 @@ function runExchange($exchangeName=false) break; case 'cryptobridge': + doCryptobridgeTrading(true); updateCryptoBridgeMarkets(); break; diff --git a/web/yaamp/core/trading/zebitex_trading.php b/web/yaamp/core/trading/zebitex_trading.php new file mode 100644 index 000000000..9320b4649 --- /dev/null +++ b/web/yaamp/core/trading/zebitex_trading.php @@ -0,0 +1,235 @@ + $OrderID)); + if($res && !isset($res->error)) { + $db_order = getdbosql('db_orders', "market=:market AND uuid=:uuid", array( + ':market'=>'zebitex', ':uuid'=>$OrderID + )); + if($db_order) $db_order->delete(); + } +} + function doZebitexTrading($quick=false) +{ + $exchange = 'zebitex'; + $updatebalances = true; + if (exchange_get($exchange, 'disabled')) return; + $data = zebitex_api_user('funds'); + if (empty($data)) return; + $savebalance = getdbosql('db_balances', "name='$exchange'"); + foreach($data as $balance) + { + if ($balance->code == 'BTC') { + if (is_object($savebalance)) { + $savebalance->balance = $balance->balance; + $savebalance->onsell = $balance->lockedBalance; + $savebalance->save(); + } + continue; + } + if ($updatebalances) { + // store available balance in market table + $coins = getdbolist('db_coins', "symbol=:symbol OR symbol2=:symbol", + array(':symbol'=>$balance->code) + ); + if (empty($coins)) continue; + foreach ($coins as $coin) { + $market = getdbosql('db_markets', "coinid=:coinid AND name='$exchange'", array(':coinid'=>$coin->id)); + if (!$market) continue; + $market->balance = $balance->balance; + $market->ontrade = $balance->lockedBalance; + $market->balancetime = time(); + $market->deposit_address = $balance->paymentAddress; + $market->save(); + } + } + } + if (!YAAMP_ALLOW_EXCHANGE) return; + // real trading, todo.. + + $flushall = rand(0, 8) == 0; + if($quick) $flushall = false; + $min_btc_trade = exchange_get($exchange, 'min_btc_trade', 0.00050000); // minimum allowed by the exchange + $sell_ask_pct = 1.05; // sell on ask price + 5% + $cancel_ask_pct = 1.20; // cancel order if our price is more than ask price + 20% + // auto trade + sleep(1); + $orders = zebitex_api_user('orders/current'); + sleep(1); + $tickers = zebitex_api_query('orders/tickers'); + foreach ($data as $balance) + { + if ($balance->balance == 0 && $balance->lockedBalance == 0) continue; + if ($balance->code == 'BTC') continue; + $coin = getdbosql('db_coins', "symbol=:symbol AND dontsell=0", array(':symbol'=>strtoupper($balance->code))); + if(!$coin) continue; + $symbol = $coin->symbol; + if (!empty($coin->symbol2)) $symbol = $coin->symbol2; + + $market = getdbosql('db_markets', "coinid=:coinid AND name='zebitex'", array(':coinid'=>$coin->id)); + if(!$market) continue; + $market->balance = floatval($balance->lockedBalance); + if (floatval($balance->lockedBalance) > floatval(0)) { + $ticker = $tickers->{strtolower($balance->code).'btc'}; + if(!$ticker || $balance->isDisabled || $balance->isFiat) continue; + } + + // {"per":10,"page":1,"total":4,"items":[{"id":86,"price":"0.001","state":"wait","ordType":"limit","amount":"25.0","originAmount":"25.0","side":"buy","cre$ + // + if(!empty($orders) && !empty($orders->items)) + foreach($orders->items as $order) + { + $pairs = explode("/", $order->pair); + $pair = $order->currency; + debuglog("pair is ".$pairs[0]); + if ($pairs[1] != 'BTC') continue; + // ignore buy orders + if(stripos($order->side, 'sell') === false) continue; + if($market->marketid == 0) { + $market->marketid = $order->id; + $market->save(); + } + $ask = bitcoinvaluetoa($ticker->sell); + $sellprice = bitcoinvaluetoa($order->price); + // cancel orders not on the wanted ask range + if($sellprice > $ask*$cancel_ask_pct || $flushall) + { + debuglog("zebitex: cancel order $pair at $sellprice, ask price is now $ask"); + sleep(1); + doZebitexCancelOrder($order->id); + } + // store existing orders + else + { + $db_order = getdbosql('db_orders', "market=:market AND uuid=:uuid", array( + ':market'=>'zebitex', ':uuid'=>$order->id + )); + if($db_order) continue; + debuglog("zebitex: store order of {$order->amount} {$symbol} at $sellprice BTC"); + $db_order = new db_orders; + $db_order->market = 'zebitex'; + $db_order->coinid = $coin->id; + $db_order->amount = $order->amount; + $db_order->price = $sellprice; + $db_order->ask = $ticker->sell; + $db_order->bid = $ticker->buy; + $db_order->uuid = $order->id; + $db_order->created = time(); // $order->TimeStamp 2016-03-07T20:04:05.3947572" + $db_order->save(); + } + } + // drop obsolete orders + $list = getdbolist('db_orders', "coinid={$coin->id} AND market='zebitex'"); + foreach($list as $db_order) + { + $found = false; + if(!empty($orders) && isset($orders->items)) + foreach($orders->items as $order) { + if(stripos($order->side, 'sell') === false) continue; + if($order->id == $db_order->uuid) { + $found = true; + break; + } + } + if(!$found) { + debuglog("zebitex: delete db order {$db_order->amount} {$coin->symbol} at {$db_order->price} BTC"); + $db_order->delete(); + } + } + if($coin->dontsell) continue; + $market->lasttraded = time(); + $market->save(); + // new orders + $amount = floatval($balance->balance); + if(!$amount) continue; + if($amount*$coin->price < $min_btc_trade || !$market->marketid) continue; + sleep(1); + $data = zebitex_api_query('orders/orderbook', array("market" => strtolower($symbol).'btc')); +// {"asks":[["0.01654547","3.0"],["0.01784895","2.654466"],["0.018799","4.0"],["0.01954657","0.345534"]],"bids":[["0.01","2.0"],["0.001","11.0"]]} + + if($coin->sellonbid) + for($i = 0; $i < 5 && $amount >= 0; $i++) + { + if(!isset($data->bids[$i])) break; + $nextbuy = $data->bids[$i]; + if($amount*1.1 < $nextbuy[1]) break; + $sellprice = bitcoinvaluetoa($nextbuy[0]); + $sellamount = min($amount, $nextbuy[1]); + if($sellamount*$sellprice < $min_btc_trade) continue; + debuglog("zebitex: selling $sellamount $symbol at $sellprice"); + sleep(1); + $params = array('bid' => 'btc', 'ask' => strtolower($symbol), 'side' => 'ask', 'price' => $sellprice, + 'amount'=>$sellamount, 'market' => strtolower($symbol).'btc', 'ord_type' => 'limit'); + $res = zebitex_api_user('orders', $params); + if(!$res || isset($res->error)) { + debuglog("zebitex create order err: ".json_encode($res)); + break; + } + $amount -= $sellamount; + } + if($amount <= 0) continue; + + sleep(1); + $ticker = $tickers->{strtolower($balance->code).'btc'}; + if(!$ticker || $balance->isDisabled || $balance->isFiat) continue; + if($coin->sellonbid) + $sellprice = bitcoinvaluetoa($ticker->buy); + else + $sellprice = bitcoinvaluetoa($ticker->sell * $sell_ask_pct); // lowest ask price +5% + if($amount*$sellprice < $min_btc_trade) continue; + debuglog("zebitex: selling $amount $symbol at $sellprice"); + sleep(1); + $params = array('bid' => 'btc', 'ask' => strtolower($symbol), 'side' => 'ask', 'price' => $sellprice, + 'amount'=>$sellamount, 'market' => strtolower($symbol).'btc', 'ord_type' => 'limit'); + $res = zebitex_api_user('orders', $params); + + if(!$res || isset($res->error)) { + debuglog("zebitex create order err: ".json_encode($res)); + continue; + } + $db_order = new db_orders; + $db_order->market = 'zebitex'; + $db_order->coinid = $coin->id; + $db_order->amount = $amount; + $db_order->price = $sellprice; + $db_order->ask = $ticker->sell; + $db_order->bid = $ticker->buy; +// $db_order->uuid = $res->id; + $db_order->created = time(); + $db_order->save(); + + } + + $withdraw_min = exchange_get($exchange, 'withdraw_min_btc', EXCH_AUTO_WITHDRAW); + $withdraw_fee = exchange_get($exchange, 'withdraw_fee_btc', 0.002); + // auto withdraw : to do + if(is_object($savebalance)) + if(floatval($withdraw_min) > 0 && $savebalance->balance >= ($withdraw_min + $withdraw_fee)) + { + // $btcaddr = exchange_get($exchange, 'withdraw_btc_address', YAAMP_BTCADDRESS); + $btcaddr = YAAMP_BTCADDRESS; + $amount = $savebalance->balance - $withdraw_fee; + debuglog("zebitex: withdraw $amount BTC to $btcaddr"); + sleep(1); + $params = array("code" => $amount."btc"); + $res = zebitex_api_user('withdrawals', $params); + if(is_object($res) && !isset($res->error)) + { + $withdraw = new db_withdraws; + $withdraw->market = 'zebitex'; + $withdraw->address = $btcaddr; + $withdraw->amount = $amount; + $withdraw->time = time(); +// $withdraw->uuid = $res->Data; + $withdraw->save(); + $savebalance->balance = 0; + $savebalance->save(); + } else { + debuglog("zebitex withdraw BTC error: ".json_encode($res)); + } + } + + } diff --git a/web/yaamp/defaultconfig.php b/web/yaamp/defaultconfig.php index 2e66fd2a0..232592b5b 100644 --- a/web/yaamp/defaultconfig.php +++ b/web/yaamp/defaultconfig.php @@ -31,17 +31,18 @@ if (!defined('EXCH_BITSTAMP_ID')) define('EXCH_BITSTAMP_ID', ''); if (!defined('EXCH_BITSTAMP_KEY')) define('EXCH_BITSTAMP_KEY',''); if (!defined('EXCH_BLEUTRADE_KEY')) define('EXCH_BLEUTRADE_KEY', ''); -if (!defined('EXCH_BTER_KEY')) define('EXCH_BTER_KEY', ''); if (!defined('EXCH_CCEX_KEY')) define('EXCH_CCEX_KEY', ''); if (!defined('EXCH_CEXIO_ID')) define('EXCH_CEXIO_ID', ''); if (!defined('EXCH_CEXIO_KEY')) define('EXCH_CEXIO_KEY', ''); if (!defined('EXCH_CREX24_KEY')) define('EXCH_CREX24_KEY', ''); +if (!defined('EXCH_CRYPTOBRIDGE_ID')) define('EXCH_CRYPTOBRIDGE_ID', ''); if (!defined('EXCH_CRYPTOPIA_KEY')) define('EXCH_CRYPTOPIA_KEY', ''); if (!defined('EXCH_HITBTC_KEY')) define('EXCH_HITBTC_KEY', ''); if (!defined('EXCH_POLONIEX_KEY')) define('EXCH_POLONIEX_KEY', ''); if (!defined('EXCH_YOBIT_KEY')) define('EXCH_YOBIT_KEY', ''); if (!defined('EXCH_KRAKEN_KEY')) define('EXCH_KRAKEN_KEY', ''); if (!defined('EXCH_KUCOIN_KEY')) define('EXCH_KUCOIN_KEY', ''); +if (!defined('EXCH_KUCOIN_PASSPHRASE')) define('EXCH_KUCOIN_PASSPHRASE', ''); if (!defined('EXCH_LIVECOIN_KEY')) define('EXCH_LIVECOIN_KEY', ''); if (!defined('EXCH_NOVA_KEY')) define('EXCH_NOVA_KEY', ''); if (!defined('EXCH_STOCKSEXCHANGE_KEY')) define('EXCH_STOCKSEXCHANGE_KEY', ''); diff --git a/web/yaamp/models/db_coinsModel.php b/web/yaamp/models/db_coinsModel.php index 5ce150dc8..c9ff57c9b 100644 --- a/web/yaamp/models/db_coinsModel.php +++ b/web/yaamp/models/db_coinsModel.php @@ -51,9 +51,11 @@ public function attributeLabels() 'hassubmitblock'=> 'Has submitblock', 'hasmasternodes'=> 'Masternodes', 'usesegwit' => 'Use segwit', + 'usefaucet' => 'Use Faucet', 'market' => 'Preferred market', 'rpcencoding' => 'RPC Type', - 'specifications'=> 'Notes' + 'dedicatedport' => 'Dedicated Port', + 'specifications'=> 'Additional Config Parameters' ); } @@ -122,4 +124,3 @@ public function createExplorerLink($label, $params=array(), $htmlOptions=array() } } - diff --git a/web/yaamp/modules/api/ApiController.php b/web/yaamp/modules/api/ApiController.php index 7505700ab..d6b896900 100644 --- a/web/yaamp/modules/api/ApiController.php +++ b/web/yaamp/modules/api/ApiController.php @@ -2,435 +2,474 @@ class ApiController extends CommonController { - public $defaultAction='status'; + public $defaultAction = 'status'; - ///////////////////////////////////////////////// - - public function actionStatus() - { - $client_ip = arraySafeVal($_SERVER,'REMOTE_ADDR'); - $whitelisted = isAdminIP($client_ip); - if (!$whitelisted && is_file(YAAMP_LOGS.'/overloaded')) { - header('HTTP/1.0 503 Disabled, server overloaded'); - return; - } - if(!$whitelisted && !LimitRequest('api-status', 10)) { - return; - } - - $json = controller()->memcache->get("api_status"); - - if (!empty($json)) { - echo $json; - return; - } - - $stats = array(); - foreach(yaamp_get_algos() as $i=>$algo) - { - $coins = (int) controller()->memcache->get_database_count_ex("api_status_coins-$algo", - 'db_coins', "enable and visible and auto_ready and algo=:algo", array(':algo'=>$algo)); - - if (!$coins) continue; - - $workers = (int) controller()->memcache->get_database_scalar("api_status_workers-$algo", - "select COUNT(id) FROM workers WHERE algo=:algo", - array(':algo'=>$algo) - ); - - $hashrate = controller()->memcache->get_database_scalar("api_status_hashrate-$algo", - "select hashrate from hashrate where algo=:algo order by time desc limit 1", array(':algo'=>$algo)); - - $price = controller()->memcache->get_database_scalar("api_status_price-$algo", - "select price from hashrate where algo=:algo order by time desc limit 1", array(':algo'=>$algo)); - - $price = bitcoinvaluetoa(take_yaamp_fee($price/1000, $algo)); - - $rental = controller()->memcache->get_database_scalar("api_status_rental-$algo", - "select rent from hashrate where algo=:algo order by time desc limit 1", array(':algo'=>$algo)); - - $rental = bitcoinvaluetoa($rental); - - $t = time() - 24*60*60; - - $avgprice = controller()->memcache->get_database_scalar("api_status_avgprice-$algo", - "select avg(price) from hashrate where algo=:algo and time>$t", array(':algo'=>$algo)); - - $avgprice = bitcoinvaluetoa(take_yaamp_fee($avgprice/1000, $algo)); - - $total1 = controller()->memcache->get_database_scalar("api_status_total-$algo", - "select sum(amount*price) from blocks where category!='orphan' and time>$t and algo=:algo", array(':algo'=>$algo)); - - $hashrate1 = (double) controller()->memcache->get_database_scalar("api_status_avghashrate-$algo", - "select avg(hashrate) from hashrate where time>$t and algo=:algo", array(':algo'=>$algo)); - - $algo_unit_factor = yaamp_algo_mBTC_factor($algo); - $btcmhday1 = $hashrate1 > 0 ? mbitcoinvaluetoa($total1 / $hashrate1 * 1000000 * 1000 * $algo_unit_factor) : 0; - - $fees = yaamp_fee($algo); - $port = getAlgoPort($algo); - - $stat = array( - "name" => $algo, - "port" => (int) $port, - "coins" => $coins, - "fees" => (double) $fees, - "hashrate" => (double) $hashrate, - "workers" => (int) $workers, - "estimate_current" => $price, - "estimate_last24h" => $avgprice, - "actual_last24h" => $btcmhday1, - "mbtc_mh_factor" => $algo_unit_factor, - "hashrate_last24h" => (double) $hashrate1, - ); - if(YAAMP_RENTAL) { - $stat["rental_current"] = $rental; - } - - $stats[$algo] = $stat; - } - - ksort($stats); - - $json = json_encode($stats); - echo $json; - - controller()->memcache->set("api_status", $json, 30, MEMCACHE_COMPRESSED); - } - - public function actionCurrencies() - { - $client_ip = arraySafeVal($_SERVER,'REMOTE_ADDR'); - $whitelisted = isAdminIP($client_ip); - if (!$whitelisted && is_file(YAAMP_LOGS.'/overloaded')) { - header('HTTP/1.0 503 Disabled, server overloaded'); - return; - } - if(!$whitelisted && !LimitRequest('api-currencies', 10)) { - return; - } - - $json = controller()->memcache->get("api_currencies"); - if (empty($json)) { - - $data = array(); - $coins = getdbolist('db_coins', "enable AND visible AND auto_ready AND IFNULL(algo,'PoS')!='PoS' ORDER BY symbol"); - foreach ($coins as $coin) - { - $symbol = $coin->symbol; - - $last = dborow("SELECT height, time FROM blocks ". - "WHERE coin_id=:id AND category IN ('immature','generate') ORDER BY height DESC LIMIT 1", - array(':id'=>$coin->id) - ); - $lastblock = (int) arraySafeVal($last,'height'); - $timesincelast = $timelast = (int) arraySafeVal($last,'time'); - if ($timelast > 0) $timesincelast = time() - $timelast; - - $workers = (int) dboscalar("SELECT count(W.userid) AS workers FROM workers W ". - "INNER JOIN accounts A ON A.id = W.userid ". - "WHERE W.algo=:algo AND A.coinid IN (:id, 6)", // 6: btc id - array(':algo'=>$coin->algo, ':id'=>$coin->id) - ); - - $since = $timelast ? $timelast : time() - 60*60; - $shares = dborow("SELECT count(id) AS shares, SUM(difficulty) AS coin_hr FROM shares WHERE time>$since AND algo=:algo AND coinid IN (0,:id)", - array(':id'=>$coin->id,':algo'=>$coin->algo) - ); - - $t24 = time() - 24*60*60; - $res24h = controller()->memcache->get_database_row("history_item2-{$coin->id}-{$coin->algo}", - "SELECT COUNT(id) as a, SUM(amount*price) as b FROM blocks ". - "WHERE coin_id=:id AND NOT category IN ('orphan','stake','generated') AND time>$t24 AND algo=:algo", - array(':id'=>$coin->id, ':algo'=>$coin->algo) - ); - - // Coin hashrate, we only store the hashrate per algo in the db, - // we need to compute the % of the coin compared to others with the same algo - if ($workers > 0) { - - $algohr = (double) dboscalar("SELECT SUM(difficulty) AS algo_hr FROM shares WHERE time>$since AND algo=:algo",array(':algo'=>$coin->algo)); - $factor = ($algohr > 0 && !empty($shares)) ? (double) $shares['coin_hr'] / $algohr : 1.; - $algo_hashrate = controller()->memcache->get_database_scalar("api_status_hashrate-{$coin->algo}", - "SELECT hashrate FROM hashrate WHERE algo=:algo ORDER BY time DESC LIMIT 1", array(':algo'=>$coin->algo) - ); - - } else { - $factor = $algo_hashrate = 0; - } - - $btcmhd = yaamp_profitability($coin); - $btcmhd = mbitcoinvaluetoa($btcmhd); - - $data[$symbol] = array( - 'algo' => $coin->algo, - 'port' => getAlgoPort($coin->algo), - 'name' => $coin->name, - 'height' => (int) $coin->block_height, - 'workers' => $workers, - 'shares' => (int) arraySafeVal($shares,'shares'), - 'hashrate' => round($factor * $algo_hashrate), - 'estimate' => $btcmhd, - //'percent' => round($factor * 100, 1), - '24h_blocks' => (int) arraySafeVal($res24h,'a'), - '24h_btc' => round(arraySafeVal($res24h,'b',0), 8), - 'lastblock' => $lastblock, - 'timesincelast' => $timesincelast, - ); - - if (!empty($coin->symbol2)) - $data[$symbol]['symbol'] = $coin->symbol2; - } - $json = json_encode($data); - controller()->memcache->set("api_currencies", $json, 15, MEMCACHE_COMPRESSED); - } - - echo str_replace("},","},\n", $json); - } - - public function actionWallet() - { - if(!LimitRequest('api-wallet', 10)) { - return; - } - if (is_file(YAAMP_LOGS.'/overloaded')) { - header('HTTP/1.0 503 Disabled, server overloaded'); - return; - } - $wallet = getparam('address'); - - $user = getuserparam($wallet); - if(!$user || $user->is_locked) return; - - $total_unsold = yaamp_convert_earnings_user($user, "status!=2"); - - $t = time() - 24*60*60; - $total_paid = bitcoinvaluetoa(controller()->memcache->get_database_scalar("api_wallet_paid-".$user->id, - "SELECT SUM(amount) FROM payouts WHERE time >= $t AND account_id=".$user->id)); - - $balance = bitcoinvaluetoa($user->balance); - $total_unpaid = bitcoinvaluetoa($balance + $total_unsold); - $total_earned = bitcoinvaluetoa($total_unpaid + $total_paid); - - $coin = getdbo('db_coins', $user->coinid); - if(!$coin) return; - - echo "{"; - echo "\"currency\": \"{$coin->symbol}\", "; - echo "\"unsold\": $total_unsold, "; - echo "\"balance\": $balance, "; - echo "\"unpaid\": $total_unpaid, "; - echo "\"paid24h\": $total_paid, "; - echo "\"total\": $total_earned"; - echo "}"; - } - - public function actionWalletEx() - { - $wallet = getparam('address'); - if (is_file(YAAMP_LOGS.'/overloaded')) { - header('HTTP/1.0 503 Disabled, server overloaded'); - return; - } - if(!LimitRequest('api-wallet', 60)) { - return; - } - - $user = getuserparam($wallet); - if(!$user || $user->is_locked) return; - - $total_unsold = yaamp_convert_earnings_user($user, "status!=2"); - - $t = time() - 24*60*60; - $total_paid = bitcoinvaluetoa(controller()->memcache->get_database_scalar("api_wallet_paid-".$user->id, - "SELECT SUM(amount) FROM payouts WHERE time >= $t AND account_id=".$user->id)); - - $balance = bitcoinvaluetoa($user->balance); - $total_unpaid = bitcoinvaluetoa($balance + $total_unsold); - $total_earned = bitcoinvaluetoa($total_unpaid + $total_paid); - - $coin = getdbo('db_coins', $user->coinid); - if(!$coin) return; - - echo "{"; - echo "\"currency\": ".json_encode($coin->symbol).", "; - echo "\"unsold\": $total_unsold, "; - echo "\"balance\": $balance, "; - echo "\"unpaid\": $total_unpaid, "; - echo "\"paid24h\": $total_paid, "; - echo "\"total\": $total_earned, "; - - echo "\"miners\": "; - echo "["; - - $workers = getdbolist('db_workers', "userid={$user->id} ORDER BY password"); - foreach($workers as $i=>$worker) - { - $user_rate1 = yaamp_worker_rate($worker->id, $worker->algo); - $user_rate1_bad = yaamp_worker_rate_bad($worker->id, $worker->algo); - - if($i) echo ", "; - - echo "{"; - echo "\"version\": ".json_encode($worker->version).", "; - echo "\"password\": ".json_encode($worker->password).", "; - echo "\"ID\": ".json_encode($worker->worker).", "; - echo "\"algo\": \"{$worker->algo}\", "; - echo "\"difficulty\": ".doubleval($worker->difficulty).", "; - echo "\"subscribe\": ".intval($worker->subscribe).", "; - echo "\"accepted\": ".round($user_rate1,3).", "; - echo "\"rejected\": ".round($user_rate1_bad,3); - echo "}"; - } - - echo "]"; - - if(YAAMP_API_PAYOUTS) - { - $json_payouts = controller()->memcache->get("api_payouts-".$user->id); - if (empty($json_payouts)) { - $json_payouts = ",\"payouts\": "; - $json_payouts .= "["; - $list = getdbolist('db_payouts', "account_id={$user->id} AND completed>0 AND tx IS NOT NULL AND time >= ".(time() - YAAMP_API_PAYOUTS_PERIOD)." ORDER BY time DESC"); - foreach($list as $j => $payout) - { - if($j) $json_payouts .= ", "; - $json_payouts .= "{"; - $json_payouts .= "\"time\": ".(0 + $payout->time).","; - $json_payouts .= "\"amount\": \"{$payout->amount}\","; - $json_payouts .= "\"tx\": \"{$payout->tx}\""; - $json_payouts .= "}"; - } - $json_payouts .= "]"; - controller()->memcache->set("api_payouts-".$user->id, $json_payouts, 60, MEMCACHE_COMPRESSED); - } - echo str_replace("},","},\n", $json_payouts); - } - - echo "}"; - } - - ///////////////////////////////////////////////// - - public function actionRental() - { - if(!LimitRequest('api-rental', 10)) return; - if(!YAAMP_RENTAL) return; - - $key = getparam('key'); - $renter = getdbosql('db_renters', "apikey=:apikey", array(':apikey'=>$key)); - if(!$renter) return; - - $balance = bitcoinvaluetoa($renter->balance); - $unconfirmed = bitcoinvaluetoa($renter->unconfirmed); - - echo "{"; - echo "\"balance\": $balance, "; - echo "\"unconfirmed\": $unconfirmed, "; - - echo "\"jobs\": ["; - $list = getdbolist('db_jobs', "renterid=$renter->id"); - foreach($list as $i=>$job) - { - if($i) echo ", "; - - $hashrate = yaamp_job_rate($job->id); - $hashrate_bad = yaamp_job_rate_bad($job->id); - - echo '{'; - echo "\"jobid\": \"$job->id\", "; - echo "\"algo\": \"$job->algo\", "; - echo "\"price\": \"$job->price\", "; - echo "\"hashrate\": \"$job->speed\", "; - echo "\"server\": \"$job->host\", "; - echo "\"port\": \"$job->port\", "; - echo "\"username\": \"$job->username\", "; - echo "\"password\": \"$job->password\", "; - echo "\"started\": \"$job->ready\", "; - echo "\"active\": \"$job->active\", "; - echo "\"accepted\": \"$hashrate\", "; - echo "\"rejected\": \"$hashrate_bad\", "; - echo "\"diff\": \"$job->difficulty\""; - - echo '}'; - } - - echo "]}"; - } - - public function actionRental_price() - { - if(!YAAMP_RENTAL) return; - - $key = getparam('key'); - $renter = getdbosql('db_renters', "apikey=:apikey", array(':apikey'=>$key)); - if(!$renter) return; - - $jobid = getparam('jobid'); - $price = getparam('price'); - - $job = getdbo('db_jobs', $jobid); - if($job->renterid != $renter->id) return; - - $job->price = $price; - $job->time = time(); - $job->save(); - } - - public function actionRental_hashrate() - { - if(!YAAMP_RENTAL) return; - - $key = getparam('key'); - $renter = getdbosql('db_renters', "apikey=:apikey", array(':apikey'=>$key)); - if(!$renter) return; - - $jobid = getparam('jobid'); - $hashrate = getparam('hashrate'); - - $job = getdbo('db_jobs', $jobid); - if($job->renterid != $renter->id) return; - - $job->speed = $hashrate; - $job->time = time(); - $job->save(); - } - - public function actionRental_start() - { - if(!YAAMP_RENTAL) return; - - $key = getparam('key'); - $renter = getdbosql('db_renters', "apikey=:apikey", array(':apikey'=>$key)); - if(!$renter || $renter->balance<=0) return; - - $jobid = getparam('jobid'); - - $job = getdbo('db_jobs', $jobid); - if($job->renterid != $renter->id) return; - - $job->ready = true; - $job->time = time(); - $job->save(); - } - - public function actionRental_stop() - { - if(!YAAMP_RENTAL) return; - - $key = getparam('key'); - $renter = getdbosql('db_renters', "apikey=:apikey", array(':apikey'=>$key)); - if(!$renter) return; - - $jobid = getparam('jobid'); - - $job = getdbo('db_jobs', $jobid); - if($job->renterid != $renter->id) return; - - $job->ready = false; - $job->time = time(); - $job->save(); - } + ///////////////////////////////////////////////// + + public function actionStatus() + { + $client_ip = arraySafeVal($_SERVER, 'REMOTE_ADDR'); + $whitelisted = isAdminIP($client_ip); + if (!$whitelisted && is_file(YAAMP_LOGS . '/overloaded')) { + header('HTTP/1.0 503 Disabled, server overloaded'); + return; + } + if (!$whitelisted && !LimitRequest('api-status', 10)) { + return; + } + + $json = controller()->memcache->get("api_status"); + + if (!empty($json)) { + echo $json; + return; + } + + $stats = array(); + foreach (yaamp_get_algos() as $i => $algo) { + $coins = (int) controller()->memcache->get_database_count_ex("api_status_coins-$algo", 'db_coins', "enable and visible and auto_ready and algo=:algo", array( + ':algo' => $algo + )); + + if (!$coins) + continue; + + $workers = (int) controller()->memcache->get_database_scalar("api_status_workers-$algo", "select COUNT(id) FROM workers WHERE algo=:algo", array( + ':algo' => $algo + )); + + $hashrate = controller()->memcache->get_database_scalar("api_status_hashrate-$algo", "select hashrate from hashrate where algo=:algo order by time desc limit 1", array( + ':algo' => $algo + )); + + $price = controller()->memcache->get_database_scalar("api_status_price-$algo", "select price from hashrate where algo=:algo order by time desc limit 1", array( + ':algo' => $algo + )); + + $price = bitcoinvaluetoa(take_yaamp_fee($price / 1000, $algo)); + + $rental = controller()->memcache->get_database_scalar("api_status_rental-$algo", "select rent from hashrate where algo=:algo order by time desc limit 1", array( + ':algo' => $algo + )); + + $rental = bitcoinvaluetoa($rental); + + $t = time() - 24 * 60 * 60; + + $avgprice = controller()->memcache->get_database_scalar("api_status_avgprice-$algo", "select avg(price) from hashrate where algo=:algo and time>$t", array( + ':algo' => $algo + )); + + $avgprice = bitcoinvaluetoa(take_yaamp_fee($avgprice / 1000, $algo)); + + $total1 = controller()->memcache->get_database_scalar("api_status_total-$algo", "select sum(amount*price) from blocks where category!='orphan' and time>$t and algo=:algo", array( + ':algo' => $algo + )); + + $hashrate1 = (double) controller()->memcache->get_database_scalar("api_status_avghashrate-$algo", "select avg(hashrate) from hashrate where time>$t and algo=:algo", array( + ':algo' => $algo + )); + + $algo_unit_factor = yaamp_algo_mBTC_factor($algo); + $btcmhday1 = $hashrate1 > 0 ? mbitcoinvaluetoa($total1 / $hashrate1 * 1000000 * 1000 * $algo_unit_factor) : 0; + + $fees = yaamp_fee($algo); + $port = getAlgoPort($algo); + + $stat = array( + "name" => $algo, + "port" => (int) $port, + "coins" => $coins, + "fees" => (double) $fees, + "hashrate" => (double) $hashrate, + "workers" => (int) $workers, + "estimate_current" => $price, + "estimate_last24h" => $avgprice, + "actual_last24h" => $btcmhday1, + "mbtc_mh_factor" => $algo_unit_factor, + "hashrate_last24h" => (double) $hashrate1 + ); + if (YAAMP_RENTAL) { + $stat["rental_current"] = $rental; + } + + $stats[$algo] = $stat; + } + + ksort($stats); + + $json = json_encode($stats); + echo $json; + + controller()->memcache->set("api_status", $json, 30, MEMCACHE_COMPRESSED); + } + + public function actionCurrencies() + { + $client_ip = arraySafeVal($_SERVER, 'REMOTE_ADDR'); + $whitelisted = isAdminIP($client_ip); + if (!$whitelisted && is_file(YAAMP_LOGS . '/overloaded')) { + header('HTTP/1.0 503 Disabled, server overloaded'); + return; + } + if (!$whitelisted && !LimitRequest('api-currencies', 10)) { + return; + } + + $json = controller()->memcache->get("api_currencies"); + if (empty($json)) { + + $data = array(); + $coins = getdbolist('db_coins', "enable AND visible AND auto_ready AND IFNULL(algo,'PoS')!='PoS' ORDER BY symbol"); + foreach ($coins as $coin) { + $symbol = $coin->symbol; + + $last = dborow("SELECT height, time FROM blocks " . "WHERE coin_id=:id AND category IN ('immature','generate') ORDER BY height DESC LIMIT 1", array( + ':id' => $coin->id + )); + $lastblock = (int) arraySafeVal($last, 'height'); + $timesincelast = $timelast = (int) arraySafeVal($last, 'time'); + if ($timelast > 0) + $timesincelast = time() - $timelast; + + $workers = (int) dboscalar("SELECT count(W.userid) AS workers FROM workers W " . "INNER JOIN accounts A ON A.id = W.userid " . "WHERE W.algo=:algo AND A.coinid IN (:id, 6)", // 6: btc id + array( + ':algo' => $coin->algo, + ':id' => $coin->id + )); + + $since = $timelast ? $timelast : time() - 60 * 60; + $shares = dborow("SELECT count(id) AS shares, SUM(difficulty) AS coin_hr FROM shares WHERE time>$since AND algo=:algo AND coinid IN (0,:id)", array( + ':id' => $coin->id, + ':algo' => $coin->algo + )); + + $t24 = time() - 24 * 60 * 60; + $res24h = controller()->memcache->get_database_row("history_item2-{$coin->id}-{$coin->algo}", "SELECT COUNT(id) as a, SUM(amount*price) as b FROM blocks " . "WHERE coin_id=:id AND NOT category IN ('orphan','stake','generated') AND time>$t24 AND algo=:algo", array( + ':id' => $coin->id, + ':algo' => $coin->algo + )); + + // Coin hashrate, we only store the hashrate per algo in the db, + // we need to compute the % of the coin compared to others with the same algo + if ($workers > 0) { + + $algohr = (double) dboscalar("SELECT SUM(difficulty) AS algo_hr FROM shares WHERE time>$since AND algo=:algo", array( + ':algo' => $coin->algo + )); + $factor = ($algohr > 0 && !empty($shares)) ? (double) $shares['coin_hr'] / $algohr : 1.; + $algo_hashrate = controller()->memcache->get_database_scalar("api_status_hashrate-{$coin->algo}", "SELECT hashrate FROM hashrate WHERE algo=:algo ORDER BY time DESC LIMIT 1", array( + ':algo' => $coin->algo + )); + + } else { + $factor = $algo_hashrate = 0; + } + + $btcmhd = yaamp_profitability($coin); + $btcmhd = mbitcoinvaluetoa($btcmhd); + + //Add network hash difficulty and symbol + $min_ttf = $coin->network_ttf > 0 ? min($coin->actual_ttf, $coin->network_ttf) : $coin->actual_ttf; + $network_hash = $coin->difficulty * 0x100000000 / ($min_ttf ? $min_ttf : 60); + + $data[$symbol] = array( + 'algo' => $coin->algo, + 'port' => getAlgoPort($coin->algo), + 'name' => $coin->name, + 'reward' => $coin->reward, + 'height' => (int) $coin->block_height, + 'difficulty' => $coin->difficulty, + 'workers' => $workers, + 'shares' => (int) arraySafeVal($shares, 'shares'), + 'hashrate' => round($factor * $algo_hashrate), + 'network_hashrate' => $network_hash, + 'estimate' => $btcmhd, + //'percent' => round($factor * 100, 1), + '24h_blocks' => (int) arraySafeVal($res24h, 'a'), + '24h_btc' => round(arraySafeVal($res24h, 'b', 0), 8), + 'lastblock' => $lastblock, + 'timesincelast' => $timesincelast + ); + + if (!empty($coin->symbol2)) + $data[$symbol]['symbol'] = $coin->symbol2; + } + $json = json_encode($data); + controller()->memcache->set("api_currencies", $json, 15, MEMCACHE_COMPRESSED); + } + + echo str_replace("},", "},\n", $json); + } + + public function actionWallet() + { + if (!LimitRequest('api-wallet', 10)) { + return; + } + if (is_file(YAAMP_LOGS . '/overloaded')) { + header('HTTP/1.0 503 Disabled, server overloaded'); + return; + } + $wallet = getparam('address'); + + $user = getuserparam($wallet); + if (!$user || $user->is_locked) + return; + + $total_unsold = yaamp_convert_earnings_user($user, "status!=2"); + + $t = time() - 24 * 60 * 60; + $total_paid = bitcoinvaluetoa(controller()->memcache->get_database_scalar("api_wallet_paid-" . $user->id, "SELECT SUM(amount) FROM payouts WHERE time >= $t AND account_id=" . $user->id)); + + $balance = bitcoinvaluetoa($user->balance); + $total_unpaid = bitcoinvaluetoa($balance + $total_unsold); + $total_earned = bitcoinvaluetoa($total_unpaid + $total_paid); + + $coin = getdbo('db_coins', $user->coinid); + if (!$coin) + return; + + echo "{"; + echo "\"currency\": \"{$coin->symbol}\", "; + echo "\"unsold\": $total_unsold, "; + echo "\"balance\": $balance, "; + echo "\"unpaid\": $total_unpaid, "; + echo "\"paid24h\": $total_paid, "; + echo "\"total\": $total_earned"; + echo "}"; + } + + public function actionWalletEx() + { + $wallet = getparam('address'); + if (is_file(YAAMP_LOGS . '/overloaded')) { + header('HTTP/1.0 503 Disabled, server overloaded'); + return; + } + if (!LimitRequest('api-wallet', 60)) { + return; + } + + $user = getuserparam($wallet); + if (!$user || $user->is_locked) + return; + + $total_unsold = yaamp_convert_earnings_user($user, "status!=2"); + + $t = time() - 24 * 60 * 60; + $total_paid = bitcoinvaluetoa(controller()->memcache->get_database_scalar("api_wallet_paid-" . $user->id, "SELECT SUM(amount) FROM payouts WHERE time >= $t AND account_id=" . $user->id)); + + $balance = bitcoinvaluetoa($user->balance); + $total_unpaid = bitcoinvaluetoa($balance + $total_unsold); + $total_earned = bitcoinvaluetoa($total_unpaid + $total_paid); + + $coin = getdbo('db_coins', $user->coinid); + if (!$coin) + return; + + echo "{"; + echo "\"currency\": " . json_encode($coin->symbol) . ", "; + echo "\"unsold\": $total_unsold, "; + echo "\"balance\": $balance, "; + echo "\"unpaid\": $total_unpaid, "; + echo "\"paid24h\": $total_paid, "; + echo "\"total\": $total_earned, "; + + echo "\"miners\": "; + echo "["; + + $workers = getdbolist('db_workers', "userid={$user->id} ORDER BY password"); + foreach ($workers as $i => $worker) { + $user_rate1 = yaamp_worker_rate($worker->id, $worker->algo); + $user_rate1_bad = yaamp_worker_rate_bad($worker->id, $worker->algo); + + if ($i) + echo ", "; + + echo "{"; + echo "\"version\": " . json_encode($worker->version) . ", "; + echo "\"password\": " . json_encode($worker->password) . ", "; + echo "\"ID\": " . json_encode($worker->worker) . ", "; + echo "\"algo\": \"{$worker->algo}\", "; + echo "\"difficulty\": " . doubleval($worker->difficulty) . ", "; + echo "\"subscribe\": " . intval($worker->subscribe) . ", "; + echo "\"accepted\": " . round($user_rate1, 3) . ", "; + echo "\"rejected\": " . round($user_rate1_bad, 3); + echo "}"; + } + + echo "]"; + + if (YAAMP_API_PAYOUTS) { + $json_payouts = controller()->memcache->get("api_payouts-" . $user->id); + if (empty($json_payouts)) { + $json_payouts = ",\"payouts\": "; + $json_payouts .= "["; + $list = getdbolist('db_payouts', "account_id={$user->id} AND completed>0 AND tx IS NOT NULL AND time >= " . (time() - YAAMP_API_PAYOUTS_PERIOD) . " ORDER BY time DESC"); + foreach ($list as $j => $payout) { + if ($j) + $json_payouts .= ", "; + $json_payouts .= "{"; + $json_payouts .= "\"time\": " . (0 + $payout->time) . ","; + $json_payouts .= "\"amount\": \"{$payout->amount}\","; + $json_payouts .= "\"tx\": \"{$payout->tx}\""; + $json_payouts .= "}"; + } + $json_payouts .= "]"; + controller()->memcache->set("api_payouts-" . $user->id, $json_payouts, 60, MEMCACHE_COMPRESSED); + } + echo str_replace("},", "},\n", $json_payouts); + } + + echo "}"; + } + + ///////////////////////////////////////////////// + + public function actionRental() + { + if (!LimitRequest('api-rental', 10)) + return; + if (!YAAMP_RENTAL) + return; + + $key = getparam('key'); + $renter = getdbosql('db_renters', "apikey=:apikey", array( + ':apikey' => $key + )); + if (!$renter) + return; + + $balance = bitcoinvaluetoa($renter->balance); + $unconfirmed = bitcoinvaluetoa($renter->unconfirmed); + + echo "{"; + echo "\"balance\": $balance, "; + echo "\"unconfirmed\": $unconfirmed, "; + + echo "\"jobs\": ["; + $list = getdbolist('db_jobs', "renterid=$renter->id"); + foreach ($list as $i => $job) { + if ($i) + echo ", "; + + $hashrate = yaamp_job_rate($job->id); + $hashrate_bad = yaamp_job_rate_bad($job->id); + + echo '{'; + echo "\"jobid\": \"$job->id\", "; + echo "\"algo\": \"$job->algo\", "; + echo "\"price\": \"$job->price\", "; + echo "\"hashrate\": \"$job->speed\", "; + echo "\"server\": \"$job->host\", "; + echo "\"port\": \"$job->port\", "; + echo "\"username\": \"$job->username\", "; + echo "\"password\": \"$job->password\", "; + echo "\"started\": \"$job->ready\", "; + echo "\"active\": \"$job->active\", "; + echo "\"accepted\": \"$hashrate\", "; + echo "\"rejected\": \"$hashrate_bad\", "; + echo "\"diff\": \"$job->difficulty\""; + + echo '}'; + } + + echo "]}"; + } + + public function actionRental_price() + { + if (!YAAMP_RENTAL) + return; + + $key = getparam('key'); + $renter = getdbosql('db_renters', "apikey=:apikey", array( + ':apikey' => $key + )); + if (!$renter) + return; + + $jobid = getparam('jobid'); + $price = getparam('price'); + + $job = getdbo('db_jobs', $jobid); + if ($job->renterid != $renter->id) + return; + + $job->price = $price; + $job->time = time(); + $job->save(); + } + + public function actionRental_hashrate() + { + if (!YAAMP_RENTAL) + return; + + $key = getparam('key'); + $renter = getdbosql('db_renters', "apikey=:apikey", array( + ':apikey' => $key + )); + if (!$renter) + return; + + $jobid = getparam('jobid'); + $hashrate = getparam('hashrate'); + + $job = getdbo('db_jobs', $jobid); + if ($job->renterid != $renter->id) + return; + + $job->speed = $hashrate; + $job->time = time(); + $job->save(); + } + + public function actionRental_start() + { + if (!YAAMP_RENTAL) + return; + + $key = getparam('key'); + $renter = getdbosql('db_renters', "apikey=:apikey", array( + ':apikey' => $key + )); + if (!$renter || $renter->balance <= 0) + return; + + $jobid = getparam('jobid'); + + $job = getdbo('db_jobs', $jobid); + if ($job->renterid != $renter->id) + return; + + $job->ready = true; + $job->time = time(); + $job->save(); + } + + public function actionRental_stop() + { + if (!YAAMP_RENTAL) + return; + + $key = getparam('key'); + $renter = getdbosql('db_renters', "apikey=:apikey", array( + ':apikey' => $key + )); + if (!$renter) + return; + + $jobid = getparam('jobid'); + + $job = getdbo('db_jobs', $jobid); + if ($job->renterid != $renter->id) + return; + + $job->ready = false; + $job->time = time(); + $job->save(); + } } - diff --git a/web/yaamp/modules/coin/index.php b/web/yaamp/modules/coin/index.php index b6252a391..76f0555e5 100644 --- a/web/yaamp/modules/coin/index.php +++ b/web/yaamp/modules/coin/index.php @@ -14,17 +14,17 @@ end; showTableSorter('maintable', "{ - tableClass: 'dataGrid', - textExtraction: { - 6: function(node, table, n) { return $(node).attr('data'); } - }, - widgets: ['zebra','filter'], - widgetOptions: { - filter_external: '.search', - filter_columnFilters: false, - filter_childRows : true, - filter_ignoreCase: true - } + tableClass: 'dataGrid', + textExtraction: { + 6: function(node, table, n) { return $(node).attr('data'); } + }, + widgets: ['zebra','filter'], + widgetOptions: { + filter_external: '.search', + filter_columnFilters: false, + filter_childRows : true, + filter_ignoreCase: true + } }"); echo << end; -$total_active = 0; +$total_active = 0; $total_installed = 0; $coins = getdbolist('db_coins', "1 ORDER BY created DESC"); -foreach($coins as $coin) -{ -// if($coin->symbol == 'BTC') continue; - if($coin->enable) $total_active++; - if($coin->installed) $total_installed++; +foreach ($coins as $coin) { + // if($coin->symbol == 'BTC') continue; + if ($coin->enable) + $total_active++; + if ($coin->installed) + $total_installed++; - $coin->errors = substr($coin->errors, 0, 30); - $coin->version = substr($coin->version, 0, 20); - $difficulty = Itoa2($coin->difficulty, 3); - $created = datetoa2($coin->created); + $coin->errors = substr($coin->errors, 0, 30); + $coin->version = substr($coin->version, 0, 20); + $difficulty = Itoa2($coin->difficulty, 3); + $created = datetoa2($coin->created); - echo ''; - echo ''; + echo ''; + echo ''; - echo ''.$coin->name.''; + echo '' . $coin->name . ''; - if($this->admin) - echo "$coin->symbol"; - else - echo "$coin->symbol"; + if ($this->admin) + echo "$coin->symbol"; + else + echo "$coin->symbol"; - echo "$coin->algo"; + echo "$coin->algo"; - if($coin->enable) - echo "running"; + if ($coin->enable) + echo "running"; - else if($coin->installed) - echo "installed"; + else if ($coin->installed) + echo "installed"; - else - echo ""; + else + echo ""; - echo "$coin->version"; - echo ''.$created.''; + echo "$coin->version"; + echo '' . $created . ''; -// echo "$difficulty"; - echo ''.$coin->block_height.''; + // echo "$difficulty"; + echo '' . $coin->block_height . ''; - echo "$coin->errors"; - echo ""; + echo "$coin->errors"; + echo ""; - if(!empty($coin->link_bitcointalk)) - echo "forum "; + if (!empty($coin->link_bitcointalk)) + echo "forum "; - if(!empty($coin->link_github)) - echo "git "; + if (!empty($coin->link_github)) + echo "git "; -// if(!empty($coin->link_explorer)) -// echo "expl "; + // if(!empty($coin->link_explorer)) + // echo "expl "; - echo "google "; + echo "google "; -// if(!empty($coin->link_exchange)) -// echo "exch "; + // if(!empty($coin->link_exchange)) + // echo "exch "; - $list2 = getdbolist('db_markets', "coinid=$coin->id"); - foreach($list2 as $market) - { - $url = getMarketUrl($coin, $market->name); - echo "$market->name "; - } + $list2 = getdbolist('db_markets', "coinid=$coin->id"); + foreach ($list2 as $market) { + $url = getMarketUrl($coin, $market->name); + echo "$market->name "; + } - echo ""; - echo ""; + echo ""; + echo ""; } echo ""; diff --git a/web/yaamp/modules/common/CommonController.php b/web/yaamp/modules/common/CommonController.php index 1466ac729..baaef7b21 100644 --- a/web/yaamp/modules/common/CommonController.php +++ b/web/yaamp/modules/common/CommonController.php @@ -1,63 +1,68 @@ admin; } - - protected function elapsedTime() - { - $t2 = microtime(true); - return ($t2 - $this->t1); - } - - protected function beforeAction($action) - { - // debuglog("before action ".$action->getId()); - - $this->memcache = new YaampMemcache; - $this->t1 = microtime(true); - - if(user()->getState('yaamp_admin')) { - $this->admin = true; - $client_ip = arraySafeVal($_SERVER,'REMOTE_ADDR'); - if (!isAdminIP($client_ip)) { - user()->setState('yaamp_admin', false); - debuglog("admin attempt from $client_ip"); - $this->admin = false; - } - } - - $algo = user()->getState('yaamp-algo'); - if(!$algo) user()->setState('yaamp-algo', YAAMP_DEFAULT_ALGO); - - return true; - } - - protected function afterAction($action) - { - // debuglog("after action ".$action->getId()); - - $d1 = $this->elapsedTime(); - - $url = "$this->id/{$this->action->id}"; - $this->memcache->add_monitoring_function($url, $d1); - } - - public function actionMaintenance() - { - $this->render('maintenance'); - } - - public function goback($count=-1) - { - Javascript("window.history.go($count);"); - die; - } + public $memcache; + public $t1; -} + // read-only via getAdmin() + private $admin = false; + protected function getAdmin() + { + return $this->admin; + } + + protected function elapsedTime() + { + $t2 = microtime(true); + return ($t2 - $this->t1); + } + + protected function beforeAction($action) + { + // debuglog("before action ".$action->getId()); + $this->memcache = new YaampMemcache; + $this->t1 = microtime(true); + + if (user() + ->getState('yaamp_admin')) + { + $this->admin = true; + $client_ip = arraySafeVal($_SERVER, 'REMOTE_ADDR'); + if (!isAdminIP($client_ip)) + { + user()->setState('yaamp_admin', false); + debuglog("admin attempt from $client_ip"); + $this->admin = false; + } + } + + $algo = user()->getState('yaamp-algo'); + if (!$algo) user()->setState('yaamp-algo', YAAMP_DEFAULT_ALGO); + return true; + } + + protected function afterAction($action) + { + // debuglog("after action ".$action->getId()); + $d1 = $this->elapsedTime(); + + $url = "$this->id/{$this + ->action->id}"; + $this + ->memcache + ->add_monitoring_function($url, $d1); + } + + public function actionMaintenance() + { + $this->render('maintenance'); + } + + public function goback($count = - 1) + { + Javascript("window.history.go($count);"); + die; + } + +} diff --git a/web/yaamp/modules/explorer/ExplorerController.php b/web/yaamp/modules/explorer/ExplorerController.php index cfa192539..3e1c71804 100644 --- a/web/yaamp/modules/explorer/ExplorerController.php +++ b/web/yaamp/modules/explorer/ExplorerController.php @@ -1,161 +1,177 @@ forward('id'); - } - elseif (strlen($actionID) <= 6 && !isset($_REQUEST['id'])) { - $coin = getdbosql('db_coins', "symbol=:symbol", array( - ':symbol'=>strtoupper($actionID) - )); - if ($coin && ($coin->visible || $this->admin)) { - if (!empty($_POST)) { - $_GET['SYM'] = $coin->symbol; - $this->forward('search'); - } - $_REQUEST['id'] = $coin->id; - $this->forward('id'); - } - } - } - return parent::run($actionID); - } - - ///////////////////////////////////////////////// - - // Hide coin id from explorer links... created by createUrl() - public function createUrl($route,$params=array(),$ampersand='&') - { - if ($route == '/explorer' && isset($params['id'])) { - $coin = getdbo('db_coins', intval($params['id'])); - if ($coin && $coin->visible && !is_numeric($coin->symbol)) { - unset($params['id']); - $route = '/explorer/'.$coin->symbol.'?'.http_build_query($params,'',$ampersand); - $params = array(); - } - } - return parent::createUrl($route, $params, $ampersand); - } - - ///////////////////////////////////////////////// - - public function actionIndex() - { - if(isset($_COOKIE['mainbtc'])) return; - if(!LimitRequest('explorer')) return; - - $id = getiparam('id'); - $coin = getdbo('db_coins', $id); - if($coin && $coin->no_explorer) { - $link = $coin->link_explorer; - //$txid = gethexparam('txid'); - //$hash = gethexparam('hash'); - //if (!empty($txid)) $link .= 'tx/'.$txid; - //elseif (!empty($hash)) $link .= 'block/'.$hash; - die("Block explorer disabled, please use $link"); - } - $height = getiparam('height'); - if($coin && intval($height)>0) - { - $remote = new WalletRPC($coin); - $hash = $remote->getblockhash(intval($height)); - } else { - $hash = gethexparam('hash'); - } - - $txid = gethexparam('txid'); - $q = gethexparam('q'); - if (strlen($q) >= 32 && ctype_xdigit($q)) { - $remote = new WalletRPC($coin); - $block = $remote->getblock($q); - if ($block) { - $hash = $q; - $height = objSafeVal($hash, 'height'); - } else { - $txid = $q; - } - } - - if($coin && !empty($txid)) - { - $remote = new WalletRPC($coin); - $tx = $remote->getrawtransaction($txid, 1); - if (!$tx) $tx = $remote->gettransaction($txid); - - $hash = arraySafeVal($tx,'blockhash'); - } - - if($coin && !empty($hash)) - $this->render('block', array('coin'=>$coin, 'hash'=>$hash)); - - else if($coin) - $this->render('coin', array('coin'=>$coin)); - - else - $this->render('index'); - } - - // alias... - public function actionId() - { - return $this->actionIndex(); - } - - // redirect POST request with url cleanup... - public function actionSearch() - { - $height = getiparam('height'); - $txid = gethexparam('txid'); - $hash = gethexparam('hash'); - $q = gethexparam('q'); - if (isset($_GET['SYM'])) { - // only for visible coins - $url = "/explorer/".$_GET['SYM']."?"; - } else if (isset($_GET['id'])) { - // only for hidden coins - $url = "/explorer/".$_GET['id']."?"; - } - if (!empty($height)) $url .= "&height=$height"; - if (!empty($txid)) $url .= "&txid=$txid"; - if (!empty($hash)) $url .= "&hash=$hash"; - if (!empty($q)) $url .= "&q=$q"; - - return $this->redirect(str_replace('?&', '?', $url)); - } - - /** - * Difficulty Graph - */ - public function actionGraph() - { - $id = getiparam('id'); - $coin = getdbo('db_coins', $id); - if ($coin) - $this->renderPartial('graph', array('coin'=>$coin)); - else - echo "[]"; - } - - /** - * Public nodes - */ - public function actionPeers() - { - $id = getiparam('id'); - $coin = getdbo('db_coins', $id); - if ($coin) - $this->renderPartial('peers', array('coin'=>$coin)); - } + public $defaultAction = 'index'; + + ///////////////////////////////////////////////// + public function run($actionID) + { + // Forward the url /explorer/BTC to the BTC block explorer + if (!empty($actionID)) + { + if (is_numeric($actionID) && isset($_REQUEST['id'])) + { + $this->forward('id'); + } + elseif (strlen($actionID) <= 6 && !isset($_REQUEST['id'])) + { + $coin = getdbosql('db_coins', "symbol=:symbol", array( + ':symbol' => strtoupper($actionID) + )); + if ($coin && ($coin->visible || $this->admin)) + { + if (!empty($_POST)) + { + $_GET['SYM'] = $coin->symbol; + $this->forward('search'); + } + $_REQUEST['id'] = $coin->id; + $this->forward('id'); + } + } + } + return parent::run($actionID); + } + + ///////////////////////////////////////////////// + // Hide coin id from explorer links... created by createUrl() + public function createUrl($route, $params = array() , $ampersand = '&') + { + if ($route == '/explorer' && isset($params['id'])) + { + $coin = getdbo('db_coins', intval($params['id'])); + if ($coin && $coin->visible && !is_numeric($coin->symbol)) + { + unset($params['id']); + $route = '/explorer/' . $coin->symbol . '?' . http_build_query($params, '', $ampersand); + $params = array(); + } + } + return parent::createUrl($route, $params, $ampersand); + } + + ///////////////////////////////////////////////// + public function actionIndex() + { + if (isset($_COOKIE['mainbtc'])) return; + if (!LimitRequest('explorer')) return; + + $id = getiparam('id'); + $coin = getdbo('db_coins', $id); + if ($coin && $coin->no_explorer) + { + $link = $coin->link_explorer; + //$txid = gethexparam('txid'); + //$hash = gethexparam('hash'); + //if (!empty($txid)) $link .= 'tx/'.$txid; + //elseif (!empty($hash)) $link .= 'block/'.$hash; + die("Block explorer disabled, please use $link"); + } + $height = getiparam('height'); + if ($coin && intval($height) > 0) + { + $remote = new WalletRPC($coin); + $hash = $remote->getblockhash(intval($height)); + } + else + { + $hash = gethexparam('hash'); + } + + $txid = gethexparam('txid'); + $q = gethexparam('q'); + if (strlen($q) >= 32 && ctype_xdigit($q)) + { + $remote = new WalletRPC($coin); + $block = $remote->getblock($q); + if ($block) + { + $hash = $q; + $height = objSafeVal($hash, 'height'); + } + else + { + $txid = $q; + } + } + + if ($coin && !empty($txid)) + { + $remote = new WalletRPC($coin); + $tx = $remote->getrawtransaction($txid, 1); + if (!$tx) $tx = $remote->gettransaction($txid); + + $hash = arraySafeVal($tx, 'blockhash'); + } + + if ($coin && !empty($hash)) $this->render('block', array( + 'coin' => $coin, + 'hash' => $hash + )); + + else if ($coin) $this->render('coin', array( + 'coin' => $coin + )); + + else $this->render('index'); + } + + // alias... + public function actionId() + { + return $this->actionIndex(); + } + + // redirect POST request with url cleanup... + public function actionSearch() + { + $height = getiparam('height'); + $txid = gethexparam('txid'); + $hash = gethexparam('hash'); + $q = gethexparam('q'); + if (isset($_GET['SYM'])) + { + // only for visible coins + $url = "/explorer/" . $_GET['SYM'] . "?"; + } + else if (isset($_GET['id'])) + { + // only for hidden coins + $url = "/explorer/" . $_GET['id'] . "?"; + } + if (!empty($height)) $url .= "&height=$height"; + if (!empty($txid)) $url .= "&txid=$txid"; + if (!empty($hash)) $url .= "&hash=$hash"; + if (!empty($q)) $url .= "&q=$q"; + + return $this->redirect(str_replace('?&', '?', $url)); + } + + /** + * Difficulty Graph + */ + public function actionGraph() + { + $id = getiparam('id'); + $coin = getdbo('db_coins', $id); + if ($coin) $this->renderPartial('graph', array( + 'coin' => $coin + )); + else echo "[]"; + } + + /** + * Public nodes + */ + public function actionPeers() + { + $id = getiparam('id'); + $coin = getdbo('db_coins', $id); + if ($coin) $this->renderPartial('peers', array( + 'coin' => $coin + )); + } } diff --git a/web/yaamp/modules/explorer/block.php b/web/yaamp/modules/explorer/block.php index e1521b1f3..2db62e849 100644 --- a/web/yaamp/modules/explorer/block.php +++ b/web/yaamp/modules/explorer/block.php @@ -1,14 +1,12 @@ pageTitle = $coin->name." block explorer"; +$this->pageTitle = $coin->name . " block explorer"; $txid = getparam('txid'); $q = getparam('q'); if (!empty($q) && ctype_xdigit($q)) $txid = $q; elseif (empty($txid)) $txid = 'txid not set'; // prevent highlight - echo << function toggleRaw(el) { @@ -54,69 +52,72 @@ function toggleRaw(el) { END; -////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////// function colorizeJson($json) { - $json = str_replace('"', '"', $json); - // strings - $res = preg_match_all("# "([^&]+)"([,\s])#", $json, $matches); - if ($res) foreach($matches[1] as $n=>$m) { - $sfx = $matches[2][$n]; - $class = ''; - if (strlen($m) == 64 && ctype_xdigit($m)) $class = 'hash'; - if (strlen($m) == 34 && ctype_alnum($m)) $class = 'addr'; - if (strlen($m) == 35 && ctype_alnum($m)) $class = 'addr'; - if (strlen($m) > 160 && ctype_alnum($m)) $class = 'data'; - if ($class == '' && strlen($m) < 64 && ctype_xdigit($m)) $class = 'hexa'; - $json = str_replace(' "'.$m.""".$sfx, ' "'.$m.'"'.$sfx, $json); - } - // keys - $res = preg_match_all("#"([^&]+)":#", $json, $matches); - if ($res) foreach($matches[1] as $n=>$m) { - $json = str_replace('"'.$m.""", '"'.$m.'"', $json); - } - // humanize timestamps like "blocktime": 1462359961, - $res = preg_match_all("#: ([0-9]{10})([,\s])#", $json, $matches); - if ($res) foreach($matches[1] as $n=>$m) { - $ts = intval($m); - if ($ts > 1400000000 && $ts < 1600000000) { - $sfx = $matches[2][$n]; - $date = strftime("%Y-%m-%d %T %z", $ts); - $json = str_replace(' '.$m.$sfx, ' "'.$date.'"'.$sfx, $json); - } - } - // numeric - $res = preg_match_all("#: ([e\-\.0-9]+)([,\s])#", $json, $matches); - if ($res) foreach($matches[1] as $n=>$m) { - $sfx = $matches[2][$n]; - $json = str_replace(' '.$m.$sfx, ' '.$m.''.$sfx, $json); - } - $json = preg_replace('#\[\s+\]#', '[]', $json); - $json = str_replace('[', '[', $json); - $json = str_replace(']', ']', $json); - $json = str_replace('{', '{', $json); - $json = str_replace('}', '}', $json); - return $json; + $json = str_replace('"', '"', $json); + // strings + $res = preg_match_all("# "([^&]+)"([,\s])#", $json, $matches); + if ($res) foreach ($matches[1] as $n => $m) + { + $sfx = $matches[2][$n]; + $class = ''; + if (strlen($m) == 64 && ctype_xdigit($m)) $class = 'hash'; + if (strlen($m) == 34 && ctype_alnum($m)) $class = 'addr'; + if (strlen($m) == 35 && ctype_alnum($m)) $class = 'addr'; + if (strlen($m) > 160 && ctype_alnum($m)) $class = 'data'; + if ($class == '' && strlen($m) < 64 && ctype_xdigit($m)) $class = 'hexa'; + $json = str_replace(' "' . $m . """ . $sfx, ' "' . $m . '"' . $sfx, $json); + } + // keys + $res = preg_match_all("#"([^&]+)":#", $json, $matches); + if ($res) foreach ($matches[1] as $n => $m) + { + $json = str_replace('"' . $m . """, '"' . $m . '"', $json); + } + // humanize timestamps like "blocktime": 1462359961, + $res = preg_match_all("#: ([0-9]{10})([,\s])#", $json, $matches); + if ($res) foreach ($matches[1] as $n => $m) + { + $ts = intval($m); + if ($ts > 1400000000 && $ts < 1600000000) + { + $sfx = $matches[2][$n]; + $date = strftime("%Y-%m-%d %T %z", $ts); + $json = str_replace(' ' . $m . $sfx, ' "' . $date . '"' . $sfx, $json); + } + } + // numeric + $res = preg_match_all("#: ([e\-\.0-9]+)([,\s])#", $json, $matches); + if ($res) foreach ($matches[1] as $n => $m) + { + $sfx = $matches[2][$n]; + $json = str_replace(' ' . $m . $sfx, ' ' . $m . '' . $sfx, $json); + } + $json = preg_replace('#\[\s+\]#', '[]', $json); + $json = str_replace('[', '[', $json); + $json = str_replace(']', ']', $json); + $json = str_replace('{', '{', $json); + $json = str_replace('}', '}', $json); + return $json; } function simplifyscript($script) { - $script = preg_replace("/[0-9a-f]+ OP_DROP ?/","", $script); - $script = preg_replace("/OP_NOP ?/","", $script); - return trim($script); + $script = preg_replace("/[0-9a-f]+ OP_DROP ?/", "", $script); + $script = preg_replace("/OP_NOP ?/", "", $script); + return trim($script); } /////////////////////////////////////////////////////////////////////////////////////////////// - $remote = new WalletRPC($coin); $block = $remote->getblock($hash); -if(!$block) return; +if (!$block) return; //debuglog($block); - $d = date('Y-m-d H:i:s', $block['time']); -$confirms = isset($block['confirmations'])? $block['confirmations']: ''; +$confirms = isset($block['confirmations']) ? $block['confirmations'] : ''; $txcount = count($block['tx']); $version = dechex($block['version']); @@ -125,49 +126,44 @@ function simplifyscript($script) echo ''; echo ''; -echo ''; -echo ''; +echo ''; +echo ''; echo ''; -echo ''; -echo ''; -echo ''; -echo ''; -echo ''; -echo ''; -echo ''; -echo ''; - -if(isset($block['flags'])) - echo ''; - -if(isset($block['previousblockhash']) && $coin->algo == 'x16r') { - echo ''; +echo ''; +echo ''; +echo ''; +echo ''; +echo ''; +echo ''; +echo ''; +echo ''; + +if (isset($block['flags'])) echo ''; + +if (isset($block['previousblockhash']) && $coin->algo == 'x16r') +{ + echo ''; } -if(isset($block['previousblockhash'])) - echo ''; +if (isset($block['previousblockhash'])) echo ''; -if(isset($block['nextblockhash'])) - echo ''; +if (isset($block['nextblockhash'])) echo ''; -echo ''; +echo ''; -echo ''; +echo ''; echo "
Coin:'.$coin->createExplorerLink($coin->name).'
Blockhash:'.$hash.'
Coin:' . $coin->createExplorerLink($coin->name) . '
Blockhash:' . $hash . '
Confirmations:'.$confirms.'
Height:'.$block['height'].'
Time:'.$d.' ('.$block['time'].')'.'
Difficulty:'.$block['difficulty'].'
Bits:'.$block['bits'].'
Nonce:'.$nonce.'
Version:'.$version.'
Size:'.$block['size'].' bytes
Flags:'.$block['flags'].'
Hash order:'. - substr($block['previousblockhash'], -16). - '
Confirmations:' . $confirms . '
Height:' . $block['height'] . '
Time:' . $d . ' (' . $block['time'] . ')' . '
Difficulty:' . $block['difficulty'] . '
Bits:' . $block['bits'] . '
Nonce:' . $nonce . '
Version:' . $version . '
Size:' . $block['size'] . ' bytes
Flags:' . $block['flags'] . '
Hash order:' . substr($block['previousblockhash'], -16) . '
Previous Hash:'. - $coin->createExplorerLink($block['previousblockhash'], array('hash'=>$block['previousblockhash'])). - '
Previous Hash:' . $coin->createExplorerLink($block['previousblockhash'], array( + 'hash' => $block['previousblockhash'] +)) . '
Next Hash:'. - $coin->createExplorerLink($block['nextblockhash'], array('hash'=>$block['nextblockhash'])). - '
Next Hash:' . $coin->createExplorerLink($block['nextblockhash'], array( + 'hash' => $block['nextblockhash'] +)) . '
Merkle Root:'.$block['merkleroot'].'
Merkle Root:' . $block['merkleroot'] . '
Transactions:'.$txcount.'
Transactions:' . $txcount . '

"; //////////////////////////////////////////////////////////////////////////////// - echo << @@ -183,140 +179,141 @@ function simplifyscript($script) end; + $ntx = 0; -foreach($block['tx'] as $txhash) +foreach ($block['tx'] as $txhash) { - $ntx++; - $tx = $remote->getrawtransaction($txhash, 1); - if(!$tx && ($ntx == 1 || $txid == $txhash)) { - // some transactions are not found directly with getrawtransaction - $tx = $remote->gettransaction($txhash); - if ($tx && isset($tx['hex'])) { - $hex = $tx['hex']; - $tx = $remote->decoderawtransaction($hex); - $tx['hex'] = $hex; - } else { - continue; - } - } - if(!$tx) continue; - - $valuetx = 0; - foreach($tx['vout'] as $vout) - $valuetx += $vout['value']; - - echo ''; - echo ''.$ntx.''; - echo ''.$tx['txid'].''; - $size = (strlen($tx['hex'])/2); - echo "$size"; - echo "$valuetx"; - - echo ""; - $segwit = false; - foreach($tx['vin'] as $vin) { - if(isset($vin['coinbase'])) - echo "Generation"; - if(isset($vin['txinwitness'])) - $segwit = true; - } - if($segwit) - echo ' '; - echo ""; - - echo ""; - $nvout = count($tx['vout']);; - if ($nvout > 500) echo "Too much addresses to display ($nvout)"; - else - foreach($tx['vout'] as $vout) - { - $value = $vout['value']; - if ($value == 0) continue; - - if(isset($vout['scriptPubKey']['addresses'][0])) - echo ''.$vout['scriptPubKey']['addresses'][0]." ($value)"; - else - echo "($value)"; - - echo '
'; - } - echo ""; - - echo '
'; - unset($tx['hex']); - echo ($nvout > 500) ? 'truncated' : colorizeJson(json_encode($tx, 128)); - echo '
'; - - echo ""; - - if ($ntx > 100) { - echo 'Too much transations to display...'; - break; - } + $ntx++; + $tx = $remote->getrawtransaction($txhash, 1); + if (!$tx && ($ntx == 1 || $txid == $txhash)) + { + // some transactions are not found directly with getrawtransaction + $tx = $remote->gettransaction($txhash); + if ($tx && isset($tx['hex'])) + { + $hex = $tx['hex']; + $tx = $remote->decoderawtransaction($hex); + $tx['hex'] = $hex; + } + else + { + continue; + } + } + if (!$tx) continue; + + $valuetx = 0; + foreach ($tx['vout'] as $vout) $valuetx += $vout['value']; + + echo ''; + echo '' . $ntx . ''; + echo '' . $tx['txid'] . ''; + $size = (strlen($tx['hex']) / 2); + echo "$size"; + echo "$valuetx"; + + echo ""; + $segwit = false; + foreach ($tx['vin'] as $vin) + { + if (isset($vin['coinbase'])) echo "Generation"; + if (isset($vin['txinwitness'])) $segwit = true; + } + if ($segwit) echo ' '; + echo ""; + + echo ""; + $nvout = count($tx['vout']);; + if ($nvout > 500) echo "Too much addresses to display ($nvout)"; + else foreach ($tx['vout'] as $vout) + { + $value = $vout['value']; + if ($value == 0) continue; + + if (isset($vout['scriptPubKey']['addresses'][0])) echo '' . $vout['scriptPubKey']['addresses'][0] . " ($value)"; + else echo "($value)"; + + echo '
'; + } + echo ""; + + echo '
'; + unset($tx['hex']); + echo ($nvout > 500) ? 'truncated' : colorizeJson(json_encode($tx, 128)); + echo '
'; + + echo ""; + + if ($ntx > 100) + { + echo 'Too much transations to display...'; + break; + } } -if ($coin->rpcencoding == 'DCR' && isset($block['stx'])) { - - echo ''; - echo 'Stake'; - echo ''; - - $ntx = 0; - foreach($block['stx'] as $txhash) - { - $ntx++; - $stx = $remote->getrawtransaction($txhash, 1); - if(!$stx) continue; - - $valuetx = 0; - foreach($stx['vout'] as $vout) - $valuetx += $vout['value']; - - echo ''; - echo ''.$ntx.''; - echo ''.$stx['txid'].''; - $size = (strlen($stx['hex'])/2); - echo "$size"; - echo "$valuetx"; - - echo ""; - if(isset($stx['vout'][0]['scriptPubKey']) && arraySafeVal($stx['vout'][0]['scriptPubKey'],'type') == 'stakesubmission') - echo "Ticket"; - else foreach($stx['vin'] as $vin) { - if (arraySafeVal($vin,'blockheight') > 0) { - echo $coin->createExplorerLink($vin['blockheight'], array('height'=>$vin['blockheight'])); - echo '
'; - } - } - echo ""; - - echo ""; - foreach($stx['vout'] as $vout) - { - $value = $vout['value']; - if ($value == 0) continue; - - if(isset($vout['scriptPubKey']['addresses'][0])) - echo ''.$vout['scriptPubKey']['addresses'][0]." ($value)"; - else - echo "($value)"; - - echo '
'; - } - echo ""; - - echo '
'; - unset($stx['hex']); - echo colorizeJson(json_encode($stx, 128)); - echo '
'; - - echo ''; - } +if ($coin->rpcencoding == 'DCR' && isset($block['stx'])) +{ + + echo ''; + echo 'Stake'; + echo ''; + + $ntx = 0; + foreach ($block['stx'] as $txhash) + { + $ntx++; + $stx = $remote->getrawtransaction($txhash, 1); + if (!$stx) continue; + + $valuetx = 0; + foreach ($stx['vout'] as $vout) $valuetx += $vout['value']; + + echo ''; + echo '' . $ntx . ''; + echo '' . $stx['txid'] . ''; + $size = (strlen($stx['hex']) / 2); + echo "$size"; + echo "$valuetx"; + + echo ""; + if (isset($stx['vout'][0]['scriptPubKey']) && arraySafeVal($stx['vout'][0]['scriptPubKey'], 'type') == 'stakesubmission') echo "Ticket"; + else foreach ($stx['vin'] as $vin) + { + if (arraySafeVal($vin, 'blockheight') > 0) + { + echo $coin->createExplorerLink($vin['blockheight'], array( + 'height' => $vin['blockheight'] + )); + echo '
'; + } + } + echo ""; + + echo ""; + foreach ($stx['vout'] as $vout) + { + $value = $vout['value']; + if ($value == 0) continue; + + if (isset($vout['scriptPubKey']['addresses'][0])) echo '' . $vout['scriptPubKey']['addresses'][0] . " ($value)"; + else echo "($value)"; + + echo '
'; + } + echo ""; + + echo '
'; + unset($stx['hex']); + echo colorizeJson(json_encode($stx, 128)); + echo '
'; + + echo ''; + } } echo ''; -$actionUrl = $coin->visible ? '/explorer/'.$coin->symbol : '/explorer/search?id='.$coin->id; +$actionUrl = $coin->visible ? '/explorer/' . $coin->symbol : '/explorer/search?id=' . $coin->id; echo << @@ -326,8 +323,7 @@ function simplifyscript($script) end; + echo '









'; echo '









'; echo '









'; - - diff --git a/web/yaamp/modules/explorer/coin.php b/web/yaamp/modules/explorer/coin.php index ce724c797..8abdf9d68 100644 --- a/web/yaamp/modules/explorer/coin.php +++ b/web/yaamp/modules/explorer/coin.php @@ -1,14 +1,13 @@ goback(); JavascriptFile("/extensions/jqplot/jquery.jqplot.js"); JavascriptFile("/extensions/jqplot/plugins/jqplot.dateAxisRenderer.js"); JavascriptFile("/extensions/jqplot/plugins/jqplot.highlighter.js"); -$this->pageTitle = $coin->name." block explorer"; +$this->pageTitle = $coin->name . " block explorer"; -$start = (int) getiparam('start'); +$start = (int)getiparam('start'); echo << @@ -25,13 +24,14 @@ END; + // version is used for multi algo coins // but each coin use different values... $multiAlgos = $coin->multialgos || versionToAlgo($coin, 0) !== false; echo '
'; echo '
'; -echo '
'.$coin->name.' Explorer
'; +echo '
' . $coin->name . ' Explorer
'; echo '
'; echo ''; @@ -50,59 +50,63 @@ echo ""; $remote = new WalletRPC($coin); -if (!$start || $start > $coin->block_height) - $start = $coin->block_height; -for($i = $start; $i > max(1, $start-21); $i--) +if (!$start || $start > $coin->block_height) $start = $coin->block_height; +for ($i = $start;$i > max(1, $start - 21);$i--) { - $hash = $remote->getblockhash($i); - if(!$hash) continue; - - $block = $remote->getblock($hash); - if(!$block) continue; - - $d = datetoa2($block['time']); - $confirms = isset($block['confirmations'])? $block['confirmations']: ''; - $tx = count($block['tx']); - $diff = $block['difficulty']; - $algo = versionToAlgo($coin, $block['version']); - $type = ''; - if (arraySafeval($block,'nonce',0) > 0) $type = 'PoW'; - else if (isset($block['auxpow'])) $type = 'Aux'; - else if (isset($block['mint']) || strstr(arraySafeVal($block,'flags',''), 'proof-of-stake')) $type = 'PoS'; - - // nonce 256bits - if ($type == '' && $coin->symbol=='ZEC') $type = 'PoW'; - -// debuglog($block); - echo ''; - echo ''; - - echo ''; - - echo ''; - echo ''; - if ($multiAlgos) echo ""; - echo ''; - echo ''; - - echo ''; - - echo ""; + $hash = $remote->getblockhash($i); + if (!$hash) continue; + + $block = $remote->getblock($hash); + if (!$block) continue; + + $d = datetoa2($block['time']); + $confirms = isset($block['confirmations']) ? $block['confirmations'] : ''; + $tx = count($block['tx']); + $diff = $block['difficulty']; + $algo = versionToAlgo($coin, $block['version']); + $type = ''; + if (arraySafeval($block, 'nonce', 0) > 0) $type = 'PoW'; + else if (isset($block['auxpow'])) $type = 'Aux'; + else if (isset($block['mint']) || strstr(arraySafeVal($block, 'flags', '') , 'proof-of-stake')) $type = 'PoS'; + + // nonce 256bits + if ($type == '' && $coin->symbol == 'ZEC') $type = 'PoW'; + + // debuglog($block); + echo ''; + echo ''; + + echo ''; + + echo ''; + echo ''; + if ($multiAlgos) echo ""; + echo ''; + echo ''; + + echo ''; + + echo ""; } echo "
'.$d.''.$coin->createExplorerLink($i, array('height'=>$i)).''.$diff.''.$type.'$algo'.$tx.''.$confirms.''; - echo $coin->createExplorerLink($hash, array('hash'=>$hash)); - echo '
' . $d . '' . $coin->createExplorerLink($i, array( + 'height' => $i + )) . '' . $diff . '' . $type . '$algo' . $tx . '' . $confirms . ''; + echo $coin->createExplorerLink($hash, array( + 'hash' => $hash + )); + echo '
"; $pager = ''; -if ($start <= $coin->block_height - 20) - $pager = $coin->createExplorerLink('<< Prev', array('start'=>min($coin->block_height,$start+20))); -if ($start != $coin->block_height) - $pager .= '  '.$coin->createExplorerLink('Now'); -if ($start > 20) - $pager .= '  '.$coin->createExplorerLink('Next >>', array('start'=>max(1,$start-20))); +if ($start <= $coin->block_height - 20) $pager = $coin->createExplorerLink('<< Prev', array( + 'start' => min($coin->block_height, $start + 20) +)); +if ($start != $coin->block_height) $pager .= '  ' . $coin->createExplorerLink('Now'); +if ($start > 20) $pager .= '  ' . $coin->createExplorerLink('Next >>', array( + 'start' => max(1, $start - 20) +)); -$actionUrl = $coin->visible ? '/explorer/'.$coin->symbol : '/explorer/search?id='.$coin->id; +$actionUrl = $coin->visible ? '/explorer/' . $coin->symbol : '/explorer/search?id=' . $coin->id; echo <<$pager
@@ -115,8 +119,8 @@
end; -if ($start != $coin->block_height) - return; + +if ($start != $coin->block_height) return; echo << @@ -210,6 +214,9 @@ function diff_graph_data(data) end; -app()->clientScript->registerScript('graph'," + +app() + ->clientScript + ->registerScript('graph', " graph_refresh(); ", CClientScript::POS_READY); diff --git a/web/yaamp/modules/explorer/graph.php b/web/yaamp/modules/explorer/graph.php index 5a69f792f..94a7c92ae 100644 --- a/web/yaamp/modules/explorer/graph.php +++ b/web/yaamp/modules/explorer/graph.php @@ -1,74 +1,101 @@ memcache->get("yiimp-explorer-diff-".$coin->symbol); - -if (empty($json)) { - - // version is used in multi algo coins - $multiAlgos = versionToAlgo($coin, 0) !== false; - - $series['diff'] = array(); - $tm = 0; - - $remote = new WalletRPC($coin); - for($i = $coin->block_height; $i > max(0, $coin->block_height-500); $i--) - { - $hash = $remote->getblockhash($i); - if(!$hash) continue; - - $block = $remote->getblock($hash); - if(!$block) continue; - - // only graph PoW blocks - if (!arraySafeval($block,'nonce',0) && !arraySafeval($block,'auxpow',0)) continue; - - $n++; - - $tm = $block['time']; - $dt = date('Y-m-d H:i:s', $tm); - $diff = floatval($block['difficulty']); - $vers = $block['version']; - $algo = versionToAlgo($coin, $vers); - - if (!$multiAlgos) { - $maxdiff = max($diff, $maxdiff); - $series['diff'][$n] = array($dt, $diff, $block['height']); - } else if ($coin->algo == $algo) { - $maxdiff = max($diff, $maxdiff); - $series[$algo][$n] = array($dt, $diff, $block['height']); - } - } - - // User blocks - if ($tm) { - $sql = "SELECT id, height, IFNULL(difficulty_user, difficulty) AS diff, time FROM blocks". - " WHERE coin_id=:coin AND algo = :algo AND time >= :tm ORDER BY id"; - $rows = dbolist($sql, array(':coin'=>$coin->id, ':algo'=>$coin->algo, ':tm'=>intval($tm))); - - $n = 0; - foreach ($rows as $row) { - $diff = floatval($row['diff']); - if ($maxdiff && $diff > ($maxdiff*1.5)) $diff = $maxdiff*1.5; - $tm = $row['time']; - $dt = date('Y-m-d H:i:s', $tm); - $series['user'][$n] = array($dt, $diff, $row['diff'], $row['height']); - $n++; - } - } - - $json = ''; - foreach ($series as $algo => $data) { - if (empty($data)) continue; - $values = array_values($data); - $json .= json_encode($values).','; - } - $json = rtrim($json, ','); - - // memcache the data - controller()->memcache->set("yiimp-explorer-diff-".$coin->symbol, $json, 120); +$n = 0; +$maxdiff = 0.0; + +$json = controller() + ->memcache + ->get("yiimp-explorer-diff-" . $coin->symbol); + +if (empty($json)) +{ + + // version is used in multi algo coins + $multiAlgos = versionToAlgo($coin, 0) !== false; + + $series['diff'] = array(); + $tm = 0; + + $remote = new WalletRPC($coin); + for ($i = $coin->block_height;$i > max(0, $coin->block_height - 500);$i--) + { + $hash = $remote->getblockhash($i); + if (!$hash) continue; + + $block = $remote->getblock($hash); + if (!$block) continue; + + // only graph PoW blocks + if (!arraySafeval($block, 'nonce', 0) && !arraySafeval($block, 'auxpow', 0)) continue; + + $n++; + + $tm = $block['time']; + $dt = date('Y-m-d H:i:s', $tm); + $diff = floatval($block['difficulty']); + $vers = $block['version']; + $algo = versionToAlgo($coin, $vers); + + if (!$multiAlgos) + { + $maxdiff = max($diff, $maxdiff); + $series['diff'][$n] = array( + $dt, + $diff, + $block['height'] + ); + } + else if ($coin->algo == $algo) + { + $maxdiff = max($diff, $maxdiff); + $series[$algo][$n] = array( + $dt, + $diff, + $block['height'] + ); + } + } + + // User blocks + if ($tm) + { + $sql = "SELECT id, height, IFNULL(difficulty_user, difficulty) AS diff, time FROM blocks" . " WHERE coin_id=:coin AND algo = :algo AND time >= :tm ORDER BY id"; + $rows = dbolist($sql, array( + ':coin' => $coin->id, + ':algo' => $coin->algo, + ':tm' => intval($tm) + )); + + $n = 0; + foreach ($rows as $row) + { + $diff = floatval($row['diff']); + if ($maxdiff && $diff > ($maxdiff * 1.5)) $diff = $maxdiff * 1.5; + $tm = $row['time']; + $dt = date('Y-m-d H:i:s', $tm); + $series['user'][$n] = array( + $dt, + $diff, + $row['diff'], + $row['height'] + ); + $n++; + } + } + + $json = ''; + foreach ($series as $algo => $data) + { + if (empty($data)) continue; + $values = array_values($data); + $json .= json_encode($values) . ','; + } + $json = rtrim($json, ','); + + // memcache the data + controller() + ->memcache + ->set("yiimp-explorer-diff-" . $coin->symbol, $json, 120); } echo "[$json]"; diff --git a/web/yaamp/modules/explorer/index.php b/web/yaamp/modules/explorer/index.php index b064a836f..d27b69da0 100644 --- a/web/yaamp/modules/explorer/index.php +++ b/web/yaamp/modules/explorer/index.php @@ -1,5 +1,4 @@ end; + showTableSorter('maintable', "{ tableClass: 'dataGrid2', textExtraction: { @@ -47,61 +47,74 @@ function wallet_peers(id) end; + $list = getdbolist('db_coins', "enable and visible order by name"); -foreach($list as $coin) +foreach ($list as $coin) { - if($coin->symbol == 'BTC') continue; - if(!empty($coin->symbol2)) continue; - - $coin->version = formatWalletVersion($coin); - - //if (!$coin->network_hash) - $coin->network_hash = controller()->memcache->get("yiimp-nethashrate-{$coin->symbol}"); - if (!$coin->network_hash) { - $remote = new WalletRPC($coin); - if ($remote) - $info = $remote->getmininginfo(); - if (isset($info['networkhashps'])) { - $coin->network_hash = $info['networkhashps']; - controller()->memcache->set("yiimp-nethashrate-{$coin->symbol}", $info['networkhashps'], 60); - } - else if (isset($info['netmhashps'])) { - $coin->network_hash = floatval($info['netmhashps']) * 1e6; - controller()->memcache->set("yiimp-nethashrate-{$coin->symbol}", $coin->network_hash, 60); - } - } - - $difficulty = Itoa2($coin->difficulty, 3); - $nethash_sfx = $coin->network_hash? strtoupper(Itoa2($coin->network_hash)).'H/s': ''; - - echo ''; - echo ''; - - echo ''.$coin->createExplorerLink($coin->name).''; - echo ''.$coin->symbol.''; - - echo ''.$coin->algo.''; - echo ''.$coin->version.''; - - echo ''.$coin->block_height.''; - $diffnote = ''; - if ($coin->algo == 'equihash' || $coin->algo == 'quark') $diffnote = '*'; - echo ''.$difficulty.$diffnote.''; - $cnx_class = (intval($coin->connections) > 3) ? '' : 'low'; - $peers_link = CHtml::link($coin->connections, "javascript:wallet_peers({$coin->id});", array('class'=>$cnx_class)); - echo ''.$peers_link.''; - echo ''.$nethash_sfx.''; - - echo ""; - - if(!empty($coin->link_bitcointalk)) - echo CHtml::link('forum', $coin->link_bitcointalk, array('target'=>'_blank')); - - elseif(!empty($coin->link_site)) - echo CHtml::link('site', $coin->link_site, array('target'=>'_blank')); - - echo ""; - echo ""; + if ($coin->symbol == 'BTC') continue; + if (!empty($coin->symbol2)) continue; + + $coin->version = formatWalletVersion($coin); + + //if (!$coin->network_hash) + $coin->network_hash = controller() + ->memcache + ->get("yiimp-nethashrate-{$coin->symbol}"); + if (!$coin->network_hash) + { + $remote = new WalletRPC($coin); + if ($remote) $info = $remote->getmininginfo(); + if (isset($info['networkhashps'])) + { + $coin->network_hash = $info['networkhashps']; + controller() + ->memcache + ->set("yiimp-nethashrate-{$coin->symbol}", $info['networkhashps'], 60); + } + else if (isset($info['netmhashps'])) + { + $coin->network_hash = floatval($info['netmhashps']) * 1e6; + controller() + ->memcache + ->set("yiimp-nethashrate-{$coin->symbol}", $coin->network_hash, 60); + } + } + + $difficulty = Itoa2($coin->difficulty, 3); + $nethash_sfx = $coin->network_hash ? strtoupper(Itoa2($coin->network_hash)) . 'H/s' : ''; + + echo ''; + echo ''; + + echo '' . $coin->createExplorerLink($coin->name) . ''; + echo '' . $coin->symbol . ''; + + echo '' . $coin->algo . ''; + echo '' . $coin->version . ''; + + echo '' . $coin->block_height . ''; + $diffnote = ''; + if ($coin->algo == 'equihash' || $coin->algo == 'quark') $diffnote = '*'; + echo '' . $difficulty . $diffnote . ''; + $cnx_class = (intval($coin->connections) > 3) ? '' : 'low'; + $peers_link = CHtml::link($coin->connections, "javascript:wallet_peers({$coin->id});", array( + 'class' => $cnx_class + )); + echo '' . $peers_link . ''; + echo '' . $nethash_sfx . ''; + + echo ""; + + if (!empty($coin->link_bitcointalk)) echo CHtml::link('forum', $coin->link_bitcointalk, array( + 'target' => '_blank' + )); + + elseif (!empty($coin->link_site)) echo CHtml::link('site', $coin->link_site, array( + 'target' => '_blank' + )); + + echo ""; + echo ""; } echo <<








end; - diff --git a/web/yaamp/modules/explorer/peers.php b/web/yaamp/modules/explorer/peers.php index 9db0e51ed..c05cbe9f0 100644 --- a/web/yaamp/modules/explorer/peers.php +++ b/web/yaamp/modules/explorer/peers.php @@ -1,16 +1,14 @@ goback(); -require dirname(__FILE__).'/../../ui/lib/pageheader.php'; +require dirname(__FILE__) . '/../../ui/lib/pageheader.php'; -$this->pageTitle = 'Peers - '.$coin->name; +$this->pageTitle = 'Peers - ' . $coin->name; $remote = new WalletRPC($coin); $info = $remote->getinfo(); ////////////////////////////////////////////////////////////////////////////////////// - echo << body { margin: 4px; } @@ -22,30 +20,30 @@
end; + $addnode = array(); $version = ''; $localheight = arraySafeVal($info, 'blocks'); $list = $remote->getpeerinfo(); -if(!empty($list)) -foreach($list as $peer) +if (!empty($list)) foreach ($list as $peer) { - $node = arraySafeVal($peer,'addr'); - if (strstr($node,'127.0.0.1')) continue; - if (strstr($node,'192.168.')) continue; - if (strstr($node,'yiimp')) continue; + $node = arraySafeVal($peer, 'addr'); + if (strstr($node, '127.0.0.1')) continue; + if (strstr($node, '192.168.')) continue; + if (strstr($node, 'yiimp')) continue; - $addnode[] = ($coin->rpcencoding=='DCR' ? 'addpeer=' : 'addnode=') . $node; + $addnode[] = ($coin->rpcencoding == 'DCR' ? 'addpeer=' : 'addnode=') . $node; - $peerver = trim(arraySafeVal($peer,'subver'),'/'); - $version = max($version, $peerver); + $peerver = trim(arraySafeVal($peer, 'subver') , '/'); + $version = max($version, $peerver); } asort($addnode); echo '
';
-echo implode("\n",$addnode);
+echo implode("\n", $addnode);
 echo '
'; echo '
'; diff --git a/web/yaamp/modules/explorer/tx.php b/web/yaamp/modules/explorer/tx.php index fea0305e3..145ca0ddc 100644 --- a/web/yaamp/modules/explorer/tx.php +++ b/web/yaamp/modules/explorer/tx.php @@ -1,8 +1,7 @@ goback(); -$this->pageTitle = $coin->name." block explorer"; +$this->pageTitle = $coin->name . " block explorer"; $remote = new WalletRPC($coin); @@ -31,47 +30,46 @@ END; + $tx = $remote->getrawtransaction($txhash, 1); -if(!$tx) continue; +if (!$tx) continue; $valuetx = 0; -foreach($tx['vout'] as $vout) - $valuetx += $vout['value']; +foreach ($tx['vout'] as $vout) $valuetx += $vout['value']; -$coinUrl = $this->createUrl('/explorer', array('id'=>$coin->id)); +$coinUrl = $this->createUrl('/explorer', array( + 'id' => $coin->id +)); echo ''; -echo ''.CHtml::link($tx['txid'], $coinUrl.'txid='.$tx['txid']).''; -echo ''.$valuetx.''; +echo '' . CHtml::link($tx['txid'], $coinUrl . 'txid=' . $tx['txid']) . ''; +echo '' . $valuetx . ''; echo ""; -foreach($tx['vin'] as $vin) +foreach ($tx['vin'] as $vin) { - if(isset($vin['coinbase'])) - echo "Generation"; + if (isset($vin['coinbase'])) echo "Generation"; } echo ""; echo ""; -foreach($tx['vout'] as $vout) +foreach ($tx['vout'] as $vout) { - $value = $vout['value']; + $value = $vout['value']; - if(isset($vout['scriptPubKey']['addresses'][0])) - echo ''.$vout['scriptPubKey']['addresses'][0]." ($value)"; - else - echo "($value)"; + if (isset($vout['scriptPubKey']['addresses'][0])) echo '' . $vout['scriptPubKey']['addresses'][0] . " ($value)"; + else echo "($value)"; - echo '
'; + echo '
'; } echo ""; echo ""; echo ""; -$actionUrl = $coin->visible ? '/explorer/'.$coin->symbol : '/explorer/search?id='.$coin->id; +$actionUrl = $coin->visible ? '/explorer/' . $coin->symbol : '/explorer/search?id=' . $coin->id; echo << @@ -81,14 +79,7 @@ end; + echo '









'; echo '









'; echo '









'; - - - - - - - - diff --git a/web/yaamp/modules/explorer/util.php b/web/yaamp/modules/explorer/util.php index 5d197cfc6..7e3628528 100644 --- a/web/yaamp/modules/explorer/util.php +++ b/web/yaamp/modules/explorer/util.php @@ -1,213 +1,289 @@ hexdec($addressversion)) - { - return false; - } - $check=substr($addr,0,strlen($addr)-8); - $check=pack("H*" , $check); - $check=strtoupper(hash("sha256",hash("sha256",$check,true))); - $check=substr($check,0,8); - return $check==substr($addr,strlen($addr)-8); + $addr = decodeBase58($addr); + if (strlen($addr) != 50) + { + return false; + } + $version = substr($addr, 0, 2); + if (hexdec($version) > hexdec($addressversion)) + { + return false; + } + $check = substr($addr, 0, strlen($addr) - 8); + $check = pack("H*", $check); + $check = strtoupper(hash("sha256", hash("sha256", $check, true))); + $check = substr($check, 0, 8); + return $check == substr($addr, strlen($addr) - 8); } function hash160($data) { - $data=pack("H*" , $data); - return strtoupper(hash("ripemd160",hash("sha256",$data,true))); + $data = pack("H*", $data); + return strtoupper(hash("ripemd160", hash("sha256", $data, true))); } function pubKeyToAddress($pubkey) { - return hash160ToAddress(hash160($pubkey)); + return hash160ToAddress(hash160($pubkey)); } function remove0x($string) { - if(substr($string,0,2)=="0x"||substr($string,0,2)=="0X") - { - $string=substr($string,2); - } - return $string; + if (substr($string, 0, 2) == "0x" || substr($string, 0, 2) == "0X") + { + $string = substr($string, 2); + } + return $string; } // version is used for multi algo coins function versionToAlgo($coin, $version) { - // could be filled by block json (chain analysis) - $algos['MYR'] = array( - 0=>'sha256', 1=>'scrypt', 2=>'myr-gr', 3=>'skein', 4=>'qubit', 5=>'yescrypt' - ); - $algos['DGB'] = array( - 0=>'scrypt', 1=>'sha256', 2=>'myr-gr', 3=>'skein', 4=>'qubit' - ); - $algos['AUR'] = array( - 0=>'sha256', 1=>'scrypt', 2=>'myr-gr', 3=>'skein', 4=>'qubit' - ); - $algos['DGC'] = array( - 0=>'scrypt', 1=>'sha256', 2=>'x11' - ); - $algos['DUO'] = array( - 0=>'sha256', 1=>'scrypt' - ); - $algos['J'] = array( - 2 =>'sha256', 3=>'x11', 4=>'x13', 5=>'x15', 6=>'scrypt', - 7 =>'nist5', 8 =>'myr-gr', 9=>'penta', 10=>'whirlpool', - 11=>'luffa', 12=>'keccak', 13=>'quark', 15=>'bastion' - ); - $algos['GCH'] = array( - 0=>'x12', 1=>'x11', 2=>'x13', 3=>'sha256', 4=>'blake2s' - ); - $algos['GLT'] = array( - 0=>'sha256', 1=>'scrypt', 2=>'x11', 3=>'neoscrypt', 4=>'equihash', 5=>'yescrypt', 6=>'hmq1725', - 7=>'xevan', 8=>'nist5', 9=>'bitcore', 10=>'pawelhash', 11=>'x13', 12=>'x14', 13=>'x15', 14=>'x17', - 15=>'lyra2v2', 16=>'blake2s', 17=>'blake2b', 18=>'astralhash', 19=>'padihash', 20=>'jeonghash', - 21=>'keccak', 22=>'zhash', 23=>'globalhash', 24=>'skein', 25=>'myr-gr', 26=>'qubit', 27=>'skunk', - 28=>'quark', 29=>'x16r' - ); - $algos['RICHX'] = array( - 0=>'sha256', 1=>'scrypt', 2=>'myr-gr', 3=>'skein', 4=>'qubit' - ); - $algos['SFR'] = array( - 0=>'sha256', 1=>'scrypt', 2=>'myr-gr', 3=>'x11', 4=>'blake' - ); - $algos['UIS'] = array( - 0=>'lyra2v2', 1=>'skein', 2=>'qubit', 3=>'yescrypt', 4=>'x11' - ); - $algos['XVG'] = array( - 0=>'scrypt', 1=>'scrypt', 2=>'myr-gr', 3=>'x17', 4=>'blake2s', 10=>'lyra2v2', - ); - $algos['XSH'] = array( - 0=>'scrypt', 1=>'scrypt', 2=>'myr-gr', 3=>'x17', 4=>'blake2s', 10=>'lyra2v2', 11=>'x16s', - ); - $algos['ARG'] = array( - 0=>'sha256', 1=>'scrypt', 2=>'lyra2v2', 3=>'myr-gr', 4=>'argon2d', 5=>'yescrypt', - ); - $symbol = $coin->symbol; - if (!empty($coin->symbol2)) $symbol = $coin->symbol2; - - if ($symbol == 'J') - return arraySafeVal($algos[$symbol], $version, ''); - else if($symbol == 'GCH') - return arraySafeVal($algos[$symbol], ($version - 9), ''); - else if($symbol == 'XVG') - return arraySafeVal($algos[$symbol], ($version >> 11), 'scrypt'); - else if($symbol == 'XSH') - return arraySafeVal($algos[$symbol], (($version-536870000) >> 11), 'scrypt'); - else if (isset($algos[$symbol])) - return arraySafeVal($algos[$symbol], ($version >> 9) & 7, ''); - return false; + // could be filled by block json (chain analysis) + $algos['MYR'] = array( + 0 => 'sha256', + 1 => 'scrypt', + 2 => 'myr-gr', + 3 => 'skein', + 4 => 'qubit', + 5 => 'yescrypt' + ); + $algos['DGB'] = array( + 0 => 'scrypt', + 1 => 'sha256', + 2 => 'myr-gr', + 3 => 'skein', + 4 => 'qubit' + ); + $algos['AUR'] = array( + 0 => 'sha256', + 1 => 'scrypt', + 2 => 'myr-gr', + 3 => 'skein', + 4 => 'qubit' + ); + $algos['DGC'] = array( + 0 => 'scrypt', + 1 => 'sha256', + 2 => 'x11' + ); + $algos['DUO'] = array( + 0 => 'sha256', + 1 => 'scrypt' + ); + $algos['J'] = array( + 2 => 'sha256', + 3 => 'x11', + 4 => 'x13', + 5 => 'x15', + 6 => 'scrypt', + 7 => 'nist5', + 8 => 'myr-gr', + 9 => 'penta', + 10 => 'whirlpool', + 11 => 'luffa', + 12 => 'keccak', + 13 => 'quark', + 15 => 'bastion' + ); + $algos['GCH'] = array( + 0 => 'x12', + 1 => 'x11', + 2 => 'x13', + 3 => 'sha256', + 4 => 'blake2s' + ); + $algos['GLT'] = array( + 0 => 'sha256', + 1 => 'scrypt', + 2 => 'x11', + 3 => 'neoscrypt', + 4 => 'equihash', + 5 => 'yescrypt', + 6 => 'hmq1725', + 7 => 'xevan', + 8 => 'nist5', + 9 => 'bitcore', + 10 => 'pawelhash', + 11 => 'x13', + 12 => 'x14', + 13 => 'x15', + 14 => 'x17', + 15 => 'lyra2v2', + 16 => 'blake2s', + 17 => 'blake2b', + 18 => 'astralhash', + 19 => 'padihash', + 20 => 'jeonghash', + 21 => 'keccak', + 22 => 'zhash', + 23 => 'globalhash', + 24 => 'skein', + 25 => 'myr-gr', + 26 => 'qubit', + 27 => 'skunk', + 28 => 'quark', + 29 => 'x16r' + ); + $algos['RICHX'] = array( + 0 => 'sha256', + 1 => 'scrypt', + 2 => 'myr-gr', + 3 => 'skein', + 4 => 'qubit' + ); + $algos['SFR'] = array( + 0 => 'sha256', + 1 => 'scrypt', + 2 => 'myr-gr', + 3 => 'x11', + 4 => 'blake' + ); + $algos['UIS'] = array( + 0 => 'lyra2v2', + 1 => 'skein', + 2 => 'qubit', + 3 => 'yescrypt', + 4 => 'x11' + ); + $algos['XVG'] = array( + 0 => 'scrypt', + 1 => 'scrypt', + 2 => 'myr-gr', + 3 => 'x17', + 4 => 'blake2s', + 10 => 'lyra2v2', + ); + $algos['XSH'] = array( + 0 => 'scrypt', + 1 => 'scrypt', + 2 => 'myr-gr', + 3 => 'x17', + 4 => 'blake2s', + 10 => 'lyra2v2', + 11 => 'x16s', + ); + $algos['ARG'] = array( + 0 => 'sha256', + 1 => 'scrypt', + 2 => 'lyra2v2', + 3 => 'myr-gr', + 4 => 'argon2d', + 5 => 'yescrypt', + ); + $symbol = $coin->symbol; + if (!empty($coin->symbol2)) $symbol = $coin->symbol2; + + if ($symbol == 'J') return arraySafeVal($algos[$symbol], $version, ''); + else if ($symbol == 'GCH') return arraySafeVal($algos[$symbol], ($version - 9) , ''); + else if ($symbol == 'XVG') return arraySafeVal($algos[$symbol], ($version >> 11) , 'scrypt'); + else if ($symbol == 'XSH') return arraySafeVal($algos[$symbol], (($version - 536870000) >> 11) , 'scrypt'); + else if (isset($algos[$symbol])) return arraySafeVal($algos[$symbol], ($version >> 9) & 7, ''); + return false; } diff --git a/web/yaamp/modules/market/MarketController.php b/web/yaamp/modules/market/MarketController.php index 5b111584f..fd2415532 100644 --- a/web/yaamp/modules/market/MarketController.php +++ b/web/yaamp/modules/market/MarketController.php @@ -1,104 +1,122 @@ admin) return; - - $market = getdbo('db_markets', getiparam('id')); - if(!$market) { - user()->setFlash('error', "invalid market"); - $this->goback(); - return; - } - $coin = getdbo('db_coins', $market->coinid); - - if(isset($_POST['db_markets'])) - { - $market->setAttributes($_POST['db_markets'], false); - if($market->save()) - $this->redirect(array('site/coin', 'id'=>$coin->id)); - } - - $this->render('update', array('market'=>$market, 'coin'=>$coin)); - } - - public function actionEnable() - { - if(!$this->admin) return; - - $enable = (int) getiparam('en'); - $market = getdbo('db_markets', getiparam('id')); - if($market) { - $market->disabled = $enable ? 0 : 9; - $market->save(); - } - $this->goback(); - } - - public function actionDelete() - { - if(!$this->admin) return; - - $market = getdbo('db_markets', getiparam('id')); - if($market) $market->delete(); - $this->goback(); - } - - public function actionSellto() - { - if(!$this->admin) return; - - $market = getdbo('db_markets', getiparam('id')); - if(!$market) { - user()->setFlash('error', "invalid market"); - $this->goback(); - return; - } - $coin = getdbo('db_coins', $market->coinid); - $amount = getparam('amount'); - - $remote = new WalletRPC($coin); - - $info = $remote->getinfo(); - if(!$info || !$info['balance']) return false; - - $deposit_info = $remote->validateaddress($market->deposit_address); - if(!$deposit_info || !isset($deposit_info['isvalid']) || !$deposit_info['isvalid']) - { - user()->setFlash('error', "invalid address $coin->name, $market->deposit_address"); - $this->redirect(array('site/coin', 'id'=>$coin->id)); - } - - $amount = min($amount, $info['balance'] - $info['paytxfee']); -// $amount = max($amount, $info['balance'] - $info['paytxfee']); - $amount = round($amount, 8); - - debuglog("selling ($market->deposit_address, $amount)"); - - $tx = $remote->sendtoaddress($market->deposit_address, $amount); - if(!$tx) - { - user()->setFlash('error', $remote->error); - $this->redirect(array('site/coin', 'id'=>$coin->id)); - } else { - $market->lastsent = time(); - $market->save(); - BackendUpdatePoolBalances($coin->id); - } - - $exchange = new db_exchange; - $exchange->market = $market->name; - $exchange->coinid = $coin->id; - $exchange->send_time = time(); - $exchange->quantity = $amount; - $exchange->price_estimate = $coin->price; - $exchange->status = 'waiting'; - $exchange->tx = $tx; - $exchange->save(); - - $this->redirect(array('site/coin', 'id'=>$coin->id)); - } + public function actionUpdate() + { + if (!$this->admin) return; + + $market = getdbo('db_markets', getiparam('id')); + if (!$market) + { + user()->setFlash('error', "invalid market"); + $this->goback(); + return; + } + $coin = getdbo('db_coins', $market->coinid); + + if (isset($_POST['db_markets'])) + { + $market->setAttributes($_POST['db_markets'], false); + if ($market->save()) $this->redirect(array( + 'site/coin', + 'id' => $coin->id + )); + } + + $this->render('update', array( + 'market' => $market, + 'coin' => $coin + )); + } + + public function actionEnable() + { + if (!$this->admin) return; + + $enable = (int)getiparam('en'); + $market = getdbo('db_markets', getiparam('id')); + if ($market) + { + $market->disabled = $enable ? 0 : 9; + $market->save(); + } + $this->goback(); + } + + public function actionDelete() + { + if (!$this->admin) return; + + $market = getdbo('db_markets', getiparam('id')); + if ($market) $market->delete(); + $this->goback(); + } + + public function actionSellto() + { + if (!$this->admin) return; + + $market = getdbo('db_markets', getiparam('id')); + if (!$market) + { + user()->setFlash('error', "invalid market"); + $this->goback(); + return; + } + $coin = getdbo('db_coins', $market->coinid); + $amount = getparam('amount'); + + $remote = new WalletRPC($coin); + + $info = $remote->getinfo(); + if (!$info || !$info['balance']) return false; + + $deposit_info = $remote->validateaddress($market->deposit_address); + if (!$deposit_info || !isset($deposit_info['isvalid']) || !$deposit_info['isvalid']) + { + user()->setFlash('error', "invalid address $coin->name, $market->deposit_address"); + $this->redirect(array( + 'site/coin', + 'id' => $coin->id + )); + } + + $amount = min($amount, $info['balance'] - $info['paytxfee']); + // $amount = max($amount, $info['balance'] - $info['paytxfee']); + $amount = round($amount, 8); + + debuglog("selling ($market->deposit_address, $amount)"); + + $tx = $remote->sendtoaddress($market->deposit_address, $amount); + if (!$tx) + { + user()->setFlash('error', $remote->error); + $this->redirect(array( + 'site/coin', + 'id' => $coin->id + )); + } + else + { + $market->lastsent = time(); + $market->save(); + BackendUpdatePoolBalances($coin->id); + } + + $exchange = new db_exchange; + $exchange->market = $market->name; + $exchange->coinid = $coin->id; + $exchange->send_time = time(); + $exchange->quantity = $amount; + $exchange->price_estimate = $coin->price; + $exchange->status = 'waiting'; + $exchange->tx = $tx; + $exchange->save(); + + $this->redirect(array( + 'site/coin', + 'id' => $coin->id + )); + } } diff --git a/web/yaamp/modules/renting/RentingController.php b/web/yaamp/modules/renting/RentingController.php index 6d3baf01f..c10a1ec0c 100644 --- a/web/yaamp/modules/renting/RentingController.php +++ b/web/yaamp/modules/renting/RentingController.php @@ -1,360 +1,372 @@ array( - 'class'=>'CCaptchaAction', - 'backColor'=>0xeeeeee, - ), - ); - } - - private function verifyparam() - { - $deposit = user()->getState('yaamp-deposit'); - $address = getparam('address'); - - if(!$this->admin && $deposit != $address) - return false; - - return true; - } - - public function actionLogin() - { - $deposit = isset($_POST['deposit_address'])? substr($_POST['deposit_address'], 0, 35): ''; - $password = isset($_POST['deposit_password'])? substr($_POST['deposit_password'], 0, 64): ''; - - $renter = getdbosql('db_renters', "address=:address", array(':address'=>$deposit)); - if(!$renter) - { - $this->render('login'); - return; - } - - if(md5($password) != $renter->password && (!empty($renter->password) || !empty($password))) - { - user()->setFlash('error', "Login failed."); - $this->render('login'); - return; - } - - user()->setState('yaamp-deposit', $renter->address); - $this->redirect("/renting"); - } - - public function actionIndex() - { - $deposit = user()->getState('yaamp-deposit'); - if(!$deposit && !$this->admin) - { - $this->render('login'); - return; - } - - $address = getparam('address'); - if($this->admin && !empty($address)) - { - $deposit = $address; - user()->setState('yaamp-deposit', $deposit); - } - - $renter = getdbosql('db_renters', "address=:deposit", array(':deposit'=>$deposit)); - if(!$renter) - { - $this->render('login'); - return; - } - - $changed = false; - if(isset($_POST['deposit_email'])) - { - $renter->email = $_POST['deposit_email']; - $changed = true; - } - - if(isset($_POST['deposit_password']) && !empty($_POST['deposit_password'])) - { - if($_POST['deposit_password'] == $_POST['deposit_confirm']) - { - $renter->password = md5($_POST['deposit_password']); - $changed = true; - } - else - { - user()->setFlash('error', "Confirm different from password."); - $this->goback(); - - return; - } - } - - if($changed) - { - debuglog("saving renter {$_SERVER['REMOTE_ADDR']} $renter->address"); - - dborun("update renters set email=:email, password=:password where id=$renter->id", - array(':email'=>$renter->email, ':password'=>$renter->password)); - -// $renter->save(); - - user()->setFlash('message', "Settings saved."); - $this->redirect("/renting"); - } - - $this->render('index', array('renter'=>$renter)); - } - - public function actionSettings() - { - $this->render('settings'); - } - - public function actionAdmin() - { - if(!$this->admin) return; - $this->render('admin'); - } - - public function actionCreate() - { - $this->render('create'); - } - - public function actionLogout() - { - user()->setState('yaamp-deposit', ''); - $this->redirect('/renting'); - } - - public function actionTx() - { - $this->renderPartial('tx'); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - - public function actionJobs_stop() - { - $job = getdbo('db_jobs', getiparam('id')); - - $renter = getdbo('db_renters', $job->renterid); - if(!$renter || $renter->address != user()->getState('yaamp-deposit')) $this->goback(); - - $job->active = false; - $job->ready = false; - $job->time = time(); -// $job->difficulty = null; - $job->save(); - - $this->goback(); - } - - public function actionJobs_start() - { - $job = getdbo('db_jobs', getiparam('id')); -// if($job->algo == 'sha256') $this->goback(); - - $renter = getdbo('db_renters', $job->renterid); - if(!$renter || $renter->balance<=0.00001000 || $renter->address != user()->getState('yaamp-deposit')) $this->goback(); - - $rent = dboscalar("select rent from hashrate where algo=:algo order by time desc limit 1", array(':algo'=>$job->algo)); - if($job->price > $rent) $job->active = true; - - $job->ready = true; - $job->time = time(); -// $job->difficulty = null; - $job->save(); - - $this->goback(); - } - - public function actionJobs_startall() - { - $deposit = user()->getState('yaamp-deposit'); - $renter = getrenterparam($deposit); - if(!$renter || $renter->balance<=0.00001000) $this->goback(); - - $list = getdbolist('db_jobs', "renterid=$renter->id"); - foreach($list as $job) - { - $rent = dboscalar("select rent from hashrate where algo=:algo order by time desc limit 1", array(':algo'=>$job->algo)); - if($job->price > $rent) $job->active = true; - - $job->ready = true; - $job->time = time(); - $job->save(); - } - - $this->goback(); - } - - public function actionJobs_stopall() - { - $deposit = user()->getState('yaamp-deposit'); - $renter = getrenterparam($deposit); - if(!$renter) $this->goback(); - - $list = getdbolist('db_jobs', "renterid=$renter->id"); - foreach($list as $job) - { - $job->active = false; - $job->ready = false; - $job->time = time(); - $job->save(); - } - - $this->goback(); - } - - ///////////////////////////////////////////////////////////////////////////////////////////// - - public function actionBalance_results() - { - if(!$this->verifyparam()) return; - $this->renderPartial('balance_results'); - } - - public function actionOrders_results() - { - if(!$this->verifyparam()) return; - $this->renderPartial('orders_results'); - } - - public function actionAll_orders_results() - { - $this->renderPartial('all_orders_results'); - } - - public function actionGraph_job_results() - { - $this->renderPartial('graph_job_results'); - } - - public function actionStatus_results() - { - $this->renderPartial('status_results'); - } - - public function actionGraph_price_results() - { - $this->renderPartial('graph_price_results'); - } - - ///////////////////////////////////////////////////////////////////////////////////////////// - - public function actionOrderDelete() - { - $job = getdbo('db_jobs', getiparam('id')); - if(!$job) return; - - $renter = getdbo('db_renters', $job->renterid); - if(!$renter || $renter->address != user()->getState('yaamp-deposit')) return; - - $job->delete(); - $this->redirect("/renting?address=$renter->address"); - } - - public function actionOrderSave() - { - $renter = getdbo('db_renters', XssFilter(''.getparam('order_renterid'))); - if(!$renter || $renter->address != user()->getState('yaamp-deposit')) return; - - $job = getdbo('db_jobs', XssFilter(''.getparam('order_id'))); - if(!$job) - { - $job = new db_jobs; - $job->renterid = getparam('order_renterid'); - } - - $job->algo = getparam('order_algo'); - $job->username = getparam('order_username'); - $job->password = getparam('order_password'); - $job->percent = getparam('order_percent'); - $job->price = getparam('order_price'); - $job->speed = getparam('order_speed')*1000000; - - if( empty($job->algo) || empty($job->username) || empty($job->password) || empty($job->price) || - empty($job->speed) || empty(''.getparam('order_address')) || empty(''.getparam('order_host'))) - { - $this->redirect('/renting'); - return; - } - - if($job->speed<100000) - { - $this->redirect('/renting'); - return; - } - - $host = str_replace('stratum+tcp://', '', getparam('order_host')); - $a = explode(':', $host); - if(!isset($a[0]) || !isset($a[1])) - { - user()->setFlash('error', "invalid server url"); - $this->redirect('/renting'); - return; - } - - $job->host = trim($a[0]); - $job->port = intval($a[1]); - - if(stripos($job->host, YAAMP_STRATUM_URL) !== false) { - user()->setFlash('error', "invalid server url"); - $this->redirect('/renting'); - return; - } - - $rent = dboscalar("select rent from hashrate where algo=:algo order by time desc limit 1", array(':algo'=>$job->algo)); - - if($job->price > $rent && $job->ready) - $job->active = true; - - else if($job->price < $rent) - $job->active = false; - - $job->time = time(); -// $job->difficulty = null; - $job->save(); - - $this->redirect("/renting?address=".getparam('order_address')); - } - - ///////////////////////////////////////////////////////////////////////////////////////////// - - public function actionOrderDialog() - { - $renter = getrenterparam(''.getparam('address')); - if(!$renter) return; - - $a = YAAMP_DEFAULT_ALGO; - $server = ''; - $username = ''; - $password = 'xx'; - $percent = ''; - $price = ''; - $speed = ''; - $id = 0; - - $job = getdbo('db_jobs', getiparam('id')); - if($job) - { - $id = $job->id; - $a = $job->algo; - $server = "$job->host:$job->port"; - $username = $job->username; - $password = $job->password; - $percent = $job->percent; - $price = mbitcoinvaluetoa($job->price); - $speed = $job->speed/1000000; - } - - echo << array( + 'class' => 'CCaptchaAction', + 'backColor' => 0xeeeeee, + ) , + ); + } + + private function verifyparam() + { + $deposit = user()->getState('yaamp-deposit'); + $address = getparam('address'); + + if (!$this->admin && $deposit != $address) return false; + + return true; + } + + public function actionLogin() + { + $deposit = isset($_POST['deposit_address']) ? substr($_POST['deposit_address'], 0, 35) : ''; + $password = isset($_POST['deposit_password']) ? substr($_POST['deposit_password'], 0, 64) : ''; + + $renter = getdbosql('db_renters', "address=:address", array( + ':address' => $deposit + )); + if (!$renter) + { + $this->render('login'); + return; + } + + if (md5($password) != $renter->password && (!empty($renter->password) || !empty($password))) + { + user()->setFlash('error', "Login failed."); + $this->render('login'); + return; + } + + user() + ->setState('yaamp-deposit', $renter->address); + $this->redirect("/renting"); + } + + public function actionIndex() + { + $deposit = user()->getState('yaamp-deposit'); + if (!$deposit && !$this->admin) + { + $this->render('login'); + return; + } + + $address = getparam('address'); + if ($this->admin && !empty($address)) + { + $deposit = $address; + user()->setState('yaamp-deposit', $deposit); + } + + $renter = getdbosql('db_renters', "address=:deposit", array( + ':deposit' => $deposit + )); + if (!$renter) + { + $this->render('login'); + return; + } + + $changed = false; + if (isset($_POST['deposit_email'])) + { + $renter->email = $_POST['deposit_email']; + $changed = true; + } + + if (isset($_POST['deposit_password']) && !empty($_POST['deposit_password'])) + { + if ($_POST['deposit_password'] == $_POST['deposit_confirm']) + { + $renter->password = md5($_POST['deposit_password']); + $changed = true; + } + else + { + user()->setFlash('error', "Confirm different from password."); + $this->goback(); + + return; + } + } + + if ($changed) + { + debuglog("saving renter {$_SERVER['REMOTE_ADDR']} $renter->address"); + + dborun("update renters set email=:email, password=:password where id=$renter->id", array( + ':email' => $renter->email, + ':password' => $renter->password + )); + + // $renter->save(); + user() + ->setFlash('message', "Settings saved."); + $this->redirect("/renting"); + } + + $this->render('index', array( + 'renter' => $renter + )); + } + + public function actionSettings() + { + $this->render('settings'); + } + + public function actionAdmin() + { + if (!$this->admin) return; + $this->render('admin'); + } + + public function actionCreate() + { + $this->render('create'); + } + + public function actionLogout() + { + user() + ->setState('yaamp-deposit', ''); + $this->redirect('/renting'); + } + + public function actionTx() + { + $this->renderPartial('tx'); + } + + //////////////////////////////////////////////////////////////////////////////////////////////////// + public function actionJobs_stop() + { + $job = getdbo('db_jobs', getiparam('id')); + + $renter = getdbo('db_renters', $job->renterid); + if (!$renter || $renter->address != user() + ->getState('yaamp-deposit')) $this->goback(); + + $job->active = false; + $job->ready = false; + $job->time = time(); + // $job->difficulty = null; + $job->save(); + + $this->goback(); + } + + public function actionJobs_start() + { + $job = getdbo('db_jobs', getiparam('id')); + // if($job->algo == 'sha256') $this->goback(); + $renter = getdbo('db_renters', $job->renterid); + if (!$renter || $renter->balance <= 0.00001000 || $renter->address != user() + ->getState('yaamp-deposit')) $this->goback(); + + $rent = dboscalar("select rent from hashrate where algo=:algo order by time desc limit 1", array( + ':algo' => $job->algo + )); + if ($job->price > $rent) $job->active = true; + + $job->ready = true; + $job->time = time(); + // $job->difficulty = null; + $job->save(); + + $this->goback(); + } + + public function actionJobs_startall() + { + $deposit = user()->getState('yaamp-deposit'); + $renter = getrenterparam($deposit); + if (!$renter || $renter->balance <= 0.00001000) $this->goback(); + + $list = getdbolist('db_jobs', "renterid=$renter->id"); + foreach ($list as $job) + { + $rent = dboscalar("select rent from hashrate where algo=:algo order by time desc limit 1", array( + ':algo' => $job->algo + )); + if ($job->price > $rent) $job->active = true; + + $job->ready = true; + $job->time = time(); + $job->save(); + } + + $this->goback(); + } + + public function actionJobs_stopall() + { + $deposit = user()->getState('yaamp-deposit'); + $renter = getrenterparam($deposit); + if (!$renter) $this->goback(); + + $list = getdbolist('db_jobs', "renterid=$renter->id"); + foreach ($list as $job) + { + $job->active = false; + $job->ready = false; + $job->time = time(); + $job->save(); + } + + $this->goback(); + } + + ///////////////////////////////////////////////////////////////////////////////////////////// + public function actionBalance_results() + { + if (!$this->verifyparam()) return; + $this->renderPartial('balance_results'); + } + + public function actionOrders_results() + { + if (!$this->verifyparam()) return; + $this->renderPartial('orders_results'); + } + + public function actionAll_orders_results() + { + $this->renderPartial('all_orders_results'); + } + + public function actionGraph_job_results() + { + $this->renderPartial('graph_job_results'); + } + + public function actionStatus_results() + { + $this->renderPartial('status_results'); + } + + public function actionGraph_price_results() + { + $this->renderPartial('graph_price_results'); + } + + ///////////////////////////////////////////////////////////////////////////////////////////// + public function actionOrderDelete() + { + $job = getdbo('db_jobs', getiparam('id')); + if (!$job) return; + + $renter = getdbo('db_renters', $job->renterid); + if (!$renter || $renter->address != user() + ->getState('yaamp-deposit')) return; + + $job->delete(); + $this->redirect("/renting?address=$renter->address"); + } + + public function actionOrderSave() + { + $renter = getdbo('db_renters', XssFilter('' . getparam('order_renterid'))); + if (!$renter || $renter->address != user() + ->getState('yaamp-deposit')) return; + + $job = getdbo('db_jobs', XssFilter('' . getparam('order_id'))); + if (!$job) + { + $job = new db_jobs; + $job->renterid = getparam('order_renterid'); + } + + $job->algo = getparam('order_algo'); + $job->username = getparam('order_username'); + $job->password = getparam('order_password'); + $job->percent = getparam('order_percent'); + $job->price = getparam('order_price'); + $job->speed = getparam('order_speed') * 1000000; + + if (empty($job->algo) || empty($job->username) || empty($job->password) || empty($job->price) || empty($job->speed) || empty('' . getparam('order_address')) || empty('' . getparam('order_host'))) + { + $this->redirect('/renting'); + return; + } + + if ($job->speed < 100000) + { + $this->redirect('/renting'); + return; + } + + $host = str_replace('stratum+tcp://', '', getparam('order_host')); + $a = explode(':', $host); + if (!isset($a[0]) || !isset($a[1])) + { + user()->setFlash('error', "invalid server url"); + $this->redirect('/renting'); + return; + } + + $job->host = trim($a[0]); + $job->port = intval($a[1]); + + if (stripos($job->host, YAAMP_STRATUM_URL) !== false) + { + user() + ->setFlash('error', "invalid server url"); + $this->redirect('/renting'); + return; + } + + $rent = dboscalar("select rent from hashrate where algo=:algo order by time desc limit 1", array( + ':algo' => $job->algo + )); + + if ($job->price > $rent && $job->ready) $job->active = true; + + else if ($job->price < $rent) $job->active = false; + + $job->time = time(); + // $job->difficulty = null; + $job->save(); + + $this->redirect("/renting?address=" . getparam('order_address')); + } + + ///////////////////////////////////////////////////////////////////////////////////////////// + public function actionOrderDialog() + { + $renter = getrenterparam('' . getparam('address')); + if (!$renter) return; + + $a = YAAMP_DEFAULT_ALGO; + $server = ''; + $username = ''; + $password = 'xx'; + $percent = ''; + $price = ''; + $speed = ''; + $id = 0; + + $job = getdbo('db_jobs', getiparam('id')); + if ($job) + { + $id = $job->id; + $a = $job->algo; + $server = "$job->host:$job->port"; + $username = $job->username; + $password = $job->password; + $percent = $job->percent; + $price = mbitcoinvaluetoa($job->price); + $speed = $job->speed / 1000000; + } + + echo << @@ -366,16 +378,17 @@ public function actionOrderDialog() Algo: Username: @@ -384,90 +397,81 @@ public function actionOrderDialog() Max Hashrate
(Mh/s): end; - if(controller()->admin) - echo "Percent:"; - echo ""; - } + if (controller()->admin) echo "Percent:"; - ////////////////////////////////////////////////////////////////////////////////////////////////////////// + echo ""; + } - public function actionResetSpent() - { - $renter = getrenterparam(''.getparam('address')); - if(!$renter) return; + ////////////////////////////////////////////////////////////////////////////////////////////////////////// + public function actionResetSpent() + { + $renter = getrenterparam('' . getparam('address')); + if (!$renter) return; - $renter->custom_start = 0; - $renter->spent = $renter->custom_balance; + $renter->custom_start = 0; + $renter->spent = $renter->custom_balance; - $renter->save(); - $this->goback(); - } + $renter->save(); + $this->goback(); + } - public function actionWithdraw() - { - $fees = YAAMP_TXFEE_RENTING_WD; // 0.002 + public function actionWithdraw() + { + $fees = YAAMP_TXFEE_RENTING_WD; // 0.002 + $deposit = user()->getState('yaamp-deposit'); + if (!$deposit) + { + $this->render('login'); + return; + } - $deposit = user()->getState('yaamp-deposit'); - if(!$deposit) - { - $this->render('login'); - return; - } + $renter = getrenterparam($deposit); + if (!$renter) + { + $this->render('login'); + return; + } - $renter = getrenterparam($deposit); - if(!$renter) - { - $this->render('login'); - return; - } + $amount = getparam('withdraw_amount'); + $address = getparam('withdraw_address'); - $amount = getparam('withdraw_amount'); - $address = getparam('withdraw_address'); + $amount = floatval(bitcoinvaluetoa(min($amount, $renter->balance - $fees))); + if ($amount < YAAMP_PAYMENTS_MINI) // 0.001 - $amount = floatval(bitcoinvaluetoa(min($amount, $renter->balance-$fees))); - if($amount < YAAMP_PAYMENTS_MINI) // 0.001 - { - user()->setFlash('error', 'Minimum withdraw is '.YAAMP_PAYMENTS_MINI); - $this->redirect("/renting"); - return; - } + { + user()->setFlash('error', 'Minimum withdraw is ' . YAAMP_PAYMENTS_MINI); + $this->redirect("/renting"); + return; + } - $coin = getdbosql('db_coins', "symbol='BTC'"); - if(!$coin) return; + $coin = getdbosql('db_coins', "symbol='BTC'"); + if (!$coin) return; - $remote = new WalletRPC($coin); + $remote = new WalletRPC($coin); - $res = $remote->validateaddress($address); - if(!$res || !isset($res['isvalid']) || !$res['isvalid']) - { - user()->setFlash('error', 'Invalid address'); - $this->redirect("/renting"); + $res = $remote->validateaddress($address); + if (!$res || !isset($res['isvalid']) || !$res['isvalid']) + { + user()->setFlash('error', 'Invalid address'); + $this->redirect("/renting"); - return; - } + return; + } - $rentertx = new db_rentertxs; - $rentertx->renterid = $renter->id; - $rentertx->time = time(); - $rentertx->amount = $amount; - $rentertx->type = 'withdraw'; - $rentertx->address = $address; - $rentertx->tx = 'scheduled'; - $rentertx->save(); + $rentertx = new db_rentertxs; + $rentertx->renterid = $renter->id; + $rentertx->time = time(); + $rentertx->amount = $amount; + $rentertx->type = 'withdraw'; + $rentertx->address = $address; + $rentertx->tx = 'scheduled'; + $rentertx->save(); - debuglog("withdraw scheduled $renter->id $renter->address, $amount to $address"); + debuglog("withdraw scheduled $renter->id $renter->address, $amount to $address"); - user()->setFlash('message', "withdraw scheduled"); - $this->redirect("/renting"); - } + user()->setFlash('message', "withdraw scheduled"); + $this->redirect("/renting"); + } } - - - - - - - - diff --git a/web/yaamp/modules/renting/admin.php b/web/yaamp/modules/renting/admin.php index 66594f1c6..d40d6cd84 100644 --- a/web/yaamp/modules/renting/admin.php +++ b/web/yaamp/modules/renting/admin.php @@ -1,12 +1,10 @@ getState('yaamp-deposit'); echo "refresh
"; //////////////////////////////////////////////////////////////////////////////////////////////////////// - $list = getdbolist('db_rentertxs', "1 order by time desc limit 10"); -if(count($list) == 0) return; +if (count($list) == 0) return; echo ""; @@ -21,39 +19,37 @@ echo ""; echo ""; -foreach($list as $tx) +foreach ($list as $tx) { - $d = datetoa2($tx->time); - $amount = bitcoinvaluetoa($tx->amount); + $d = datetoa2($tx->time); + $amount = bitcoinvaluetoa($tx->amount); - $renter = getdbo('db_renters', $tx->renterid); - if(!$renter) continue; + $renter = getdbo('db_renters', $tx->renterid); + if (!$renter) continue; - echo ""; + echo ""; - echo ""; - echo ""; + echo ""; + echo ""; - echo ""; - echo ""; - echo ""; + echo ""; + echo ""; + echo ""; - if(strlen($tx->tx) > 32) - { - $tx_show = substr($tx->tx, 0, 36).'...'; - $txurl = "https://blockchain.info/tx/$tx->tx"; - echo ""; - } - else - echo ""; + if (strlen($tx->tx) > 32) + { + $tx_show = substr($tx->tx, 0, 36) . '...'; + $txurl = "https://blockchain.info/tx/$tx->tx"; + echo ""; + } + else echo ""; - echo ""; + echo ""; } echo "
$renter->id$renter->address$renter->id$renter->address$d ago$tx->type$amount$d ago$tx->type$amount$tx_show$tx->tx$tx_show$tx->tx

"; ///////////////////////////////////////////////////////////////////////////////////////////////////////// - echo "
"; echo ""; echo ""; @@ -69,31 +65,28 @@ echo ""; $list = getdbolist('db_renters', "balance>0 order by balance desc"); -foreach($list as $renter) +foreach ($list as $renter) { - $count = dboscalar("select count(*) from jobs where renterid=$renter->id"); - $active = dboscalar("select count(*) from jobs where renterid=$renter->id and active"); - - if($deposit == $renter->address) - echo ""; - else - echo ""; - - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; + $count = dboscalar("select count(*) from jobs where renterid=$renter->id"); + $active = dboscalar("select count(*) from jobs where renterid=$renter->id and active"); + + if ($deposit == $renter->address) echo ""; + else echo ""; + + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; } echo "
$renter->id$renter->address$renter->email$renter->spent$renter->balance$renter->unconfirmed$count$active
$renter->id$renter->address$renter->email$renter->spent$renter->balance$renter->unconfirmed$count$active
"; ///////////////////////////////////////////////////////////////////////////// - echo "
"; echo ""; echo ""; @@ -112,37 +105,33 @@ echo ""; $list = getdbolist('db_jobs', "ready"); -foreach($list as $job) +foreach ($list as $job) { - $hashrate = yaamp_job_rate($job->id); - $hashrate = $hashrate? Itoa2($hashrate).'h/s': ''; - - $speed = Itoa2($job->speed).'h/s'; - - $renter = getdbo('db_renters', $job->renterid); - if(!$renter) continue; - - if($deposit == $renter->address) - echo ""; - else - echo ""; - - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; + $hashrate = yaamp_job_rate($job->id); + $hashrate = $hashrate ? Itoa2($hashrate) . 'h/s' : ''; + + $speed = Itoa2($job->speed) . 'h/s'; + + $renter = getdbo('db_renters', $job->renterid); + if (!$renter) continue; + + if ($deposit == $renter->address) echo ""; + else echo ""; + + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; } echo "
$job->renterid$job->id$renter->address$job->algo$job->host:$job->port$job->price$speed$hashrate$job->difficulty$job->ready$job->active
$job->renterid$job->id$renter->address$job->algo$job->host:$job->port$job->price$speed$hashrate$job->difficulty$job->ready$job->active
"; echo "









"; - - diff --git a/web/yaamp/modules/renting/all_orders_results.php b/web/yaamp/modules/renting/all_orders_results.php index 249be8f84..581608be9 100644 --- a/web/yaamp/modules/renting/all_orders_results.php +++ b/web/yaamp/modules/renting/all_orders_results.php @@ -1,11 +1,12 @@ getState('yaamp-algo'); -$rent = dboscalar("select rent from hashrate where algo=:algo order by time desc limit 1", array(':algo'=>$defaultalgo)); +$rent = dboscalar("select rent from hashrate where algo=:algo order by time desc limit 1", array( + ':algo' => $defaultalgo +)); $rent = mbitcoinvaluetoa($rent); -$renter = getrenterparam(''.getparam('address')); +$renter = getrenterparam('' . getparam('address')); echo "
"; echo "
All started jobs ($defaultalgo) - Current Price $rent
"; @@ -25,55 +26,52 @@ echo ""; echo ""; -$list = getdbolist('db_jobs', "ready and algo=:algo order by price desc, time", array(':algo'=>$defaultalgo)); -foreach($list as $job) +$list = getdbolist('db_jobs', "ready and algo=:algo order by price desc, time", array( + ':algo' => $defaultalgo +)); +foreach ($list as $job) { - $hashrate_bad = yaamp_job_rate_bad($job->id); - $hashrate = yaamp_job_rate($job->id)+$hashrate_bad; - - $title_percent = ''; - if($hashrate_bad) - { - $percent = round($hashrate_bad/$hashrate*100, 1).'%'; - $hashrate_bad = Itoa2($hashrate_bad).'h/s'; + $hashrate_bad = yaamp_job_rate_bad($job->id); + $hashrate = yaamp_job_rate($job->id) + $hashrate_bad; - $title_percent = "Rejected $hashrate_bad ($percent)"; - } + $title_percent = ''; + if ($hashrate_bad) + { + $percent = round($hashrate_bad / $hashrate * 100, 1) . '%'; + $hashrate_bad = Itoa2($hashrate_bad) . 'h/s'; - $hashrate = $hashrate? Itoa2($hashrate).'h/s': ''; - $maxhash = $job->speed? Itoa2($job->speed).'h/s': ''; + $title_percent = "Rejected $hashrate_bad ($percent)"; + } - $title = controller()->admin? "-o stratum+tcp://$job->host:$job->port -u $job->username -p $job->password": ''; + $hashrate = $hashrate ? Itoa2($hashrate) . 'h/s' : ''; + $maxhash = $job->speed ? Itoa2($job->speed) . 'h/s' : ''; - $servername = substr($job->host, 0, 22); - $price = mbitcoinvaluetoa($job->price); + $title = controller()->admin ? "-o stratum+tcp://$job->host:$job->port -u $job->username -p $job->password" : ''; - $diff = $job->difficulty>0? round($job->difficulty, 3): ''; - $d = datetoa2($job->time); + $servername = substr($job->host, 0, 22); + $price = mbitcoinvaluetoa($job->price); - if($job->active) - echo ""; - else - echo ""; + $diff = $job->difficulty > 0 ? round($job->difficulty, 3) : ''; + $d = datetoa2($job->time); - if($renter && $renter->id == $job->renterid) - echo "$job->host"; - else - echo ""; + if ($job->active) echo ""; + else echo ""; -// echo "$d"; -// echo "$job->algo"; + if ($renter && $renter->id == $job->renterid) echo "$job->host"; + else echo ""; - echo "$price"; - echo "$maxhash"; - echo "$hashrate"; - echo "$diff"; - echo ""; + // echo "$d"; + // echo "$job->algo"; + echo "$price"; + echo "$maxhash"; + echo "$hashrate"; + echo "$diff"; + echo ""; - $style_ext = ''; //$job->active? 'background-color: #dfd;': ''; - echo ""; - echo "
"; - echo ""; + $style_ext = ''; //$job->active? 'background-color: #dfd;': ''; + echo ""; + echo "
"; + echo ""; } echo ""; @@ -85,11 +83,3 @@ echo "
"; echo "

"; - - - - - - - - diff --git a/web/yaamp/modules/renting/balance_results.php b/web/yaamp/modules/renting/balance_results.php index 66f99e3a9..39323bd4a 100644 --- a/web/yaamp/modules/renting/balance_results.php +++ b/web/yaamp/modules/renting/balance_results.php @@ -1,14 +1,12 @@ "; echo "
Deposit $renter->address
"; echo "
"; -if(!YAAMP_RENTAL) - echo "

Renting is temporarily disabled.

"; +if (!YAAMP_RENTAL) echo "

Renting is temporarily disabled.

"; echo ""; @@ -19,38 +17,36 @@ echo ""; echo ""; -if($renter->balance>=0.001) - echo ""; -else if($renter->balance>0) - echo ""; +if ($renter->balance >= 0.001) echo ""; +else if ($renter->balance > 0) echo ""; echo ""; -if($unconfirmed > 0) +if ($unconfirmed > 0) { - echo ""; + echo ""; } -if(controller()->admin) +if (controller()->admin) { - echo " + echo ""; - if($renter->id == 7) - { -// $balance = $renter->custom_balance - $renter->custom_start; - $profit = $renter->custom_start + $renter->custom_balance - $spent; + if ($renter->id == 7) + { + // $balance = $renter->custom_balance - $renter->custom_start; + $profit = $renter->custom_start + $renter->custom_balance - $spent; - $start = bitcoinvaluetoa($renter->custom_start); - $balance = bitcoinvaluetoa($renter->custom_balance); - $profit = bitcoinvaluetoa($profit); + $start = bitcoinvaluetoa($renter->custom_start); + $balance = bitcoinvaluetoa($renter->custom_balance); + $profit = bitcoinvaluetoa($profit); - echo ""; - echo ""; - echo ""; - } + echo ""; + echo ""; + echo ""; + } } echo "
Deposit Address$renter->address
Balance$balance BTC(withdraw minimum 0.001)(withdraw minimum 0.001)
Unconfirmed$unconfirmed BTC"; - echo " (waiting for 1 confirmation)"; - echo "
Unconfirmed$unconfirmed BTC"; + echo " (waiting for 1 confirmation)"; + echo "
Spent$spent BTC
Spent$spent BTC
Received$start BTC
Unpaid$balance BTC
Profit$profit BTC
Received$start BTC
Unpaid$balance BTC
Profit$profit BTC

"; @@ -61,9 +57,8 @@ echo "

"; //////////////////////////////////////////////////////////////////////////////////////////////////////// - $list = getdbolist('db_rentertxs', "renterid=$renter->id order by time desc limit 5"); -if(count($list) == 0) return; +if (count($list) == 0) return; echo "
"; echo "
Last 5 transactions $renter->address
"; @@ -80,36 +75,29 @@ echo ""; echo ""; -foreach($list as $tx) +foreach ($list as $tx) { - $d = datetoa2($tx->time); - $amount = bitcoinvaluetoa($tx->amount); + $d = datetoa2($tx->time); + $amount = bitcoinvaluetoa($tx->amount); - echo ""; + echo ""; - echo "$d ago"; - echo "$tx->type"; - echo "$amount"; + echo "$d ago"; + echo "$tx->type"; + echo "$amount"; - if(strlen($tx->tx) > 32) - { - $tx_show = substr($tx->tx, 0, 36).'...'; - $txurl = "https://blockchain.info/tx/$tx->tx"; - echo "$tx_show"; - } - else - echo "$tx->tx"; + if (strlen($tx->tx) > 32) + { + $tx_show = substr($tx->tx, 0, 36) . '...'; + $txurl = "https://blockchain.info/tx/$tx->tx"; + echo "$tx_show"; + } + else echo "$tx->tx"; - echo ""; + echo ""; } echo "
"; echo "
"; echo "
"; - - - - - - diff --git a/web/yaamp/modules/renting/create.php b/web/yaamp/modules/renting/create.php index 55de45f0a..446dd8bac 100644 --- a/web/yaamp/modules/renting/create.php +++ b/web/yaamp/modules/renting/create.php @@ -1,23 +1,22 @@ redirect('/renting'); - return; + controller()->redirect('/renting'); + return; } -$captcha = new CCaptchaAction(controller(), 'captcha'); +$captcha = new CCaptchaAction(controller() , 'captcha'); $b = $captcha->validate($code, false); -if(!$b) +if (!$b) { - controller()->redirect('/renting'); - return; + controller()->redirect('/renting'); + return; } // get a new btc address $btc = getdbosql('db_coins', "symbol='BTC'"); -if(!$btc) return; +if (!$btc) return; $remote = new WalletRPC($btc); $renter = new db_renters; @@ -31,24 +30,23 @@ $renter = getdbo('db_renters', $renter->id); $renter->address = $remote->getaccountaddress(yaamp_renter_account($renter)); -$renter->apikey = hash("sha256", $renter->address.time().rand()); +$renter->apikey = hash("sha256", $renter->address . time() . rand()); $renter->save(); -$received1 = $remote->getbalance(yaamp_renter_account($renter), 1); -if($received1>0) +$received1 = $remote->getbalance(yaamp_renter_account($renter) , 1); +if ($received1 > 0) { - $moved = $remote->move(yaamp_renter_account($renter), '', $received1); - debuglog("create new renter, moving initial $received1"); + $moved = $remote->move(yaamp_renter_account($renter) , '', $received1); + debuglog("create new renter, moving initial $received1"); } -$raw_recents = isset($_COOKIE['deposits'])? explode("|", $_COOKIE['deposits']): array(); +$raw_recents = isset($_COOKIE['deposits']) ? explode("|", $_COOKIE['deposits']) : array(); $recents = array(); -foreach($raw_recents as $addr) $recents[$addr] = $addr; -$recents[$renter->address] = $renter->address; -setcookie('deposits', implode("|", $recents), time()+60*60*24*30, '/'); +foreach ($raw_recents as $addr) $recents[$addr] = $addr; +$recents[$renter + ->address] = $renter->address; +setcookie('deposits', implode("|", $recents) , time() + 60 * 60 * 24 * 30, '/'); user()->setState('yaamp-deposit', $renter->address); -controller()->redirect('settings'); - - - +controller() + ->redirect('settings'); diff --git a/web/yaamp/modules/renting/graph_job_results.php b/web/yaamp/modules/renting/graph_job_results.php index 6005ee984..cf88055bc 100644 --- a/web/yaamp/modules/renting/graph_job_results.php +++ b/web/yaamp/modules/renting/graph_job_results.php @@ -1,74 +1,79 @@ $t and jobid=:jobid order by time", array(':jobid'=>$jobid)); +$stats = getdbolist('db_hashrenter', "time>$t and jobid=:jobid order by time", array( + ':jobid' => $jobid +)); $averages = array(); echo '[['; -for($i = $t+$step, $j = 0; $i < time(); $i += $step) +for ($i = $t + $step, $j = 0;$i < time();$i += $step) { - if($i != $t+$step) echo ','; - $m = 0; + if ($i != $t + $step) echo ','; + $m = 0; + + if ($i + $step >= time()) + { + $m = round(yaamp_job_rate($jobid) / 1000000, 3); + // debuglog("last $m"); - if($i + $step >= time()) - { - $m = round(yaamp_job_rate($jobid)/1000000, 3); - // debuglog("last $m"); - } + } - else if(isset($stats[$j]) && $i > $stats[$j]->time) - { - $m = round($stats[$j]->hashrate/1000000, 3); - $j++; - } + else if (isset($stats[$j]) && $i > $stats[$j]->time) + { + $m = round($stats[$j]->hashrate / 1000000, 3); + $j++; + } - $d = date('Y-m-d H:i:s', $i); - echo "[\"$d\",$m]"; + $d = date('Y-m-d H:i:s', $i); + echo "[\"$d\",$m]"; - $averages[] = array($d, $m); + $averages[] = array( + $d, + $m + ); } echo '],['; $average = $averages[0][1]; -foreach($averages as $i=>$n) +foreach ($averages as $i => $n) { - if($i) echo ','; + if ($i) echo ','; - $average = ($average*(100-$percent) + $n[1]*$percent) / 100; - $m = round($average, 3); + $average = ($average * (100 - $percent) + $n[1] * $percent) / 100; + $m = round($average, 3); - echo "[\"{$n[0]}\",$m]"; + echo "[\"{$n[0]}\",$m]"; } echo '],['; -for($i = $t+$step, $j = 0; $i < time(); $i += $step) +for ($i = $t + $step, $j = 0;$i < time();$i += $step) { - if($i != $t+$step) echo ','; - $m = 0; - - if($i + $step >= time()) - { - $m = round(yaamp_user_rate_bad($jobid)/1000000, 3); - // debuglog("last $m"); - } - - else if(isset($stats[$j]) && $i > $stats[$j]->time) - { - $m = round($stats[$j]->hashrate_bad/1000000, 3); - $j++; - } - - $d = date('Y-m-d H:i:s', $i); - echo "[\"$d\",$m]"; + if ($i != $t + $step) echo ','; + $m = 0; + + if ($i + $step >= time()) + { + $m = round(yaamp_user_rate_bad($jobid) / 1000000, 3); + // debuglog("last $m"); + + } + + else if (isset($stats[$j]) && $i > $stats[$j]->time) + { + $m = round($stats[$j]->hashrate_bad / 1000000, 3); + $j++; + } + + $d = date('Y-m-d H:i:s', $i); + echo "[\"$d\",$m]"; } echo ']]'; - diff --git a/web/yaamp/modules/renting/graph_price_results.php b/web/yaamp/modules/renting/graph_price_results.php index 1b696fd69..d226ad0b4 100644 --- a/web/yaamp/modules/renting/graph_price_results.php +++ b/web/yaamp/modules/renting/graph_price_results.php @@ -1,54 +1,55 @@ getState('yaamp-algo'); -$step = 15*60; -$t = time() - 24*60*60; +$step = 15 * 60; +$t = time() - 24 * 60 * 60; -$stats = getdbolist('db_hashrate', "time>$t and algo=:algo order by time", array(':algo'=>$algo)); +$stats = getdbolist('db_hashrate', "time>$t and algo=:algo order by time", array( + ':algo' => $algo +)); $averages = array(); echo '[['; -for($i = 0; $i < 95-count($stats); $i++) +for ($i = 0;$i < 95 - count($stats);$i++) { - $d = date('Y-m-d H:i:s', $t); - echo "[\"$d\",0],"; - - $t += $step; - $averages[] = array($d, 0); + $d = date('Y-m-d H:i:s', $t); + echo "[\"$d\",0],"; + + $t += $step; + $averages[] = array( + $d, + 0 + ); } -foreach($stats as $i=>$n) +foreach ($stats as $i => $n) { - $m = $n->rent; - if($m == null) $m=0; - if($i) echo ','; + $m = $n->rent; + if ($m == null) $m = 0; + if ($i) echo ','; - $d = date('Y-m-d H:i:s', $n->time); - echo "[\"$d\",$m]"; + $d = date('Y-m-d H:i:s', $n->time); + echo "[\"$d\",$m]"; - $averages[] = array($d, $m); + $averages[] = array( + $d, + $m + ); } echo '],['; $average = $averages[0][1]; -foreach($averages as $i=>$n) +foreach ($averages as $i => $n) { - if($i) echo ','; + if ($i) echo ','; - $average = ($average*(100-$percent) + $n[1]*$percent) / 100; - $m = round($average, 5); + $average = ($average * (100 - $percent) + $n[1] * $percent) / 100; + $m = round($average, 5); - echo "[\"{$n[0]}\",$m]"; + echo "[\"{$n[0]}\",$m]"; } echo ']]'; - - - - - - diff --git a/web/yaamp/modules/renting/index.php b/web/yaamp/modules/renting/index.php index 7cb068895..8292ea233 100644 --- a/web/yaamp/modules/renting/index.php +++ b/web/yaamp/modules/renting/index.php @@ -1,5 +1,4 @@ getState('yaamp-algo'); JavascriptFile("/extensions/jqplot/jquery.jqplot.js"); @@ -306,13 +305,3 @@ function yaamp_withdraw() END; - - - - - - - - - - diff --git a/web/yaamp/modules/renting/login.php b/web/yaamp/modules/renting/login.php index e7ad453a4..c1f646a09 100644 --- a/web/yaamp/modules/renting/login.php +++ b/web/yaamp/modules/renting/login.php @@ -1,5 +1,4 @@ getState('yaamp-algo'); JavascriptFile("/extensions/jqplot/jquery.jqplot.js"); @@ -12,9 +11,10 @@ $this->widget('UniForm'); $address = getparam('address'); -if($address == 0) $address = ''; -if (!empty($address) && preg_match('/[^A-Za-z0-9]/', $address)) { - die; +if ($address == 0) $address = ''; +if (!empty($address) && preg_match('/[^A-Za-z0-9]/', $address)) +{ + die; } echo <<Renting is temporarily disabled.

"; + +if (!YAAMP_RENTAL) echo "

Renting is temporarily disabled.

"; echo <<You need to login to access the renting area.

@@ -60,27 +60,28 @@ end; -$recents = isset($_COOKIE['deposits'])? explode("|", $_COOKIE['deposits']): array(); -if(controller()->admin || sizeof($recents) < 10) - echo ""; +$recents = isset($_COOKIE['deposits']) ? explode("|", $_COOKIE['deposits']) : array(); + +if (controller()->admin || sizeof($recents) < 10) echo ""; echo "

"; echo ""; -foreach($recents as $address) +foreach ($recents as $address) { - if(empty($address)) continue; - - $renter = getdbosql('db_renters', "address=:address", array(':address'=>$address)); - if(!$renter) continue; -// debuglog($address); - - echo ""; - echo ""; + if (empty($address)) continue; + + $renter = getdbosql('db_renters', "address=:address", array( + ':address' => $address + )); + if (!$renter) continue; + // debuglog($address); + echo ""; + echo ""; } echo "
"; - echo ""; - echo "$address
"; + echo ""; + echo "$address

"; @@ -233,10 +234,3 @@ function deposit_create() end; - - - - - - - diff --git a/web/yaamp/modules/renting/orders_results.php b/web/yaamp/modules/renting/orders_results.php index fe7c4d43a..3f4b99321 100644 --- a/web/yaamp/modules/renting/orders_results.php +++ b/web/yaamp/modules/renting/orders_results.php @@ -1,7 +1,6 @@ "; echo "
Jobs $renter->address
"; @@ -24,88 +23,81 @@ echo ""; $list = getdbolist('db_jobs', "renterid=$renter->id order by algo, price desc"); -foreach($list as $job) +foreach ($list as $job) { - $hashrate_bad = yaamp_job_rate_bad($job->id); - $hashrate = yaamp_job_rate($job->id)+$hashrate_bad; + $hashrate_bad = yaamp_job_rate_bad($job->id); + $hashrate = yaamp_job_rate($job->id) + $hashrate_bad; - $title_percent = ''; - if($hashrate_bad) - { - $percent = 100; - if ($hashrate) - $percent = round($hashrate_bad/$hashrate * 100, 1).'%'; - $hashrate_bad = Itoa2($hashrate_bad).'h/s'; + $title_percent = ''; + if ($hashrate_bad) + { + $percent = 100; + if ($hashrate) $percent = round($hashrate_bad / $hashrate * 100, 1) . '%'; + $hashrate_bad = Itoa2($hashrate_bad) . 'h/s'; - $title_percent = "Rejected $hashrate_bad ($percent)"; - } + $title_percent = "Rejected $hashrate_bad ($percent)"; + } - $hashrate = $hashrate? Itoa2($hashrate).'h/s': ''; + $hashrate = $hashrate ? Itoa2($hashrate) . 'h/s' : ''; - $maxhash = $job->speed? Itoa2($job->speed).'h/s': ''; - $title = "-o stratum+tcp://$job->host:$job->port -u $job->username -p $job->password"; + $maxhash = $job->speed ? Itoa2($job->speed) . 'h/s' : ''; + $title = "-o stratum+tcp://$job->host:$job->port -u $job->username -p $job->password"; - $servername = substr($job->host, 0, 22); - $price = mbitcoinvaluetoa($job->price); + $servername = substr($job->host, 0, 22); + $price = mbitcoinvaluetoa($job->price); - $rent = dboscalar("select rent from hashrate where algo=:algo order by time desc limit 1", array(':algo'=>$job->algo)); - $rent = mbitcoinvaluetoa($rent); + $rent = dboscalar("select rent from hashrate where algo=:algo order by time desc limit 1", array( + ':algo' => $job->algo + )); + $rent = mbitcoinvaluetoa($rent); - $diff = $job->difficulty>0? round($job->difficulty, 3): ''; + $diff = $job->difficulty > 0 ? round($job->difficulty, 3) : ''; - if($job->active) - echo ""; - else - echo ""; + if ($job->active) echo ""; + else echo ""; - echo " + echo " "; - $p = $job->percent? "($job->percent%)": ''; - - echo "$servername"; - echo "$job->algo"; - echo "$price $p"; -// echo "$rent"; - echo "$maxhash"; - echo "$hashrate"; - echo "$diff"; + $p = $job->percent ? "($job->percent%)" : ''; - echo ""; + echo "$servername"; + echo "$job->algo"; + echo "$price $p"; + // echo "$rent"; + echo "$maxhash"; + echo "$hashrate"; + echo "$diff"; - if(YAAMP_RENTAL) - { - if($job->ready) - echo ""; - else - echo ""; - } + echo ""; - echo "  "; - echo ""; + if (YAAMP_RENTAL) + { + if ($job->ready) echo ""; + else echo ""; + } - echo ""; + echo "  "; + echo ""; - $style_ext = ''; //$job->active? 'background-color: #dfd;': ''; + echo ""; - echo ""; - echo "
"; - echo ""; + $style_ext = ''; //$job->active? 'background-color: #dfd;': ''; + echo ""; + echo "
"; + echo ""; } echo ""; -if(count($list) > 20 && !controller()->admin) - ; -else if($renter->balance > 0) - echo "
"; -else - echo "

You have to fund your account by sending bitcoin to your deposit address before you can start creating mining jobs.

"; +if (count($list) > 20 && !controller()->admin); +else if ($renter->balance > 0) echo "
"; +else echo "

You have to fund your account by sending bitcoin to your deposit address before you can start creating mining jobs.

"; -if(YAAMP_RENTAL) +if (YAAMP_RENTAL) { -echo " "; -echo " "; + echo " "; + echo " "; } echo "

"; @@ -126,7 +118,3 @@ echo "
"; echo "
"; - - - - diff --git a/web/yaamp/modules/renting/settings.php b/web/yaamp/modules/renting/settings.php index 67225852b..4ba7098d5 100644 --- a/web/yaamp/modules/renting/settings.php +++ b/web/yaamp/modules/renting/settings.php @@ -1,5 +1,4 @@ getState('yaamp-algo'); JavascriptFile("/extensions/jqplot/jquery.jqplot.js"); @@ -12,7 +11,7 @@ $this->widget('UniForm'); $renter = getrenterparam(user()->getState('yaamp-deposit')); -if(!$renter) return; +if (!$renter) return; echo << @@ -149,8 +148,3 @@ function graph_init_price(data) end; - - - - - diff --git a/web/yaamp/modules/renting/status_results.php b/web/yaamp/modules/renting/status_results.php index d9fa8cc14..184d1c2c9 100644 --- a/web/yaamp/modules/renting/status_results.php +++ b/web/yaamp/modules/renting/status_results.php @@ -1,5 +1,4 @@ getState('yaamp-algo'); echo "
"; @@ -23,68 +22,79 @@ echo ""; $algos = array(); -foreach(yaamp_get_algos() as $algo) +foreach (yaamp_get_algos() as $algo) { - $algo_norm = yaamp_get_algo_norm($algo); + $algo_norm = yaamp_get_algo_norm($algo); - $price = controller()->memcache->get_database_scalar("current_price-$algo", - "select price from hashrate where algo=:algo order by time desc limit 1", array(':algo'=>$algo)); + $price = controller() + ->memcache + ->get_database_scalar("current_price-$algo", "select price from hashrate where algo=:algo order by time desc limit 1", array( + ':algo' => $algo + )); - $norm = $price*$algo_norm; - $norm = take_yaamp_fee($norm, $algo); + $norm = $price * $algo_norm; + $norm = take_yaamp_fee($norm, $algo); - $algos[] = array($norm, $algo); + $algos[] = array( + $norm, + $algo + ); } function cmp($a, $b) { - return $a[0] < $b[0]; + return $a[0] < $b[0]; } usort($algos, 'cmp'); -foreach($algos as $item) +foreach ($algos as $item) { - $norm = $item[0]; - $algo = $item[1]; - - $count1 = getdbocount('db_jobs', "algo=:algo and ready and active", array(':algo'=>$algo)); - $count2 = getdbocount('db_jobs', "algo=:algo and ready", array(':algo'=>$algo)); - - $total = yaamp_pool_rate($algo); - $hashrate = yaamp_pool_rate_rentable($algo); - $hashrate_jobs = yaamp_rented_rate($algo); - - $hashrate = min($total, $hashrate); - $hashrate_jobs = min($hashrate, $hashrate_jobs); - - $available = $hashrate - $hashrate_jobs; - $percent = $hashrate_jobs && $hashrate? '('.round($hashrate_jobs/$hashrate*100, 1).'%)': ''; - - $hashrate_jobs = $hashrate_jobs>0? Itoa2($hashrate_jobs).'h/s': ''; - $available = $available>0? Itoa2($available).'h/s': ''; - $hashrate = $hashrate>0? Itoa2($hashrate).'h/s': ''; - $total = $total>0? Itoa2($total).'h/s': ''; - - $renting = controller()->memcache->get_database_scalar("current_renting-$algo", - "select rent from hashrate where algo=:algo order by time desc limit 1", array(':algo'=>$algo)); - $renting = mbitcoinvaluetoa($renting); - - if($defaultalgo == $algo) - echo ""; - else - echo ""; - - echo "$algo"; - echo "$count1 / $count2"; -// echo "$total"; - echo "$hashrate"; - echo "$hashrate_jobs"; - echo "$percent"; - echo "$available"; -// echo "$price"; - echo "$renting"; - echo ""; + $norm = $item[0]; + $algo = $item[1]; + + $count1 = getdbocount('db_jobs', "algo=:algo and ready and active", array( + ':algo' => $algo + )); + $count2 = getdbocount('db_jobs', "algo=:algo and ready", array( + ':algo' => $algo + )); + + $total = yaamp_pool_rate($algo); + $hashrate = yaamp_pool_rate_rentable($algo); + $hashrate_jobs = yaamp_rented_rate($algo); + + $hashrate = min($total, $hashrate); + $hashrate_jobs = min($hashrate, $hashrate_jobs); + + $available = $hashrate - $hashrate_jobs; + $percent = $hashrate_jobs && $hashrate ? '(' . round($hashrate_jobs / $hashrate * 100, 1) . '%)' : ''; + + $hashrate_jobs = $hashrate_jobs > 0 ? Itoa2($hashrate_jobs) . 'h/s' : ''; + $available = $available > 0 ? Itoa2($available) . 'h/s' : ''; + $hashrate = $hashrate > 0 ? Itoa2($hashrate) . 'h/s' : ''; + $total = $total > 0 ? Itoa2($total) . 'h/s' : ''; + + $renting = controller() + ->memcache + ->get_database_scalar("current_renting-$algo", "select rent from hashrate where algo=:algo order by time desc limit 1", array( + ':algo' => $algo + )); + $renting = mbitcoinvaluetoa($renting); + + if ($defaultalgo == $algo) echo ""; + else echo ""; + + echo "$algo"; + echo "$count1 / $count2"; + // echo "$total"; + echo "$hashrate"; + echo "$hashrate_jobs"; + echo "$percent"; + echo "$available"; + // echo "$price"; + echo "$renting"; + echo ""; } echo ""; @@ -95,9 +105,3 @@ function cmp($a, $b)

"; echo "

"; - - - - - - diff --git a/web/yaamp/modules/renting/tx.php b/web/yaamp/modules/renting/tx.php index 28eea68ad..cc21df2a3 100644 --- a/web/yaamp/modules/renting/tx.php +++ b/web/yaamp/modules/renting/tx.php @@ -1,9 +1,8 @@ pageTitle = "$renter->address | yiimp"; @@ -22,44 +21,41 @@ echo ""; $btc = getdbosql('db_coins', "symbol='BTC'"); -if(!$btc) return; +if (!$btc) return; $remote = new WalletRPC($btc); -$ts = $remote->listtransactions(yaamp_renter_account($renter), 10); +$ts = $remote->listtransactions(yaamp_renter_account($renter) , 10); $res_array = array(); -foreach($ts as $val) +foreach ($ts as $val) { - $t = $val['time']; - if($t<$renter->created) continue; - $res_array[$t] = $val; + $t = $val['time']; + if ($t < $renter->created) continue; + $res_array[$t] = $val; } krsort($res_array); $total = 0; -foreach($res_array as $transaction) +foreach ($res_array as $transaction) { - if($transaction['category'] != 'receive') continue; - $d = datetoa2($transaction['time']); + if ($transaction['category'] != 'receive') continue; + $d = datetoa2($transaction['time']); - echo ""; - echo "$d"; - echo "{$transaction['amount']}"; + echo ""; + echo "$d"; + echo "{$transaction['amount']}"; - if(isset($transaction['confirmations'])) - echo "{$transaction['confirmations']}"; - else - echo ""; + if (isset($transaction['confirmations'])) echo "{$transaction['confirmations']}"; + else echo ""; - echo ""; - if(isset($transaction['txid'])) - echo "{$transaction['txid']}"; + echo ""; + if (isset($transaction['txid'])) echo "{$transaction['txid']}"; - echo ""; - echo ""; + echo ""; + echo ""; - $total += $transaction['amount']; + $total += $transaction['amount']; } echo ""; @@ -68,7 +64,3 @@ echo "
"; echo "
"; - - - - diff --git a/web/yaamp/modules/site/SiteController.php b/web/yaamp/modules/site/SiteController.php index 80cf6a54c..7f87b6017 100644 --- a/web/yaamp/modules/site/SiteController.php +++ b/web/yaamp/modules/site/SiteController.php @@ -2,1194 +2,1309 @@ class SiteController extends CommonController { - public $defaultAction='index'; - - /////////////////////////////////////////////////// - // Security Note: You can rename this action as you - // want, to customize the admin entrance url... - // - public function actionAdminRights() - { - $client_ip = arraySafeVal($_SERVER,'REMOTE_ADDR'); - $valid = isAdminIP($client_ip); - - if (arraySafeVal($_SERVER,'HTTP_X_FORWARDED_FOR','') != '') { - debuglog("admin access attempt via IP spoofing!"); - $valid = false; - } - - if ($valid) - debuglog("admin connect from $client_ip"); - else - debuglog("admin connect failure from $client_ip"); - - user()->setState('yaamp_admin', $valid); - - $this->redirect("/site/common"); - } - - ///////////////////////////////////////////////// - - public function actionCreate() - { - if(!$this->admin) return; - - $coin = new db_coins; - $coin->txmessage = true; - $coin->created = time(); - $coin->index_avg = 1; - $coin->difficulty = 1; - $coin->installed = 1; - $coin->visible = 1; - - // $coin->deposit_minimum = 1; - $coin->lastblock = ''; - - if(isset($_POST['db_coins'])) - { - $coin->setAttributes($_POST['db_coins'], false); - if($coin->save()) - $this->redirect(array('admin')); - } - - $this->render('coin_form', array('update'=>false, 'coin'=>$coin)); - } - - public function actionUpdate() - { - if(!$this->admin) return; - $coin = getdbo('db_coins', getiparam('id')); - $txfee = $coin->txfee; - - if($coin && isset($_POST['db_coins'])) - { - $coin->setScenario('update'); - $coin->setAttributes($_POST['db_coins'], false); - - if($coin->save()) - { - if($txfee != $coin->txfee) - { - $remote = new WalletRPC($coin); - $remote->settxfee($coin->txfee); - } - $this->redirect(array('coin', 'id'=>$coin->id)); - // $this->goback(); - } - } - - $this->render('coin_form', array('update'=>true, 'coin'=>$coin)); - } - - ///////////////////////////////////////////////// - - public function actionPeers() - { - if(!$this->admin) return; - $coin = getdbo('db_coins', getiparam('id')); - if (!$coin) { - $this->goback(); - } - - $this->render('coin_peers', array('coin'=>$coin)); - } - - public function actionPeerRemove() - { - if(!$this->admin) return; - $coin = getdbo('db_coins', getiparam('id')); - $node = getparam('node'); - if ($coin && $node) { - $remote = new WalletRPC($coin); - if ($coin->rpcencoding == 'DCR') { - $res = $remote->node('disconnect', $node); - if (!$res) $res = $remote->node('remove', $node); - $remote->error = false; // ignore - } else { - $res = $remote->addnode($node, 'remove'); - } - if (!$res && $remote->error) { - user()->setFlash('error', "$node ".$remote->error); - } - } - $this->goback(); - } - - public function actionPeerAdd() - { - if(!$this->admin) return; - $coin = getdbo('db_coins', getiparam('id')); - $node = arraySafeVal($_POST, 'node'); - if ($coin && $node) { - $remote = new WalletRPC($coin); - if ($coin->rpcencoding == 'DCR') { - $remote->addnode($node, 'add'); - usleep(500*1000); - $remote->node('connect', $node); - sleep(1); - } else { - $res = $remote->addnode($node, 'add'); - if (!$res) { - user()->setFlash('error', "$node ".$remote->error); - } else { - sleep(1); - } - } - } - $this->goback(); - } - - ///////////////////////////////////////////////// - - public function actionTickets() - { - if(!$this->admin) return; - $coin = getdbo('db_coins', getiparam('id')); - if (!$coin) { - $this->goback(); - } - - $this->render('coin_tickets', array('coin'=>$coin)); - } - - public function actionTicketBuy() - { - if(!$this->admin) return; - $coin = getdbo('db_coins', getiparam('id')); - $spendlimit = (double) arraySafeVal($_POST, 'spendlimit'); - $quantity = (int) arraySafeVal($_POST, 'quantity'); - if ($coin && $spendlimit) { - $remote = new WalletRPC($coin); - if ($quantity <= 1) - $res = $remote->purchaseticket($coin->account, $spendlimit); - else - $res = $remote->purchaseticket($coin->account, $spendlimit, 1, $coin->master_wallet, $quantity); - if ($res === false) - user()->setFlash('error', $remote->error); - else - user()->setFlash('message', is_string($res) ? "ticket txid: $res" : json_encode($res)); - } - $this->goback(); - } - - ///////////////////////////////////////////////// - - public function actionBookmarkAdd() - { - if(!$this->admin) return; - $coin = getdbo('db_coins', getiparam('id')); - if ($coin) { - $bookmark = new db_bookmarks; - $bookmark->isNewRecord = true; - $bookmark->idcoin = $coin->id; - if (isset($_POST['db_bookmarks'])) { - $bookmark->setAttributes($_POST['db_bookmarks'], false); - if($bookmark->save()) - $this->redirect(array('/site/coin', 'id'=>$coin->id)); - } - $this->render('bookmark', array('bookmark'=>$bookmark, 'coin'=>$coin)); - } else { - $this->goback(); - } - } - - public function actionBookmarkDel() - { - if(!$this->admin) return; - $bookmark = getdbo('db_bookmarks', getiparam('id')); - if ($bookmark) { - $bookmark->delete(); - } - $this->goback(); - } - - public function actionBookmarkEdit() - { - if(!$this->admin) return; - $bookmark = getdbo('db_bookmarks', getiparam('id')); - if($bookmark) { - $coin = getdbo('db_coins', $bookmark->idcoin); - if ($coin && isset($_POST['db_bookmarks'])) { - $bookmark->setAttributes($_POST['db_bookmarks'], false); - if($bookmark->save()) - $this->redirect(array('/site/coin', 'id'=>$coin->id)); - } - $this->render('bookmark', array('bookmark'=>$bookmark, 'coin'=>$coin)); - } else { - user()->setFlash('error', "invalid bookmark"); - $this->goback(); - } - } - - public function actionBookmarkSend() - { - if(!$this->admin) return; - - $bookmark = getdbo('db_bookmarks', getiparam('id')); - if($bookmark) { - $coin = getdbo('db_coins', $bookmark->idcoin); - $amount = getparam('amount'); - - $remote = new WalletRPC($coin); - - $info = $remote->getinfo(); - if(!$info || !$info['balance']) return false; - - $deposit_info = $remote->validateaddress($bookmark->address); - if(!$deposit_info || !isset($deposit_info['isvalid']) || !$deposit_info['isvalid']) { - user()->setFlash('error', "invalid address for {$coin->name}, {$bookmark->address}"); - $this->redirect(array('site/coin', 'id'=>$coin->id)); - } - - $amount = min($amount, $info['balance'] - $info['paytxfee']); - $amount = round($amount, 8); - - $tx = $remote->sendtoaddress($bookmark->address, $amount); - if(!$tx) { - debuglog("unable to send $amount {$coin->symbol} to bookmark {$bookmark->address}"); - debuglog($remote->error); - user()->setFlash('error', $remote->error); - $this->redirect(array('site/coin', 'id'=>$coin->id)); - } else { - debuglog("sent $amount {$coin->symbol} to bookmark {$bookmark->address}"); - $bookmark->lastused = time(); - $bookmark->save(); - BackendUpdatePoolBalances($coin->id); - } - } - - $this->redirect(array('site/coin', 'id'=>$coin->id)); - } - - ///////////////////////////////////////////////// - - public function actionConsole() - { - if(!$this->admin || !YAAMP_ADMIN_WEBCONSOLE) return; - $coin = getdbo('db_coins', getiparam('id')); - if (!$coin) { - $this->goback(); - } - - $this->render('coin_console', array( - 'coin'=>$coin, - 'query'=>arraySafeVal($_POST,'query'), - )); - } - - ///////////////////////////////////////////////// - - public function actionTriggers() - { - if(!$this->admin) return; - $coin = getdbo('db_coins', getiparam('id')); - if (!$coin) { - $this->goback(); - } - - $this->render('coin_triggers', array( - 'coin'=>$coin, - )); - } - - public function actionTriggerEnable() - { - if(!$this->admin) return; - $rule = getdbo('db_notifications', getiparam('id')); - if ($rule) { - $rule->enabled = (int) getiparam('en'); - $rule->save(); - } - - $this->goback(); - } - - public function actionTriggerReset() - { - if(!$this->admin) return; - $rule = getdbo('db_notifications', getiparam('id')); - if ($rule) { - $rule->lasttriggered = 0; - $rule->save(); - } - - $this->goback(); - } - - public function actionTriggerDel() - { - if(!$this->admin) return; - $rule = getdbo('db_notifications', getiparam('id')); - if ($rule) { - $rule->delete(); - } - - $this->goback(); - } - - public function actionTriggerAdd() - { - if(!$this->admin) return; - $coin = getdbo('db_coins', getiparam('id')); - if (!$coin) { - $this->goback(); - } - - $valid = true; - $rule = new db_notifications; - $rule->idcoin = $coin->id; - $rule->notifytype = $_POST['notifytype']; - $rule->conditiontype = $_POST['conditiontype']; - $rule->conditionvalue = $_POST['conditionvalue']; - $rule->notifycmd = $_POST['notifycmd']; - $rule->description = $_POST['description']; - $rule->enabled = 1; - $rule->lastchecked = 0; // time - $rule->lasttriggered = 0; - - $words = explode(' ', $rule->conditiontype); - if (count($words) < 2) { - user()->setFlash('error', "missing space in condition, sample : 'balance <' 5"); - $valid = false; - } - if ($valid) { - $rule->save(); - } - - $this->goback(); - } - - ///////////////////////////////////////////////// - - public function actionBotnets() - { - if(!$this->admin) return; - - $this->render('botnets'); - } - - ///////////////////////////////////////////////// - - public function actionIndex() - { - if(isset($_GET['address'])) - $this->render('wallet'); - else - $this->render('index'); - } - - public function actionApi() - { - $this->render('api'); - } - - public function actionBenchmarks() - { - $this->render('benchmarks'); - } - - public function actionDiff() - { - $this->render('diff'); - } - - public function actionMultialgo() - { - $this->render('multialgo'); - } - - public function actionMining() - { - $this->render('mining'); - } - - public function actionMiners() - { - $this->render('miners'); - } - - ///////////////////////////////// - - protected function renderPartialAlgoMemcached($partial, $cachetime=15) - { - $algo = user()->getState('yaamp-algo'); - $memcache = controller()->memcache->memcache; - $memkey = $algo.'_'.str_replace('/','_',$partial); - $html = controller()->memcache->get($memkey); - - if (!empty($html)) { - echo $html; - return; - } - - ob_start(); - ob_implicit_flush(false); - $this->renderPartial($partial); - $html = ob_get_clean(); - echo $html; - - controller()->memcache->set($memkey, $html, $cachetime, MEMCACHE_COMPRESSED); - } - - // Pool Status : public right panel with all algos and live stats - public function actionCurrent_results() - { - $this->renderPartialAlgoMemcached('results/current_results', 30); - } - - // Home Tab : Pool Stats (algo) on the bottom right - public function actionHistory_results() - { - $this->renderPartialAlgoMemcached('results/history_results'); - } - - // Pool Tab : Top left panel with estimated profit per coin - public function actionMining_results() - { - if ($this->admin) - $this->renderPartial('results/mining_results'); - else - $this->renderPartialAlgoMemcached('results/mining_results'); - } - - public function actionMiners_results() - { - if ($this->admin) - $this->renderPartial('results/miners_results'); - else - $this->renderPartialAlgoMemcached('results/miners_results'); - } - - // Pool tab: graph algo pool hashrate (json data) - public function actionGraph_hashrate_results() - { - $this->renderPartialAlgoMemcached('results/graph_hashrate_results'); - } - - // Pool tab: graph algo estimate history (json data) - public function actionGraph_price_results() - { - $this->renderPartialAlgoMemcached('results/graph_price_results'); - } - - // Pool tab: last 50 blocks - public function actionFound_results() - { - $this->renderPartialAlgoMemcached('results/found_results'); - } - - public function actionWallet_results() - { - $this->renderPartial('results/wallet_results'); - } - - public function actionWallet_miners_results() - { - $this->renderPartial('results/wallet_miners_results'); - } - - public function actionWallet_graphs_results() - { - $this->renderPartial('results/wallet_graphs_results'); - } - - public function actionGraph_earnings_results() - { - $this->renderPartial('results/graph_earnings_results'); - } - - public function actionUser_earning_results() - { - $this->renderPartial('results/user_earning_results'); - } - - public function actionGraph_user_results() - { - $this->renderPartial('results/graph_user_results'); - } - - public function actionGraph_assets_results() - { - $this->renderPartial('results/graph_assets_results'); - } - - public function actionGraph_negative_results() - { - $this->renderPartial('results/graph_negative_results'); - } - - public function actionGraph_profit_results() - { - $this->renderPartial('results/graph_profit_results'); - } - - public function actionTitle_results() - { - $user = getuserparam(getparam('address')); - if($user) - { - $balance = bitcoinvaluetoa($user->balance); - $coin = getdbo('db_coins', $user->coinid); - - if($coin) - echo "$balance $coin->symbol - ".YAAMP_SITE_NAME; - else - echo "$balance - ".YAAMP_SITE_NAME; - } - else - echo YAAMP_SITE_URL; - } - - ///////////////////////////////////////////////// - - public function actionGraphMarketPrices() - { - if (!$this->admin) return; - $this->renderPartial('results/graph_market_prices', array('id'=> getiparam('id'))); - } - - public function actionGraphMarketBalance() - { - if (!$this->admin) return; - $this->renderPartial('results/graph_market_balance', array('id'=> getiparam('id'))); - } - - ///////////////////////////////////////////////// - - public function actionAbout() - { - $this->render('about'); - } - - public function actionTerms() - { - $this->render('terms'); - } - - ///////////////////////////////////////////////// - - public function actionAdmin() - { - if(!$this->admin) return; - $this->render('admin'); - } - - public function actionAdmin_results() - { - if(!$this->admin) return; - $this->renderPartial('admin_results'); - } - - ///////////////////////////////////////////////// - - public function actionConnections() - { - if(!$this->admin) return; - $this->render('connections'); - } - - public function actionConnections_results() - { - if(!$this->admin) return; - $this->renderPartial('connections_results'); - } - - ///////////////////////////////////////////////// - - public function actionBlock() - { - $this->render('block'); - } - - public function actionBlock_results() - { - $this->renderPartial('block_results'); - } - - ///////////////////////////////////////////////// - - public function actionEarning() - { - if(!$this->admin) return; - $this->render('earning'); - } - - public function actionEarning_results() - { - if(!$this->admin) return; - $this->renderPartial('earning_results'); - } - - // called from the wallet - public function actionClearearnings() - { - if(!$this->admin) return; - $coin = getdbo('db_coins', getiparam('id')); - if ($coin) { - BackendClearEarnings($coin->id); - } - $this->goback(); - } - - // called from the earnings page - public function actionClearearning() - { - if(!$this->admin) return; - $earning = getdbo('db_earnings', getiparam('id')); - if ($earning && $earning->status == 0) { - $earning->delete(); - } - $this->goback(); - } - - ///////////////////////////////////////////////// - - public function actionPayments() - { - if(!$this->admin) return; - $this->render('payments'); - } - - public function actionPayments_results() - { - if(!$this->admin) return; - $this->renderPartial('payments_results'); - } - - public function actionCancelUserPayment() - { - if(!$this->admin) return; - $user = getdbo('db_accounts', getiparam('id')); - if ($user) { - BackendUserCancelFailedPayment($user->id); - } - $this->goback(); - } - - public function actionCancelUsersPayment() - { - if(!$this->admin) return; - $coin = getdbo('db_coins', getiparam('id')); - if ($coin) { - $amount_failed = 0.0; $cnt = 0; - $time = time() - (48 * 3600); - $failed = getdbolist('db_payouts', "idcoin=:id AND IFNULL(tx,'') = '' AND time>$time", array(':id'=>$coin->id)); - if (!empty($failed)) { - foreach ($failed as $payout) { - $user = getdbo('db_accounts', $payout->account_id); - if ($user) { - $user->balance += floatval($payout->amount); - if ($user->save()) { - $amount_failed += floatval($payout->amount); - $cnt++; - } - } - $payout->delete(); - } - user()->setFlash('message', "Restored $cnt failed txs to user balances, $amount_failed {$coin->symbol}"); - } else { - user()->setFlash('message', 'No failed txs found'); - } - } else { - user()->setFlash('error', 'Invalid coin id!'); - } - $this->goback(); - } - - ///////////////////////////////////////////////// - - public function actionUser() - { - if(!$this->admin) return; - $this->render('user'); - } - - public function actionUser_results() - { - if(!$this->admin) return; - $this->renderPartial('user_results'); - } - - ///////////////////////////////////////////////// - - public function actionWorker() - { - if(!$this->admin) return; - $this->render('worker'); - } - - public function actionWorker_results() - { - if(!$this->admin) return; - $this->renderPartial('worker_results'); - } - - ///////////////////////////////////////////////// - - public function actionVersion() - { - if(!$this->admin) return; - $this->render('version'); - } - - public function actionVersion_results() - { - if(!$this->admin) return; - $this->renderPartial('version_results'); - } - - ///////////////////////////////////////////////// - - public function actionCommon() - { - if(!$this->admin) return; - $this->render('common'); - } - - public function actionCommon_results() - { - if(!$this->admin) return; - $this->renderPartial('common_results'); - } - - ///////////////////////////////////////////////// - - public function actionBalances() - { - if(!$this->admin) return; - $this->render('balances'); - } - - public function actionBalances_results() - { - if(!$this->admin) return; - $this->renderPartial('balances_results'); - } - - public function actionBalanceUpdate() - { - if(!$this->admin) return; - $id = getiparam('market'); - $market = getdbo('db_markets', $id); - if ($market) { - exchange_update_market_by_id($id); - $this->redirect(array('/site/balances', 'exch'=>$market->name)); - } else { - $this->goback(); - } - } - - ///////////////////////////////////////////////// - - public function actionExchange() - { - if(!$this->admin) return; - $this->render('exchange'); - } - - public function actionExchange_results() - { - if(!$this->admin) return; - $this->renderPartial('exchange_results'); - } - - ///////////////////////////////////////////////// - - public function actionCoin() - { - if(!$this->admin) return; - $this->render('coin'); - } - - public function actionCoin_results() - { - if(!$this->admin) return; - $this->renderPartial('coin_results'); - } - - public function actionMemcached() - { - if(!$this->admin) return; - $this->render('memcached'); - } - - public function actionMonsters() - { - if(!$this->admin) return; - $this->render('monsters'); - } - - public function actionEmptyMarkets() - { - if(!$this->admin) return; - $this->render('emptymarkets'); - } - - ////////////////////////////////////////////////////////////////////////////////////// - - public function actionTx() - { - $this->renderPartial('tx'); - } - - ////////////////////////////////////////////////////////////////////////////////////// - - public function actionResetBlockchain() - { - if(!$this->admin) return; - $coin = getdbo('db_coins', getiparam('id')); - $coin->action = 3; - $coin->save(); - - $this->redirect("/site/coin?id=$coin->id"); - } - - ////////////////////////////////////////////////////////////////////////////////////// - - public function actionRestartCoin() - { - if(!$this->admin) return; - $coin = getdbo('db_coins', getiparam('id')); - - $coin->action = 4; - $coin->enable = false; - $coin->auto_ready = false; - $coin->installed = true; - $coin->connections = 0; - $coin->save(); - - $this->redirect('/site/admin'); - // $this->goback(); - } - - public function actionStartCoin() - { - if(!$this->admin) return; - $coin = getdbo('db_coins', getiparam('id')); - - $coin->action = 1; - $coin->enable = true; - $coin->auto_ready = false; - $coin->installed = true; - $coin->connections = 0; - $coin->save(); - - $this->redirect('/site/admin'); - // $this->goback(); - } - - public function actionStopCoin() - { - if(!$this->admin) return; - $coin = getdbo('db_coins', getiparam('id')); - - $coin->action = 2; - $coin->enable = false; - $coin->auto_ready = false; - $coin->connections = 0; - $coin->save(); - - $this->redirect('/site/admin'); - // $this->goback(); - } - - public function actionMakeConfigfile() - { - if(!$this->admin) return; - $coin = getdbo('db_coins', getiparam('id')); - - $coin->action = 5; - $coin->installed = true; - $coin->save(); - - $this->redirect('/site/admin'); - // $this->goback(); - } - - ////////////////////////////////////////////////////////////////////////////////////// - - public function actionSetauto() - { - if(!$this->admin) return; - $coin = getdbo('db_coins', getiparam('id')); - - $coin->auto_ready = true; - $coin->save(); - - $this->redirect('/site/admin'); - // $this->goback(); - } - - public function actionUnsetauto() - { - if(!$this->admin) return; - $coin = getdbo('db_coins', getiparam('id')); - - $coin->auto_ready = false; - $coin->save(); - - $this->redirect('/site/admin'); - // $this->goback(); - } - - ////////////////////////////////////////////////////////////////////////////////////////////////// - - public function actionBanUser() - { - if(!$this->admin) return; - - $user = getdbo('db_accounts', getiparam('id')); - if($user) { - $user->is_locked = true; - $user->balance = 0; - $user->save(); - } - - $this->goback(); - } - - public function actionBlockuser() - { - if(!$this->admin) return; - - $wallet = getparam('wallet'); - $user = getuserparam($wallet); - if($user) { - $user->is_locked = true; - $user->save(); - } - - $this->goback(); - } - - public function actionUnblockuser() - { - if(!$this->admin) return; - - $wallet = getparam('wallet'); - $user = getuserparam($wallet); - if($user) { - $user->is_locked = false; - $user->save(); - } - - $this->goback(); - } - - public function actionLoguser() - { - if(!$this->admin) return; - - $user = getdbo('db_accounts', getiparam('id')); - if($user) { - $user->logtraffic = getiparam('en'); - $user->save(); - } - - $this->goback(); - } - - ////////////////////////////////////////////////////////////////////////////////////////////////// - - // called from the wallet - public function actionPayuserscoin() - { - if(!$this->admin) return; - $coin = getdbo('db_coins', getiparam('id')); - if($coin) { - BackendCoinPayments($coin); - } - $this->goback(); - } - - // called from the wallet - public function actionCheckblocks() - { - if(!$this->admin) return; - $coin = getdbo('db_coins', getiparam('id')); - if($coin) { - BackendBlockFind1($coin->id); - BackendBlocksUpdate($coin->id); - BackendBlockFind2($coin->id); - BackendUpdatePoolBalances($coin->id); - } - $this->goback(); - } - - //// - - // called from the wallet - public function actionDeleteEarnings() - { - if(!$this->admin) return; - $coin = getdbo('db_coins', getiparam('id')); - if($coin) { - dborun("DELETE FROM earnings WHERE coinid={$coin->id}"); - } - $this->goback(); - } - - // called from the earnings page - public function actionDeleteEarning() - { - if(!$this->admin) return; - $earning = getdbo('db_earnings', getiparam('id')); - if($earning) { - $earning->delete(); - } - $this->goback(); - } - - ////////////////////////////////////////////////////////////////////////////////////////////////// - - public function actionDeleteExchange() - { - if(!$this->admin) return; - $exchange = getdbo('db_exchange', getiparam('id')); - if ($exchange) { - $exchange->status = 'deleted'; - $exchange->price = 0; - $exchange->receive_time = time(); - $exchange->save(); - } - $this->goback(); - } - - public function actionClearMarket() - { - if(!$this->admin) return; - $market = getdbo('db_markets', getiparam('id')); - if($market) { - $market->lastsent = null; - $market->save(); - } - $this->goback(); - } - - // called from the dashboard page - public function actionClearorder() - { - if(!$this->admin) return; - $order = getdbo('db_orders', getiparam('id')); - if ($order) { - $order->delete(); - } - $this->goback(); - } - - public function actionCancelorder() - { - if(!$this->admin) return; - $order = getdbo('db_orders', getiparam('id')); - - cancelExchangeOrder($order); - - $this->goback(); - } - - //////////////////////////////////////////////////////////////////////////////////////// - - public function actionAlgo() - { - $algo = getalgoparam(); - $a = getdbosql('db_algos', "name=:name", array(':name'=>$algo)); - - if($a) - user()->setState('yaamp-algo', $a->name); - else - user()->setState('yaamp-algo', 'all'); - - $route = getparam('r'); - if (!empty($route)) - $this->redirect($route); - else - $this->goback(); - } - - public function actionGomining() - { - $algo = getalgoparam(); - if ($algo == 'all') { - return; - } - user()->setState('yaamp-algo', $algo); - $this->redirect("/site/mining"); - } - - public function actionUpdatePrice() - { - if(!$this->admin) return; - BackendPricesUpdate(); - $this->goback(); - } - - public function actionUninstallCoin() - { - if(!$this->admin) return; - - $coin = getdbo('db_coins', getiparam('id')); - if($coin) - { - // dborun("delete from blocks where coin_id=$coin->id"); - dborun("delete from exchange where coinid=$coin->id"); - dborun("delete from earnings where coinid=$coin->id"); - // dborun("delete from markets where coinid=$coin->id"); - dborun("delete from orders where coinid=$coin->id"); - dborun("delete from shares where coinid=$coin->id"); - - $coin->enable = false; - $coin->installed = false; - $coin->auto_ready = false; - $coin->master_wallet = null; - $coin->mint = 0; - $coin->balance = 0; - $coin->save(); - } - - $this->redirect("/site/admin"); - } - - public function actionOptimize() - { - BackendOptimizeTables(); - $this->goback(); - } - - public function actionRunExchange() - { - if(!$this->admin) return; - - $id = getiparam('id'); - $balance = getdbo('db_balances', $id); - - if($balance) - runExchange($balance->name); - - $tm = round($this->elapsedTime(), 3); - - if ($balance) - debuglog("runexchange done ({$balance->name}) {$tm} sec"); - else - debuglog("runexchange failed (no id!)"); - - $this->redirect("/site/common"); - } - - public function actionEval() - { -// if(!$this->admin) return; - -// $param = getparam('param'); -// if($param) eval($param); -// else $param = ''; - -// $this->render('eval', array('param'=>$param)); - } - - public function actionMainbtc() - { - debuglog(__METHOD__); - setcookie('mainbtc', '1', time()+60*60*24, '/'); - } + public $defaultAction = 'index'; + + /////////////////////////////////////////////////// + // Security Note: You can rename this action as you + // want, to customize the admin entrance url... + // + public function actionAdminRights() + { + $client_ip = arraySafeVal($_SERVER, 'REMOTE_ADDR'); + $valid = isAdminIP($client_ip); + + if (arraySafeVal($_SERVER, 'HTTP_X_FORWARDED_FOR', '') != '') { + debuglog("admin access attempt via IP spoofing!"); + $valid = false; + } + + if ($valid) + debuglog("admin connect from $client_ip"); + else + debuglog("admin connect failure from $client_ip"); + + user()->setState('yaamp_admin', $valid); + + $this->redirect("/site/common"); + } + + ///////////////////////////////////////////////// + + public function actionCreate() + { + if (!$this->admin) + return; + + $coin = new db_coins; + $coin->txmessage = true; + $coin->created = time(); + $coin->index_avg = 1; + $coin->difficulty = 1; + $coin->installed = 1; + $coin->visible = 1; + + // $coin->deposit_minimum = 1; + $coin->lastblock = ''; + + if (isset($_POST['db_coins'])) { + $coin->setAttributes($_POST['db_coins'], false); + if ($coin->save()) + $this->redirect(array( + 'admin' + )); + } + + $this->render('coin_form', array( + 'update' => false, + 'coin' => $coin + )); + } + + public function actionUpdate() + { + if (!$this->admin) + return; + $coin = getdbo('db_coins', getiparam('id')); + $txfee = $coin->txfee; + + if ($coin && isset($_POST['db_coins'])) { + $coin->setScenario('update'); + $coin->setAttributes($_POST['db_coins'], false); + + if ($coin->save()) { + if ($txfee != $coin->txfee) { + $remote = new WalletRPC($coin); + $remote->settxfee($coin->txfee); + } + $this->redirect(array( + 'coin', + 'id' => $coin->id + )); + // $this->goback(); + } + } + + $this->render('coin_form', array( + 'update' => true, + 'coin' => $coin + )); + } + + ///////////////////////////////////////////////// + + public function actionPeers() + { + if (!$this->admin) + return; + $coin = getdbo('db_coins', getiparam('id')); + if (!$coin) { + $this->goback(); + } + + $this->render('coin_peers', array( + 'coin' => $coin + )); + } + + public function actionPeerRemove() + { + if (!$this->admin) + return; + $coin = getdbo('db_coins', getiparam('id')); + $node = getparam('node'); + if ($coin && $node) { + $remote = new WalletRPC($coin); + if ($coin->rpcencoding == 'DCR') { + $res = $remote->node('disconnect', $node); + if (!$res) + $res = $remote->node('remove', $node); + $remote->error = false; // ignore + } else { + $res = $remote->addnode($node, 'remove'); + } + if (!$res && $remote->error) { + user()->setFlash('error', "$node " . $remote->error); + } + } + $this->goback(); + } + + public function actionPeerAdd() + { + if (!$this->admin) + return; + $coin = getdbo('db_coins', getiparam('id')); + $node = arraySafeVal($_POST, 'node'); + if ($coin && $node) { + $remote = new WalletRPC($coin); + if ($coin->rpcencoding == 'DCR') { + $remote->addnode($node, 'add'); + usleep(500 * 1000); + $remote->node('connect', $node); + sleep(1); + } else { + $res = $remote->addnode($node, 'add'); + if (!$res) { + user()->setFlash('error', "$node " . $remote->error); + } else { + sleep(1); + } + } + } + $this->goback(); + } + + ///////////////////////////////////////////////// + + public function actionTickets() + { + if (!$this->admin) + return; + $coin = getdbo('db_coins', getiparam('id')); + if (!$coin) { + $this->goback(); + } + + $this->render('coin_tickets', array( + 'coin' => $coin + )); + } + + public function actionTicketBuy() + { + if (!$this->admin) + return; + $coin = getdbo('db_coins', getiparam('id')); + $spendlimit = (double) arraySafeVal($_POST, 'spendlimit'); + $quantity = (int) arraySafeVal($_POST, 'quantity'); + if ($coin && $spendlimit) { + $remote = new WalletRPC($coin); + if ($quantity <= 1) + $res = $remote->purchaseticket($coin->account, $spendlimit); + else + $res = $remote->purchaseticket($coin->account, $spendlimit, 1, $coin->master_wallet, $quantity); + if ($res === false) + user()->setFlash('error', $remote->error); + else + user()->setFlash('message', is_string($res) ? "ticket txid: $res" : json_encode($res)); + } + $this->goback(); + } + + ///////////////////////////////////////////////// + + public function actionBookmarkAdd() + { + if (!$this->admin) + return; + $coin = getdbo('db_coins', getiparam('id')); + if ($coin) { + $bookmark = new db_bookmarks; + $bookmark->isNewRecord = true; + $bookmark->idcoin = $coin->id; + if (isset($_POST['db_bookmarks'])) { + $bookmark->setAttributes($_POST['db_bookmarks'], false); + if ($bookmark->save()) + $this->redirect(array( + '/site/coin', + 'id' => $coin->id + )); + } + $this->render('bookmark', array( + 'bookmark' => $bookmark, + 'coin' => $coin + )); + } else { + $this->goback(); + } + } + + public function actionBookmarkDel() + { + if (!$this->admin) + return; + $bookmark = getdbo('db_bookmarks', getiparam('id')); + if ($bookmark) { + $bookmark->delete(); + } + $this->goback(); + } + + public function actionBookmarkEdit() + { + if (!$this->admin) + return; + $bookmark = getdbo('db_bookmarks', getiparam('id')); + if ($bookmark) { + $coin = getdbo('db_coins', $bookmark->idcoin); + if ($coin && isset($_POST['db_bookmarks'])) { + $bookmark->setAttributes($_POST['db_bookmarks'], false); + if ($bookmark->save()) + $this->redirect(array( + '/site/coin', + 'id' => $coin->id + )); + } + $this->render('bookmark', array( + 'bookmark' => $bookmark, + 'coin' => $coin + )); + } else { + user()->setFlash('error', "invalid bookmark"); + $this->goback(); + } + } + + public function actionBookmarkSend() + { + if (!$this->admin) + return; + + $bookmark = getdbo('db_bookmarks', getiparam('id')); + if ($bookmark) { + $coin = getdbo('db_coins', $bookmark->idcoin); + $amount = getparam('amount'); + + $remote = new WalletRPC($coin); + + $info = $remote->getinfo(); + if (!$info || !$info['balance']) + return false; + + $deposit_info = $remote->validateaddress($bookmark->address); + if (!$deposit_info || !isset($deposit_info['isvalid']) || !$deposit_info['isvalid']) { + user()->setFlash('error', "invalid address for {$coin->name}, {$bookmark->address}"); + $this->redirect(array( + 'site/coin', + 'id' => $coin->id + )); + } + + $amount = min($amount, $info['balance'] - $info['paytxfee']); + $amount = round($amount, 8); + + $tx = $remote->sendtoaddress($bookmark->address, $amount); + if (!$tx) { + debuglog("unable to send $amount {$coin->symbol} to bookmark {$bookmark->address}"); + debuglog($remote->error); + user()->setFlash('error', $remote->error); + $this->redirect(array( + 'site/coin', + 'id' => $coin->id + )); + } else { + debuglog("sent $amount {$coin->symbol} to bookmark {$bookmark->address}"); + $bookmark->lastused = time(); + $bookmark->save(); + BackendUpdatePoolBalances($coin->id); + } + } + + $this->redirect(array( + 'site/coin', + 'id' => $coin->id + )); + } + + ///////////////////////////////////////////////// + + public function actionConsole() + { + if (!$this->admin || !YAAMP_ADMIN_WEBCONSOLE) + return; + $coin = getdbo('db_coins', getiparam('id')); + if (!$coin) { + $this->goback(); + } + + $this->render('coin_console', array( + 'coin' => $coin, + 'query' => arraySafeVal($_POST, 'query') + )); + } + + ///////////////////////////////////////////////// + + public function actionTriggers() + { + if (!$this->admin) + return; + $coin = getdbo('db_coins', getiparam('id')); + if (!$coin) { + $this->goback(); + } + + $this->render('coin_triggers', array( + 'coin' => $coin + )); + } + + public function actionTriggerEnable() + { + if (!$this->admin) + return; + $rule = getdbo('db_notifications', getiparam('id')); + if ($rule) { + $rule->enabled = (int) getiparam('en'); + $rule->save(); + } + + $this->goback(); + } + + public function actionTriggerReset() + { + if (!$this->admin) + return; + $rule = getdbo('db_notifications', getiparam('id')); + if ($rule) { + $rule->lasttriggered = 0; + $rule->save(); + } + + $this->goback(); + } + + public function actionTriggerDel() + { + if (!$this->admin) + return; + $rule = getdbo('db_notifications', getiparam('id')); + if ($rule) { + $rule->delete(); + } + + $this->goback(); + } + + public function actionTriggerAdd() + { + if (!$this->admin) + return; + $coin = getdbo('db_coins', getiparam('id')); + if (!$coin) { + $this->goback(); + } + + $valid = true; + $rule = new db_notifications; + $rule->idcoin = $coin->id; + $rule->notifytype = $_POST['notifytype']; + $rule->conditiontype = $_POST['conditiontype']; + $rule->conditionvalue = $_POST['conditionvalue']; + $rule->notifycmd = $_POST['notifycmd']; + $rule->description = $_POST['description']; + $rule->enabled = 1; + $rule->lastchecked = 0; // time + $rule->lasttriggered = 0; + + $words = explode(' ', $rule->conditiontype); + if (count($words) < 2) { + user()->setFlash('error', "missing space in condition, sample : 'balance <' 5"); + $valid = false; + } + if ($valid) { + $rule->save(); + } + + $this->goback(); + } + + ///////////////////////////////////////////////// + + public function actionBotnets() + { + if (!$this->admin) + return; + + $this->render('botnets'); + } + + ///////////////////////////////////////////////// + + public function actionIndex() + { + if (isset($_GET['address'])) + $this->render('wallet'); + else + $this->render('index'); + } + + public function actionApi() + { + $this->render('api'); + } + + public function actionBenchmarks() + { + $this->render('benchmarks'); + } + + public function actionDiff() + { + $this->render('diff'); + } + + public function actionMultialgo() + { + $this->render('multialgo'); + } + + public function actionMining() + { + $this->render('mining'); + } + + public function actionMiners() + { + $this->render('miners'); + } + + ///////////////////////////////// + + protected function renderPartialAlgoMemcached($partial, $cachetime = 15) + { + $algo = user()->getState('yaamp-algo'); + $memcache = controller()->memcache->memcache; + $memkey = $algo . '_' . str_replace('/', '_', $partial); + $html = controller()->memcache->get($memkey); + + if (!empty($html)) { + echo $html; + return; + } + + ob_start(); + ob_implicit_flush(false); + $this->renderPartial($partial); + $html = ob_get_clean(); + echo $html; + + controller()->memcache->set($memkey, $html, $cachetime, MEMCACHE_COMPRESSED); + } + + // Pool Status : public right panel with all algos and live stats + public function actionCurrent_results() + { + $this->renderPartialAlgoMemcached('results/current_results', 30); + } + + // Home Tab : Pool Stats (algo) on the bottom right + public function actionHistory_results() + { + $this->renderPartialAlgoMemcached('results/history_results'); + } + + // Pool Tab : Top left panel with estimated profit per coin + public function actionMining_results() + { + if ($this->admin) + $this->renderPartial('results/mining_results'); + else + $this->renderPartialAlgoMemcached('results/mining_results'); + } + + public function actionMiners_results() + { + if ($this->admin) + $this->renderPartial('results/miners_results'); + else + $this->renderPartialAlgoMemcached('results/miners_results'); + } + + // Pool tab: graph algo pool hashrate (json data) + public function actionGraph_hashrate_results() + { + $this->renderPartialAlgoMemcached('results/graph_hashrate_results'); + } + + // Pool tab: graph algo estimate history (json data) + public function actionGraph_price_results() + { + $this->renderPartialAlgoMemcached('results/graph_price_results'); + } + + // Pool tab: last 50 blocks + public function actionFound_results() + { + $this->renderPartialAlgoMemcached('results/found_results'); + } + + public function actionWallet_results() + { + $this->renderPartial('results/wallet_results'); + } + + public function actionWallet_miners_results() + { + $this->renderPartial('results/wallet_miners_results'); + } + + public function actionWallet_graphs_results() + { + $this->renderPartial('results/wallet_graphs_results'); + } + + public function actionGraph_earnings_results() + { + $this->renderPartial('results/graph_earnings_results'); + } + + public function actionUser_earning_results() + { + $this->renderPartial('results/user_earning_results'); + } + + public function actionGraph_user_results() + { + $this->renderPartial('results/graph_user_results'); + } + + public function actionGraph_assets_results() + { + $this->renderPartial('results/graph_assets_results'); + } + + public function actionGraph_negative_results() + { + $this->renderPartial('results/graph_negative_results'); + } + + public function actionGraph_profit_results() + { + $this->renderPartial('results/graph_profit_results'); + } + + public function actionTitle_results() + { + $user = getuserparam(getparam('address')); + if ($user) { + $balance = bitcoinvaluetoa($user->balance); + $coin = getdbo('db_coins', $user->coinid); + + if ($coin) + echo "$balance $coin->symbol - " . YAAMP_SITE_NAME; + else + echo "$balance - " . YAAMP_SITE_NAME; + } else + echo YAAMP_SITE_URL; + } + + ///////////////////////////////////////////////// + + public function actionGraphMarketPrices() + { + if (!$this->admin) + return; + $this->renderPartial('results/graph_market_prices', array( + 'id' => getiparam('id') + )); + } + + public function actionGraphMarketBalance() + { + if (!$this->admin) + return; + $this->renderPartial('results/graph_market_balance', array( + 'id' => getiparam('id') + )); + } + + ///////////////////////////////////////////////// + + public function actionAbout() + { + $this->render('about'); + } + + public function actionTerms() + { + $this->render('terms'); + } + + ///////////////////////////////////////////////// + + public function actionAdmin() + { + if (!$this->admin) + return; + $this->render('admin'); + } + + public function actionAdmin_results() + { + if (!$this->admin) + return; + $this->renderPartial('admin_results'); + } + + ///////////////////////////////////////////////// + + public function actionConnections() + { + if (!$this->admin) + return; + $this->render('connections'); + } + + public function actionConnections_results() + { + if (!$this->admin) + return; + $this->renderPartial('connections_results'); + } + + ///////////////////////////////////////////////// + + public function actionBlock() + { + $this->render('block'); + } + + public function actionBlock_results() + { + $this->renderPartial('block_results'); + } + + ///////////////////////////////////////////////// + + public function actionEarning() + { + if (!$this->admin) + return; + $this->render('earning'); + } + + public function actionEarning_results() + { + if (!$this->admin) + return; + $this->renderPartial('earning_results'); + } + + // called from the wallet + public function actionClearearnings() + { + if (!$this->admin) + return; + $coin = getdbo('db_coins', getiparam('id')); + if ($coin) { + BackendClearEarnings($coin->id); + } + $this->goback(); + } + + // called from the earnings page + public function actionClearearning() + { + if (!$this->admin) + return; + $earning = getdbo('db_earnings', getiparam('id')); + if ($earning && $earning->status == 0) { + $earning->delete(); + } + $this->goback(); + } + + ///////////////////////////////////////////////// + + public function actionPayments() + { + if (!$this->admin) + return; + $this->render('payments'); + } + + public function actionPayments_results() + { + if (!$this->admin) + return; + $this->renderPartial('payments_results'); + } + + public function actionCancelUserPayment() + { + if (!$this->admin) + return; + $user = getdbo('db_accounts', getiparam('id')); + if ($user) { + BackendUserCancelFailedPayment($user->id); + } + $this->goback(); + } + + public function actionCancelUsersPayment() + { + if (!$this->admin) + return; + $coin = getdbo('db_coins', getiparam('id')); + if ($coin) { + $amount_failed = 0.0; + $cnt = 0; + $time = time() - (48 * 3600); + $failed = getdbolist('db_payouts', "idcoin=:id AND IFNULL(tx,'') = '' AND time>$time", array( + ':id' => $coin->id + )); + if (!empty($failed)) { + foreach ($failed as $payout) { + $user = getdbo('db_accounts', $payout->account_id); + if ($user) { + $user->balance += floatval($payout->amount); + if ($user->save()) { + $amount_failed += floatval($payout->amount); + $cnt++; + } + } + $payout->delete(); + } + user()->setFlash('message', "Restored $cnt failed txs to user balances, $amount_failed {$coin->symbol}"); + } else { + user()->setFlash('message', 'No failed txs found'); + } + } else { + user()->setFlash('error', 'Invalid coin id!'); + } + $this->goback(); + } + + ///////////////////////////////////////////////// + + public function actionUser() + { + if (!$this->admin) + return; + $this->render('user'); + } + + public function actionUser_results() + { + if (!$this->admin) + return; + $this->renderPartial('user_results'); + } + + ///////////////////////////////////////////////// + + public function actionWorker() + { + if (!$this->admin) + return; + $this->render('worker'); + } + + public function actionWorker_results() + { + if (!$this->admin) + return; + $this->renderPartial('worker_results'); + } + + ///////////////////////////////////////////////// + + public function actionVersion() + { + if (!$this->admin) + return; + $this->render('version'); + } + + public function actionVersion_results() + { + if (!$this->admin) + return; + $this->renderPartial('version_results'); + } + + ///////////////////////////////////////////////// + + public function actionCommon() + { + if (!$this->admin) + return; + $this->render('common'); + } + + public function actionCommon_results() + { + if (!$this->admin) + return; + $this->renderPartial('common_results'); + } + + ///////////////////////////////////////////////// + + public function actionBalances() + { + if (!$this->admin) + return; + $this->render('balances'); + } + + public function actionBalances_results() + { + if (!$this->admin) + return; + $this->renderPartial('balances_results'); + } + + public function actionBalanceUpdate() + { + if (!$this->admin) + return; + $id = getiparam('market'); + $market = getdbo('db_markets', $id); + if ($market) { + exchange_update_market_by_id($id); + $this->redirect(array( + '/site/balances', + 'exch' => $market->name + )); + } else { + $this->goback(); + } + } + + ///////////////////////////////////////////////// + + public function actionExchange() + { + if (!$this->admin) + return; + $this->render('exchange'); + } + + public function actionExchange_results() + { + if (!$this->admin) + return; + $this->renderPartial('exchange_results'); + } + + ///////////////////////////////////////////////// + + public function actionCoin() + { + if (!$this->admin) + return; + $this->render('coin'); + } + + public function actionCoin_results() + { + if (!$this->admin) + return; + $this->renderPartial('coin_results'); + } + + public function actionMemcached() + { + if (!$this->admin) + return; + $this->render('memcached'); + } + + public function actionMonsters() + { + if (!$this->admin) + return; + $this->render('monsters'); + } + + public function actionEmptyMarkets() + { + if (!$this->admin) + return; + $this->render('emptymarkets'); + } + + ////////////////////////////////////////////////////////////////////////////////////// + + public function actionTx() + { + $this->renderPartial('tx'); + } + + ////////////////////////////////////////////////////////////////////////////////////// + + public function actionResetBlockchain() + { + if (!$this->admin) + return; + $coin = getdbo('db_coins', getiparam('id')); + $coin->action = 3; + $coin->save(); + + $this->redirect("/site/coin?id=$coin->id"); + } + + ////////////////////////////////////////////////////////////////////////////////////// + + public function actionRestartCoin() + { + if (!$this->admin) + return; + $coin = getdbo('db_coins', getiparam('id')); + + $coin->action = 4; + $coin->enable = false; + $coin->auto_ready = false; + $coin->installed = true; + $coin->connections = 0; + $coin->save(); + + $this->redirect('/site/admin'); + // $this->goback(); + } + + public function actionStartCoin() + { + if (!$this->admin) + return; + $coin = getdbo('db_coins', getiparam('id')); + + $coin->action = 1; + $coin->enable = true; + $coin->auto_ready = false; + $coin->installed = true; + $coin->connections = 0; + $coin->save(); + + $this->redirect('/site/admin'); + // $this->goback(); + } + + public function actionStopCoin() + { + if (!$this->admin) + return; + $coin = getdbo('db_coins', getiparam('id')); + + $coin->action = 2; + $coin->enable = false; + $coin->auto_ready = false; + $coin->connections = 0; + $coin->save(); + + $this->redirect('/site/admin'); + // $this->goback(); + } + + public function actionMakeConfigfile() + { + if (!$this->admin) + return; + $coin = getdbo('db_coins', getiparam('id')); + + $coin->action = 5; + $coin->installed = true; + $coin->save(); + + $this->redirect('/site/admin'); + // $this->goback(); + } + + ////////////////////////////////////////////////////////////////////////////////////// + + public function actionSetauto() + { + if (!$this->admin) + return; + $coin = getdbo('db_coins', getiparam('id')); + + $coin->auto_ready = true; + $coin->save(); + + $this->redirect('/site/admin'); + // $this->goback(); + } + + public function actionUnsetauto() + { + if (!$this->admin) + return; + $coin = getdbo('db_coins', getiparam('id')); + + $coin->auto_ready = false; + $coin->save(); + + $this->redirect('/site/admin'); + // $this->goback(); + } + + ////////////////////////////////////////////////////////////////////////////////////////////////// + + public function actionBanUser() + { + if (!$this->admin) + return; + + $user = getdbo('db_accounts', getiparam('id')); + if ($user) { + $user->is_locked = true; + $user->balance = 0; + $user->save(); + } + + $this->goback(); + } + + public function actionBlockuser() + { + if (!$this->admin) + return; + + $wallet = getparam('wallet'); + $user = getuserparam($wallet); + if ($user) { + $user->is_locked = true; + $user->save(); + } + + $this->goback(); + } + + public function actionUnblockuser() + { + if (!$this->admin) + return; + + $wallet = getparam('wallet'); + $user = getuserparam($wallet); + if ($user) { + $user->is_locked = false; + $user->save(); + } + + $this->goback(); + } + + public function actionLoguser() + { + if (!$this->admin) + return; + + $user = getdbo('db_accounts', getiparam('id')); + if ($user) { + $user->logtraffic = getiparam('en'); + $user->save(); + } + + $this->goback(); + } + + ////////////////////////////////////////////////////////////////////////////////////////////////// + + // called from the wallet + public function actionPayuserscoin() + { + if (!$this->admin) + return; + $coin = getdbo('db_coins', getiparam('id')); + if ($coin) { + BackendCoinPayments($coin); + } + $this->goback(); + } + + // called from the wallet + public function actionCheckblocks() + { + if (!$this->admin) + return; + $coin = getdbo('db_coins', getiparam('id')); + if ($coin) { + BackendBlockFind1($coin->id); + BackendBlocksUpdate($coin->id); + BackendBlockFind2($coin->id); + BackendUpdatePoolBalances($coin->id); + } + $this->goback(); + } + + //// + + // called from the wallet + public function actionDeleteEarnings() + { + if (!$this->admin) + return; + $coin = getdbo('db_coins', getiparam('id')); + if ($coin) { + dborun("DELETE FROM earnings WHERE coinid={$coin->id}"); + } + $this->goback(); + } + + // called from the earnings page + public function actionDeleteEarning() + { + if (!$this->admin) + return; + $earning = getdbo('db_earnings', getiparam('id')); + if ($earning) { + $earning->delete(); + } + $this->goback(); + } + + ////////////////////////////////////////////////////////////////////////////////////////////////// + + public function actionDeleteExchange() + { + if (!$this->admin) + return; + $exchange = getdbo('db_exchange', getiparam('id')); + if ($exchange) { + $exchange->status = 'deleted'; + $exchange->price = 0; + $exchange->receive_time = time(); + $exchange->save(); + } + $this->goback(); + } + + public function actionClearMarket() + { + if (!$this->admin) + return; + $market = getdbo('db_markets', getiparam('id')); + if ($market) { + $market->lastsent = null; + $market->save(); + } + $this->goback(); + } + + // called from the dashboard page + public function actionClearorder() + { + if (!$this->admin) + return; + $order = getdbo('db_orders', getiparam('id')); + if ($order) { + $order->delete(); + } + $this->goback(); + } + + public function actionCancelorder() + { + if (!$this->admin) + return; + $order = getdbo('db_orders', getiparam('id')); + + cancelExchangeOrder($order); + + $this->goback(); + } + + //////////////////////////////////////////////////////////////////////////////////////// + + public function actionAlgo() + { + $algo = getalgoparam(); + $a = getdbosql('db_algos', "name=:name", array( + ':name' => $algo + )); + + if ($a) + user()->setState('yaamp-algo', $a->name); + else + user()->setState('yaamp-algo', 'all'); + + $route = getparam('r'); + if (!empty($route)) + $this->redirect($route); + else + $this->goback(); + } + + public function actionGomining() + { + $algo = getalgoparam(); + if ($algo == 'all') { + return; + } + user()->setState('yaamp-algo', $algo); + $this->redirect("/site/mining"); + } + + public function actionUpdatePrice() + { + if (!$this->admin) + return; + BackendPricesUpdate(); + $this->goback(); + } + + public function actionUninstallCoin() + { + if (!$this->admin) + return; + + $coin = getdbo('db_coins', getiparam('id')); + if ($coin) { + // dborun("delete from blocks where coin_id=$coin->id"); + dborun("delete from exchange where coinid=$coin->id"); + dborun("delete from earnings where coinid=$coin->id"); + // dborun("delete from markets where coinid=$coin->id"); + dborun("delete from orders where coinid=$coin->id"); + dborun("delete from shares where coinid=$coin->id"); + + $coin->enable = false; + $coin->installed = false; + $coin->auto_ready = false; + $coin->master_wallet = null; + $coin->mint = 0; + $coin->balance = 0; + $coin->save(); + } + + $this->redirect("/site/admin"); + } + + public function actionOptimize() + { + BackendOptimizeTables(); + $this->goback(); + } + + public function actionRunExchange() + { + if (!$this->admin) + return; + + $id = getiparam('id'); + $balance = getdbo('db_balances', $id); + + if ($balance) + runExchange($balance->name); + + $tm = round($this->elapsedTime(), 3); + + if ($balance) + debuglog("runexchange done ({$balance->name}) {$tm} sec"); + else + debuglog("runexchange failed (no id!)"); + + $this->redirect("/site/common"); + } + + public function actionEval() + { + // if(!$this->admin) return; + + // $param = getparam('param'); + // if($param) eval($param); + // else $param = ''; + + // $this->render('eval', array('param'=>$param)); + } + + public function actionMainbtc() + { + debuglog(__METHOD__); + setcookie('mainbtc', '1', time() + 60 * 60 * 24, '/'); + } } diff --git a/web/yaamp/modules/site/about.php b/web/yaamp/modules/site/about.php index 3d61b59aa..a24d4995c 100644 --- a/web/yaamp/modules/site/about.php +++ b/web/yaamp/modules/site/about.php @@ -4,56 +4,15 @@
-

Although i've been exposed by friends who are mining bitcoin or some other dogecoin -for a little while already, i'm pretty new to the cryptocoin mining universe. I do like -the concept of cryptocurrency for many reasons. One of them being certainly to lessen the -monetary policy control from the few hands. Cryptocurrencies seem well suited to something -that looks like a libertarianism political philosophy. That's probably going to be a very -slow and long term shift, but i guess that's a step toward freedom and democracy. Numbers -would normally eventually outweigh the few. Another reason is because it's fun.

- -

I must say that it's the maxcoin launch that really got my attention. Because mining -early is good and because i feel Max Keiser is a relevant voice for cryptocurrencies. I -got myself a decent GPU and started mining maxcoin. I've got a few by mining at 1gh.com -for a week. It did the job very well. Then i've been aware of a possible 51% attack on -cryptocurrency. I really don't think 1gh.com would mess with anything, but still, that's -an issue. As there are already many other mining pools, it looks like anonymous mining is -popular. Especially at maxcoin launch when they all got ddosed. I went from one to -another before i got something working on 1gh.com. Then i agreed that anonymous mining -is great and my password paper notebook had enough.

- -

I understand the only available implementation out there is not anonymous. Everyone has -the same stratum-mining + MPOS implementation. Only 1gh.com and dwarfmining seem to have -their own original modified implementation or i didn't find correctly. So i saw there an -opportunity for another anonymous mining pool. For a whole day, i tried to refrain myself -from this crazy idea of making another mining pool. I'm some kind of compulsive coder. I -do it for a living and i do it for fun. And that's the kind of project i like.

- -

Crazy idea because there aren't much chances for success. I mean nobody is going to -come to an empty mining site. The opportunity window is very early at the coin launch -when low hashpower can still find blocks. Even though it was a few days late to start -such a project for maxcoin, the next day, that was too strong, i had to do it. Else i -was stuck from doing my other projects. In any way, if i'm going to be involved in the -cryptocurrency world, it's going to be also as a programmer or at hacking here and there -sooner or later. That was also an opportunity to jump in some python code.

- -

This server is online for at least one year. I do have other servers for other projects -too. They are so cheap. So i'll continue to plug in my miner (and play a little less world -of warcraft) and look forward to acquire more hashpower. But another thing i get from this -last weekend journey is some knowledge of the technology so i can think about contributing -to the programming effort whenever i can and be ready whenever there's another interesting -coin launch.

- -

Now i can go back to work,

- -

Long life to maxcoin,

- -

neozon

- -

19/02/2014

+

cryptopool.builders for all your crypto-server needs. Our team has been working in the crypto world for the last 5 years. +We have been hired by over 50 clients during the last two years to install their crypto-pools. +We are pleased to offer everyone this free script to help you in setting up your own pools.

+ +

cryptopool.builders

+ +

16/09/2018





















- diff --git a/web/yaamp/modules/site/admin.php b/web/yaamp/modules/site/admin.php index 92620c64b..911945697 100644 --- a/web/yaamp/modules/site/admin.php +++ b/web/yaamp/modules/site/admin.php @@ -17,8 +17,8 @@ end; $serverlist = dbolist("SELECT DISTINCT rpchost FROM coins WHERE installed=1 ORDER BY rpchost"); -foreach ($serverlist as $srv) { - echo ''; +foreach ($serverlist as $srv) { + echo ''; } echo << end; - - diff --git a/web/yaamp/modules/site/admin_results.php b/web/yaamp/modules/site/admin_results.php index 4d253081a..412177039 100644 --- a/web/yaamp/modules/site/admin_results.php +++ b/web/yaamp/modules/site/admin_results.php @@ -1,11 +1,12 @@ ${1}', $html); - return $html; +function valuetocell($amount) +{ + $html = $amount ? bitcoinvaluetoa($amount) : '-'; + //$html = rtrim($html,'0'); + //$html = rtrim($html,'.'); + $html = preg_replace('/([0]+)$/', '${1}', $html); + return $html; } ///////////////////////////////////////////////////////////////////////////////////// @@ -25,12 +26,12 @@ function valuetocell($amount) { tableClass: "dataGrid", widgets: ["zebra","filter","Storage","saveSort"], widgetOptions: { - saveSort: true, - filter_saveFilters: true, - filter_external: ".search", - filter_columnFilters: false, - filter_childRows : true, - filter_ignoreCase: true + saveSort: true, + filter_saveFilters: true, + filter_external: ".search", + filter_columnFilters: false, + filter_childRows : true, + filter_ignoreCase: true }}'); echo <<$server)); -} -else - $coins = getdbolist('db_coins', "(installed OR enable OR watch) ORDER BY algo, index_avg DESC"); +if (!empty($server)) { + $coins = getdbolist('db_coins', "(installed OR enable OR watch) AND rpchost=:server ORDER BY algo, index_avg DESC", array( + ':server' => $server + )); +} else + $coins = getdbolist('db_coins', "(installed OR enable OR watch) ORDER BY algo, index_avg DESC"); $mining = getdbosql('db_mining'); -foreach($coins as $coin) -{ - echo ''; - - $lowsymbol = strtolower($coin->symbol); - echo ''; - - $algo_color = getAlgoColors($coin->algo); - echo ''; - - if(!$coin->enable) echo ''; - else if($coin->auto_ready) echo 'A'; - else echo 'D'; - - if($coin->visible) echo 'V'; - else echo 'H'; - - if($coin->auxpow) echo 'X'; - else echo ' '; - - echo '
'; - - if($coin->rpccurl) echo 'C'; - else echo ' '; - - if($coin->rpcssl) echo 'S'; - else echo ' '; - - if($coin->watch) echo 'W'; - else echo ' '; - - if($coin->block_height < $coin->target_height) { - $percent = round($coin->block_height*100/$coin->target_height, 1); - echo '
'.$percent.'%'; - } - - echo ""; - $version = formatWalletVersion($coin); - if (!empty($coin->symbol2)) $version .= " ({$coin->symbol2})"; - - echo "$coin->name ($coin->symbol) -
$version"; - - echo "$coin->rpchost:$coin->rpcport"; - if($coin->connections) echo " ($coin->connections)"; - echo "
$coin->rpcencoding   ($coin->algo)  "; - - $difficulty = Itoa2($coin->difficulty, 3); - if ($difficulty > 1e20) $difficulty = ' '; - - if(!empty($coin->errors)) - echo ''.$difficulty.'
'.$coin->block_height.''; - else - echo ''.$difficulty.'
'.$coin->block_height.''; - - $btcmhd = yaamp_profitability($coin); - $btcmhd = mbitcoinvaluetoa($btcmhd); - - $h = $coin->block_height-100; - $ss1 = dboscalar("SELECT count(*) FROM blocks WHERE coin_id={$coin->id} AND height>=$h AND category!='orphan'"); - $ss2 = dboscalar("SELECT count(*) FROM blocks WHERE coin_id={$coin->id} AND height>=$h AND category='orphan'"); - - $percent_pool1 = $ss1? $ss1.'%': ''; - $percent_pool2 = $ss2? $ss2.'%': ''; - -// $network_ttf = $coin->network_ttf? sectoa($coin->network_ttf): ''; -// $actual_ttf = $coin->actual_ttf? sectoa($coin->actual_ttf): ''; -// $pool_ttf = $coin->pool_ttf? sectoa($coin->pool_ttf): ''; -// echo "$network_ttf
$actual_ttf"; -// echo "$pool_ttf
"; - - echo ''; - if($ss1 > 50) - echo ''.$btcmhd.'
'.$percent_pool1.''; - else - echo ''.$btcmhd.'
'.$percent_pool1; - echo ' '.$percent_pool2.''; - - $price = bitcoinvaluetoa($coin->price); - $price2 = bitcoinvaluetoa($coin->price2); - - if($coin->dontsell && YAAMP_ALLOW_EXCHANGE) - echo "$price
$price2"; - else - echo "$price
$price2"; - -// $stakebtc = bitcoinvaluetoa($coin->stake*$coin->price); -// if ($coin->stake) -// echo ''.$coin->stake.'
'.$stakebtc.''; -// else -// echo ''; - - $cell = valuetocell($coin->mint).'
'.valuetocell($coin->cleared); - - if($coin->balance+$coin->mint < $coin->cleared) - echo ''.$cell.''; - else - echo ''.$cell.''; - - $cell = valuetocell($coin->balance).'
'.valuetocell($coin->available); - echo ''.$cell.''; - - $btc = bitcoinvaluetoa($coin->balance * $coin->price); - $available = bitcoinvaluetoa($coin->available * $coin->price); - echo ''.$btc.'
'.$available.''; - - $fiat = round($coin->balance * $coin->price * $mining->usdbtc, 2). ' $'; - $available = round($coin->available * $coin->price * $mining->usdbtc, 2). ' $'; - echo ''.$fiat.'
'.$available.''; - - $marketname = ''; - $bestmarket = getBestMarket($coin); - if($bestmarket) $marketname = $bestmarket->name; - - echo "$coin->reward
$marketname"; - - echo ""; +foreach ($coins as $coin) { + echo ''; + + $lowsymbol = strtolower($coin->symbol); + echo ''; + + $algo_color = getAlgoColors($coin->algo); + echo ''; + + if (!$coin->enable) + echo ''; + else if ($coin->auto_ready) + echo 'A'; + else + echo 'D'; + + if ($coin->visible) + echo 'V'; + else + echo 'H'; + + if ($coin->auxpow) + echo 'X'; + else + echo ' '; + + echo '
'; + + if ($coin->rpccurl) + echo 'C'; + else + echo ' '; + + if ($coin->rpcssl) + echo 'S'; + else + echo ' '; + + if ($coin->watch) + echo 'W'; + else + echo ' '; + + if ($coin->block_height < $coin->target_height) { + $percent = round($coin->block_height * 100 / $coin->target_height, 1); + echo '
' . $percent . '%'; + } + + echo ""; + $version = formatWalletVersion($coin); + if (!empty($coin->symbol2)) + $version .= " ({$coin->symbol2})"; + + echo "$coin->name ($coin->symbol) +
$version"; + + echo "$coin->rpchost:$coin->rpcport"; + if ($coin->connections) + echo " ($coin->connections)"; + echo "
$coin->rpcencoding   ($coin->algo)  "; + + $difficulty = Itoa2($coin->difficulty, 3); + if ($difficulty > 1e20) + $difficulty = ' '; + + if (!empty($coin->errors)) + echo '' . $difficulty . '
' . $coin->block_height . ''; + else + echo '' . $difficulty . '
' . $coin->block_height . ''; + + $btcmhd = yaamp_profitability($coin); + $btcmhd = mbitcoinvaluetoa($btcmhd); + + $h = $coin->block_height - 100; + $ss1 = dboscalar("SELECT count(*) FROM blocks WHERE coin_id={$coin->id} AND height>=$h AND category!='orphan'"); + $ss2 = dboscalar("SELECT count(*) FROM blocks WHERE coin_id={$coin->id} AND height>=$h AND category='orphan'"); + + $percent_pool1 = $ss1 ? $ss1 . '%' : ''; + $percent_pool2 = $ss2 ? $ss2 . '%' : ''; + + // $network_ttf = $coin->network_ttf? sectoa($coin->network_ttf): ''; + // $actual_ttf = $coin->actual_ttf? sectoa($coin->actual_ttf): ''; + // $pool_ttf = $coin->pool_ttf? sectoa($coin->pool_ttf): ''; + // echo "$network_ttf
$actual_ttf"; + // echo "$pool_ttf
"; + + echo ''; + if ($ss1 > 50) + echo '' . $btcmhd . '
' . $percent_pool1 . ''; + else + echo '' . $btcmhd . '
' . $percent_pool1; + echo ' ' . $percent_pool2 . ''; + + $price = bitcoinvaluetoa($coin->price); + $price2 = bitcoinvaluetoa($coin->price2); + + if ($coin->dontsell && YAAMP_ALLOW_EXCHANGE) + echo "$price
$price2"; + else + echo "$price
$price2"; + + // $stakebtc = bitcoinvaluetoa($coin->stake*$coin->price); + // if ($coin->stake) + // echo ''.$coin->stake.'
'.$stakebtc.''; + // else + // echo ''; + + $cell = valuetocell($coin->mint) . '
' . valuetocell($coin->cleared); + + if ($coin->balance + $coin->mint < $coin->cleared) + echo '' . $cell . ''; + else + echo '' . $cell . ''; + + $cell = valuetocell($coin->balance) . '
' . valuetocell($coin->available); + echo '' . $cell . ''; + + $btc = bitcoinvaluetoa($coin->balance * $coin->price); + $available = bitcoinvaluetoa($coin->available * $coin->price); + echo '' . $btc . '
' . $available . ''; + + $fiat = round($coin->balance * $coin->price * $mining->usdbtc, 2) . ' $'; + $available = round($coin->available * $coin->price * $mining->usdbtc, 2) . ' $'; + echo '' . $fiat . '
' . $available . ''; + + $marketname = ''; + $bestmarket = getBestMarket($coin); + if ($bestmarket) + $marketname = $bestmarket->name; + + echo "$coin->reward
$marketname"; + + echo ""; } $total = count($coins); echo ''; -echo ''.$total.' wallets'; +echo '' . $total . ' wallets'; echo ''; ////////////////////////////////////////// echo "
"; - - - - - - - - - - - - - diff --git a/web/yaamp/modules/site/api.php b/web/yaamp/modules/site/api.php index 01c4f8bc2..12a041e6d 100644 --- a/web/yaamp/modules/site/api.php +++ b/web/yaamp/modules/site/api.php @@ -10,7 +10,7 @@ request:

- http:///api/wallet?address=WALLET_ADDRESS

+ http:///api/wallet?address=WALLET_ADDRESS

result:
@@ -25,7 +25,7 @@
 
 request:
 

- http:///api/walletEx?address=WALLET_ADDRESS

+ http:///api/walletEx?address=WALLET_ADDRESS

result:
@@ -45,24 +45,25 @@
 		"accepted": 82463372.083,
 		"rejected": 0
 	}]
-
+
 	,"payouts":[{
 		"time": 1529860641,
 		"amount": "0.001",
 		"tx": "transaction_id_of_the_payout"
 	}]
-
+
 }
 

Pool Status

request:

- http:///api/status

+ http:///api/status

result:
@@ -88,7 +89,8 @@
 
 request:
 

- http:///api/currencies

+ http:///api/currencies

result:
@@ -111,13 +113,14 @@
 }
 
- +

Rental Status

request:

- http:///api/rental?key=API_KEY

+ http:///api/rental?key=API_KEY

result:
@@ -154,7 +157,8 @@
 
 request:
 

- http:///api/rental_price?key=API_KEY&jobid=xx&price=xx

+ http:///api/rental_price?key=API_KEY&jobid=xx&price=xx

@@ -164,7 +168,8 @@ request:

- http:///api/rental_hashrate?key=API_KEY&jobid=xx&hashrate=xx

+ http:///api/rental_hashrate?key=API_KEY&jobid=xx&hashrate=xx

@@ -172,7 +177,8 @@ request:

- http:///api/rental_start?key=API_KEY&jobid=xx

+ http:///api/rental_start?key=API_KEY&jobid=xx

@@ -180,11 +186,13 @@ request:

- http:///api/rental_stop?key=API_KEY&jobid=xx

+ http:///api/rental_stop?key=API_KEY&jobid=xx

- +

@@ -199,5 +207,3 @@ - - diff --git a/web/yaamp/modules/site/backup.php b/web/yaamp/modules/site/backup.php index 329bb90e2..ca87a5492 100644 --- a/web/yaamp/modules/site/backup.php +++ b/web/yaamp/modules/site/backup.php @@ -20,8 +20,6 @@
- - -

- +'.$symbol.""; - echo ''.$market->name.''; - echo ''.$price.''; - echo ''.$price2.''; - echo ''.$ptime.''; - echo ''.$ontrade.''; - echo ''.$balance.''; - echo $total>0.1? "$total": "$total"; - echo $total>0.1? "$total_usd": ''.sprintf('%.2f',$total_usd).''; - echo ''.$btime.''; - echo ''.$market->deposit_address.''; - $disabled = $market->disabled > 0 ? 'market disabled ('.$market->disabled.')' : 'OK'; - if (!$coin->enable) $disabled = "coin disabled"; - echo ''.$disabled.''; - - echo 'update ticker'; - - $totals_trade += $market->ontrade*$price; - $totals += $total; $totals_usd += $total_usd; - - echo ""; +$symbols = array(); + +foreach ($markets as $market) { + if ($market->pricetime == 0) + continue; + $balance = $market->balance; + $balance += $market->ontrade; + if ($balance * $market->price2 < 200 * 1e-8) + continue; + + $coin = getdbo('db_coins', $market->coinid); + $coinimg = CHtml::image($coin->image, $coin->symbol, array( + 'width' => '16' + )); + $symbol = $coin->symbol; + if (!empty($coin->symbol2)) + $symbol = $coin->symbol2; + + if (arraySafeVal($symbols, $symbol)) + continue; // prevent dups + $symbols[$symbol] = 1; + + $marketurl = getMarketUrl($coin, $market->name); + + echo ""; + + $btime = $market->balancetime ? datetoa2($market->balancetime) . ' ago' : 'never'; + $ptime = $market->pricetime ? datetoa2($market->pricetime) . ' ago' : 'never'; + $price = $market->price ? bitcoinvaluetoa($market->price) : bitcoinvaluetoa($coin->price); + $price2 = $market->price2 ? bitcoinvaluetoa($market->price2) : bitcoinvaluetoa($coin->price2); + $ontrade = $market->ontrade ? $market->ontrade : '-'; + $total = bitcoinvaluetoa($balance * $price); + $total_usd = round($balance * $price * $mining->usdbtc, 2); + + $tdclass = $market->disabled ? 'disabled' : ''; + + echo '' . $coinimg . ''; + echo '' . $symbol . ""; + echo '' . $market->name . ''; + echo '' . $price . ''; + echo '' . $price2 . ''; + echo '' . $ptime . ''; + echo '' . $ontrade . ''; + echo '' . $balance . ''; + echo $total > 0.1 ? "$total" : "$total"; + echo $total > 0.1 ? "$total_usd" : '' . sprintf('%.2f', $total_usd) . ''; + echo '' . $btime . ''; + echo '' . $market->deposit_address . ''; + $disabled = $market->disabled > 0 ? 'market disabled (' . $market->disabled . ')' : 'OK'; + if (!$coin->enable) + $disabled = "coin disabled"; + echo '' . $disabled . ''; + + echo 'update ticker'; + + $totals_trade += $market->ontrade * $price; + $totals += $total; + $totals_usd += $total_usd; + + echo ""; } echo ""; @@ -101,8 +110,8 @@ echo ''; echo 'Total'; -echo ''.bitcoinvaluetoa($totals).''; -echo ''.round($totals_usd,2).''; +echo '' . bitcoinvaluetoa($totals) . ''; +echo '' . round($totals_usd, 2) . ''; echo ''; echo ''; echo ''; diff --git a/web/yaamp/modules/site/benchmarks.php b/web/yaamp/modules/site/benchmarks.php index 35e97adff..77992ddbb 100644 --- a/web/yaamp/modules/site/benchmarks.php +++ b/web/yaamp/modules/site/benchmarks.php @@ -1,13 +1,13 @@
-
YIIMP BENCHMARKS
+
cryptopool.builders Benchmarks
-

YiiMP now allow users to share their ccminer (1.7.6+) device hashrate, more supported miners will come later.

+

cryptopool.builders now allow users to share their ccminer (1.7.6+) device hashrate, more supported miners will come later.

--o stratum+tcp://:<PORT> -a <algo> -u <wallet_adress> -p stats
+-o stratum+tcp://:<PORT> -a <algo> -u <wallet_adress> -p stats
 

@@ -33,4 +33,3 @@





























- diff --git a/web/yaamp/modules/site/block.php b/web/yaamp/modules/site/block.php index 963a8e260..5ade74ecc 100644 --- a/web/yaamp/modules/site/block.php +++ b/web/yaamp/modules/site/block.php @@ -1,5 +1,4 @@ end; - - diff --git a/web/yaamp/modules/site/block_results.php b/web/yaamp/modules/site/block_results.php index fe2145482..0d7374bbd 100644 --- a/web/yaamp/modules/site/block_results.php +++ b/web/yaamp/modules/site/block_results.php @@ -1,10 +1,11 @@ $id)); +$id = (int)getiparam('id'); +$db_blocks = getdbolist('db_blocks', "coin_id=:id order by time desc limit 250", array( + ':id' => $id +)); $coin = getdbo('db_coins', $id); showTableSorter('maintable', "{ @@ -48,87 +49,80 @@ end; -foreach($db_blocks as $db_block) -{ - if(!$db_block->coin_id) continue; - - if(!$coin) continue; - - if($db_block->category == 'stake' && !$this->admin) continue; - if($db_block->category == 'generated' && !$this->admin) continue; // mature stake income - -// $remote = new WalletRPC($coin); - -// $blockext = $remote->getblock($db_block->blockhash); -// $tx = $remote->gettransaction($blockext['tx'][0]); - -// $db_block->category = $tx['details'][0]['category']; - - if($db_block->category == 'immature') - echo ""; - else - echo ""; - - echo ''; - - $flags = $db_block->segwit ? ' ' : ''; - - echo ''; - if ($this->admin) - echo ''.$coin->name.''; - else - echo ''.$coin->name.''; - echo ' ('.$coin->symbol.')'.$flags.''; - -// $db_block->confirmations = $blockext['confirmations']; -// $db_block->save(); - $d = datetoa2($db_block->time); - echo ''.$d.' ago'; - echo ''.$coin->createExplorerLink($db_block->height, array('height'=>$db_block->height)).''; - echo ''.$db_block->amount.''; - echo ''; - - if($db_block->category == 'orphan') - echo "Orphan"; - - else if($db_block->category == 'immature') { - $eta = ''; - if ($coin->block_time && $coin->mature_blocks) { - $t = (int) ($coin->mature_blocks - $db_block->confirmations) * $coin->block_time; - $eta = "ETA: ".sprintf('%dh %02dmn', ($t/3600), ($t/60)%60); - } - echo "Immature ({$db_block->confirmations})"; - } - - else if($db_block->category == 'generate') - echo 'Confirmed'; - - else if($db_block->category == 'stake') - echo "Stake ({$db_block->confirmations})"; - - else if($db_block->category == 'generated') - echo 'Stake'; - - echo ""; - - echo ''.round_difficulty($db_block->difficulty).''; - $diff_user = $db_block->difficulty_user; - if (!$diff_user && substr($db_block->blockhash,0,4) == '0000') - $diff_user = hash_to_difficulty($coin, $db_block->blockhash); - echo ''.round_difficulty($diff_user).''; - - $finder = ''; - if (!empty($db_block->userid)) { - $user = getdbo('db_accounts', $db_block->userid); - $finder = $user ? substr($user->username, 0, 7).'...' : ''; - } - echo ''.$finder.''; - echo ''; - echo $coin->createExplorerLink($db_block->blockhash, array('hash'=>$db_block->blockhash)); - echo ""; - echo ""; +foreach ($db_blocks as $db_block) +{ + if (!$db_block->coin_id) continue; + + if (!$coin) continue; + + if ($db_block->category == 'stake' && !$this->admin) continue; + if ($db_block->category == 'generated' && !$this->admin) continue; // mature stake income + // $remote = new WalletRPC($coin); + // $blockext = $remote->getblock($db_block->blockhash); + // $tx = $remote->gettransaction($blockext['tx'][0]); + // $db_block->category = $tx['details'][0]['category']; + if ($db_block->category == 'immature') echo ""; + else echo ""; + + echo ''; + + $flags = $db_block->segwit ? ' ' : ''; + + echo ''; + if ($this->admin) echo '' . $coin->name . ''; + else echo '' . $coin->name . ''; + echo ' (' . $coin->symbol . ')' . $flags . ''; + + // $db_block->confirmations = $blockext['confirmations']; + // $db_block->save(); + $d = datetoa2($db_block->time); + echo '' . $d . ' ago'; + echo '' . $coin->createExplorerLink($db_block->height, array( + 'height' => $db_block->height + )) . ''; + echo '' . $db_block->amount . ''; + echo ''; + + if ($db_block->category == 'orphan') echo "Orphan"; + + else if ($db_block->category == 'immature') + { + $eta = ''; + if ($coin->block_time && $coin->mature_blocks) + { + $t = (int)($coin->mature_blocks - $db_block->confirmations) * $coin->block_time; + $eta = "ETA: " . sprintf('%dh %02dmn', ($t / 3600) , ($t / 60) % 60); + } + echo "Immature ({$db_block->confirmations})"; + } + + else if ($db_block->category == 'generate') echo 'Confirmed'; + + else if ($db_block->category == 'stake') echo "Stake ({$db_block->confirmations})"; + + else if ($db_block->category == 'generated') echo 'Stake'; + + echo ""; + + echo '' . round_difficulty($db_block->difficulty) . ''; + $diff_user = $db_block->difficulty_user; + if (!$diff_user && substr($db_block->blockhash, 0, 4) == '0000') $diff_user = hash_to_difficulty($coin, $db_block->blockhash); + echo '' . round_difficulty($diff_user) . ''; + + $finder = ''; + if (!empty($db_block->userid)) + { + $user = getdbo('db_accounts', $db_block->userid); + $finder = $user ? substr($user->username, 0, 7) . '...' : ''; + } + echo '' . $finder . ''; + echo ''; + echo $coin->createExplorerLink($db_block->blockhash, array( + 'hash' => $db_block->blockhash + )); + echo ""; + echo ""; } echo ""; - diff --git a/web/yaamp/modules/site/bookmark.php b/web/yaamp/modules/site/bookmark.php index 03b8cb649..75893ebea 100644 --- a/web/yaamp/modules/site/bookmark.php +++ b/web/yaamp/modules/site/bookmark.php @@ -1,7 +1,5 @@ id}'>{$coin->name} "; echo "Bookmark: $bookmark->label
"; @@ -9,17 +7,23 @@ echo CUFHtml::beginForm(); echo CUFHtml::errorSummary($bookmark); -echo CUFHtml::openTag('fieldset', array('class'=>'inlineLabels')); +echo CUFHtml::openTag('fieldset', array( + 'class' => 'inlineLabels' +)); echo CUFHtml::openActiveCtrlHolder($bookmark, 'label'); echo CUFHtml::activeLabelEx($bookmark, 'label'); -echo CUFHtml::activeTextField($bookmark, 'label', array('maxlength'=>32)); +echo CUFHtml::activeTextField($bookmark, 'label', array( + 'maxlength' => 32 +)); echo "

.

"; echo CUFHtml::closeCtrlHolder(); echo CUFHtml::openActiveCtrlHolder($bookmark, 'address'); echo CUFHtml::activeLabelEx($bookmark, 'address'); -echo CUFHtml::activeTextField($bookmark, 'address', array('maxlength'=>128)); +echo CUFHtml::activeTextField($bookmark, 'address', array( + 'maxlength' => 128 +)); echo "

.

"; echo CUFHtml::closeCtrlHolder(); diff --git a/web/yaamp/modules/site/botnets.php b/web/yaamp/modules/site/botnets.php index b2c9c05c9..1f97a0c0d 100644 --- a/web/yaamp/modules/site/botnets.php +++ b/web/yaamp/modules/site/botnets.php @@ -1,11 +1,9 @@ pageTitle = 'Botnets'; -echo getAdminSideBarLinks().'

'; +echo getAdminSideBarLinks() . '

'; ////////////////////////////////////////////////////////////////////////////////////// - JavascriptFile("/yaamp/ui/js/jquery.metadata.js"); JavascriptFile("/yaamp/ui/js/jquery.tablesorter.widgets.js"); @@ -17,6 +15,7 @@ end; + showTableSorter('maintable', "{ tableClass: 'dataGrid', textExtraction: { @@ -45,63 +44,60 @@ end; -$botnets = dbolist("SELECT userid, algo, pid, max(time) AS time, count(userid) AS workers, count(DISTINCT ip) AS ips, max(version) AS version ". - " FROM workers GROUP BY userid, algo, pid HAVING ips > 10 ORDER BY ips DESC" -); -if(!empty($botnets)) -foreach($botnets as $botnet) +$botnets = dbolist("SELECT userid, algo, pid, max(time) AS time, count(userid) AS workers, count(DISTINCT ip) AS ips, max(version) AS version " . " FROM workers GROUP BY userid, algo, pid HAVING ips > 10 ORDER BY ips DESC"); + +if (!empty($botnets)) foreach ($botnets as $botnet) { - if (!$botnet['userid']) continue; + if (!$botnet['userid']) continue; - $user = getdbo('db_accounts', $botnet['userid']); - if (!$user) continue; + $user = getdbo('db_accounts', $botnet['userid']); + if (!$user) continue; - $coin = getdbo('db_coins', $user->coinid); - if (!$coin) continue; + $coin = getdbo('db_coins', $user->coinid); + if (!$coin) continue; - $coinsym = $coin->symbol; - $coinimg = CHtml::image($coin->image, $coin->symbol, array('width'=>'16')); - $coinlink = CHtml::link($coin->name, '/site/coin?id='.$coin->id); + $coinsym = $coin->symbol; + $coinimg = CHtml::image($coin->image, $coin->symbol, array( + 'width' => '16' + )); + $coinlink = CHtml::link($coin->name, '/site/coin?id=' . $coin->id); - $d = datetoa2($botnet['time']); + $d = datetoa2($botnet['time']); - echo ''; + echo ''; - echo ''.$coinimg.''; - echo ''.$coinsym.''; - echo ''.$botnet['algo'].''; - echo ''.CHtml::link($user->username, '/?address='.$user->username).''; - echo ''.$d.''; - echo ''.$botnet['pid'].''; - echo ''.$botnet['ips'].''; - echo ''.$botnet['workers'].''; - echo ''.$botnet['version'].''; + echo '' . $coinimg . ''; + echo '' . $coinsym . ''; + echo '' . $botnet['algo'] . ''; + echo '' . CHtml::link($user->username, '/?address=' . $user->username) . ''; + echo '' . $d . ''; + echo '' . $botnet['pid'] . ''; + echo '' . $botnet['ips'] . ''; + echo '' . $botnet['workers'] . ''; + echo '' . $botnet['version'] . ''; - echo ''; + echo ''; - if ($user->logtraffic) - echo 'unwatch '; - else - echo 'watch '; + if ($user->logtraffic) echo 'unwatch '; + else echo 'watch '; - if ($user->is_locked) - echo 'unblock '; - else - echo 'block '; + if ($user->is_locked) echo 'unblock '; + else echo 'block '; - echo 'BAN'; + echo 'BAN'; - echo ''; + echo ''; - echo ''; + echo ''; } echo ''; echo ''; -if(empty($botnets)) { - echo ''."No botnets detected".''; +if (empty($botnets)) +{ + echo '' . "No botnets detected" . ''; } echo ''; diff --git a/web/yaamp/modules/site/coin.php b/web/yaamp/modules/site/coin.php index 9431db201..8edfdfa44 100644 --- a/web/yaamp/modules/site/coin.php +++ b/web/yaamp/modules/site/coin.php @@ -1,36 +1,37 @@ goback(); +if (!$coin) +{ + $this->goback(); } -$this->pageTitle = 'Wallet - '.$coin->symbol; +$this->pageTitle = 'Wallet - ' . $coin->symbol; // force a refresh after 10mn to prevent memory leaks in chrome -app()->clientScript->registerMetaTag('600', null, 'refresh'); +app() + ->clientScript + ->registerMetaTag('600', null, 'refresh'); -if (!empty($coin->algo) && $coin->algo != 'PoS') - user()->setState('yaamp-algo', $coin->algo); +if (!empty($coin->algo) && $coin->algo != 'PoS') user() + ->setState('yaamp-algo', $coin->algo); $remote = new WalletRPC($coin); $info = $remote->getinfo(); $sellamount = $coin->balance; //if ($info) $sellamount = floatval($sellamount) - arraySafeVal($info, "paytxfee") * 3; - -echo getAdminSideBarLinks().'

'; +echo getAdminSideBarLinks() . '

'; echo getAdminWalletLinks($coin, $info, 'wallet'); -$maxrows = arraySafeVal($_REQUEST,'rows', 500); -$since = arraySafeVal($_REQUEST,'since', time() - (7*24*3600)); // one week - +$maxrows = arraySafeVal($_REQUEST, 'rows', 500); +$since = arraySafeVal($_REQUEST, 'since', time() - (7 * 24 * 3600)); // one week echo '
'; -app()->clientScript->registerCoreScript('jquery.ui'); // dialog - -/* +app() + ->clientScript + ->registerCoreScript('jquery.ui'); // dialog +/* echo "
MAKE CONFIG & START"; if($info) @@ -154,11 +155,15 @@ function showSellAmountDialog(marketname, address, marketid, bookmarkid) END; + JavascriptReady("main_refresh();"); -if ($coin->watch) { - $this->renderPartial('coin_market_graph', array('coin'=>$coin)); - JavascriptReady("$(window).resize(graph_resized);"); +if ($coin->watch) +{ + $this->renderPartial('coin_market_graph', array( + 'coin' => $coin + )); + JavascriptReady("$(window).resize(graph_resized);"); } ////////////////////////////////////////////////////////////////////////////////////// diff --git a/web/yaamp/modules/site/coin_console.php b/web/yaamp/modules/site/coin_console.php index cffe37cd4..9e336d40f 100644 --- a/web/yaamp/modules/site/coin_console.php +++ b/web/yaamp/modules/site/coin_console.php @@ -1,64 +1,74 @@ goback(); -$this->pageTitle = 'Console - '.$coin->symbol; +if (!$coin) + $this->goback(); +$this->pageTitle = 'Console - ' . $coin->symbol; $remote = new WalletRPC($coin); -echo getAdminSideBarLinks().'

'; +echo getAdminSideBarLinks() . '

'; $info = $remote->getinfo(); if (!$info) { - echo $remote->error; - return; + echo $remote->error; + return; } -echo getAdminWalletLinks($coin, $info, 'console').'

'; +echo getAdminWalletLinks($coin, $info, 'console') . '

'; ////////////////////////////////////////////////////////////////////////////////////// function colorizeJson($json) { - $json = str_replace('"', '"', $json); - // strings - $res = preg_match_all("# "([^&]+)"([,\s])#", $json, $matches); - if ($res) foreach($matches[1] as $n=>$m) { - $sfx = $matches[2][$n]; - $class = ''; - if (strlen($m) == 64 && ctype_xdigit($m)) $class = 'hash'; - if (strlen($m) == 34 && ctype_alnum($m)) $class = 'addr'; - if (strlen($m) == 35 && ctype_alnum($m)) $class = 'addr'; - if (strlen($m) > 160 && ctype_alnum($m)) $class = 'data'; - if ($class == '' && strlen($m) < 64 && ctype_xdigit($m)) $class = 'hexa'; - $json = str_replace(' "'.$m.""".$sfx, ' "'.$m.'"'.$sfx, $json); - } - // keys - $res = preg_match_all("#"([^&]+)":#", $json, $matches); - if ($res) foreach($matches[1] as $n=>$m) { - $json = str_replace('"'.$m.""", '"'.$m.'"', $json); - } - // humanize timestamps like "blocktime": 1462359961, - $res = preg_match_all("#: ([0-9]{10})([,\s])#", $json, $matches); - if ($res) foreach($matches[1] as $n=>$m) { - $ts = intval($m); - if ($ts > 1400000000 && $ts < 1600000000) { - $sfx = $matches[2][$n]; - $date = strftime("%Y-%m-%d %T %z", $ts); - $json = str_replace(' '.$m.$sfx, ' "'.$date.'"'.$sfx, $json); - } - } - // numeric - $res = preg_match_all("#: ([e\-\.0-9]+)([,\s])#", $json, $matches); - if ($res) foreach($matches[1] as $n=>$m) { - $sfx = $matches[2][$n]; - $json = str_replace(' '.$m.$sfx, ' '.$m.''.$sfx, $json); - } - $json = preg_replace('#\[\s+\]#', '[]', $json); - $json = str_replace('[', '[', $json); - $json = str_replace(']', ']', $json); - $json = str_replace('{', '{', $json); - $json = str_replace('}', '}', $json); - return $json; + $json = str_replace('"', '"', $json); + // strings + $res = preg_match_all("# "([^&]+)"([,\s])#", $json, $matches); + if ($res) + foreach ($matches[1] as $n => $m) { + $sfx = $matches[2][$n]; + $class = ''; + if (strlen($m) == 64 && ctype_xdigit($m)) + $class = 'hash'; + if (strlen($m) == 34 && ctype_alnum($m)) + $class = 'addr'; + if (strlen($m) == 35 && ctype_alnum($m)) + $class = 'addr'; + if (strlen($m) > 160 && ctype_alnum($m)) + $class = 'data'; + if ($class == '' && strlen($m) < 64 && ctype_xdigit($m)) + $class = 'hexa'; + $json = str_replace(' "' . $m . """ . $sfx, ' "' . $m . '"' . $sfx, $json); + } + // keys + $res = preg_match_all("#"([^&]+)":#", $json, $matches); + if ($res) + foreach ($matches[1] as $n => $m) { + $json = str_replace('"' . $m . """, '"' . $m . '"', $json); + } + // humanize timestamps like "blocktime": 1462359961, + $res = preg_match_all("#: ([0-9]{10})([,\s])#", $json, $matches); + if ($res) + foreach ($matches[1] as $n => $m) { + $ts = intval($m); + if ($ts > 1400000000 && $ts < 1600000000) { + $sfx = $matches[2][$n]; + $date = strftime("%Y-%m-%d %T %z", $ts); + $json = str_replace(' ' . $m . $sfx, ' "' . $date . '"' . $sfx, $json); + } + } + // numeric + $res = preg_match_all("#: ([e\-\.0-9]+)([,\s])#", $json, $matches); + if ($res) + foreach ($matches[1] as $n => $m) { + $sfx = $matches[2][$n]; + $json = str_replace(' ' . $m . $sfx, ' ' . $m . '' . $sfx, $json); + } + $json = preg_replace('#\[\s+\]#', '[]', $json); + $json = str_replace('[', '[', $json); + $json = str_replace(']', ']', $json); + $json = str_replace('{', '{', $json); + $json = str_replace('}', '}', $json); + return $json; } ////////////////////////////////////////////////////////////////////////////////////// @@ -68,34 +78,34 @@ function colorizeJson($json) echo << function main_resize() { - var w = 0 + jQuery('div.form').width(); - var wpx = (w - 100).toString() + 'px'; - jQuery('.main-text-input').css({width: wpx}); + var w = 0 + jQuery('div.form').width(); + var wpx = (w - 100).toString() + 'px'; + jQuery('.main-text-input').css({width: wpx}); } var lazyLinks; function main_json_links() { - if (lazyLinks) clearTimeout(lazyLinks); - jQuery('s.addr').each(function(n) { - var el = $(this); - var addr = el[0].innerText; - var link = '' + addr + ''; - el.html(link); - }); - jQuery('s.hash').each(function(n) { - var el = $(this); - var hash = el[0].innerText; - var link = '' + hash + ''; - el.html(link); - }); + if (lazyLinks) clearTimeout(lazyLinks); + jQuery('s.addr').each(function(n) { + var el = $(this); + var addr = el[0].innerText; + var link = '' + addr + ''; + el.html(link); + }); + jQuery('s.hash').each(function(n) { + var el = $(this); + var hash = el[0].innerText; + var link = '' + hash + ''; + el.html(link); + }); } end; + showTableSorter('maintable', "{ tableClass: 'dataGrid', textExtraction: { @@ -56,37 +56,39 @@ end; + $notifications = getdbolist('db_notifications', "idcoin={$coin->id}"); -foreach($notifications as $rule) +foreach ($notifications as $rule) { - if ($rule->enabled) - $operations = 'disable'; - else - $operations = 'enable'; - $operations .= ' delete'; - - if ($rule->lasttriggered && $rule->lasttriggered == $rule->lastchecked) { - $status = 'Triggered'; - $operations = 'reset'.' '.$operations; - } else { - $status = ''; - } - - $description = $rule->description; - if (!empty($description) && !empty($rule->notifycmd)) $description .= '
'; - $description .= ''.$rule->notifycmd.''; - - echo ''; - - echo ''.$rule->notifytype.''; - echo ''.$rule->conditiontype.''; - echo ''.$rule->conditionvalue.''; - echo ''.$description.''; - echo ''.$status.''; - echo ''.datetoa2($rule->lastchecked).''; - echo ''.$operations.''; - - echo ""; + if ($rule->enabled) $operations = 'disable'; + else $operations = 'enable'; + $operations .= ' delete'; + + if ($rule->lasttriggered && $rule->lasttriggered == $rule->lastchecked) + { + $status = 'Triggered'; + $operations = 'reset' . ' ' . $operations; + } + else + { + $status = ''; + } + + $description = $rule->description; + if (!empty($description) && !empty($rule->notifycmd)) $description .= '
'; + $description .= '' . $rule->notifycmd . ''; + + echo ''; + + echo '' . $rule->notifytype . ''; + echo '' . $rule->conditiontype . ''; + echo '' . $rule->conditionvalue . ''; + echo '' . $description . ''; + echo '' . $status . ''; + echo '' . datetoa2($rule->lastchecked) . ''; + echo '' . $operations . ''; + + echo ""; } echo '
'; @@ -127,4 +129,6 @@ end; -?> \ No newline at end of file + + +?> diff --git a/web/yaamp/modules/site/common.php b/web/yaamp/modules/site/common.php index 244057aee..4e4a59504 100644 --- a/web/yaamp/modules/site/common.php +++ b/web/yaamp/modules/site/common.php @@ -221,6 +221,3 @@ function graph_init_negative(data) - - - diff --git a/web/yaamp/modules/site/common_results.php b/web/yaamp/modules/site/common_results.php index 88abe8b11..3b4f0e60a 100644 --- a/web/yaamp/modules/site/common_results.php +++ b/web/yaamp/modules/site/common_results.php @@ -17,11 +17,11 @@ tableClass: "dataGrid", widgets: ["Storage","saveSort"], textExtraction: { - 1: function(node, table, cellIndex) { return $(node).attr("data"); }, - 5: function(node, table, cellIndex) { return $(node).attr("data"); } + 1: function(node, table, cellIndex) { return $(node).attr("data"); }, + 5: function(node, table, cellIndex) { return $(node).attr("data"); } }, widgetOptions: { - saveSort: true + saveSort: true }}'); echo << end; -$total_coins = 0; -$total_workers = 0; -$total_hashrate = 0; +$total_coins = 0; +$total_workers = 0; +$total_hashrate = 0; $total_hashrate_bad = 0; $algos = array(); -foreach(yaamp_get_algos() as $algo) -{ - $algo_norm = yaamp_get_algo_norm($algo); +foreach (yaamp_get_algos() as $algo) { + $algo_norm = yaamp_get_algo_norm($algo); - $t = time() - 48*60*60; - $price = controller()->memcache->get_database_scalar("current_price-$algo", - "SELECT price FROM hashrate WHERE algo=:algo AND time>$t ORDER BY time DESC LIMIT 1", array(':algo'=>$algo)); + $t = time() - 48 * 60 * 60; + $price = controller()->memcache->get_database_scalar("current_price-$algo", "SELECT price FROM hashrate WHERE algo=:algo AND time>$t ORDER BY time DESC LIMIT 1", array( + ':algo' => $algo + )); - $norm = $price*$algo_norm; - $norm = take_yaamp_fee($norm, $algo); + $norm = $price * $algo_norm; + $norm = take_yaamp_fee($norm, $algo); - $algos[] = array($norm, $algo); + $algos[] = array( + $norm, + $algo + ); } function cmp($a, $b) { - return $a[0] < $b[0]; + return $a[0] < $b[0]; } usort($algos, 'cmp'); -foreach($algos as $item) -{ - $norm = $item[0]; - $algo = $item[1]; - - $algo_color = getAlgoColors($algo); - $algo_norm = yaamp_get_algo_norm($algo); - - $coins = getdbocount('db_coins', "enable AND auto_ready AND algo=:algo", array(':algo'=>$algo)); - $count = getdbocount('db_workers', "algo=:algo", array(':algo'=>$algo)); - - $total_coins += $coins; - $total_workers += $count; - - $t1 = time() - 24*60*60; - $total1 = dboscalar("SELECT sum(amount*price) FROM blocks WHERE category!='orphan' AND time>$t1 AND algo=:algo", array(':algo'=>$algo)); - if (!$coins && !$total1) continue; - $hashrate1 = dboscalar("SELECT avg(hashrate) FROM hashrate WHERE time>$t1 AND algo=:algo", array(':algo'=>$algo)); - - $hashrate = dboscalar("SELECT hashrate FROM hashrate WHERE algo=:algo ORDER BY time DESC LIMIT 1", array(':algo'=>$algo)); - $hashrate_bad = dboscalar("SELECT hashrate_bad FROM hashrate WHERE algo=:algo ORDER BY time DESC LIMIT 1", array(':algo'=>$algo)); - $bad = ($hashrate+$hashrate_bad)? round($hashrate_bad * 100 / ($hashrate+$hashrate_bad), 1): ''; - - $total_hashrate += $hashrate; - $total_hashrate_bad += $hashrate_bad; - - $hashrate_sfx = $hashrate? Itoa2($hashrate).'h/s': '-'; - $hashrate_bad = $hashrate_bad? Itoa2($hashrate_bad).'h/s': '-'; - - $hashrate_jobs = yaamp_rented_rate($algo); - $hashrate_jobs = $hashrate_jobs>0? Itoa2($hashrate_jobs).'h/s': ''; - - $price = dboscalar("SELECT price FROM hashrate WHERE algo=:algo ORDER BY time DESC LIMIT 1", array(':algo'=>$algo)); - $price = $price? mbitcoinvaluetoa($price): '-'; - - $rent = dboscalar("SELECT rent FROM hashrate WHERE algo=:algo ORDER BY time DESC LIMIT 1", array(':algo'=>$algo)); - $rent = $rent? mbitcoinvaluetoa($rent): '-'; - - $norm = mbitcoinvaluetoa($norm); - - $t = time() - 24*60*60; - $avgprice = dboscalar("SELECT avg(price) FROM hashrate WHERE algo=:algo AND time>$t", array(':algo'=>$algo)); - $avgprice = $avgprice? mbitcoinvaluetoa(take_yaamp_fee($avgprice, $algo)): '-'; - - $algo_unit_factor = yaamp_algo_mBTC_factor($algo); - $btcmhday1 = $hashrate1 != 0? mbitcoinvaluetoa($total1 / $hashrate1 * 1000000 * 1000 * $algo_unit_factor): '-'; - - $fees = yaamp_fee($algo); - - // todo: show per port data ? - $stratum = getdbosql('db_stratums', "algo=:algo ORDER BY started DESC", array(':algo'=>$algo)); - $isup = Booltoa($stratum); - $time = $isup ? datetoa2($stratum->started) : ''; - $ts = $isup ? datetoa2($stratum->started) : ''; - - echo ''; - echo ''; - echo CHtml::link($algo, '/site/gomining?algo='.$algo); - echo ''; - echo ''.$isup.' '.$time.''; - echo ''.(empty($coins) ? '-' : $coins).''; - echo ''.(empty($count) ? '-' : $count).''; - echo ''.(empty($fees) ? '-' : "$fees %").''; - echo ''.$hashrate_sfx.''; - echo ''.$hashrate_jobs.''; - - if ($bad > 10) - echo ''.$bad.'%'; - else if($bad > 5) - echo ''.$bad.'%'; - else - echo ''.(empty($bad) ? '-' : "$bad %").''; - - if ($norm>0) - echo ''.($price == 0.0 ? '-' : $price).''; - else - echo ''.($price == 0.0 ? '-' : $price).''; - - echo ''.$rent.''; - - // Norm - echo ''.($norm == 0.0 ? '-' : $norm).''; - - // 24E - echo ''.($avgprice == 0.0 ? '-' : $avgprice).''; - - // 24A - $style = ''; - if ($btcmhday1 != '-') - { - $avgprice = (double) $avgprice; - $btcmhd = (double) $btcmhday1; - - if($btcmhd > $avgprice*1.1) - $style = 'color: white; background-color: #5cb85c;'; - else if($btcmhd*1.3 < $avgprice) - $style = 'color: white; background-color: #d9534f;'; - else if($btcmhd*1.2 < $avgprice) - $style = 'color: white; background-color: #e4804e;'; - else if($btcmhd*1.1 < $avgprice) - $style = 'color: white; background-color: #f0ad4e;'; - } - echo ''.$btcmhday1.''; - - echo ''; +foreach ($algos as $item) { + $norm = $item[0]; + $algo = $item[1]; + + $algo_color = getAlgoColors($algo); + $algo_norm = yaamp_get_algo_norm($algo); + + $coins = getdbocount('db_coins', "enable AND auto_ready AND algo=:algo", array( + ':algo' => $algo + )); + $count = getdbocount('db_workers', "algo=:algo", array( + ':algo' => $algo + )); + + $total_coins += $coins; + $total_workers += $count; + + $t1 = time() - 24 * 60 * 60; + $total1 = dboscalar("SELECT sum(amount*price) FROM blocks WHERE category!='orphan' AND time>$t1 AND algo=:algo", array( + ':algo' => $algo + )); + if (!$coins && !$total1) + continue; + $hashrate1 = dboscalar("SELECT avg(hashrate) FROM hashrate WHERE time>$t1 AND algo=:algo", array( + ':algo' => $algo + )); + + $hashrate = dboscalar("SELECT hashrate FROM hashrate WHERE algo=:algo ORDER BY time DESC LIMIT 1", array( + ':algo' => $algo + )); + $hashrate_bad = dboscalar("SELECT hashrate_bad FROM hashrate WHERE algo=:algo ORDER BY time DESC LIMIT 1", array( + ':algo' => $algo + )); + $bad = ($hashrate + $hashrate_bad) ? round($hashrate_bad * 100 / ($hashrate + $hashrate_bad), 1) : ''; + + $total_hashrate += $hashrate; + $total_hashrate_bad += $hashrate_bad; + + $hashrate_sfx = $hashrate ? Itoa2($hashrate) . 'h/s' : '-'; + $hashrate_bad = $hashrate_bad ? Itoa2($hashrate_bad) . 'h/s' : '-'; + + $hashrate_jobs = yaamp_rented_rate($algo); + $hashrate_jobs = $hashrate_jobs > 0 ? Itoa2($hashrate_jobs) . 'h/s' : ''; + + $price = dboscalar("SELECT price FROM hashrate WHERE algo=:algo ORDER BY time DESC LIMIT 1", array( + ':algo' => $algo + )); + $price = $price ? mbitcoinvaluetoa($price) : '-'; + + $rent = dboscalar("SELECT rent FROM hashrate WHERE algo=:algo ORDER BY time DESC LIMIT 1", array( + ':algo' => $algo + )); + $rent = $rent ? mbitcoinvaluetoa($rent) : '-'; + + $norm = mbitcoinvaluetoa($norm); + + $t = time() - 24 * 60 * 60; + $avgprice = dboscalar("SELECT avg(price) FROM hashrate WHERE algo=:algo AND time>$t", array( + ':algo' => $algo + )); + $avgprice = $avgprice ? mbitcoinvaluetoa(take_yaamp_fee($avgprice, $algo)) : '-'; + + $algo_unit_factor = yaamp_algo_mBTC_factor($algo); + $btcmhday1 = $hashrate1 != 0 ? mbitcoinvaluetoa($total1 / $hashrate1 * 1000000 * 1000 * $algo_unit_factor) : '-'; + + $fees = yaamp_fee($algo); + + // todo: show per port data ? + $stratum = getdbosql('db_stratums', "algo=:algo ORDER BY started DESC", array( + ':algo' => $algo + )); + $isup = Booltoa($stratum); + $time = $isup ? datetoa2($stratum->started) : ''; + $ts = $isup ? datetoa2($stratum->started) : ''; + + echo ''; + echo ''; + echo CHtml::link($algo, '/site/gomining?algo=' . $algo); + echo ''; + echo '' . $isup . ' ' . $time . ''; + echo '' . (empty($coins) ? '-' : $coins) . ''; + echo '' . (empty($count) ? '-' : $count) . ''; + echo '' . (empty($fees) ? '-' : "$fees %") . ''; + echo '' . $hashrate_sfx . ''; + echo '' . $hashrate_jobs . ''; + + if ($bad > 10) + echo '' . $bad . '%'; + else if ($bad > 5) + echo '' . $bad . '%'; + else + echo '' . (empty($bad) ? '-' : "$bad %") . ''; + + if ($norm > 0) + echo '' . ($price == 0.0 ? '-' : $price) . ''; + else + echo '' . ($price == 0.0 ? '-' : $price) . ''; + + echo '' . $rent . ''; + + // Norm + echo '' . ($norm == 0.0 ? '-' : $norm) . ''; + + // 24E + echo '' . ($avgprice == 0.0 ? '-' : $avgprice) . ''; + + // 24A + $style = ''; + if ($btcmhday1 != '-') { + $avgprice = (double) $avgprice; + $btcmhd = (double) $btcmhday1; + + if ($btcmhd > $avgprice * 1.1) + $style = 'color: white; background-color: #5cb85c;'; + else if ($btcmhd * 1.3 < $avgprice) + $style = 'color: white; background-color: #d9534f;'; + else if ($btcmhd * 1.2 < $avgprice) + $style = 'color: white; background-color: #e4804e;'; + else if ($btcmhd * 1.1 < $avgprice) + $style = 'color: white; background-color: #f0ad4e;'; + } + echo '' . $btcmhday1 . ''; + + echo ''; } echo ''; -$bad = ($total_hashrate+$total_hashrate_bad)? round($total_hashrate_bad * 100 / ($total_hashrate+$total_hashrate_bad), 1): ''; -$total_hashrate = Itoa2($total_hashrate).'h/s'; +$bad = ($total_hashrate + $total_hashrate_bad) ? round($total_hashrate_bad * 100 / ($total_hashrate + $total_hashrate_bad), 1) : ''; +$total_hashrate = Itoa2($total_hashrate) . 'h/s'; echo ''; echo ''; -echo ''.$total_coins.''; -echo ''.$total_workers.''; +echo '' . $total_coins . ''; +echo '' . $total_workers . ''; echo ''; -echo ''.$total_hashrate.''; +echo '' . $total_hashrate . ''; echo ''; -echo ''.($bad ? $bad.'%' : '').''; +echo '' . ($bad ? $bad . '%' : '') . ''; echo ''; echo ''; echo ''; @@ -201,10 +223,11 @@ function cmp($a, $b) /////////////////////////////////////////////////////////////////////////////////////////////////////// -$markets = getdbolist('db_balances', "1 order by name"); -$salebalances = array(); $alt_balances = array(); +$markets = getdbolist('db_balances', "1 order by name"); +$salebalances = array(); +$alt_balances = array(); $total_onsell = $total_altcoins = 0.0; -$total_usd = $total_total = $total_balance = 0.0; +$total_usd = $total_total = $total_balance = 0.0; echo ''; echo ''; @@ -212,8 +235,8 @@ function cmp($a, $b) echo ''; echo ''; -foreach($markets as $market) - echo ''; +foreach ($markets as $market) + echo ''; echo ''; @@ -223,130 +246,126 @@ function cmp($a, $b) // ---------------------------------------------------------------------------------------------------- echo ''; -foreach($markets as $market) -{ - $balance = bitcoinvaluetoa($market->balance); - - if($balance > 0.250) - echo ''; - else if($balance > 0.200) - echo ''; - else if($balance == 0.0) - echo ''; - else - echo ''; - - $total_balance += $balance; +foreach ($markets as $market) { + $balance = bitcoinvaluetoa($market->balance); + + if ($balance > 0.250) + echo ''; + else if ($balance > 0.200) + echo ''; + else if ($balance == 0.0) + echo ''; + else + echo ''; + + $total_balance += $balance; } $total_balance = bitcoinvaluetoa($total_balance); -echo ''; +echo ''; echo ''; // ---------------------------------------------------------------------------------------------------- echo ''; if (YAAMP_ALLOW_EXCHANGE) { - // yaamp mode - foreach($markets as $market) { - $exchange = $market->name; - $onsell = bitcoinvaluetoa(dboscalar("SELECT sum(amount*bid) FROM orders WHERE market='$exchange'")); - $salebalances[$exchange] = $onsell; - - if($onsell > 0.2) - echo ''; - else if($onsell > 0.1) - echo ''; - else if($onsell == 0.0) - echo ''; - else - echo ''; - - $total_onsell += $onsell; - } + // yaamp mode + foreach ($markets as $market) { + $exchange = $market->name; + $onsell = bitcoinvaluetoa(dboscalar("SELECT sum(amount*bid) FROM orders WHERE market='$exchange'")); + $salebalances[$exchange] = $onsell; + + if ($onsell > 0.2) + echo ''; + else if ($onsell > 0.1) + echo ''; + else if ($onsell == 0.0) + echo ''; + else + echo ''; + + $total_onsell += $onsell; + } } else { - // yiimp mode - $ontrade = dbolist("SELECT name, onsell FROM balances B ORDER by name"); - foreach($ontrade as $row) { - $exchange = $row['name']; - $onsell = bitcoinvaluetoa($row['onsell']); - $salebalances[$exchange] = $onsell; + // yiimp mode + $ontrade = dbolist("SELECT name, onsell FROM balances B ORDER by name"); + foreach ($ontrade as $row) { + $exchange = $row['name']; + $onsell = bitcoinvaluetoa($row['onsell']); + $salebalances[$exchange] = $onsell; - echo ''; + echo ''; - $total_onsell += (double) $onsell; - } + $total_onsell += (double) $onsell; + } } $total_onsell = bitcoinvaluetoa($total_onsell); -echo ''; +echo ''; echo ''; // ---------------------------------------------------------------------------------------------------- -$t = time() - 48*60*60; +$t = time() - 48 * 60 * 60; $altmarkets = dbolist(" - SELECT B.name, SUM((M.balance+M.ontrade)*M.price) AS balance - FROM balances B LEFT JOIN markets M ON M.name = B.name - WHERE IFNULL(M.base_coin,'BTC') IN ('','BTC') AND IFNULL(M.deleted,0)=0 - GROUP BY B.name ORDER BY B.name + SELECT B.name, SUM((M.balance+M.ontrade)*M.price) AS balance + FROM balances B LEFT JOIN markets M ON M.name = B.name + WHERE IFNULL(M.base_coin,'BTC') IN ('','BTC') AND IFNULL(M.deleted,0)=0 + GROUP BY B.name ORDER BY B.name "); echo ''; -foreach($altmarkets as $row) -{ - $balance = bitcoinvaluetoa($row['balance']); - $exchange = $row['name']; - if($balance == 0.0) { - echo ''; - } else { - // to prevent duplicates on multi-algo coins, ignore symbols with a "-" - $balance = dboscalar(" - SELECT SUM((M.balance+M.ontrade)*M.price) FROM markets M INNER JOIN coins C on C.id = M.coinid - WHERE M.name='$exchange' AND IFNULL(M.deleted,0)=0 AND INSTR(C.symbol,'-')=0 - "); - $balance = bitcoinvaluetoa($balance); - echo ''; - } - $alt_balances[$exchange] = $balance; - $total_altcoins += $balance; +foreach ($altmarkets as $row) { + $balance = bitcoinvaluetoa($row['balance']); + $exchange = $row['name']; + if ($balance == 0.0) { + echo ''; + } else { + // to prevent duplicates on multi-algo coins, ignore symbols with a "-" + $balance = dboscalar(" + SELECT SUM((M.balance+M.ontrade)*M.price) FROM markets M INNER JOIN coins C on C.id = M.coinid + WHERE M.name='$exchange' AND IFNULL(M.deleted,0)=0 AND INSTR(C.symbol,'-')=0 + "); + $balance = bitcoinvaluetoa($balance); + echo ''; + } + $alt_balances[$exchange] = $balance; + $total_altcoins += $balance; } $total_altcoins = bitcoinvaluetoa($total_altcoins); -echo ''; +echo ''; echo ''; // ---------------------------------------------------------------------------------------------------- echo ''; echo ''; -foreach($markets as $market) -{ - $total = $market->balance + arraySafeVal($alt_balances,$market->name,0) + arraySafeVal($salebalances,$market->name,0); +foreach ($markets as $market) { + $total = $market->balance + arraySafeVal($alt_balances, $market->name, 0) + arraySafeVal($salebalances, $market->name, 0); - echo ''; - $total_total += $total; + echo ''; + $total_total += $total; } $total_total = bitcoinvaluetoa($total_total); -echo ''; +echo ''; echo ''; // ---------------------------------------------------------------------------------------------------- echo ''; -foreach($markets as $market) -{ - $total = $market->balance + arraySafeVal($alt_balances,$market->name,0) + arraySafeVal($salebalances,$market->name,0); - $usd = $total * $mining->usdbtc; +foreach ($markets as $market) { + $total = $market->balance + arraySafeVal($alt_balances, $market->name, 0) + arraySafeVal($salebalances, $market->name, 0); + $usd = $total * $mining->usdbtc; - echo ''; - $total_usd += $usd; + echo ''; + $total_usd += $usd; } -echo ''; +echo ''; echo ''; echo ''; @@ -354,8 +373,8 @@ function cmp($a, $b) ////////////////////////////////////////////////////////////////////////////////////////////////// -$minsent = time()-2*60*60; -$list = getdbolist('db_markets', "lastsent<$minsent and lastsent>lasttraded order by lastsent"); +$minsent = time() - 2 * 60 * 60; +$list = getdbolist('db_markets', "lastsent<$minsent and lastsent>lasttraded order by lastsent"); echo '
'.$market->name.'' . $market->name . 'Total
BTC'.$balance.''.$balance.'-'.$balance.'' . $balance . '' . $balance . '-' . $balance . ''.$total_balance.'' . $total_balance . '
orders'.$onsell.''.$onsell.'-'.$onsell.'' . $onsell . '' . $onsell . '-' . $onsell . ''.($onsell == 0 ? '-' : $onsell).'' . ($onsell == 0 ? '-' : $onsell) . ''.$total_onsell.'' . $total_onsell . '
other-'.$balance.'-' . $balance . ''.$total_altcoins.'' . $total_altcoins . '
Total'.($total > 0.0 ? bitcoinvaluetoa($total) : '-').'' . ($total > 0.0 ? bitcoinvaluetoa($total) : '-') . ''.$total_total.'' . $total_total . '
USD'.($usd > 0.0 ? round($usd,2) : '-').'' . ($usd > 0.0 ? round($usd, 2) : '-') . ''.round($total_usd,2).' $' . round($total_usd, 2) . ' $
'; echo ''; @@ -370,30 +389,29 @@ function cmp($a, $b) echo ''; echo ''; -foreach($list as $market) -{ - $price = bitcoinvaluetoa($market->price); - $coin = getdbo('db_coins', $market->coinid); +foreach ($list as $market) { + $price = bitcoinvaluetoa($market->price); + $coin = getdbo('db_coins', $market->coinid); - $marketurl = getMarketUrl($coin, $market->name); + $marketurl = getMarketUrl($coin, $market->name); -// echo ''; - $algo_color = getAlgoColors($coin->algo); - echo ''; + // echo ''; + $algo_color = getAlgoColors($coin->algo); + echo ''; - echo ''; - echo ''; + echo ''; + echo ''; - echo ''; + echo ''; - $sent = datetoa2($market->lastsent); - $traded = datetoa2($market->lasttraded); + $sent = datetoa2($market->lastsent); + $traded = datetoa2($market->lasttraded); - echo ''; - echo ''; + echo ''; + echo ''; - echo ''; - echo ''; + echo ''; + echo ''; } echo '
'.$coin->name.' ('.$coin->symbol.')' . $coin->name . ' (' . $coin->symbol . ')'.$market->name.'' . $market->name . ''.$sent.' ago'.$traded.' ago' . $sent . ' ago' . $traded . ' agoclear
clear

'; @@ -419,59 +437,59 @@ function cmp($a, $b) echo ''; $totalvalue = 0; -$totalbid = 0; - -foreach($orders as $order) -{ - $coin = getdbo('db_coins', $order->coinid); - if(!$coin) continue; - - $marketurl = getMarketUrl($coin, $order->market); - - $algo_color = getAlgoColors($coin->algo); - echo ''; - - $created = datetoa2($order->created). ' ago'; - $price = $order->price? bitcoinvaluetoa($order->price): ''; - - $price = bitcoinvaluetoa($order->price); - $bid = bitcoinvaluetoa($order->bid); - $value = bitcoinvaluetoa($order->amount*$order->price); - $bidvalue = bitcoinvaluetoa($order->amount*$order->bid); - $totalvalue += $value; - $totalbid += $bidvalue; - $bidpercent = $value>0? round(($value-$bidvalue)/$value*100, 1): 0; - $amount = round($order->amount, 3); - - echo ''; - echo ''.$coin->name.''; - echo ''.$order->market.''; - - echo ''.$created.''; - echo ''.$amount.''; - echo ''.$price.''; - echo ''."$bid ({$bidpercent}%)".''; - echo $bidvalue>0.01? ''.$bidvalue.'': ''.$bidvalue.''; - - echo ''; - echo 'cancel '; - echo 'clear '; -// echo 'sell'; - echo ''; - echo ''; +$totalbid = 0; + +foreach ($orders as $order) { + $coin = getdbo('db_coins', $order->coinid); + if (!$coin) + continue; + + $marketurl = getMarketUrl($coin, $order->market); + + $algo_color = getAlgoColors($coin->algo); + echo ''; + + $created = datetoa2($order->created) . ' ago'; + $price = $order->price ? bitcoinvaluetoa($order->price) : ''; + + $price = bitcoinvaluetoa($order->price); + $bid = bitcoinvaluetoa($order->bid); + $value = bitcoinvaluetoa($order->amount * $order->price); + $bidvalue = bitcoinvaluetoa($order->amount * $order->bid); + $totalvalue += $value; + $totalbid += $bidvalue; + $bidpercent = $value > 0 ? round(($value - $bidvalue) / $value * 100, 1) : 0; + $amount = round($order->amount, 3); + + echo ''; + echo '' . $coin->name . ''; + echo '' . $order->market . ''; + + echo '' . $created . ''; + echo '' . $amount . ''; + echo '' . $price . ''; + echo '' . "$bid ({$bidpercent}%)" . ''; + echo $bidvalue > 0.01 ? '' . $bidvalue . '' : '' . $bidvalue . ''; + + echo ''; + echo 'cancel '; + echo 'clear '; + // echo 'sell'; + echo ''; + echo ''; } -$bidpercent = $totalvalue>0? round(($totalvalue-$totalbid)/$totalvalue*100, 1): ''; +$bidpercent = $totalvalue > 0 ? round(($totalvalue - $totalbid) / $totalvalue * 100, 1) : ''; if ($totalvalue) { -echo ''; -echo ''; -echo 'Total'; -echo ''; -echo ''.$totalvalue.''; -echo ''."$totalbid ({$bidpercent}%)"; -echo ''; -echo ''; + echo ''; + echo ''; + echo 'Total'; + echo ''; + echo '' . $totalvalue . ''; + echo '' . "$totalbid ({$bidpercent}%)"; + echo ''; + echo ''; } echo '
'; @@ -484,79 +502,78 @@ function cmp($a, $b) function cronstate2text($state) { - switch($state - 1) - { - case 0: - return 'new coins'; - case 1: - return 'trade'; - case 2: - return 'trade2'; - case 3: - return 'prices'; - case 4: - return 'blocks'; - case 5: - return 'sell'; - case 6: - return 'find2'; - case 7: - return 'notify'; - default: - return ''; - } + switch ($state - 1) { + case 0: + return 'new coins'; + case 1: + return 'trade'; + case 2: + return 'trade2'; + case 3: + return 'prices'; + case 4: + return 'blocks'; + case 5: + return 'sell'; + case 6: + return 'find2'; + case 7: + return 'notify'; + default: + return ''; + } } $state_main = (int) $this->memcache->get('cronjob_main_state'); -$btc = getdbosql('db_coins', "symbol='BTC'"); -if (!$btc) $btc = json_decode('{"id": 6, "balance": 0}'); +$btc = getdbosql('db_coins', "symbol='BTC'"); +if (!$btc) + $btc = json_decode('{"id": 6, "balance": 0}'); echo ''; -for($i=0; $i<10; $i++) -{ - if($i != $state_main-1 && $state_main>0) - { - $state = $this->memcache->get("cronjob_main_state_$i"); - if($state) echo "main $i "; - } +for ($i = 0; $i < 10; $i++) { + if ($i != $state_main - 1 && $state_main > 0) { + $state = $this->memcache->get("cronjob_main_state_$i"); + if ($state) + echo "main $i "; + } } echo ''; -$block_time = sectoa(time()-$this->memcache->get("cronjob_block_time_start")); -$loop2_time = sectoa(time()-$this->memcache->get("cronjob_loop2_time_start")); -$main_time2 = sectoa(time()-$this->memcache->get("cronjob_main_time_start")); +$block_time = sectoa(time() - $this->memcache->get("cronjob_block_time_start")); +$loop2_time = sectoa(time() - $this->memcache->get("cronjob_loop2_time_start")); +$main_time2 = sectoa(time() - $this->memcache->get("cronjob_main_time_start")); $main_time = sectoa($this->memcache->get("cronjob_main_time")); $main_text = cronstate2text($state_main); echo "*** main ($main_time) $state_main $main_text ($main_time2), loop2 ($loop2_time), block ($block_time)
"; -$topay = dboscalar("select sum(balance) from accounts where coinid=$btc->id"); //here: take other currencies too +$topay = dboscalar("select sum(balance) from accounts where coinid=$btc->id"); //here: take other currencies too $topay2 = bitcoinvaluetoa(dboscalar("select sum(balance) from accounts where coinid=$btc->id and balance>0.001")); $renter = dboscalar("select sum(balance) from renters"); -$stats = getdbosql('db_stats', "1 order by time desc"); +$stats = getdbosql('db_stats', "1 order by time desc"); $margin2 = bitcoinvaluetoa($btc->balance - $topay - $renter + $stats->balances + $stats->onsell + $stats->wallets); $margin = bitcoinvaluetoa($btc->balance - $topay - $renter); -$topay = bitcoinvaluetoa($topay); +$topay = bitcoinvaluetoa($topay); $renter = bitcoinvaluetoa($renter); $immature = dboscalar("select sum(amount*price) from earnings where status=0"); -$mints = dboscalar("select sum(mint*price) from coins where enable"); -$off = $mints-$immature; +$mints = dboscalar("select sum(mint*price) from coins where enable"); +$off = $mints - $immature; $immature = bitcoinvaluetoa($immature); -$mints = bitcoinvaluetoa($mints); -$off = bitcoinvaluetoa($off); +$mints = bitcoinvaluetoa($mints); +$off = bitcoinvaluetoa($off); $btcaddr = YAAMP_BTCADDRESS; //'14LS7Uda6EZGXLtRrFEZ2kWmarrxobkyu9'; -echo 'Bitstamp '.$mining->usdbtc.', '; -echo 'wallet '.$btc->balance.', next payout '.$topay2.'
'; +echo 'Bitstamp ' . $mining->usdbtc . ', '; +echo 'wallet ' . $btc->balance . ', next payout ' . $topay2 . '
'; echo "pay $topay, renter $renter, marg $margin, $margin2
"; echo "mint $mints immature $immature off $off
"; @@ -586,74 +603,71 @@ function cronstate2text($state) echo ''; echo ''; -foreach($db_blocks as $db_block) -{ - $d = datetoa2($db_block->time); - if(!$db_block->coin_id) - { - if (!$showrental) - continue; - - $reward = bitcoinvaluetoa($db_block->amount); - - $algo_color = getAlgoColors($db_block->algo); - echo ''; - echo ''; - echo 'Rental ('.$db_block->algo.')'; - echo '$reward BTC'; - echo ''; - echo ''; - echo ''.$d.' ago'; - echo ''; - echo 'Confirmed'; - echo ''; - echo ''; - continue; - } - - $coin = getdbo('db_coins', $db_block->coin_id); - if(!$coin) - { - debuglog("coin not found {$db_block->coin_id}"); - continue; - } - - $height = number_format($db_block->height, 0, '.', ' '); - $diff = Itoa2($db_block->difficulty, 3); - - $algo_color = getAlgoColors($coin->algo); - echo ''; - echo ''; - $flags = $db_block->segwit ? ' ' : ''; - echo ''.$coin->name.''.$flags.''; - - echo ''.$db_block->amount.' '.$coin->symbol.''; - echo ''.$diff.''; - - echo ''.$height.''; - echo ''.$d.' ago'; - echo ''; - - if($db_block->category == 'orphan') - echo 'Orphan'; - - else if($db_block->category == 'immature') - echo 'Immature ('.$db_block->confirmations.')'; - - else if($db_block->category == 'stake') - echo 'Stake ('.$db_block->confirmations.')'; - - else if($db_block->category == 'generated') - echo 'Confirmed'; - - else if($db_block->category == 'generate') - echo 'Confirmed'; - - else if($db_block->category == 'new') - echo 'New'; - - echo ''; - echo ''; +foreach ($db_blocks as $db_block) { + $d = datetoa2($db_block->time); + if (!$db_block->coin_id) { + if (!$showrental) + continue; + + $reward = bitcoinvaluetoa($db_block->amount); + + $algo_color = getAlgoColors($db_block->algo); + echo ''; + echo ''; + echo 'Rental (' . $db_block->algo . ')'; + echo '$reward BTC'; + echo ''; + echo ''; + echo '' . $d . ' ago'; + echo ''; + echo 'Confirmed'; + echo ''; + echo ''; + continue; + } + + $coin = getdbo('db_coins', $db_block->coin_id); + if (!$coin) { + debuglog("coin not found {$db_block->coin_id}"); + continue; + } + + $height = number_format($db_block->height, 0, '.', ' '); + $diff = Itoa2($db_block->difficulty, 3); + + $algo_color = getAlgoColors($coin->algo); + echo ''; + echo ''; + $flags = $db_block->segwit ? ' ' : ''; + echo '' . $coin->name . '' . $flags . ''; + + echo '' . $db_block->amount . ' ' . $coin->symbol . ''; + echo '' . $diff . ''; + + echo '' . $height . ''; + echo '' . $d . ' ago'; + echo ''; + + if ($db_block->category == 'orphan') + echo 'Orphan'; + + else if ($db_block->category == 'immature') + echo 'Immature (' . $db_block->confirmations . ')'; + + else if ($db_block->category == 'stake') + echo 'Stake (' . $db_block->confirmations . ')'; + + else if ($db_block->category == 'generated') + echo 'Confirmed'; + + else if ($db_block->category == 'generate') + echo 'Confirmed'; + + else if ($db_block->category == 'new') + echo 'New'; + + echo ''; + echo ''; } @@ -663,11 +677,14 @@ function cronstate2text($state) ?> - + - - + diff --git a/web/yaamp/modules/site/connections.php b/web/yaamp/modules/site/connections.php index 6751b8d09..247ec7042 100644 --- a/web/yaamp/modules/site/connections.php +++ b/web/yaamp/modules/site/connections.php @@ -1,5 +1,4 @@ end; - - - - - - diff --git a/web/yaamp/modules/site/connections_results.php b/web/yaamp/modules/site/connections_results.php index 3429f35ea..09c7251a5 100644 --- a/web/yaamp/modules/site/connections_results.php +++ b/web/yaamp/modules/site/connections_results.php @@ -1,5 +1,4 @@ "; echo ""; -foreach($list as $conn) +foreach ($list as $conn) { - echo ""; - - $d1 = sectoa($conn->idle); - $d2 = datetoa2($conn->created); - $d3 = datetoa2($conn->last); - $b = Booltoa($conn->last == $last); - - echo "$conn->id"; - echo "$conn->user"; - echo "$conn->host"; - echo "$conn->db"; - echo "$d1"; - echo "$d2"; - echo "$d3"; - echo "$b"; - - echo ""; + echo ""; + + $d1 = sectoa($conn->idle); + $d2 = datetoa2($conn->created); + $d3 = datetoa2($conn->last); + $b = Booltoa($conn->last == $last); + + echo "$conn->id"; + echo "$conn->user"; + echo "$conn->host"; + echo "$conn->db"; + echo "$d1"; + echo "$d2"; + echo "$d3"; + echo "$b"; + + echo ""; } echo "
"; -echo count($list)." connections to the database
"; +echo count($list) . " connections to the database
"; diff --git a/web/yaamp/modules/site/diff.php b/web/yaamp/modules/site/diff.php index 085b3b08d..4a8888c90 100644 --- a/web/yaamp/modules/site/diff.php +++ b/web/yaamp/modules/site/diff.php @@ -1,7 +1,7 @@
-
YIIMP STRATUM DIFFICULTY
+
cryptopool.builders Stratum Difficulty

By default, yiimp will adjust the difficulty of your miner automatically over time until @@ -28,6 +28,3 @@





























- - - diff --git a/web/yaamp/modules/site/earning.php b/web/yaamp/modules/site/earning.php index 49520136b..5823f511c 100644 --- a/web/yaamp/modules/site/earning.php +++ b/web/yaamp/modules/site/earning.php @@ -2,9 +2,10 @@ echo getAdminSideBarLinks(); $coin_id = getiparam('id'); -if ($coin_id) { - $coin = getdbo('db_coins', $coin_id); - $this->pageTitle = 'Earnings - '.$coin->symbol; +if ($coin_id) +{ + $coin = getdbo('db_coins', $coin_id); + $this->pageTitle = 'Earnings - ' . $coin->symbol; } JavascriptFile("/yaamp/ui/js/jquery.metadata.js"); @@ -32,7 +33,8 @@ function main_error() function main_refresh() { - var url = '/site/earning_results?id='; + var url = '/site/earning_results?id='; var minh = $(window).height() - 150; $('#main_results').css({'min-height': minh + 'px'}); @@ -43,5 +45,4 @@ function main_refresh() @@ -16,6 +15,7 @@ end; + $coin_id = getiparam('id'); $saveSort = $coin_id ? 'false' : 'true'; @@ -53,106 +53,115 @@ end; + $coin_id = getiparam('id'); -$sqlFilter = $coin_id ? "AND coinid={$coin_id}": ''; +$sqlFilter = $coin_id ? "AND coinid={$coin_id}" : ''; $limit = $coin_id ? '' : 'LIMIT 1500'; $earnings = getdbolist('db_earnings', "status!=2 $sqlFilter ORDER BY create_time DESC $limit"); -$total = 0.; $total_btc = 0.; $totalimmat = 0.; $totalfees = 0.; $totalstake = 0.; +$total = 0.; +$total_btc = 0.; +$totalimmat = 0.; +$totalfees = 0.; +$totalstake = 0.; -foreach($earnings as $earning) +foreach ($earnings as $earning) { -// if(!$earning) debuglog($earning); - $coin = getdbo('db_coins', $earning->coinid); - if(!$coin) continue; - - $user = getdbo('db_accounts', $earning->userid); - if(!$user) continue; - - $block = getdbo('db_blocks', $earning->blockid); - if(!$block) continue; - - $t1 = datetoa2($earning->create_time). ' ago'; - $t2 = datetoa2($earning->mature_time); - if ($t2) $t2 = '+'.$t2; - - $coinimg = CHtml::image($coin->image, $coin->symbol, array('width'=>'16')); - $coinlink = CHtml::link($coin->name, '/site/coin?id='.$coin->id); - - echo ''; - echo "$coinimg"; - echo "$coinlink ($coin->symbol_show)"; - echo ''.$user->username.''; - echo ''.bitcoinvaluetoa($earning->amount).''; - echo ''.bitcoinvaluetoa($earning->amount * $earning->price).''; - echo ''.$block->height.''; - echo ''."$block->category ($block->confirmations)"; - echo ''."$t1 $t2"; - - echo ''; - echo 'clear '; - echo 'delete'; - echo ''; - -// echo "$earning->tx"; - echo ""; - -// if($block->category == 'generate' && $earning->status == 0) -// { -// $earning->status = 1; -// $earning->mature_time = time()-100*60; -// $earning->save(); -// } - - if($block->category == 'immature') { - $total += (double) $earning->amount; - $total_btc += (double) $earning->amount * $earning->price; - $totalimmat += (double) $earning->amount; - } - if($block->category == 'generate') { - $total += (double) $earning->amount; // "Exchange" state - $total_btc += (double) $earning->amount * $earning->price; - } - else if($block->category == 'stake' || $block->category == 'generated') { - $totalstake += (double) $earning->amount; - } + // if(!$earning) debuglog($earning); + $coin = getdbo('db_coins', $earning->coinid); + if (!$coin) continue; + + $user = getdbo('db_accounts', $earning->userid); + if (!$user) continue; + + $block = getdbo('db_blocks', $earning->blockid); + if (!$block) continue; + + $t1 = datetoa2($earning->create_time) . ' ago'; + $t2 = datetoa2($earning->mature_time); + if ($t2) $t2 = '+' . $t2; + + $coinimg = CHtml::image($coin->image, $coin->symbol, array( + 'width' => '16' + )); + $coinlink = CHtml::link($coin->name, '/site/coin?id=' . $coin->id); + + echo ''; + echo "$coinimg"; + echo "$coinlink ($coin->symbol_show)"; + echo '' . $user->username . ''; + echo '' . bitcoinvaluetoa($earning->amount) . ''; + echo '' . bitcoinvaluetoa($earning->amount * $earning->price) . ''; + echo '' . $block->height . ''; + echo '' . "$block->category ($block->confirmations)"; + echo '' . "$t1 $t2"; + + echo ''; + echo 'clear '; + echo 'delete'; + echo ''; + + // echo "$earning->tx"; + echo ""; + + // if($block->category == 'generate' && $earning->status == 0) + // { + // $earning->status = 1; + // $earning->mature_time = time()-100*60; + // $earning->save(); + // } + if ($block->category == 'immature') + { + $total += (double)$earning->amount; + $total_btc += (double)$earning->amount * $earning->price; + $totalimmat += (double)$earning->amount; + } + if ($block->category == 'generate') + { + $total += (double)$earning->amount; // "Exchange" state + $total_btc += (double)$earning->amount * $earning->price; + } + else if ($block->category == 'stake' || $block->category == 'generated') + { + $totalstake += (double)$earning->amount; + } } echo ''; echo ''; -echo count($earnings).' records'; +echo count($earnings) . ' records'; if (count($earnings) >= 1000) echo " ($limit)"; echo ''; echo ''; -if ($coin_id) { - $coin = getdbo('db_coins', $coin_id); - if (!$coin) exit; - $symbol = $coin->symbol; - $feepct = yaamp_fee($coin->algo); - $totalfees = ($total / ((100 - $feepct) / 100.)) - $total; - - $cleared = dboscalar("SELECT SUM(balance) FROM accounts WHERE coinid={$coin->id}"); - - echo '

'; - - echo ''; - echo '"; - echo '"; - //echo '"; - echo '"; - if ($coin->rpcencoding == 'POS') - echo '"; - echo '
Immature'.bitcoinvaluetoa($totalimmat)." $symbol
Total owed'.bitcoinvaluetoa($total)." $symbol
Total BTC'.bitcoinvaluetoa($total_btc)." BTC
Pool Fees '.round($feepct,1).'%'.bitcoinvaluetoa($totalfees)." $symbol
Stake'.bitcoinvaluetoa($totalstake)." $symbol
'; - - echo ''; - echo '"; - echo '"; - $exchange = $total - $totalimmat; - echo ''; - echo '"; - echo '
Balance'.bitcoinvaluetoa($coin->balance)." $symbol
Cleared'.bitcoinvaluetoa($cleared)." $symbol
Available'.bitcoinvaluetoa($coin->balance - $exchange - $cleared)." $symbol
'; - - echo '
'; -} \ No newline at end of file +if ($coin_id) +{ + $coin = getdbo('db_coins', $coin_id); + if (!$coin) exit; + $symbol = $coin->symbol; + $feepct = yaamp_fee($coin->algo); + $totalfees = ($total / ((100 - $feepct) / 100.)) - $total; + + $cleared = dboscalar("SELECT SUM(balance) FROM accounts WHERE coinid={$coin->id}"); + + echo '
'; + + echo ''; + echo '"; + echo '"; + //echo '"; + echo '"; + if ($coin->rpcencoding == 'POS') echo '"; + echo '
Immature' . bitcoinvaluetoa($totalimmat) . " $symbol
Total owed' . bitcoinvaluetoa($total) . " $symbol
Total BTC'.bitcoinvaluetoa($total_btc)." BTC
Pool Fees ' . round($feepct, 1) . '%' . bitcoinvaluetoa($totalfees) . " $symbol
Stake' . bitcoinvaluetoa($totalstake) . " $symbol
'; + + echo ''; + echo '"; + echo '"; + $exchange = $total - $totalimmat; + echo ''; + echo '"; + echo '
Balance' . bitcoinvaluetoa($coin->balance) . " $symbol
Cleared' . bitcoinvaluetoa($cleared) . " $symbol
Available' . bitcoinvaluetoa($coin->balance - $exchange - $cleared) . " $symbol
'; + + echo '
'; +} diff --git a/web/yaamp/modules/site/emptymarkets.php b/web/yaamp/modules/site/emptymarkets.php index 7070b8cd4..3cb606b65 100644 --- a/web/yaamp/modules/site/emptymarkets.php +++ b/web/yaamp/modules/site/emptymarkets.php @@ -1,5 +1,4 @@ end; + showTableSorter('maintable', "{ tableClass: 'dataGrid', headers: { 0: { sorter: false} }, @@ -40,26 +40,27 @@ (markets.deposit_address IS NULL OR (markets.message is not null and markets.message!='')) ORDER BY coins.id DESC, markets.id DESC"); -if (!empty($list)) -foreach($list as $item) +if (!empty($list)) foreach ($list as $item) { - $coin = getdbo('db_coins', $item['coinid']); - $market = getdbo('db_markets', $item['marketid']); + $coin = getdbo('db_coins', $item['coinid']); + $market = getdbo('db_markets', $item['marketid']); - $coinimg = CHtml::image($coin->image, $coin->symbol, array('width'=>'16')); + $coinimg = CHtml::image($coin->image, $coin->symbol, array( + 'width' => '16' + )); - echo ""; - echo "{$coinimg}"; - echo "$coin->name"; - echo "$market->name"; - echo "".bitcoinvaluetoa($market->price).""; - echo "$market->message"; - echo "$market->deposit_address"; - echo ""; + echo ""; + echo "{$coinimg}"; + echo "$coin->name"; + echo "$market->name"; + echo "" . bitcoinvaluetoa($market->price) . ""; + echo "$market->message"; + echo "$market->deposit_address"; + echo ""; } echo ""; echo '









'; -echo 'Note: this table displays the enabled coin markets which does not have a deposit address (or have a message set)'; \ No newline at end of file +echo 'Note: this table displays the enabled coin markets which does not have a deposit address (or have a message set)'; diff --git a/web/yaamp/modules/site/exchange.php b/web/yaamp/modules/site/exchange.php index 0fb8e7d1d..6ff63bfe1 100644 --- a/web/yaamp/modules/site/exchange.php +++ b/web/yaamp/modules/site/exchange.php @@ -39,6 +39,3 @@ function main_refresh() } - - - diff --git a/web/yaamp/modules/site/exchange_results.php b/web/yaamp/modules/site/exchange_results.php index 54b64b732..ff5ddcf9d 100644 --- a/web/yaamp/modules/site/exchange_results.php +++ b/web/yaamp/modules/site/exchange_results.php @@ -1,5 +1,4 @@ "; @@ -21,43 +20,45 @@ $totalvalue = 0; $totalbid = 0; -foreach($orders as $order) +foreach ($orders as $order) { - $coin = getdbo('db_coins', $order->coinid); - $marketurl = getMarketUrl($coin, $order->market); - $coinimg = CHtml::image($coin->image, $coin->symbol, array('width'=>'16')); - - echo ""; - - $created = datetoa2($order->created). ' ago'; - $price = $order->price? bitcoinvaluetoa($order->price): ''; - - $price = bitcoinvaluetoa($order->price); - $bid = bitcoinvaluetoa($order->bid); - $value = bitcoinvaluetoa($order->amount*$order->price); - $bidvalue = bitcoinvaluetoa($order->amount*$order->bid); - $totalvalue += $value; - $totalbid += $bidvalue; - $bidpercent = $value>0? round(($value-$bidvalue)/$value*100, 1): 0; - - echo ''; - echo ""; - echo ""; - - echo ""; - echo ""; - echo ""; - echo ""; - echo $bidvalue>0.01? "": ""; - -// echo ""; - echo ""; + $coin = getdbo('db_coins', $order->coinid); + $marketurl = getMarketUrl($coin, $order->market); + $coinimg = CHtml::image($coin->image, $coin->symbol, array( + 'width' => '16' + )); + + echo ""; + + $created = datetoa2($order->created) . ' ago'; + $price = $order->price ? bitcoinvaluetoa($order->price) : ''; + + $price = bitcoinvaluetoa($order->price); + $bid = bitcoinvaluetoa($order->bid); + $value = bitcoinvaluetoa($order->amount * $order->price); + $bidvalue = bitcoinvaluetoa($order->amount * $order->bid); + $totalvalue += $value; + $totalbid += $bidvalue; + $bidpercent = $value > 0 ? round(($value - $bidvalue) / $value * 100, 1) : 0; + + echo ''; + echo ""; + echo ""; + + echo ""; + echo ""; + echo ""; + echo ""; + echo $bidvalue > 0.01 ? "" : ""; + + // echo ""; + echo ""; } -$bidpercent = $totalvalue? round(($totalvalue-$totalbid)/$totalvalue*100, 1): ''; +$bidpercent = $totalvalue ? round(($totalvalue - $totalbid) / $totalvalue * 100, 1) : ''; echo ""; echo ""; @@ -71,10 +72,8 @@ echo "
'.$coinimg.'$coin->name ($coin->symbol)$order->market$created$order->amount$price$bid ({$bidpercent}%)$bidvalue$bidvalue"; -// echo "[cancel] "; -// echo "[sell]"; -// echo "
' . $coinimg . '$coin->name ($coin->symbol)$order->market$created$order->amount$price$bid ({$bidpercent}%)$bidvalue$bidvalue"; + // echo "[cancel] "; + // echo "[sell]"; + // echo "
"; ////////////////////////////////////////////////////////////////////////////////////////////////////////////// - $exchanges = getdbolist('db_exchange', "1 order by send_time desc limit 150"); //$exchanges = getdbolist('db_exchange', "status='waiting' order by send_time desc"); - echo "
"; echo ""; echo ""; @@ -90,45 +89,44 @@ echo ""; echo ""; -foreach($exchanges as $exchange) +foreach ($exchanges as $exchange) { - $coin = getdbo('db_coins', $exchange->coinid); - $lowsymbol = strtolower($coin->symbol); - $coinimg = CHtml::image($coin->image, $coin->symbol, array('width'=>'16')); - - $marketurl = getMarketUrl($coin, $exchange->market); - - if($exchange->status == 'waiting') - echo ""; - else - echo ""; - - $sent = datetoa2($exchange->send_time). ' ago'; - $received = $exchange->receive_time? sectoa($exchange->receive_time-$exchange->send_time): ''; - $price = $exchange->price? bitcoinvaluetoa($exchange->price): bitcoinvaluetoa($coin->price); - $estimate = bitcoinvaluetoa($exchange->price_estimate); - $total = $exchange->price? bitcoinvaluetoa($exchange->quantity*$exchange->price): bitcoinvaluetoa($exchange->quantity*$coin->price); - - echo ''; - echo '"; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo $total>0.01? "": ""; - - echo ""; - echo ""; + $coin = getdbo('db_coins', $exchange->coinid); + $lowsymbol = strtolower($coin->symbol); + $coinimg = CHtml::image($coin->image, $coin->symbol, array( + 'width' => '16' + )); + + $marketurl = getMarketUrl($coin, $exchange->market); + + if ($exchange->status == 'waiting') echo ""; + else echo ""; + + $sent = datetoa2($exchange->send_time) . ' ago'; + $received = $exchange->receive_time ? sectoa($exchange->receive_time - $exchange->send_time) : ''; + $price = $exchange->price ? bitcoinvaluetoa($exchange->price) : bitcoinvaluetoa($coin->price); + $estimate = bitcoinvaluetoa($exchange->price_estimate); + $total = $exchange->price ? bitcoinvaluetoa($exchange->quantity * $exchange->price) : bitcoinvaluetoa($exchange->quantity * $coin->price); + + echo ''; + echo '"; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo $total > 0.01 ? "" : ""; + + echo ""; + echo ""; } echo "
'.$coinimg.''."$coin->name ($coin->symbol)'.$exchange->market.''.$sent.''.$exchange->quantity.''.$estimate.''.$price.'$total$total"; - - if($exchange->status == 'waiting') - { - // echo "[clear]"; - echo "[del]"; - } - - echo "
' . $coinimg . '' . "$coin->name ($coin->symbol)' . $exchange->market . '' . $sent . '' . $exchange->quantity . '' . $estimate . '' . $price . '$total$total"; + + if ($exchange->status == 'waiting') + { + // echo "[clear]"; + echo "[del]"; + } + + echo "
"; - diff --git a/web/yaamp/modules/site/index.php b/web/yaamp/modules/site/index.php index a1888b8ce..c7feec31c 100644 --- a/web/yaamp/modules/site/index.php +++ b/web/yaamp/modules/site/index.php @@ -1,5 +1,4 @@ getState('yaamp-algo'); JavascriptFile("/extensions/jqplot/jquery.jqplot.js"); @@ -12,15 +11,15 @@ $height = '240px'; $min_payout = floatval(YAAMP_PAYMENTS_MINI); -$min_sunday = $min_payout/10; +$min_sunday = $min_payout / 10; -$payout_freq = (YAAMP_PAYMENTS_FREQ / 3600)." hours"; +$payout_freq = (YAAMP_PAYMENTS_FREQ / 3600) . " hours"; ?> + padding: 10px; margin-left: 20px; margin-right: 20px; margin-top: 15px; cursor: pointer; display: none;' + onclick='auto_page_resume();' align=center> + Auto refresh is paused - Click to resume
"; echo ""; -if (!empty($res)) -foreach($res as $item) +if (!empty($res)) foreach ($res as $item) { -// debuglog("$i => $n"); - - $url = $item[0]; - $n = $item[1]; - $d = round($item[2], 3); - $avg = round($item[3], 3); - - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; + // debuglog("$i => $n"); + $url = $item[0]; + $n = $item[1]; + $d = round($item[2], 3); + $avg = round($item[3], 3); + + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; } echo "
@@ -28,16 +27,18 @@
-
YII MINING POOLS
+
domain
    -
  • YiiMP is a pool management solution based on the Yii Framework.
  • -
  • This fork was based on the yaamp source code and is now an open source project.
  • +
  • Welcome to your new mining pool, domain!
  • +
  • This installation was completed using the Ultimate Crypto-Server Setup Installer.
  • +
  • Any edits to this page should be made to, /home/crypto-data/yiimp/site/web/yaamp/modules/site/index.php
  • +
  •  
  • No registration is required, we do payouts in the currency you mine. Use your wallet address as the username.
  •  
  • -
  • Payouts are made automatically every for all balances above , or on Sunday.
  • +
  • Payouts are made automatically every for all balances above , or on Sunday.
  • For some coins, there is an initial delay before the first payout, please wait at least 6 hours before asking for support.
  • Blocks are distributed proportionally among valid submitted shares.
  • @@ -47,65 +48,151 @@

- +
-
STRATUM SERVERS
+
How to mine with domain
-
    - -
  • -

    - -o stratum+tcp://:<PORT> -u <WALLET_ADDRESS> [-p <OPTIONS>]

    -
  • - - -
  • <WALLET_ADDRESS> can be one of any currency we mine or a BTC address.
  • - -
  • <WALLET_ADDRESS> should be valid for the currency you mine. DO NOT USE a BTC address here, the auto exchange is disabled!
  • - -
  • As optional password, you can use -p c=<SYMBOL> if yiimp does not set the currency correctly on the Wallet page.
  • -
  • See the "Pool Status" area on the right for PORT numbers. Algorithms without associated coins are disabled.
  • + + + + + + + + + + + + + + + + + + + + + + + + + +
    Stratum LocationCoinWallet AddressRig Name
    + + + + + + + + + + + +

    -a -o stratum+tcp://stratum.domain:0000 -u . -p c=

    +
    +
      +
    • <WALLET_ADDRESS> must be valid for the currency you mine. DO NOT USE a BTC address here, the auto exchange is disabled on these stratums!
    • + +
    • See the "domain coins" area on the right for PORT numbers. You may mine any coin regardless if the coin is enabled or not for autoexchange. Payouts will only be made in that coins currency.
    • +
    • Payouts are made automatically every hour for all balances above , or on Sunday.

    • -

- +
-
LINKS
+
domain Links

- +
+
domain Support
+
- - + +

-
@@ -127,40 +214,62 @@ function page_refresh() { - pool_current_refresh(); - pool_history_refresh(); + pool_current_refresh(); + pool_history_refresh(); } function select_algo(algo) { - window.location.href = '/site/algo?algo='+algo+'&r=/'; + window.location.href = '/site/algo?algo='+algo+'&r=/'; } //////////////////////////////////////////////////// function pool_current_ready(data) { - $('#pool_current_results').html(data); + $('#pool_current_results').html(data); } function pool_current_refresh() { - var url = "/site/current_results"; - $.get(url, '', pool_current_ready); + var url = "/site/current_results"; + $.get(url, '', pool_current_ready); } //////////////////////////////////////////////////// function pool_history_ready(data) { - $('#pool_history_results').html(data); + $('#pool_history_results').html(data); } function pool_history_refresh() { - var url = "/site/history_results"; - $.get(url, '', pool_history_ready); + var url = "/site/history_results"; + $.get(url, '', pool_history_ready); } + diff --git a/web/yaamp/modules/site/memcached.php b/web/yaamp/modules/site/memcached.php index a1252a68a..1c27c4820 100644 --- a/web/yaamp/modules/site/memcached.php +++ b/web/yaamp/modules/site/memcached.php @@ -1,59 +1,70 @@ refresh
"; -$a = controller()->memcache->memcache->get( 'url-map'); +$a = controller() + ->memcache + ->memcache + ->get('url-map'); function printStats($stat) { - echo "
"; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - - $percCacheHit=((real)$stat["get_hits"]/ (real)$stat["cmd_get"] *100); - $percCacheHit=round($percCacheHit,3); - $percCacheMiss=100-$percCacheHit; - - echo ""; - echo ""; - - $MBRead= (real)$stat["bytes_read"]/(1024*1024); - - echo ""; - $MBWrite=(real) $stat["bytes_written"]/(1024*1024) ; - echo ""; - $MBSize=(real) $stat["limit_maxbytes"]/(1024*1024) ; - echo ""; - echo ""; - echo "
Memcache Server version ".$stat["version"]."
Process id of this server process".$stat["pid"]."
Server uptime ".$stat["uptime"]." seconds
Accumulated user time for this process".round($stat["rusage_user"],1)." seconds
Accumulated system time for this process".round($stat["rusage_system"],1)." seconds
Total number of items stored by this server start".$stat["total_items"]."
Number of open connections ".$stat["curr_connections"]."
Total number of connections opened since server start".$stat["total_connections"]."
Number of connection structures allocated by the server".$stat["connection_structures"]."
Cumulative number of retrieval requests".$stat["cmd_get"]."
Cumulative number of storage requests".$stat["cmd_set"]."
Number of keys that have been requested and found".$stat["get_hits"]." ($percCacheHit%)
Number of items that have been requested and not found".$stat["get_misses"]." ($percCacheMiss%)
Total number of bytes read by this server from network".$MBRead." MB
Total number of bytes sent by this server to network".$MBWrite." MB
Size allowed to use for storage".$MBSize." MB
Items removed from cache to free memory for new items".$stat["evictions"]."
"; + echo "
"; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + + $percCacheHit = ((real)$stat["get_hits"] / (real)$stat["cmd_get"] * 100); + $percCacheHit = round($percCacheHit, 3); + $percCacheMiss = 100 - $percCacheHit; + + echo ""; + echo ""; + + $MBRead = (real)$stat["bytes_read"] / (1024 * 1024); + + echo ""; + $MBWrite = (real)$stat["bytes_written"] / (1024 * 1024); + echo ""; + $MBSize = (real)$stat["limit_maxbytes"] / (1024 * 1024); + echo ""; + echo ""; + echo "
Memcache Server version " . $stat["version"] . "
Process id of this server process" . $stat["pid"] . "
Server uptime " . $stat["uptime"] . " seconds
Accumulated user time for this process" . round($stat["rusage_user"], 1) . " seconds
Accumulated system time for this process" . round($stat["rusage_system"], 1) . " seconds
Total number of items stored by this server start" . $stat["total_items"] . "
Number of open connections " . $stat["curr_connections"] . "
Total number of connections opened since server start" . $stat["total_connections"] . "
Number of connection structures allocated by the server" . $stat["connection_structures"] . "
Cumulative number of retrieval requests" . $stat["cmd_get"] . "
Cumulative number of storage requests" . $stat["cmd_set"] . "
Number of keys that have been requested and found" . $stat["get_hits"] . " ($percCacheHit%)
Number of items that have been requested and not found" . $stat["get_misses"] . " ($percCacheMiss%)
Total number of bytes read by this server from network" . $MBRead . " MB
Total number of bytes sent by this server to network" . $MBWrite . " MB
Size allowed to use for storage" . $MBSize . " MB
Items removed from cache to free memory for new items" . $stat["evictions"] . "
"; } -printStats($this->memcache->memcache->getStats()); +printStats($this + ->memcache + ->memcache + ->getStats()); $res = array(); function cmp($a, $b) { - return $a[2] < $b[2]; + return $a[2] < $b[2]; } -if (!empty($a)) -foreach($a as $url=>$n) +if (!empty($a)) foreach ($a as $url => $n) { - $d = $this->memcache->get("$url-time"); - $avg = $d/$n; - - $res[] = array($url, $n, $d, $avg); + $d = $this + ->memcache + ->get("$url-time"); + $avg = $d / $n; + + $res[] = array( + $url, + $n, + $d, + $avg + ); } usort($res, 'cmp'); @@ -69,22 +80,20 @@ function cmp($a, $b) echo "
$url$n$d$avg
$url$n$d$avg
"; diff --git a/web/yaamp/modules/site/miners.php b/web/yaamp/modules/site/miners.php index c72df2992..0c4371b3e 100644 --- a/web/yaamp/modules/site/miners.php +++ b/web/yaamp/modules/site/miners.php @@ -13,9 +13,9 @@ echo <<
+ padding: 10px; margin-left: 20px; margin-right: 20px; margin-top: 15px; cursor: pointer; display: none;' + onclick='auto_page_resume();' align=center> + Auto refresh is paused - Click to resume
"; + echo ""; - echo ""; + echo ""; - if(!$coin) - echo ''; - else { - $coinlink = CHtml::link($coin->symbol, '/site/coin?id='.$coin->id); - echo ''; - } + if (!$coin) + echo ''; + else { + $coinlink = CHtml::link($coin->symbol, '/site/coin?id=' . $coin->id); + echo ''; + } - echo ""; - echo ""; - echo ""; + echo ""; + echo ""; + echo ""; - echo ""; - echo ""; + echo ""; + echo ""; - if(intval($paid) > 0.01) - echo ""; - else - echo ""; + if (intval($paid) > 0.01) + echo ""; + else + echo ""; - echo ""; - echo ""; + echo ""; + echo ""; - if($user->is_locked) - { - echo ""; - echo ""; - } + if ($user->is_locked) { + echo ""; + echo ""; + } - else - { - echo ""; - echo ""; - } + else { + echo ""; + echo ""; + } - echo ""; + echo ""; } -$t = time()-24*60*60; +$t = time() - 24 * 60 * 60; $list = dbolist("select userid from shares where pid is null or pid not in (select pid from stratums) group by userid"); -foreach($list as $item) - showUser($item['userid'], 'pid'); +foreach ($list as $item) + showUser($item['userid'], 'pid'); $list = dbolist("select id from accounts where balance>0.001 and id not in (select distinct userid from blocks where userid is not null and time>$t)"); -foreach($list as $item) - showUser($item['id'], 'blocks'); +foreach ($list as $item) + showUser($item['id'], 'blocks'); $monsters = dbolist("SELECT COUNT(*) AS total, userid FROM workers GROUP BY userid ORDER BY total DESC LIMIT 5"); -foreach($monsters as $item) - showUser($item['userid'], 'miners'); +foreach ($monsters as $item) + showUser($item['userid'], 'miners'); $monsters = dbolist("SELECT COUNT(*) AS total, workerid FROM shares GROUP BY workerid ORDER BY total DESC LIMIT 5"); -foreach($monsters as $item) -{ - $worker = getdbo('db_workers', $item['workerid']); - if(!$worker) continue; +foreach ($monsters as $item) { + $worker = getdbo('db_workers', $item['workerid']); + if (!$worker) + continue; - showUser($worker->userid, 'shares'); + showUser($worker->userid, 'shares'); } $list = getdbolist('db_accounts', "is_locked"); -foreach($list as $user) - showUser($user->id, 'locked'); +foreach ($list as $user) + showUser($user->id, 'locked'); echo "
@@ -42,47 +42,42 @@ function page_refresh() { - miners_refresh(); - pool_current_refresh(); + miners_refresh(); + pool_current_refresh(); } function select_algo(algo) { - window.location.href = '/site/algo?algo='+algo+'&r=/site/miners'; + window.location.href = '/site/algo?algo='+algo+'&r=/site/miners'; } //////////////////////////////////////////////////// function pool_current_ready(data) { - $('#pool_current_results').html(data); + $('#pool_current_results').html(data); } function pool_current_refresh() { - var url = "/site/current_results"; - $.get(url, '', pool_current_ready); + var url = "/site/current_results"; + $.get(url, '', pool_current_ready); } //////////////////////////////////////////////////// function miners_ready(data) { - $('#miners_results').html(data); + $('#miners_results').html(data); } function miners_refresh() { - var url = "/site/miners_results"; - $.get(url, '', miners_ready); + var url = "/site/miners_results"; + $.get(url, '', miners_ready); } end; - - - - - diff --git a/web/yaamp/modules/site/mining.php b/web/yaamp/modules/site/mining.php index 89fa54190..730f4c920 100644 --- a/web/yaamp/modules/site/mining.php +++ b/web/yaamp/modules/site/mining.php @@ -43,7 +43,10 @@ $algo_unit = 'Mh'; $algo_factor = yaamp_algo_mBTC_factor($algo); +if ($algo_factor == 0.001) $algo_unit = 'Kh'; if ($algo_factor == 1000) $algo_unit = 'Gh'; +if ($algo_factor == 1000000) $algo_unit = 'Th'; +if ($algo_factor == 1000000000) $algo_unit = 'Ph'; echo << @@ -194,7 +197,7 @@ function pool_hashrate_graph_init(data) var t = $.parseJSON(data); var plot1 = $.jqplot('pool_hashrate_results', t, { - title: 'Pool Hashrate (Mh/s)', + title: 'Pool Hashrate ({$algo_unit}/s)', axes: { xaxis: { tickInterval: 7200, @@ -232,8 +235,3 @@ function pool_hashrate_graph_init(data) end; - - - - - diff --git a/web/yaamp/modules/site/monsters.php b/web/yaamp/modules/site/monsters.php index 23187c6a3..da68f24a9 100644 --- a/web/yaamp/modules/site/monsters.php +++ b/web/yaamp/modules/site/monsters.php @@ -12,15 +12,15 @@ end; showTableSorter('maintable', "{ - tableClass: 'dataGrid', - headers: { 1: { sorter: false} }, - widgets: ['zebra','filter'], - widgetOptions: { - filter_external: '.search', - filter_columnFilters: false, - filter_childRows : true, - filter_ignoreCase: true - } + tableClass: 'dataGrid', + headers: { 1: { sorter: false} }, + widgets: ['zebra','filter'], + widgetOptions: { + filter_external: '.search', + filter_columnFilters: false, + filter_childRows : true, + filter_ignoreCase: true + } }"); echo <<last_earning); - $balance = bitcoinvaluetoa($user->balance); - $paid = dboscalar("select sum(amount) from payouts where account_id=$user->id"); - $paid = bitcoinvaluetoa($paid); + $d = datetoa2($user->last_earning); + $balance = bitcoinvaluetoa($user->balance); + $paid = dboscalar("select sum(amount) from payouts where account_id=$user->id"); + $paid = bitcoinvaluetoa($paid); - $t = time()-24*60*60; + $t = time() - 24 * 60 * 60; - $miner_count = getdbocount('db_workers', "userid=$user->id"); - $share_count = getdbocount('db_shares', "userid=$user->id"); - $block_count = getdbocount('db_blocks', "userid=$user->id and time>$t"); + $miner_count = getdbocount('db_workers', "userid=$user->id"); + $share_count = getdbocount('db_shares', "userid=$user->id"); + $block_count = getdbocount('db_blocks', "userid=$user->id and time>$t"); - $coin = getdbo('db_coins', $user->coinid); + $coin = getdbo('db_coins', $user->coinid); - echo "
$user->id$user->id'.$coinlink.'' . $coinlink . '$user->username$what$d$user->username$what$d$block_count$balance$block_count$balance$paid$paid$paid$paid$miner_count$share_count$miner_count$share_countlockedunblocklockedunblockblockblock
"; - - - - - - - - - - - diff --git a/web/yaamp/modules/site/multialgo.php b/web/yaamp/modules/site/multialgo.php index cfcf5ca80..17df52457 100644 --- a/web/yaamp/modules/site/multialgo.php +++ b/web/yaamp/modules/site/multialgo.php @@ -39,11 +39,11 @@ :start -ccminer -r 0 -a x11 -o stratum+tcp://:3533 -u joe -p x11,x13,x14,x15,quark,lyra2 -ccminer -r 0 -a x13 -o stratum+tcp://:3633 -u joe -p x11,x13,x14,x15,quark,lyra2 -ccminer -r 0 -a x15 -o stratum+tcp://:3733 -u joe -p x11,x13,x14,x15,quark,lyra2 -ccminer -r 0 -a lyra2 -o stratum+tcp://:4433 -u joe -p x11,x13,x14,x15,quark,lyra2 -ccminer -r 0 -a quark -o stratum+tcp://:4033 -u joe -p x11,x13,x14,x15,quark,lyra2 +ccminer -r 0 -a x11 -o stratum+tcp://:3533 -u joe -p x11,x13,x14,x15,quark,lyra2 +ccminer -r 0 -a x13 -o stratum+tcp://:3633 -u joe -p x11,x13,x14,x15,quark,lyra2 +ccminer -r 0 -a x15 -o stratum+tcp://:3733 -u joe -p x11,x13,x14,x15,quark,lyra2 +ccminer -r 0 -a lyra2 -o stratum+tcp://:4433 -u joe -p x11,x13,x14,x15,quark,lyra2 +ccminer -r 0 -a quark -o stratum+tcp://:4033 -u joe -p x11,x13,x14,x15,quark,lyra2 sleep 5000 goto start @@ -83,5 +83,3 @@ - - diff --git a/web/yaamp/modules/site/payments.php b/web/yaamp/modules/site/payments.php index 2a146a4ae..ea4d70bc9 100644 --- a/web/yaamp/modules/site/payments.php +++ b/web/yaamp/modules/site/payments.php @@ -3,8 +3,8 @@ $coin_id = getiparam('id'); if ($coin_id) { - $coin = getdbo('db_coins', $coin_id); - $this->pageTitle = 'Payments - '.$coin->symbol; + $coin = getdbo('db_coins', $coin_id); + $this->pageTitle = 'Payments - ' . $coin->symbol; } JavascriptFile("/yaamp/ui/js/jquery.metadata.js"); @@ -21,23 +21,23 @@ function main_ready(data) { - $('#main_results').html(data); - main_timeout = setTimeout(main_refresh, main_delay); + $('#main_results').html(data); + main_timeout = setTimeout(main_refresh, main_delay); } function main_error() { - main_timeout = setTimeout(main_refresh, main_delay*2); + main_timeout = setTimeout(main_refresh, main_delay*2); } function main_refresh() { - var url = '/site/payments_results?id='; - var minh = $(window).height() - 150; - $('#main_results').css({'min-height': minh + 'px'}); + var url = '/site/payments_results?id='; + var minh = $(window).height() - 150; + $('#main_results').css({'min-height': minh + 'px'}); - clearTimeout(main_timeout); - $.get(url, '', main_ready).error(main_error); + clearTimeout(main_timeout); + $.get(url, '', main_ready).error(main_error); } diff --git a/web/yaamp/modules/site/payments_results.php b/web/yaamp/modules/site/payments_results.php index e20a8644c..0d886e4c6 100644 --- a/web/yaamp/modules/site/payments_results.php +++ b/web/yaamp/modules/site/payments_results.php @@ -22,19 +22,19 @@ $saveSort = $coin_id ? 'false' : 'true'; showTableSorter('maintable', "{ - tableClass: 'dataGrid', - textExtraction: { - 3: function(node, table, n) { return $(node).attr('data'); } - }, - widgets: ['zebra','filter','Storage','saveSort'], - widgetOptions: { - saveSort: {$saveSort}, - filter_saveFilters: {$saveSort}, - filter_external: '.search', - filter_columnFilters: false, - filter_childRows : true, - filter_ignoreCase: true - } + tableClass: 'dataGrid', + textExtraction: { + 3: function(node, table, n) { return $(node).attr('data'); } + }, + widgets: ['zebra','filter','Storage','saveSort'], + widgetOptions: { + saveSort: {$saveSort}, + filter_saveFilters: {$saveSort}, + filter_external: '.search', + filter_columnFilters: false, + filter_childRows : true, + filter_ignoreCase: true + } }"); echo << 0 OR last_earning > (UNIX_TIMESTAMP()-60*60) OR id IN (SELECT DISTINCT account_id FROM payouts WHERE tx IS NULL)". - ") ORDER BY last_earning DESC $limit"); - -$total = 0.; $totalimmat = 0.; $totalfailed = 0.; -foreach($list as $user) -{ - $coin = getdbo('db_coins', $user->coinid); - $d = datetoa2($user->last_earning); - - echo ''; - - if($coin) { - $coinbalance = $coin->balance ? bitcoinvaluetoa($coin->balance) : ''; - echo ''; - echo ''.$coin->name.' ('.$coin->symbol_show.')'; - $immkey = "{$coin->id}-{$user->id}"; - } else { - $coinbalance = '-'; - echo ''; - echo ''; - $immkey = "0-{$user->id}"; - } - - echo ''.$user->username.''; - echo ''.$d.''; - - echo ''.$coinbalance.''; - - $balance = $user->balance ? bitcoinvaluetoa($user->balance) : ''; - $total += (double) $user->balance; - echo ''.$balance.''; - - $immbalance = arraySafeVal($immature, $immkey, 0); - $totalimmat += (double) $immbalance; - $immbalance = $immbalance ? bitcoinvaluetoa($immbalance) : ''; - echo ''.$immbalance.''; - - $failbalance = arraySafeVal($failed, $user->id, 0); - $totalfailed += (double) $failbalance; - $failbalance = $failbalance ? bitcoinvaluetoa($failbalance) : ''; - echo ''.$failbalance.''; - - echo ''; - if ($failbalance != '-') - echo '[add to balance]'; - echo ''; - - echo ""; +if (!empty($data)) + foreach ($data as $row) { + $uid = $row['account_id']; + $failed[$uid] = $row['failed']; + } + +$list = getdbolist('db_accounts', "is_locked != 1 $sqlFilter AND (" . "balance > 0 OR last_earning > (UNIX_TIMESTAMP()-60*60) OR id IN (SELECT DISTINCT account_id FROM payouts WHERE tx IS NULL)" . ") ORDER BY last_earning DESC $limit"); + +$total = 0.; +$totalimmat = 0.; +$totalfailed = 0.; +foreach ($list as $user) { + $coin = getdbo('db_coins', $user->coinid); + $d = datetoa2($user->last_earning); + + echo ''; + + if ($coin) { + $coinbalance = $coin->balance ? bitcoinvaluetoa($coin->balance) : ''; + echo ''; + echo '' . $coin->name . ' (' . $coin->symbol_show . ')'; + $immkey = "{$coin->id}-{$user->id}"; + } else { + $coinbalance = '-'; + echo ''; + echo ''; + $immkey = "0-{$user->id}"; + } + + echo '' . $user->username . ''; + echo '' . $d . ''; + + echo '' . $coinbalance . ''; + + $balance = $user->balance ? bitcoinvaluetoa($user->balance) : ''; + $total += (double) $user->balance; + echo '' . $balance . ''; + + $immbalance = arraySafeVal($immature, $immkey, 0); + $totalimmat += (double) $immbalance; + $immbalance = $immbalance ? bitcoinvaluetoa($immbalance) : ''; + echo '' . $immbalance . ''; + + $failbalance = arraySafeVal($failed, $user->id, 0); + $totalfailed += (double) $failbalance; + $failbalance = $failbalance ? bitcoinvaluetoa($failbalance) : ''; + echo '' . $failbalance . ''; + + echo ''; + if ($failbalance != '-') + echo '[add to balance]'; + echo ''; + + echo ""; } echo ''; echo ''; -echo count($list).' users'; -if (count($list) == 100) echo " ($limit)"; +echo count($list) . ' users'; +if (count($list) == 100) + echo " ($limit)"; echo ''; echo ''; if ($coin_id) { - $coin = getdbo('db_coins', $coin_id); - $symbol = $coin->symbol; - echo '
'; - echo ''; - echo '"; - echo '"; - if ($totalfailed) { - echo '"; - echo ''; - } - echo '
Balances'.bitcoinvaluetoa($total)." $symbol
Immature'.bitcoinvaluetoa($totalimmat)." $symbol
Failed'.bitcoinvaluetoa($totalfailed)." $symbol
'.'Reset all failed
'; - echo '
'; + $coin = getdbo('db_coins', $coin_id); + $symbol = $coin->symbol; + echo '
'; + echo ''; + echo '"; + echo '"; + if ($totalfailed) { + echo '"; + echo ''; + } + echo '
Balances' . bitcoinvaluetoa($total) . " $symbol
Immature' . bitcoinvaluetoa($totalimmat) . " $symbol
Failed' . bitcoinvaluetoa($totalfailed) . " $symbol
' . 'Reset all failed
'; + echo '
'; } diff --git a/web/yaamp/modules/site/results/current_results.php b/web/yaamp/modules/site/results/current_results.php index c24a925bb..72520a014 100644 --- a/web/yaamp/modules/site/results/current_results.php +++ b/web/yaamp/modules/site/results/current_results.php @@ -1,184 +1,244 @@ getState('yaamp-algo'); - echo "
"; echo "
Pool Status
"; echo "
"; - showTableSorter('maintable1', "{ - tableClass: 'dataGrid2', - textExtraction: { - 4: function(node, table, n) { return $(node).attr('data'); }, - 8: function(node, table, n) { return $(node).attr('data'); } - } + tableClass: 'dataGrid2', + textExtraction: { + 4: function(node, table, n) { return $(node).attr('data'); }, + 8: function(node, table, n) { return $(node).attr('data'); } + } }"); - echo << -Algo -Port -Coins -Miners -Hashrate -Fees** -Current
Estimate +Coins +Auto Exchanged +Port +Symbol +Miners +Pool HashRate +Network Hashrate +Fees** + -24 Hours
Estimated -24 Hours
Actual*** + +24 Hours
Actual*** END; - $best_algo = ''; $best_norm = 0; - $algos = array(); -foreach(yaamp_get_algos() as $algo) -{ - $algo_norm = yaamp_get_algo_norm($algo); - - $price = controller()->memcache->get_database_scalar("current_price-$algo", - "select price from hashrate where algo=:algo order by time desc limit 1", array(':algo'=>$algo)); - - $norm = $price*$algo_norm; - $norm = take_yaamp_fee($norm, $algo); - $algos[] = array($norm, $algo); - - if($norm > $best_norm) - { - $best_norm = $norm; - $best_algo = $algo; - } +foreach (yaamp_get_algos() as $algo) +{ + $algo_norm = yaamp_get_algo_norm($algo); + $price = controller() + ->memcache + ->get_database_scalar("current_price-$algo", "select price from hashrate where algo=:algo order by time desc limit 1", array( + ':algo' => $algo + )); + $norm = $price * $algo_norm; + $norm = take_yaamp_fee($norm, $algo); + $algos[] = array( + $norm, + $algo + ); + if ($norm > $best_norm) + { + $best_norm = $norm; + $best_algo = $algo; + } } function cmp($a, $b) { - return $a[0] < $b[0]; + return $a[0] < $b[0]; } usort($algos, 'cmp'); - $total_coins = 0; $total_miners = 0; - $showestimates = false; - echo ""; -foreach($algos as $item) -{ - $norm = $item[0]; - $algo = $item[1]; - - $coinsym = ''; - $coins = getdbocount('db_coins', "enable and visible and auto_ready and algo=:algo", array(':algo'=>$algo)); - if ($coins == 1) { - // If we only mine one coin, show it... - $coin = getdbosql('db_coins', "enable and visible and auto_ready and algo=:algo", array(':algo'=>$algo)); - $coinsym = empty($coin->symbol2) ? $coin->symbol : $coin->symbol2; - $coinsym = ''.$coinsym.''; - } - - if (!$coins) continue; - - $workers = getdbocount('db_workers', "algo=:algo", array(':algo'=>$algo)); - - $hashrate = controller()->memcache->get_database_scalar("current_hashrate-$algo", - "select hashrate from hashrate where algo=:algo order by time desc limit 1", array(':algo'=>$algo)); - $hashrate_sfx = $hashrate? Itoa2($hashrate).'h/s': '-'; - - $price = controller()->memcache->get_database_scalar("current_price-$algo", - "select price from hashrate where algo=:algo order by time desc limit 1", array(':algo'=>$algo)); - - $price = $price? mbitcoinvaluetoa(take_yaamp_fee($price, $algo)): '-'; - $norm = mbitcoinvaluetoa($norm); - - $t = time() - 24*60*60; - - $avgprice = controller()->memcache->get_database_scalar("current_avgprice-$algo", - "select avg(price) from hashrate where algo=:algo and time>$t", array(':algo'=>$algo)); - $avgprice = $avgprice? mbitcoinvaluetoa(take_yaamp_fee($avgprice, $algo)): '-'; - - $total1 = controller()->memcache->get_database_scalar("current_total-$algo", - "SELECT SUM(amount*price) AS total FROM blocks WHERE time>$t AND algo=:algo AND NOT category IN ('orphan','stake','generated')", - array(':algo'=>$algo) - ); - $hashrate1 = controller()->memcache->get_database_scalar("current_hashrate1-$algo", - "select avg(hashrate) from hashrate where time>$t and algo=:algo", array(':algo'=>$algo)); - - $algo_unit_factor = yaamp_algo_mBTC_factor($algo); - $btcmhday1 = $hashrate1 != 0? mbitcoinvaluetoa($total1 / $hashrate1 * 1000000 * 1000 * $algo_unit_factor): ''; - - $fees = yaamp_fee($algo); - $port = getAlgoPort($algo); - - if($defaultalgo == $algo) - echo ""; - else - echo ""; - - echo "$algo"; - echo "$port"; - echo "".($coins==1 ? $coinsym : $coins).""; - echo "$workers"; - echo ''.$hashrate_sfx.''; - echo "{$fees}%"; - - if($algo == $best_algo) - echo ''.$price.'*'; - else if($norm>0) - echo ''.$price.''; - - else - echo ''.$price.''; - - - echo ''.$avgprice.''; - - if($algo == $best_algo) - echo ''.$btcmhday1.'*'; - else - echo ''.$btcmhday1.''; - - echo ""; - - $total_coins += $coins; - $total_miners += $workers; +foreach ($algos as $item) +{ + $norm = $item[0]; + $algo = $item[1]; + $coinsym = ''; + $coins = getdbocount('db_coins', "enable and visible and auto_ready and algo=:algo", array( + ':algo' => $algo + )); + if ($coins == 2) + { + + // If we only mine one coin, show it... + $coin = getdbosql('db_coins', "enable and visible and auto_ready and algo=:algo", array( + ':algo' => $algo + )); + $coinsym = empty($coin->symbol2) ? $coin->symbol : $coin->symbol2; + $coinsym = '' . $coinsym . ''; + } + + if (!$coins) continue; + $workers = getdbocount('db_workers', "algo=:algo", array( + ':algo' => $algo + )); + $hashrate = controller() + ->memcache + ->get_database_scalar("current_hashrate-$algo", "select hashrate from hashrate where algo=:algo order by time desc limit 1", array( + ':algo' => $algo + )); + $hashrate_sfx = $hashrate ? Itoa2($hashrate) . 'h/s' : '-'; + $price = controller() + ->memcache + ->get_database_scalar("current_price-$algo", "select price from hashrate where algo=:algo order by time desc limit 1", array( + ':algo' => $algo + )); + $price = $price ? mbitcoinvaluetoa(take_yaamp_fee($price, $algo)) : '-'; + $norm = mbitcoinvaluetoa($norm); + $t = time() - 24 * 60 * 60; + $avgprice = controller() + ->memcache + ->get_database_scalar("current_avgprice-$algo", "select avg(price) from hashrate where algo=:algo and time>$t", array( + ':algo' => $algo + )); + $avgprice = $avgprice ? mbitcoinvaluetoa(take_yaamp_fee($avgprice, $algo)) : '-'; + $total1 = controller() + ->memcache + ->get_database_scalar("current_total-$algo", "SELECT SUM(amount*price) AS total FROM blocks WHERE time>$t AND algo=:algo AND NOT category IN ('orphan','stake','generated')", array( + ':algo' => $algo + )); + $hashrate1 = controller() + ->memcache + ->get_database_scalar("current_hashrate1-$algo", "select avg(hashrate) from hashrate where time>$t and algo=:algo", array( + ':algo' => $algo + )); + $algo_unit_factor = yaamp_algo_mBTC_factor($algo); + $btcmhday1 = $hashrate1 != 0 ? mbitcoinvaluetoa($total1 / $hashrate1 * 1000000 * 1000 * $algo_unit_factor) : ''; + $fees = yaamp_fee($algo); + $port = getAlgoPort($algo); + + if ($defaultalgo == $algo) echo ""; + else echo ""; + echo "$algo"; + echo ""; + echo ""; + echo ""; + echo ""; + echo ''; + echo ''; + echo ""; + echo ""; + if ($algo == $best_algo) echo '' . $price . '*'; + else if ($norm > 0) echo '' . $price . ''; + else echo ''; + echo ''; + if ($algo == $best_algo) echo '' . $btcmhday1 . '*'; + else echo '' . $btcmhday1 . ''; + echo ""; + if ($coins > 0) + { + $list = getdbolist('db_coins', "enable and visible and auto_ready and algo=:algo order by index_avg desc", array( + ':algo' => $algo + )); + + foreach ($list as $coin) + { + $name = substr($coin->name, 0, 18); + $symbol = $coin->getOfficialSymbol(); + echo " $name "; + $port_count = getdbocount('db_stratums', "algo=:algo and symbol=:symbol", array( + ':algo' => $algo, + ':symbol' => $symbol + )); + $port_db = getdbosql('db_stratums', "algo=:algo and symbol=:symbol", array( + ':algo' => $algo, + ':symbol' => $symbol + )); + + $dontsell = $coin->dontsell; + if ($dontsell == 1) echo ""; + else echo ""; + + if ($port_count == 1) echo "" . $port_db->port . ""; + else echo "$port"; + echo "$symbol"; + if ($port_count == 1) echo "" . $port_db->workers . ""; + else echo "$workers"; + $pool_hash = yaamp_coin_rate($coin->id); + $pool_hash_sfx = $pool_hash ? Itoa2($pool_hash) . 'h/s' : ''; + echo "$pool_hash_sfx"; + $pool_hash_sfx = $pool_hash ? Itoa2($pool_hash) . 'h/s' : ''; + $min_ttf = $coin->network_ttf > 0 ? min($coin->actual_ttf, $coin->network_ttf) : $coin->actual_ttf; + $network_hash = controller() + ->memcache + ->get("yiimp-nethashrate-{$coin->symbol}"); + if (!$network_hash) + { + $remote = new WalletRPC($coin); + if ($remote) $info = $remote->getmininginfo(); + if (isset($info['networkhashps'])) + { + $network_hash = $info['networkhashps']; + controller() + ->memcache + ->set("yiimp-nethashrate-{$coin->symbol}", $info['networkhashps'], 60); + } + else if (isset($info['netmhashps'])) + { + $network_hash = floatval($info['netmhashps']) * 1e6; + controller() + ->memcache + ->set("yiimp-nethashrate-{$coin->symbol}", $network_hash, 60); + } + } + $network_hash = $network_hash ? Itoa2($network_hash) . 'h/s' : ''; + echo "$network_hash"; + echo "{$fees}%"; + $btcmhd = yaamp_profitability($coin); + $btcmhd = mbitcoinvaluetoa($btcmhd); + echo "$btcmhd"; + echo ""; + } + } + + $total_coins += $coins; + $total_miners += $workers; } echo ""; -if($defaultalgo == 'all') - echo ""; -else - echo ""; - +if ($defaultalgo == 'all') echo ""; +else echo ""; echo "all"; echo ""; -echo "$total_coins"; -echo "$total_miners"; +echo ""; +echo "$total_coins"; +echo "$total_miners"; echo ""; echo ""; echo ''; echo ''; echo ""; +echo ""; echo ""; - echo ""; - echo '

 * values in mBTC/MH/day, per GH for sha & blake algos

'; - -echo "

"; +echo "

"; ?> - + - - + diff --git a/web/yaamp/modules/site/results/found_results.php b/web/yaamp/modules/site/results/found_results.php index e37a6365b..082c1ef09 100644 --- a/web/yaamp/modules/site/results/found_results.php +++ b/web/yaamp/modules/site/results/found_results.php @@ -1,27 +1,47 @@ "; - echo "
$title
"; - echo "
"; + echo "
"; + echo "
$title
"; + echo "
"; } -$showrental = (bool) YAAMP_RENTAL; +$showrental = (bool)YAAMP_RENTAL; -$algo = user()->getState('yaamp-algo'); +$algo_from_query_param = getparam('algo'); +if ($algo_from_query_param) +{ + // Query param is set + if ($algo_from_query_param != 'all') + { + $r_algo = array_map('trim', explode(',', $algo_from_query_param)); + $r_algo = preg_replace('/[^A-Za-z0-9\-]/', '', $r_algo); + } +} +else +{ + // Filter out algo from user's preferences + $algo_from_user_pref = user()->getState('yaamp-algo'); + if ($algo_from_user_pref != 'all') + { + $r_algo = array( + $algo_from_user_pref + ); + } +} $count = getparam('count'); -$count = $count? $count: 50; +$count = $count ? $count : 50; -WriteBoxHeader("Last $count Blocks ($algo)"); +$algo_header = isset($r_algo) ? implode(',', $r_algo) : 'any algo'; +WriteBoxHeader("Last $count Blocks ($algo_header)"); $criteria = new CDbCriteria(); $criteria->condition = "t.category NOT IN ('stake','generated')"; $criteria->condition .= " AND IFNULL(coin.visible,1)=1"; // ifnull for rental -if($algo != 'all') { - $criteria->condition .= " AND t.algo=:algo"; - $criteria->params = array(':algo'=>$algo); +if (isset($r_algo)) +{ + $criteria->addInCondition('t.algo', $r_algo); } $criteria->limit = $count; $criteria->order = 't.time DESC'; @@ -54,74 +74,71 @@ function WriteBoxHeader($title) EOT; -foreach($db_blocks as $db_block) + +foreach ($db_blocks as $db_block) { - $d = datetoa2($db_block->time); - if(!$db_block->coin_id) - { - if (!$showrental) - continue; - - $reward = bitcoinvaluetoa($db_block->amount); - - echo ''; - echo ''; - echo 'Rental ('.$db_block->algo.')'; - echo ''.$reward.' BTC'; - echo ''; - echo ''; - echo ''.$d.' ago'; - echo ''; - echo 'Confirmed'; - echo ''; - echo ''; - - continue; - } - - $reward = round($db_block->amount, 3); - $coin = $db_block->coin ? $db_block->coin : getdbo('db_coins', $db_block->coin_id); - $difficulty = Itoa2($db_block->difficulty, 3); - $height = number_format($db_block->height, 0, '.', ' '); - - $link = $coin->createExplorerLink($coin->name, array('hash'=>$db_block->blockhash)); - - $flags = $db_block->segwit ? ' ' : ''; - - echo ''; - echo ''; - echo ''.$link.' ('.$db_block->algo.')'.$flags.''; - echo ''.$reward.' '.$coin->symbol_show.''; - echo ''.$difficulty.''; - echo ''.$height.''; - echo ''.$d.' ago'; - echo ''; - - if($db_block->category == 'orphan') - echo 'Orphan'; - - else if($db_block->category == 'immature') { - $eta = ''; - if ($coin->block_time && $coin->mature_blocks) { - $t = (int) ($coin->mature_blocks - $db_block->confirmations) * $coin->block_time; - $eta = "ETA: ".sprintf('%dh %02dmn', ($t/3600), ($t/60)%60); - } - echo 'Immature ('.$db_block->confirmations.')'; - } - else if($db_block->category == 'generate') - echo 'Confirmed'; - - else if($db_block->category == 'new') - echo 'New'; - - echo ""; - echo ""; + $d = datetoa2($db_block->time); + if (!$db_block->coin_id) + { + if (!$showrental) continue; + + $reward = bitcoinvaluetoa($db_block->amount); + + echo ''; + echo ''; + echo 'Rental (' . $db_block->algo . ')'; + echo '' . $reward . ' BTC'; + echo ''; + echo ''; + echo '' . $d . ' ago'; + echo ''; + echo 'Confirmed'; + echo ''; + echo ''; + + continue; + } + + $reward = round($db_block->amount, 3); + $coin = $db_block->coin ? $db_block->coin : getdbo('db_coins', $db_block->coin_id); + $difficulty = Itoa2($db_block->difficulty, 3); + $height = number_format($db_block->height, 0, '.', ' '); + + $link = $coin->createExplorerLink($coin->name, array( + 'hash' => $db_block->blockhash + )); + + $flags = $db_block->segwit ? ' ' : ''; + + echo ''; + echo ''; + echo '' . $link . ' (' . $db_block->algo . ')' . $flags . ''; + echo '' . $reward . ' ' . $coin->symbol_show . ''; + echo '' . $difficulty . ''; + echo '' . $height . ''; + echo '' . $d . ' ago'; + echo ''; + + if ($db_block->category == 'orphan') echo 'Orphan'; + + else if ($db_block->category == 'immature') + { + $eta = ''; + if ($coin->block_time && $coin->mature_blocks) + { + $t = (int)($coin->mature_blocks - $db_block->confirmations) * $coin->block_time; + $eta = "ETA: " . sprintf('%dh %02dmn', ($t / 3600) , ($t / 60) % 60); + } + echo 'Immature (' . $db_block->confirmations . ')'; + } + else if ($db_block->category == 'generate') echo 'Confirmed'; + + else if ($db_block->category == 'new') echo 'New'; + + echo ""; + echo ""; } echo ""; echo "

"; - - - - diff --git a/web/yaamp/modules/site/results/graph_assets_results.php b/web/yaamp/modules/site/results/graph_assets_results.php index 24db908f2..a91200129 100644 --- a/web/yaamp/modules/site/results/graph_assets_results.php +++ b/web/yaamp/modules/site/results/graph_assets_results.php @@ -1,58 +1,51 @@ $t order by time"); echo '[['; -foreach($stats as $i=>$n) +foreach ($stats as $i => $n) { - $m = round($n->margin - $n->renters, 8); - if($i) echo ','; + $m = round($n->margin - $n->renters, 8); + if ($i) echo ','; - $d = date('Y-m-d H:i:s', $n->time); - echo "[\"$d\",$m]"; + $d = date('Y-m-d H:i:s', $n->time); + echo "[\"$d\",$m]"; } echo '],['; -foreach($stats as $i=>$n) +foreach ($stats as $i => $n) { -// $m = round($n->margin+$n->balances, 8); - $m = round($n->balances, 8); - if($i) echo ','; + // $m = round($n->margin+$n->balances, 8); + $m = round($n->balances, 8); + if ($i) echo ','; - $d = date('Y-m-d H:i:s', $n->time); - echo "[\"$d\",$m]"; + $d = date('Y-m-d H:i:s', $n->time); + echo "[\"$d\",$m]"; } echo '],['; -foreach($stats as $i=>$n) +foreach ($stats as $i => $n) { -// $m = round($n->margin+$n->balances+$n->onsell, 8); - $m = round($n->onsell, 8); - if($i) echo ','; + // $m = round($n->margin+$n->balances+$n->onsell, 8); + $m = round($n->onsell, 8); + if ($i) echo ','; - $d = date('Y-m-d H:i:s', $n->time); - echo "[\"$d\",$m]"; + $d = date('Y-m-d H:i:s', $n->time); + echo "[\"$d\",$m]"; } echo '],['; -foreach($stats as $i=>$n) +foreach ($stats as $i => $n) { -// $m = round($n->margin+$n->balances+$n->onsell, 8); - $m = round($n->wallets, 8); - if($i) echo ','; + // $m = round($n->margin+$n->balances+$n->onsell, 8); + $m = round($n->wallets, 8); + if ($i) echo ','; - $d = date('Y-m-d H:i:s', $n->time); - echo "[\"$d\",$m]"; + $d = date('Y-m-d H:i:s', $n->time); + echo "[\"$d\",$m]"; } echo ']]'; - - - - - - diff --git a/web/yaamp/modules/site/results/graph_earnings_results.php b/web/yaamp/modules/site/results/graph_earnings_results.php index 7b9579feb..c8230062c 100644 --- a/web/yaamp/modules/site/results/graph_earnings_results.php +++ b/web/yaamp/modules/site/results/graph_earnings_results.php @@ -1,47 +1,45 @@ $t and userid=$user->id order by time"); echo '[['; -for($i = $t+$step, $j = 0; $i < time(); $i += $step) +for ($i = $t + $step, $j = 0;$i < time();$i += $step) { - if($i != $t+$step) echo ','; - $m = 0; + if ($i != $t + $step) echo ','; + $m = 0; - if(isset($stats[$j]) && $i > $stats[$j]->time) - { - $m = bitcoinvaluetoa($stats[$j]->balance); - $j++; - } + if (isset($stats[$j]) && $i > $stats[$j]->time) + { + $m = bitcoinvaluetoa($stats[$j]->balance); + $j++; + } - $d = date('Y-m-d H:i:s', $i); - echo "[\"$d\",$m]"; + $d = date('Y-m-d H:i:s', $i); + echo "[\"$d\",$m]"; } echo '],['; -for($i = $t+$step, $j = 0; $i < time(); $i += $step) +for ($i = $t + $step, $j = 0;$i < time();$i += $step) { - if($i != $t+$step) echo ','; - $m = 0; + if ($i != $t + $step) echo ','; + $m = 0; - if(isset($stats[$j]) && $i > $stats[$j]->time) - { - $m = bitcoinvaluetoa($stats[$j]->pending); - $j++; - } + if (isset($stats[$j]) && $i > $stats[$j]->time) + { + $m = bitcoinvaluetoa($stats[$j]->pending); + $j++; + } - $d = date('Y-m-d H:i:s', $i); - echo "[\"$d\",$m]"; + $d = date('Y-m-d H:i:s', $i); + echo "[\"$d\",$m]"; } echo ']]'; - diff --git a/web/yaamp/modules/site/results/graph_hashrate_results.php b/web/yaamp/modules/site/results/graph_hashrate_results.php index b585fb069..37b2050d4 100644 --- a/web/yaamp/modules/site/results/graph_hashrate_results.php +++ b/web/yaamp/modules/site/results/graph_hashrate_results.php @@ -1,43 +1,54 @@ getState('yaamp-algo'); $factor = yaamp_algo_mBTC_factor($algo); // 1000 sha (GH/s), 1 for normal MH/s - -$step = 15*60; -$t = time() - 24*60*60; +$step = 15 * 60; +$t = time() - 24 * 60 * 60; $t = intval($t / $step) * $step; -$stats = getdbolist('db_hashrate', "time >= $t AND algo=:algo ORDER BY time", array(':algo'=>$algo)); +$stats = getdbolist('db_hashrate', "time >= $t AND algo=:algo ORDER BY time", array( + ':algo' => $algo +)); $tfirst = empty($stats) ? $t : $stats[0]->time; $averages = array(); -for($i = 0; $i < 95-count($stats); $i++) { - $d = date('Y-m-d H:i:s', $t); - $averages[] = array($d, 0); - $t += $step; - if ($t >= $tfirst) break; +for ($i = 0;$i < 95 - count($stats);$i++) +{ + $d = date('Y-m-d H:i:s', $t); + $averages[] = array( + $d, + 0 + ); + $t += $step; + if ($t >= $tfirst) break; } -foreach($stats as $n) +foreach ($stats as $n) { - $r = $n->hashrate/1000000; - $m = round($r / $factor, 3); + $r = $n->hashrate / 1000000; + $m = round($r / $factor, 3); - $d = date('Y-m-d H:i:s', $n->time); + $d = date('Y-m-d H:i:s', $n->time); - $averages[] = array($d, $m); + $averages[] = array( + $d, + $m + ); } if ($averages[0][1] == 0) $averages[0][1] = $averages[1][1]; $avg2 = array(); $average = $averages[0][1]; -foreach($averages as $n) { - $average = ($average*(100-$percent) + $n[1]*$percent) / 100; - $m = round($average, 3); - $avg2[] = array($n[0], $m); +foreach ($averages as $n) +{ + $average = ($average * (100 - $percent) + $n[1] * $percent) / 100; + $m = round($average, 3); + $avg2[] = array( + $n[0], + $m + ); } -echo '['.json_encode($averages).",\n".json_encode($avg2).']'; +echo '[' . json_encode($averages) . ",\n" . json_encode($avg2) . ']'; diff --git a/web/yaamp/modules/site/results/graph_market_balance.php b/web/yaamp/modules/site/results/graph_market_balance.php index fcfd097e7..337a2eca1 100644 --- a/web/yaamp/modules/site/results/graph_market_balance.php +++ b/web/yaamp/modules/site/results/graph_market_balance.php @@ -1,12 +1,11 @@ 0 ORDER BY M.priority DESC, M.name"); -$stackedMax = (double) 0; +$stackedMax = (double)0; $series = array(); -foreach ($markets as $m) { +foreach ($markets as $m) +{ - $market = getdbo('db_markets', $m['id']); + $market = getdbo('db_markets', $m['id']); - $stats = getdbolist('db_market_history', "time>$t AND idmarket={$market->id} ORDER BY time"); + $stats = getdbolist('db_market_history', "time>$t AND idmarket={$market->id} ORDER BY time"); - $max = 0; - foreach($stats as $histo) { - $d = date('Y-m-d H:i', $histo->time); - $series[$m['name']][] = array($d, (double) bitcoinvaluetoa($histo->balance)); + $max = 0; + foreach ($stats as $histo) + { + $d = date('Y-m-d H:i', $histo->time); + $series[$m['name']][] = array( + $d, + (double)bitcoinvaluetoa($histo->balance) + ); - $max = max($max, $histo->balance); - } + $max = max($max, $histo->balance); + } - $stackedMax += $max; + $stackedMax += $max; } // "yiimp" balance - $stats = getdbolist('db_market_history', "time>$t AND idcoin={$id} AND idmarket IS NULL ORDER BY time"); $max = 0; -foreach($stats as $histo) { - $d = date('Y-m-d H:i', $histo->time); - $series[YAAMP_SITE_NAME][] = array($d, (double) bitcoinvaluetoa($histo->balance)); - $max = max($max, $histo->balance); +foreach ($stats as $histo) +{ + $d = date('Y-m-d H:i', $histo->time); + $series[YAAMP_SITE_NAME][] = array( + $d, + (double)bitcoinvaluetoa($histo->balance) + ); + $max = max($max, $histo->balance); } $stackedMax += $max; // Stacked graph specific : seems to require same amount of points :/ -$max = 0; $seriefull = ''; -foreach ($series as $name => $serie) { - if (count($serie) > $max) $seriefull = $name; - $max = max($max, count($serie)); +$max = 0; +$seriefull = ''; +foreach ($series as $name => $serie) +{ + if (count($serie) > $max) $seriefull = $name; + $max = max($max, count($serie)); } -foreach ($series as $name => $serie) { - if ($seriefull && count($serie) < $max) { - $first_dt = $serie[0][0]; - $fill_start = ($first_dt > $series[$seriefull][0][0]); - } - for ($i = count($serie), $n = 0; $i < $max; $i++, $n++) { - if ($seriefull == '') { - $dt = $serie[0][0]; - array_unshift($series[$name], array($dt, 0)); - continue; - } - if ($fill_start) { - if ($series[$seriefull][$n][0] >= $first_dt) { - array_unshift($series[$name], array($dt, 0)); - $fill_start = false; - } else { - $dt = $series[$seriefull][$n][0]; - array_unshift($series[$name], array($dt, 0)); - } - } else { - $dt = $series[$seriefull][$i][0]; - $last = end($series[$name]); - $series[$name][] = array($dt, $last[1]); - } - } +foreach ($series as $name => $serie) +{ + if ($seriefull && count($serie) < $max) + { + $first_dt = $serie[0][0]; + $fill_start = ($first_dt > $series[$seriefull][0][0]); + } + for ($i = count($serie) , $n = 0;$i < $max;$i++, $n++) + { + if ($seriefull == '') + { + $dt = $serie[0][0]; + array_unshift($series[$name], array( + $dt, + 0 + )); + continue; + } + if ($fill_start) + { + if ($series[$seriefull][$n][0] >= $first_dt) + { + array_unshift($series[$name], array( + $dt, + 0 + )); + $fill_start = false; + } + else + { + $dt = $series[$seriefull][$n][0]; + array_unshift($series[$name], array( + $dt, + 0 + )); + } + } + else + { + $dt = $series[$seriefull][$i][0]; + $last = end($series[$name]); + $series[$name][] = array( + $dt, + $last[1] + ); + } + } } echo json_encode(array( - 'data'=>array_values($series), - 'labels'=>array_keys($series), - 'rangeMin'=> (double) 0.0, - 'rangeMax'=> ($stackedMax * 1.10), + 'data' => array_values($series) , + 'labels' => array_keys($series) , + 'rangeMin' => (double)0.0, + 'rangeMax' => ($stackedMax * 1.10) , )); diff --git a/web/yaamp/modules/site/results/graph_market_prices.php b/web/yaamp/modules/site/results/graph_market_prices.php index e8144cbc0..ef24da52a 100644 --- a/web/yaamp/modules/site/results/graph_market_prices.php +++ b/web/yaamp/modules/site/results/graph_market_prices.php @@ -1,12 +1,11 @@ $t AND idmarket={$market->id} ORDER BY time"); + $stats = getdbolist('db_market_history', "time>$t AND idmarket={$market->id} ORDER BY time"); - foreach($stats as $histo) - { - $d = date('Y-m-d H:i', $histo->time); - $series[$m['name']][] = array($d, (double) bitcoinvaluetoa($histo->price)); - } + foreach ($stats as $histo) + { + $d = date('Y-m-d H:i', $histo->time); + $series[$m['name']][] = array( + $d, + (double)bitcoinvaluetoa($histo->price) + ); + } - if ($histo && $market->pricetime && $market->pricetime > $histo->time) { - $d = date('Y-m-d H:i', $market->pricetime); - $series[$m['name']][] = array($d, (double) bitcoinvaluetoa($market->price)); - } + if ($histo && $market->pricetime && $market->pricetime > $histo->time) + { + $d = date('Y-m-d H:i', $market->pricetime); + $series[$m['name']][] = array( + $d, + (double)bitcoinvaluetoa($market->price) + ); + } - $min = min($min, (double) $m['min']); - $max = max($max, (double) $m['max']); + $min = min($min, (double)$m['min']); + $max = max($max, (double)$m['max']); } -if ($min == 999999999) { - // empty - $min = 0; +if ($min == 999999999) +{ + // empty + $min = 0; } // "yiimp" price - $stats = getdbolist('db_market_history', "time>$t AND idcoin={$id} AND idmarket IS NULL ORDER BY time"); -foreach($stats as $histo) { - $d = date('Y-m-d H:i', $histo->time); - $series[YAAMP_SITE_NAME][] = array($d, (double) bitcoinvaluetoa($histo->price)); - $max = max($max, $histo->price); +foreach ($stats as $histo) +{ + $d = date('Y-m-d H:i', $histo->time); + $series[YAAMP_SITE_NAME][] = array( + $d, + (double)bitcoinvaluetoa($histo->price) + ); + $max = max($max, $histo->price); } echo json_encode(array( - 'data'=>array_values($series), - 'labels'=>array_keys($series), - 'rangeMin'=> (double) ($min * 0.95), - 'rangeMax'=> (double) ($max * 1.05), + 'data' => array_values($series) , + 'labels' => array_keys($series) , + 'rangeMin' => (double)($min * 0.95) , + 'rangeMax' => (double)($max * 1.05) , )); diff --git a/web/yaamp/modules/site/results/graph_negative_results.php b/web/yaamp/modules/site/results/graph_negative_results.php index d2db32780..b5bbd2ea5 100644 --- a/web/yaamp/modules/site/results/graph_negative_results.php +++ b/web/yaamp/modules/site/results/graph_negative_results.php @@ -1,36 +1,29 @@ $t order by time"); echo '[['; -foreach($stats as $i=>$n) +foreach ($stats as $i => $n) { - $m = round($n->waiting, 8); - if($i) echo ','; + $m = round($n->waiting, 8); + if ($i) echo ','; - $d = date('Y-m-d H:i:s', $n->time); - echo "[\"$d\",$m]"; + $d = date('Y-m-d H:i:s', $n->time); + echo "[\"$d\",$m]"; } echo '],['; -foreach($stats as $i=>$n) +foreach ($stats as $i => $n) { - $m = round($n->immature, 8); - if($i) echo ','; + $m = round($n->immature, 8); + if ($i) echo ','; - $d = date('Y-m-d H:i:s', $n->time); - echo "[\"$d\",$m]"; + $d = date('Y-m-d H:i:s', $n->time); + echo "[\"$d\",$m]"; } echo ']]'; - - - - - - diff --git a/web/yaamp/modules/site/results/graph_price_results.php b/web/yaamp/modules/site/results/graph_price_results.php index 77873cb35..71f96879e 100644 --- a/web/yaamp/modules/site/results/graph_price_results.php +++ b/web/yaamp/modules/site/results/graph_price_results.php @@ -1,38 +1,51 @@ getState('yaamp-algo'); -$step = 15*60; -$t = time() - 24*60*60; +$step = 15 * 60; +$t = time() - 24 * 60 * 60; $t = intval($t / $step) * $step; -$stats = getdbolist('db_hashrate', "time >= $t AND algo=:algo ORDER BY time", array(':algo'=>$algo)); +$stats = getdbolist('db_hashrate', "time >= $t AND algo=:algo ORDER BY time", array( + ':algo' => $algo +)); $tfirst = empty($stats) ? $t : $stats[0]->time; -$pfirst = empty($stats) ? 0.0 : (double) altcoinvaluetoa($stats[0]->price); +$pfirst = empty($stats) ? 0.0 : (double)altcoinvaluetoa($stats[0]->price); $averages = array(); -for($i = 0; $i < 95-count($stats); $i++) { - $d = date('Y-m-d H:i:s', $t); - $averages[] = array($d, $pfirst); - $t += $step; - if ($t >= $tfirst) break; +for ($i = 0;$i < 95 - count($stats);$i++) +{ + $d = date('Y-m-d H:i:s', $t); + $averages[] = array( + $d, + $pfirst + ); + $t += $step; + if ($t >= $tfirst) break; } -foreach($stats as $n) { - $m = (double) altcoinvaluetoa($n->price); - $d = date('Y-m-d H:i:s', $n->time); - $averages[] = array($d, $m); +foreach ($stats as $n) +{ + $m = (double)altcoinvaluetoa($n->price); + $d = date('Y-m-d H:i:s', $n->time); + $averages[] = array( + $d, + $m + ); } $avg2 = array(); $average = $averages[0][1]; -foreach($averages as $n) { - $average = ($average*(100-$percent) + $n[1]*$percent) / 100; - $m = round($average, 5); - - $avg2[] = array($n[0], $m); +foreach ($averages as $n) +{ + $average = ($average * (100 - $percent) + $n[1] * $percent) / 100; + $m = round($average, 5); + + $avg2[] = array( + $n[0], + $m + ); } -echo '['.json_encode($averages).",\n".json_encode($avg2).']'; +echo '[' . json_encode($averages) . ",\n" . json_encode($avg2) . ']'; diff --git a/web/yaamp/modules/site/results/graph_profit_results.php b/web/yaamp/modules/site/results/graph_profit_results.php index bba24ff41..6ab0ffcb6 100644 --- a/web/yaamp/modules/site/results/graph_profit_results.php +++ b/web/yaamp/modules/site/results/graph_profit_results.php @@ -1,25 +1,18 @@ $t order by time"); echo '[['; -foreach($stats as $i=>$n) +foreach ($stats as $i => $n) { - $m = round($n->profit, 8); - if($i) echo ','; + $m = round($n->profit, 8); + if ($i) echo ','; - $d = date('Y-m-d H:i:s', $n->time); - echo "[\"$d\",$m]"; + $d = date('Y-m-d H:i:s', $n->time); + echo "[\"$d\",$m]"; } echo ']]'; - - - - - - diff --git a/web/yaamp/modules/site/results/graph_user_results.php b/web/yaamp/modules/site/results/graph_user_results.php index 6be03c366..f103256aa 100644 --- a/web/yaamp/modules/site/results/graph_user_results.php +++ b/web/yaamp/modules/site/results/graph_user_results.php @@ -1,81 +1,86 @@ getState('yaamp-algo'); +if (empty($algo)) $algo = user()->getState('yaamp-algo'); $target = yaamp_hashrate_constant($algo); -$step = 15*60; -$t = time() - 24*60*60; +$step = 15 * 60; +$t = time() - 24 * 60 * 60; -$stats = getdbolist('db_hashuser', "time>$t and algo=:algo and userid=$user->id order by time", array(':algo'=>$algo)); +$stats = getdbolist('db_hashuser', "time>$t and algo=:algo and userid=$user->id order by time", array( + ':algo' => $algo +)); $averages = array(); echo '[['; -for($i = $t+$step, $j = 0; $i < time(); $i += $step) +for ($i = $t + $step, $j = 0;$i < time();$i += $step) { - if($i != $t+$step) echo ','; - $m = 0; + if ($i != $t + $step) echo ','; + $m = 0; + + if ($i + $step >= time()) + { + $m = round(yaamp_user_rate($user->id, $algo) / 1000000, 3); + // debuglog("last $m"); - if($i + $step >= time()) - { - $m = round(yaamp_user_rate($user->id, $algo)/1000000, 3); - // debuglog("last $m"); - } + } - else if(isset($stats[$j]) && $i > $stats[$j]->time) - { - $m = round($stats[$j]->hashrate/1000000, 3); - $j++; - } + else if (isset($stats[$j]) && $i > $stats[$j]->time) + { + $m = round($stats[$j]->hashrate / 1000000, 3); + $j++; + } - $d = date('Y-m-d H:i:s', $i); - echo "[\"$d\",$m]"; + $d = date('Y-m-d H:i:s', $i); + echo "[\"$d\",$m]"; - $averages[] = array($d, $m); + $averages[] = array( + $d, + $m + ); } echo '],['; $average = $averages[0][1]; -foreach($averages as $i=>$n) +foreach ($averages as $i => $n) { - if($i) echo ','; + if ($i) echo ','; - $average = ($average*(100-$percent) + $n[1]*$percent) / 100; - $m = round($average, 3); + $average = ($average * (100 - $percent) + $n[1] * $percent) / 100; + $m = round($average, 3); - echo "[\"{$n[0]}\",$m]"; + echo "[\"{$n[0]}\",$m]"; } echo '],['; -for($i = $t+$step, $j = 0; $i < time(); $i += $step) +for ($i = $t + $step, $j = 0;$i < time();$i += $step) { - if($i != $t+$step) echo ','; - $m = 0; - - if($i + $step >= time()) - { - $m = round(yaamp_user_rate_bad($user->id, $algo)/1000000, 3); - // debuglog("last $m"); - } - - else if(isset($stats[$j]) && $i > $stats[$j]->time) - { - $m = round($stats[$j]->hashrate_bad/1000000, 3); - $j++; - } - - $d = date('Y-m-d H:i:s', $i); - echo "[\"$d\",$m]"; + if ($i != $t + $step) echo ','; + $m = 0; + + if ($i + $step >= time()) + { + $m = round(yaamp_user_rate_bad($user->id, $algo) / 1000000, 3); + // debuglog("last $m"); + + } + + else if (isset($stats[$j]) && $i > $stats[$j]->time) + { + $m = round($stats[$j]->hashrate_bad / 1000000, 3); + $j++; + } + + $d = date('Y-m-d H:i:s', $i); + echo "[\"$d\",$m]"; } echo ']]'; - diff --git a/web/yaamp/modules/site/results/history_results.php b/web/yaamp/modules/site/results/history_results.php index fd30ab502..d66dcace3 100644 --- a/web/yaamp/modules/site/results/history_results.php +++ b/web/yaamp/modules/site/results/history_results.php @@ -1,8 +1,7 @@ getState('yaamp-algo'); -if($algo == 'all') return; +if ($algo == 'all') return; echo "
"; echo "
Pool Stats ($algo)
"; @@ -34,10 +33,11 @@ END; -$t1 = time() - 60*60; -$t2 = time() - 24*60*60; -$t3 = time() - 7*24*60*60; -$t4 = time() - 30*24*60*60; + +$t1 = time() - 60 * 60; +$t2 = time() - 24 * 60 * 60; +$t3 = time() - 7 * 24 * 60 * 60; +$t4 = time() - 30 * 24 * 60 * 60; $total1 = 0; $total2 = 0; @@ -48,105 +48,131 @@ $algo = user()->getState('yaamp-algo'); $list = dbolist("SELECT coin_id FROM blocks WHERE coin_id IN (select id from coins where algo=:algo and enable=1 and visible=1) - AND time>$t4 AND NOT category IN ('orphan','stake','generated') GROUP BY coin_id ORDER BY coin_id DESC", - array(':algo'=>$algo) -); + AND time>$t4 AND NOT category IN ('orphan','stake','generated') GROUP BY coin_id ORDER BY coin_id DESC", array( + ':algo' => $algo +)); -foreach($list as $item) +foreach ($list as $item) { - $coin = getdbo('db_coins', $item['coin_id']); - - $id = $coin->id; - $main_ids[$id] = $coin->symbol; - - if($coin->symbol == 'BTC') continue; - - $res1 = controller()->memcache->get_database_row("history_item1-$id-$algo", - "SELECT COUNT(id) as a, SUM(amount*price) as b FROM blocks WHERE coin_id=$id AND NOT category IN ('orphan','stake','generated') AND time>$t1 AND algo=:algo", - array(':algo'=>$algo)); - - $res2 = controller()->memcache->get_database_row("history_item2-$id-$algo", - "SELECT COUNT(id) as a, SUM(amount*price) as b FROM blocks WHERE coin_id=$id AND NOT category IN ('orphan','stake','generated') AND time>$t2 AND algo=:algo", - array(':algo'=>$algo)); - - $res3 = controller()->memcache->get_database_row("history_item3-$id-$algo", - "SELECT COUNT(id) as a, SUM(amount*price) as b, MIN(time) as t FROM blocks WHERE coin_id=$id AND NOT category IN ('orphan','stake','generated') AND time>$t3 AND algo=:algo", - array(':algo'=>$algo)); - - $res4 = controller()->memcache->get_database_row("history_item4-$id-$algo", - "SELECT COUNT(id) as a, SUM(amount*price) as b, MIN(time) as t FROM blocks WHERE coin_id=$id AND NOT category IN ('orphan','stake','generated') AND time>$t4 AND algo=:algo", - array(':algo'=>$algo)); - - $total1 += $res1['b']; - $total2 += $res2['b']; - $total3 += $res3['b']; - $total4 += $res4['b']; - - if ($res3['a'] == $res2['a'] || count($list) == 1) { - // blocks table may be purged before 7 days, so use same source as stat graphs - // TODO: add block count in hashstats or keep longer cleared blocks - if ($res3['t'] > ($t3 + 24*60*60)) $res3['a'] = '-'; - $total3 = controller()->memcache->get_database_scalar("history_item3-$id-$algo-btc", - "SELECT SUM(earnings) as b FROM hashstats WHERE time>$t3 AND algo=:algo", array(':algo'=>$algo)); - } - - if ($res4['a'] == $res3['a'] || count($list) == 1) { - $res4['a'] = '-'; - $total4 = controller()->memcache->get_database_scalar("history_item4-$id-$algo-btc", - "SELECT SUM(earnings) as b FROM hashstats WHERE time>$t4 AND algo=:algo", array(':algo'=>$algo)); - } - - $name = substr($coin->name, 0, 12); - - echo ''; - - echo ''; - echo ''.$name.''; - echo ''.$coin->symbol.''; - - echo ''.$res1['a'].''; - echo ''.$res2['a'].''; - echo ''.$res3['a'].''; - echo ''.$res4['a'].''; - - echo ''; + $coin = getdbo('db_coins', $item['coin_id']); + + $id = $coin->id; + $main_ids[$id] = $coin->symbol; + + if ($coin->symbol == 'BTC') continue; + + $res1 = controller() + ->memcache + ->get_database_row("history_item1-$id-$algo", "SELECT COUNT(id) as a, SUM(amount*price) as b FROM blocks WHERE coin_id=$id AND NOT category IN ('orphan','stake','generated') AND time>$t1 AND algo=:algo", array( + ':algo' => $algo + )); + + $res2 = controller() + ->memcache + ->get_database_row("history_item2-$id-$algo", "SELECT COUNT(id) as a, SUM(amount*price) as b FROM blocks WHERE coin_id=$id AND NOT category IN ('orphan','stake','generated') AND time>$t2 AND algo=:algo", array( + ':algo' => $algo + )); + + $res3 = controller() + ->memcache + ->get_database_row("history_item3-$id-$algo", "SELECT COUNT(id) as a, SUM(amount*price) as b, MIN(time) as t FROM blocks WHERE coin_id=$id AND NOT category IN ('orphan','stake','generated') AND time>$t3 AND algo=:algo", array( + ':algo' => $algo + )); + + $res4 = controller() + ->memcache + ->get_database_row("history_item4-$id-$algo", "SELECT COUNT(id) as a, SUM(amount*price) as b, MIN(time) as t FROM blocks WHERE coin_id=$id AND NOT category IN ('orphan','stake','generated') AND time>$t4 AND algo=:algo", array( + ':algo' => $algo + )); + + $total1 += $res1['b']; + $total2 += $res2['b']; + $total3 += $res3['b']; + $total4 += $res4['b']; + + if ($res3['a'] == $res2['a'] || count($list) == 1) + { + // blocks table may be purged before 7 days, so use same source as stat graphs + // TODO: add block count in hashstats or keep longer cleared blocks + if ($res3['t'] > ($t3 + 24 * 60 * 60)) $res3['a'] = '-'; + $total3 = controller() + ->memcache + ->get_database_scalar("history_item3-$id-$algo-btc", "SELECT SUM(earnings) as b FROM hashstats WHERE time>$t3 AND algo=:algo", array( + ':algo' => $algo + )); + } + + if ($res4['a'] == $res3['a'] || count($list) == 1) + { + $res4['a'] = '-'; + $total4 = controller() + ->memcache + ->get_database_scalar("history_item4-$id-$algo-btc", "SELECT SUM(earnings) as b FROM hashstats WHERE time>$t4 AND algo=:algo", array( + ':algo' => $algo + )); + } + + $name = substr($coin->name, 0, 12); + + echo ''; + + echo ''; + echo '' . $name . ''; + echo '' . $coin->symbol . ''; + + echo '' . $res1['a'] . ''; + echo '' . $res2['a'] . ''; + echo '' . $res3['a'] . ''; + echo '' . $res4['a'] . ''; + + echo ''; } $others = dbolist("SELECT id, image, symbol, name FROM coins - WHERE algo=:algo AND installed=1 AND enable=1 AND auto_ready=1 AND visible=1 ORDER BY symbol", - array(':algo'=>$algo) -); + WHERE algo=:algo AND installed=1 AND enable=1 AND auto_ready=1 AND visible=1 ORDER BY symbol", array( + ':algo' => $algo +)); -foreach($others as $item) +foreach ($others as $item) { - if (array_key_exists($item['id'], $main_ids)) - continue; - echo ''; - echo ''; - echo ''.$item['name'].''; - echo ''.$item['symbol'].''; - echo ''; - echo ''; + if (array_key_exists($item['id'], $main_ids)) continue; + echo ''; + echo ''; + echo '' . $item['name'] . ''; + echo '' . $item['symbol'] . ''; + echo ''; + echo ''; } /////////////////////////////////////////////////////////////////////// - -$hashrate1 = controller()->memcache->get_database_scalar("history_hashrate1-$algo", - "SELECT AVG(hashrate) FROM hashrate WHERE time>$t1 AND algo=:algo", array(':algo'=>$algo)); - -$hashrate2 = controller()->memcache->get_database_scalar("history_hashrate2-$algo", - "SELECT AVG(hashrate) FROM hashrate WHERE time>$t2 AND algo=:algo", array(':algo'=>$algo)); - -$hashrate3 = controller()->memcache->get_database_scalar("history_hashrate3-$algo", - "SELECT AVG(hashrate) FROM hashrate WHERE time>$t3 AND algo=:algo", array(':algo'=>$algo)); - -$hashrate4 = controller()->memcache->get_database_scalar("history_hashrate4-$algo", - "SELECT AVG(hashrate) FROM hashstats WHERE time>$t4 AND algo=:algo", array(':algo'=>$algo)); - -$hashrate1 = max($hashrate1 , 1); -$hashrate2 = max($hashrate2 , 1); -$hashrate3 = max($hashrate3 , 1); -$hashrate4 = max($hashrate4 , 1); +$hashrate1 = controller() + ->memcache + ->get_database_scalar("history_hashrate1-$algo", "SELECT AVG(hashrate) FROM hashrate WHERE time>$t1 AND algo=:algo", array( + ':algo' => $algo +)); + +$hashrate2 = controller() + ->memcache + ->get_database_scalar("history_hashrate2-$algo", "SELECT AVG(hashrate) FROM hashrate WHERE time>$t2 AND algo=:algo", array( + ':algo' => $algo +)); + +$hashrate3 = controller() + ->memcache + ->get_database_scalar("history_hashrate3-$algo", "SELECT AVG(hashrate) FROM hashrate WHERE time>$t3 AND algo=:algo", array( + ':algo' => $algo +)); + +$hashrate4 = controller() + ->memcache + ->get_database_scalar("history_hashrate4-$algo", "SELECT AVG(hashrate) FROM hashstats WHERE time>$t4 AND algo=:algo", array( + ':algo' => $algo +)); + +$hashrate1 = max($hashrate1, 1); +$hashrate2 = max($hashrate2, 1); +$hashrate3 = max($hashrate3, 1); +$hashrate4 = max($hashrate4, 1); $btcmhday1 = mbitcoinvaluetoa($total1 / $hashrate1 * 1000000 * 24 * 1000); $btcmhday2 = mbitcoinvaluetoa($total2 / $hashrate2 * 1000000 * 1 * 1000); @@ -167,49 +193,40 @@ echo ''; echo 'BTC Value'; -echo ''.$total1.''; -echo ''.$total2.''; -echo ''.$total3.''; -echo ''.$total4.''; +echo '' . $total1 . ''; +echo '' . $total2 . ''; +echo '' . $total3 . ''; +echo '' . $total4 . ''; echo ""; /////////////////////////////////////////////////////////////////////// - echo ''; echo ''; echo 'Avg Hashrate'; -echo ''.$hashrate1.'h/s'; -echo ''.$hashrate2.'h/s'; -echo ''.$hashrate3.'h/s'; -echo ''.$hashrate4.'h/s'; +echo '' . $hashrate1 . 'h/s'; +echo '' . $hashrate2 . 'h/s'; +echo '' . $hashrate3 . 'h/s'; +echo '' . $hashrate4 . 'h/s'; echo ''; /////////////////////////////////////////////////////////////////////// - echo ''; echo ''; echo 'mBTC/Mh/d'; -echo ''.$btcmhday1.''; -echo ''.$btcmhday2.''; -echo ''.$btcmhday3.''; -echo ''.$btcmhday4.''; +echo '' . $btcmhday1 . ''; +echo '' . $btcmhday2 . ''; +echo '' . $btcmhday3 . ''; +echo '' . $btcmhday4 . ''; echo ''; echo ''; - echo '
'; echo '
'; echo '

'; - - - - - - diff --git a/web/yaamp/modules/site/results/miners_results.php b/web/yaamp/modules/site/results/miners_results.php index a3c1e6b3d..65616bcb5 100644 --- a/web/yaamp/modules/site/results/miners_results.php +++ b/web/yaamp/modules/site/results/miners_results.php @@ -2,27 +2,33 @@ function WriteBoxHeader($title) { - echo "
"; - echo "
$title
"; - echo "
"; + echo "
"; + echo "
$title
"; + echo "
"; } $algo = user()->getState('yaamp-algo'); -$target = yaamp_hashrate_constant($algo); +$target = yaamp_hashrate_constant($algo); $interval = yaamp_hashrate_step(); -$delay = time()-$interval; - -$total_workers = getdbocount('db_workers', "algo=:algo", array(':algo'=>$algo)); -$total_extranonce = getdbocount('db_workers', "algo=:algo and subscribe", array(':algo'=>$algo)); -$total_hashrate = controller()->memcache->get_database_scalar("current_hashrate-$algo", - //"SELECT SUM(difficulty) * $target / $interval / 1000 FROM shares WHERE valid AND time>$delay AND algo=:algo", array(':algo'=>$algo) - "SELECT hashrate FROM hashrate WHERE algo=:algo ORDER BY time DESC LIMIT 1", array(':algo'=>$algo) -); -$total_invalid = !$this->admin ? 0 : controller()->memcache->get_database_scalar("current_hashrate_bad-$algo", - //"SELECT SUM(difficulty) * $target / $interval / 1000 FROM shares WHERE NOT valid AND time>$delay AND algo=:algo", array(':algo'=>$algo) - "SELECT hashrate_bad FROM hashrate WHERE algo=:algo ORDER BY time DESC LIMIT 1", array(':algo'=>$algo) -); +$delay = time() - $interval; + +$total_workers = getdbocount('db_workers', "algo=:algo", array( + ':algo' => $algo +)); +$total_extranonce = getdbocount('db_workers', "algo=:algo and subscribe", array( + ':algo' => $algo +)); +$total_hashrate = controller()->memcache->get_database_scalar("current_hashrate-$algo", +//"SELECT SUM(difficulty) * $target / $interval / 1000 FROM shares WHERE valid AND time>$delay AND algo=:algo", array(':algo'=>$algo) + "SELECT hashrate FROM hashrate WHERE algo=:algo ORDER BY time DESC LIMIT 1", array( + ':algo' => $algo +)); +$total_invalid = !$this->admin ? 0 : controller()->memcache->get_database_scalar("current_hashrate_bad-$algo", +//"SELECT SUM(difficulty) * $target / $interval / 1000 FROM shares WHERE NOT valid AND time>$delay AND algo=:algo", array(':algo'=>$algo) + "SELECT hashrate_bad FROM hashrate WHERE algo=:algo ORDER BY time DESC LIMIT 1", array( + ':algo' => $algo +)); WriteBoxHeader("Miners Version ($algo)"); @@ -45,126 +51,125 @@ function WriteBoxHeader($title) end; $error_tab = array( - 20=>'Invalid nonce size', - 21=>'Invalid job id', - 22=>'Duplicate share', - 23=>'Invalid time rolling', - 24=>'Invalid extranonce2 size', - 25=>'Invalid share', - 26=>'Low difficulty share', - 27=>'Invalid extranonce', + 20 => 'Invalid nonce size', + 21 => 'Invalid job id', + 22 => 'Duplicate share', + 23 => 'Invalid time rolling', + 24 => 'Invalid extranonce2 size', + 25 => 'Invalid share', + 26 => 'Low difficulty share', + 27 => 'Invalid extranonce' ); $total_donators = 0; -$versions = dbolist("select version, count(*) as c, sum(subscribe) as s from workers where algo=:algo group by version order by c desc", array(':algo'=>$algo)); -foreach($versions as $item) -{ - $version = $item['version']; - $count = $item['c']; - $extranonce = $item['s']; - - $hashrate = controller()->memcache->get_database_scalar("miners-valid-$algo-v$version", - "SELECT sum(difficulty) * $target / $interval / 1000 FROM shares WHERE valid AND time>$delay - AND workerid IN (SELECT id FROM workers WHERE algo=:algo and version=:version)", - array(':algo'=>$algo, ':version'=>$version) - ); - - if (!$hashrate && !$this->admin) continue; - - $invalid = !$total_invalid ? 0 : controller()->memcache->get_database_scalar("miners-invalid-$algo-v$version", - "SELECT SUM(difficulty) * $target / $interval / 1000 FROM shares WHERE not valid AND time>$delay - AND workerid IN (SELECT id FROM workers WHERE algo=:algo AND version=:version)", - array(':algo'=>$algo, ':version'=>$version) - ); - - $title = ''; - foreach($error_tab as $i=>$s) - { - $invalid2 = !$total_invalid ? 0 : controller()->memcache->get_database_scalar("miners-invalid-$algo-v$version-err$i", - "SELECT sum(difficulty) * $target / $interval / 1000 from shares WHERE error=$i AND time>$delay - AND workerid in (SELECT id FROM workers WHERE algo=:algo AND version=:version)", - array(':algo'=>$algo, ':version'=>$version) - ); - - if($invalid2) { - $bad2 = round($invalid2*100/($hashrate+$invalid2), 2).'%'; - $title .= "$bad2 - $s\n"; - } - } - - $donators = dboscalar( - "SELECT COUNT(*) AS donators FROM workers W LEFT JOIN accounts A ON A.id = W.userid". - " WHERE W.algo=:algo AND W.version=:version AND A.donation > 0", - array(':algo'=>$algo, ':version'=>$version) - ); - $total_donators += $donators; - - $percent = $total_hashrate && $hashrate ? round($hashrate * 100 / $total_hashrate, 2).'%': ''; - if (!$percent || $percent == '0%') $percent = '-'; - $bad = ($hashrate+$invalid)? round($invalid*100/($hashrate+$invalid), 1).'%': ''; - if (!$bad || $bad == '0%') $bad = '-'; - $avg = intval($count) ? $hashrate / intval($count) : ''; - $avg = $avg? Itoa2($avg).'H/s': ''; - $hashrate = $hashrate? Itoa2($hashrate).'H/s': ''; - $version = substr($version, 0, 30); - - echo ''; - echo ''.$version.''; - echo ''.$count.''; - echo ''.($donators ? $donators : '-').''; - echo ''.($extranonce ? $extranonce : '-').''; - if (floatval($percent) > 50) - echo ''.$percent.''; - else - echo ''.$percent.''; - echo ''.$hashrate.''; - echo ''.$avg.''; - echo ''.$bad.''; - echo ''; +$versions = dbolist("select version, count(*) as c, sum(subscribe) as s from workers where algo=:algo group by version order by c desc", array( + ':algo' => $algo +)); +foreach ($versions as $item) { + $version = $item['version']; + $count = $item['c']; + $extranonce = $item['s']; + + $hashrate = controller()->memcache->get_database_scalar("miners-valid-$algo-v$version", "SELECT sum(difficulty) * $target / $interval / 1000 FROM shares WHERE valid AND time>$delay + AND workerid IN (SELECT id FROM workers WHERE algo=:algo and version=:version)", array( + ':algo' => $algo, + ':version' => $version + )); + + if (!$hashrate && !$this->admin) + continue; + + $invalid = !$total_invalid ? 0 : controller()->memcache->get_database_scalar("miners-invalid-$algo-v$version", "SELECT SUM(difficulty) * $target / $interval / 1000 FROM shares WHERE not valid AND time>$delay + AND workerid IN (SELECT id FROM workers WHERE algo=:algo AND version=:version)", array( + ':algo' => $algo, + ':version' => $version + )); + + $title = ''; + foreach ($error_tab as $i => $s) { + $invalid2 = !$total_invalid ? 0 : controller()->memcache->get_database_scalar("miners-invalid-$algo-v$version-err$i", "SELECT sum(difficulty) * $target / $interval / 1000 from shares WHERE error=$i AND time>$delay + AND workerid in (SELECT id FROM workers WHERE algo=:algo AND version=:version)", array( + ':algo' => $algo, + ':version' => $version + )); + + if ($invalid2) { + $bad2 = round($invalid2 * 100 / ($hashrate + $invalid2), 2) . '%'; + $title .= "$bad2 - $s\n"; + } + } + + $donators = dboscalar("SELECT COUNT(*) AS donators FROM workers W LEFT JOIN accounts A ON A.id = W.userid" . " WHERE W.algo=:algo AND W.version=:version AND A.donation > 0", array( + ':algo' => $algo, + ':version' => $version + )); + $total_donators += $donators; + + $percent = $total_hashrate && $hashrate ? round($hashrate * 100 / $total_hashrate, 2) . '%' : ''; + if (!$percent || $percent == '0%') + $percent = '-'; + $bad = ($hashrate + $invalid) ? round($invalid * 100 / ($hashrate + $invalid), 1) . '%' : ''; + if (!$bad || $bad == '0%') + $bad = '-'; + $avg = intval($count) ? $hashrate / intval($count) : ''; + $avg = $avg ? Itoa2($avg) . 'H/s' : ''; + $hashrate = $hashrate ? Itoa2($hashrate) . 'H/s' : ''; + $version = substr($version, 0, 30); + + echo ''; + echo '' . $version . ''; + echo '' . $count . ''; + echo '' . ($donators ? $donators : '-') . ''; + echo '' . ($extranonce ? $extranonce : '-') . ''; + if (floatval($percent) > 50) + echo '' . $percent . ''; + else + echo '' . $percent . ''; + echo '' . $hashrate . ''; + echo '' . $avg . ''; + echo '' . $bad . ''; + echo ''; } echo ""; $title = ''; -foreach($error_tab as $i=>$s) -{ - $invalid2 = !$total_invalid ? 0 : controller()->memcache->get_database_scalar("miners-invalid-$algo-err$i", - "SELECT SUM(difficulty) * $target / $interval / 1000 FROM shares WHERE time>$delay AND algo=:algo AND error=$i ". - "AND workerid IN (SELECT id FROM workers WHERE algo=:algo)", array(':algo'=>$algo) - ); - - if($invalid2) { - $bad2 = round($invalid2*100/($total_hashrate+$invalid2), 2); - $title .= "$bad2 - $s\n"; - } +foreach ($error_tab as $i => $s) { + $invalid2 = !$total_invalid ? 0 : controller()->memcache->get_database_scalar("miners-invalid-$algo-err$i", "SELECT SUM(difficulty) * $target / $interval / 1000 FROM shares WHERE time>$delay AND algo=:algo AND error=$i " . "AND workerid IN (SELECT id FROM workers WHERE algo=:algo)", array( + ':algo' => $algo + )); + + if ($invalid2) { + $bad2 = round($invalid2 * 100 / ($total_hashrate + $invalid2), 2); + $title .= "$bad2 - $s\n"; + } } -$bad = ($total_hashrate+$total_invalid) && $total_invalid ? round($total_invalid*100/($total_hashrate+$total_invalid), 1).'%': ''; -$avg = intval($total_workers) ? Itoa2($total_hashrate / intval($total_workers)).'H/s' : ''; -$total_hashrate = Itoa2($total_hashrate).'H/s'; +$bad = ($total_hashrate + $total_invalid) && $total_invalid ? round($total_invalid * 100 / ($total_hashrate + $total_invalid), 1) . '%' : ''; +$avg = intval($total_workers) ? Itoa2($total_hashrate / intval($total_workers)) . 'H/s' : ''; +$total_hashrate = Itoa2($total_hashrate) . 'H/s'; echo ''; echo 'Total'; -echo ''.$total_workers.''; -echo ''.$total_donators.''; -echo ''.$total_extranonce.''; +echo '' . $total_workers . ''; +echo '' . $total_donators . ''; +echo '' . $total_extranonce . ''; echo ''; -echo ''.$total_hashrate.''; -echo ''.$avg.''; -echo ''.$bad.''; +echo '' . $total_hashrate . ''; +echo '' . $avg . ''; +echo '' . $bad . ''; echo ''; echo ""; echo "

-  * approximate from the last 5 minutes submitted shares
-

"; +  * approximate from the last 5 minutes submitted shares
+

"; echo "

"; if ($this->admin) { - // show reject column - echo ''; + // show reject column + echo ''; } - diff --git a/web/yaamp/modules/site/results/mining_results.php b/web/yaamp/modules/site/results/mining_results.php index d6fb39cd6..a46858b7a 100644 --- a/web/yaamp/modules/site/results/mining_results.php +++ b/web/yaamp/modules/site/results/mining_results.php @@ -2,48 +2,54 @@ function WriteBoxHeader($title) { - echo "
"; - echo "
$title
"; - echo "
"; + echo "
"; + echo "
$title
"; + echo "
"; } $showrental = (bool) YAAMP_RENTAL; $algo = user()->getState('yaamp-algo'); -$total_rate = yaamp_pool_rate(); -$total_rate_d = $total_rate? 'at '.Itoa2($total_rate).'h/s': ''; +$total_rate = yaamp_pool_rate(); +$total_rate_d = $total_rate ? 'at ' . Itoa2($total_rate) . 'h/s' : ''; -if($algo == 'all') - $list = getdbolist('db_coins', "enable and visible order by index_avg desc"); +if ($algo == 'all') + $list = getdbolist('db_coins', "enable and visible order by index_avg desc"); else - $list = getdbolist('db_coins', "enable and visible and algo=:algo order by index_avg desc", array(':algo'=>$algo)); + $list = getdbolist('db_coins', "enable and visible and algo=:algo order by index_avg desc", array( + ':algo' => $algo + )); $count = count($list); -if($algo == 'all') - $worker = getdbocount('db_workers'); +if ($algo == 'all') + $worker = getdbocount('db_workers'); else - $worker = getdbocount('db_workers', "algo=:algo", array(':algo'=>$algo)); + $worker = getdbocount('db_workers', "algo=:algo", array( + ':algo' => $algo + )); if ($showrental) - $services = getdbolist('db_services', "algo=:algo ORDER BY price DESC", array(':algo'=>$algo)); + $services = getdbolist('db_services', "algo=:algo ORDER BY price DESC", array( + ':algo' => $algo + )); else - $services = array(); + $services = array(); //////////////////////////////////////////////////////////////////////////////////// -$coin_count = $count > 1 ? "on $count wallets" : 'on a single wallet'; +$coin_count = $count > 1 ? "on $count wallets" : 'on a single wallet'; $miner_count = $worker > 1 ? "$worker miners" : "$worker miner"; WriteBoxHeader("Mining $coin_count $total_rate_d, $miner_count"); showTableSorter('maintable3', "{ - tableClass: 'dataGrid2', - textExtraction: { - 3: function(node, table, n) { return $(node).attr('data'); }, - 6: function(node, table, n) { return $(node).attr('data'); }, - 7: function(node, table, n) { return $(node).attr('data'); } - } + tableClass: 'dataGrid2', + textExtraction: { + 3: function(node, table, n) { return $(node).attr('data'); }, + 6: function(node, table, n) { return $(node).attr('data'); }, + 7: function(node, table, n) { return $(node).attr('data'); } + } }"); echo << END; -if($algo != 'all' && $showrental) -{ - $hashrate_jobs = yaamp_rented_rate($algo); - $hashrate_jobs = $hashrate_jobs? Itoa2($hashrate_jobs).'h/s': ''; +if ($algo != 'all' && $showrental) { + $hashrate_jobs = yaamp_rented_rate($algo); + $hashrate_jobs = $hashrate_jobs ? Itoa2($hashrate_jobs) . 'h/s' : ''; - $price_rent = dboscalar("select rent from hashrate where algo=:algo order by time desc", array(':algo'=>$algo)); - $price_rent = mbitcoinvaluetoa($price_rent); + $price_rent = dboscalar("select rent from hashrate where algo=:algo order by time desc", array( + ':algo' => $algo + )); + $price_rent = mbitcoinvaluetoa($price_rent); - $amount_rent = dboscalar("select sum(amount) from jobsubmits where status=1 and algo=:algo", array(':algo'=>$algo)); - $amount_rent = bitcoinvaluetoa($amount_rent); + $amount_rent = dboscalar("select sum(amount) from jobsubmits where status=1 and algo=:algo", array( + ':algo' => $algo + )); + $amount_rent = bitcoinvaluetoa($amount_rent); } -foreach($list as $coin) -{ - $name = substr($coin->name, 0, 12); - $difficulty = Itoa2($coin->difficulty, 3); - $price = bitcoinvaluetoa($coin->price); - $height = number_format($coin->block_height, 0, '.', ' '); -// $pool_ttf = $coin->pool_ttf? sectoa2($coin->pool_ttf): ''; - $pool_ttf = $total_rate? $coin->difficulty * 0x100000000 / $total_rate: 0; - $reward = round($coin->reward, 3); - - $btcmhd = yaamp_profitability($coin); - $pool_hash = yaamp_coin_rate($coin->id); - $real_ttf = $pool_hash? $coin->difficulty * 0x100000000 / $pool_hash: 0; - - $pool_hash_sfx = $pool_hash? Itoa2($pool_hash).'h/s': ''; - $real_ttf = $real_ttf? sectoa2($real_ttf): ''; - $pool_ttf = $pool_ttf? sectoa2($pool_ttf): ''; - - $pool_hash_pow = yaamp_pool_rate_pow($coin->algo); - $pool_hash_pow_sfx = $pool_hash_pow? Itoa2($pool_hash_pow).'h/s': ''; - - $min_ttf = $coin->network_ttf>0? min($coin->actual_ttf, $coin->network_ttf): $coin->actual_ttf; - $network_hash = $coin->difficulty * 0x100000000 / ($min_ttf? $min_ttf: 60); - $network_hash = $network_hash? 'network hash '.Itoa2($network_hash).'h/s': ''; - - if(controller()->admin && $services) - { - foreach($services as $i=>$service) - { - if($service->price*1000 < $btcmhd) continue; - $service_btcmhd = mbitcoinvaluetoa($service->price*1000); - - echo ""; - echo ""; - echo "$service->name"; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo "$service_btcmhd"; - echo ""; - - unset($services[$i]); - } - } - - if(isset($price_rent) && $price_rent > $btcmhd) - { - echo ""; - echo ""; - echo "Rental"; - echo "$amount_rent BTC"; - echo ""; - echo ""; - echo ""; - echo "$hashrate_jobs"; - echo "$price_rent"; - echo ""; - - unset($price_rent); - } - - if(!$coin->auto_ready) - echo ""; - else - echo ""; - - echo ''; - echo $coin->createExplorerLink(''); - echo ''; - - $owed = dboscalar("select sum(balance) from accounts where coinid=$coin->id"); - if(YAAMP_ALLOW_EXCHANGE && $coin->balance+$coin->mint < $owed*0.9 ) { - $owed2 = bitcoinvaluetoa($owed - $coin->balance); - $symbol = $coin->getOfficialSymbol(); - $title = "We are short of this currency ($owed2 $symbol). Please switch to another currency until we find more $symbol blocks."; - echo "id}\" title=\"$title\" style=\"color: #c55;\">$name ({$coin->algo})"; - } else { - echo "$name ($coin->algo)"; - } - echo "$reward $coin->symbol_show"; - - $title = "POW $coin->difficulty"; - if($coin->rpcencoding == 'POS') - $title .= "\nPOS $coin->difficulty_pos"; - - echo ''.$difficulty.''; - - if(!empty($coin->errors)) - echo "$height"; - else - echo "$height"; - - if(!YAAMP_ALLOW_EXCHANGE && !empty($real_ttf)) - echo ''.$real_ttf.''; - elseif(!empty($real_ttf)) - echo ''.$pool_ttf.''; - else - echo ''.$pool_ttf.''; - - if($coin->auxpow && $coin->auto_ready) - echo "$pool_hash_pow_sfx"; - else - echo "$pool_hash_sfx"; - - $btcmhd = mbitcoinvaluetoa($btcmhd); - echo "$btcmhd"; - echo ""; +foreach ($list as $coin) { + $name = substr($coin->name, 0, 12); + $difficulty = Itoa2($coin->difficulty, 3); + $price = bitcoinvaluetoa($coin->price); + $height = number_format($coin->block_height, 0, '.', ' '); + // $pool_ttf = $coin->pool_ttf? sectoa2($coin->pool_ttf): ''; + $pool_ttf = $total_rate ? $coin->difficulty * 0x100000000 / $total_rate : 0; + $reward = round($coin->reward, 3); + + $btcmhd = yaamp_profitability($coin); + $pool_hash = yaamp_coin_rate($coin->id); + $real_ttf = $pool_hash ? $coin->difficulty * 0x100000000 / $pool_hash : 0; + + $pool_hash_sfx = $pool_hash ? Itoa2($pool_hash) . 'h/s' : ''; + $real_ttf = $real_ttf ? sectoa2($real_ttf) : ''; + $pool_ttf = $pool_ttf ? sectoa2($pool_ttf) : ''; + + $pool_hash_pow = yaamp_pool_rate_pow($coin->algo); + $pool_hash_pow_sfx = $pool_hash_pow ? Itoa2($pool_hash_pow) . 'h/s' : ''; + + $min_ttf = $coin->network_ttf > 0 ? min($coin->actual_ttf, $coin->network_ttf) : $coin->actual_ttf; + $network_hash = controller() + ->memcache + ->get("yiimp-nethashrate-{$coin->symbol}"); + if (!$network_hash) + { + $remote = new WalletRPC($coin); + if ($remote) $info = $remote->getmininginfo(); + if (isset($info['networkhashps'])) + { + $network_hash = $info['networkhashps']; + controller() + ->memcache + ->set("yiimp-nethashrate-{$coin->symbol}", $info['networkhashps'], 60); + } + else if (isset($info['netmhashps'])) + { + $network_hash = floatval($info['netmhashps']) * 1e6; + controller() + ->memcache + ->set("yiimp-nethashrate-{$coin->symbol}", $network_hash, 60); + } + } + $network_hash = $network_hash ? Itoa2($network_hash) . 'h/s' : ''; + + if (controller()->admin && $services) { + foreach ($services as $i => $service) { + if ($service->price * 1000 < $btcmhd) + continue; + $service_btcmhd = mbitcoinvaluetoa($service->price * 1000); + + echo ""; + echo ""; + echo "$service->name"; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo "$service_btcmhd"; + echo ""; + + unset($services[$i]); + } + } + + if (isset($price_rent) && $price_rent > $btcmhd) { + echo ""; + echo ""; + echo "Rental"; + echo "$amount_rent BTC"; + echo ""; + echo ""; + echo ""; + echo "$hashrate_jobs"; + echo "$price_rent"; + echo ""; + + unset($price_rent); + } + + if (!$coin->auto_ready) + echo ""; + else + echo ""; + + echo ''; + echo $coin->createExplorerLink(''); + echo ''; + + $owed = dboscalar("select sum(balance) from accounts where coinid=$coin->id"); + if (YAAMP_ALLOW_EXCHANGE && $coin->balance + $coin->mint < $owed * 0.9) { + $owed2 = bitcoinvaluetoa($owed - $coin->balance); + $symbol = $coin->getOfficialSymbol(); + $title = "We are short of this currency ($owed2 $symbol). Please switch to another currency until we find more $symbol blocks."; + echo "id}\" title=\"$title\" style=\"color: #c55;\">$name ({$coin->algo})"; + } else { + echo "$name ($coin->algo)"; + } + echo "$reward $coin->symbol_show"; + + $title = "POW $coin->difficulty"; + if ($coin->rpcencoding == 'POS') + $title .= "\nPOS $coin->difficulty_pos"; + + echo '' . $difficulty . ''; + + if (!empty($coin->errors)) + echo "$height"; + else + echo "$height"; + + if (!YAAMP_ALLOW_EXCHANGE && !empty($real_ttf)) + echo '' . $real_ttf . ''; + elseif (!empty($real_ttf)) + echo '' . $pool_ttf . ''; + else + echo '' . $pool_ttf . ''; + + if ($coin->auxpow && $coin->auto_ready) + echo "$pool_hash_pow_sfx"; + else + echo "$pool_hash_sfx"; + + $btcmhd = mbitcoinvaluetoa($btcmhd); + echo "$btcmhd"; + echo ""; } -if(controller()->admin && $services) -{ - foreach($services as $i=>$service) - { - $service_btcmhd = mbitcoinvaluetoa($service->price*1000); - - echo ""; - echo ""; - echo "$service->name"; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo "$service_btcmhd"; - echo ""; - } +if (controller()->admin && $services) { + foreach ($services as $i => $service) { + $service_btcmhd = mbitcoinvaluetoa($service->price * 1000); + + echo ""; + echo ""; + echo "$service->name"; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo "$service_btcmhd"; + echo ""; + } } -if(isset($price_rent) && $showrental) -{ - echo ""; - echo ""; - echo "Rental"; - echo "$amount_rent BTC"; - echo ""; - echo ""; - echo ""; - echo "$hashrate_jobs"; - echo "$price_rent"; - echo ""; - - unset($price_rent); +if (isset($price_rent) && $showrental) { + echo ""; + echo ""; + echo "Rental"; + echo "$amount_rent BTC"; + echo ""; + echo ""; + echo ""; + echo "$hashrate_jobs"; + echo "$price_rent"; + echo ""; + + unset($price_rent); } echo ""; echo '

-  *** estimated average time to find a block at full pool speed
-  ** approximate from the last 5 minutes submitted shares
-  * 24h estimation from net difficulty in mBTC/MH/day (GH/day for sha & blake algos)
+  *** estimated average time to find a block at full pool speed
+  ** approximate from the last 5 minutes submitted shares
+  * 24h estimation from net difficulty in mBTC/MH/day (GH/day for sha & blake algos)

'; echo "

"; - - diff --git a/web/yaamp/modules/site/results/user_earning_results.php b/web/yaamp/modules/site/results/user_earning_results.php index 1bf239e08..d2962cd7f 100644 --- a/web/yaamp/modules/site/results/user_earning_results.php +++ b/web/yaamp/modules/site/results/user_earning_results.php @@ -1,22 +1,23 @@ "; - echo "
$title
"; - echo "
"; + echo "
"; + echo "
$title
"; + echo "
"; } $algo = user()->getState('yaamp-algo'); $user = getuserparam(getparam('address')); -if(!$user || $user->is_locked) return; +if (!$user || $user->is_locked) return; $count = getparam('count'); -$count = $count? $count: 50; +$count = $count ? $count : 50; WriteBoxHeader("Last $count Earnings: $user->username"); -$earnings = getdbolist('db_earnings', "userid=$user->id order by create_time desc limit :count", array(':count'=>$count)); +$earnings = getdbolist('db_earnings', "userid=$user->id order by create_time desc limit :count", array( + ':count' => $count +)); echo <<coinid); - $block = getdbo('db_blocks', $earning->blockid); - if (!$block) { - debuglog("missing block id {$earning->blockid}!"); - continue; - } - - $d = datetoa2($earning->create_time); - if(!$coin) - { - if (!$showrental) - continue; - - $reward = bitcoinvaluetoa($earning->amount); - $value = mbitcoinvaluetoa($earning->amount*1000); - $percent = $block->amount ? percentvaluetoa($earning->amount * 100/$block->amount) : 0; - - echo ''; - echo ''; - echo 'Rental ('.$block->algo.')'; - echo ''.$reward.' BTC'; - echo ''.$percent.'%'; - echo ''.$value.''; - echo ''.$d.' ago'; - echo 'Cleared'; - echo ''; - - continue; - } - - $reward = altcoinvaluetoa($earning->amount); - $percent = $block->amount ? percentvaluetoa($earning->amount * 100/$block->amount) : 0; - $value = mbitcoinvaluetoa($earning->amount*$earning->price*1000); - - $blockUrl = $coin->createExplorerLink($coin->name, array('height'=>$block->height)); - echo ''; - echo ''; - echo ''.$blockUrl.' ('.$coin->algo.')'; - echo ''.$reward.' '.$coin->symbol_show.''; - echo ''.$percent.'%'; - echo ''.$value.''; - echo ''.$d.' ago'; - echo ''; - - if($earning->status == 0) { - $eta = ''; - if ($coin->block_time && $coin->mature_blocks) { - $t = (int) ($coin->mature_blocks - $block->confirmations) * $coin->block_time; - $eta = "ETA: ".sprintf('%dh %02dmn', ($t/3600), ($t/60)%60); - } - echo 'Immature ('.$block->confirmations.')'; - } - - else if($earning->status == 1) - echo ''.(YAAMP_ALLOW_EXCHANGE ? 'Exchange' : 'Confirmed').''; - - else if($earning->status == 2) - echo 'Cleared'; - - else if($earning->status == -1) - echo 'Invalid'; - - echo ""; - echo ""; + $coin = getdbo('db_coins', $earning->coinid); + $block = getdbo('db_blocks', $earning->blockid); + if (!$block) + { + debuglog("missing block id {$earning->blockid}!"); + continue; + } + + $d = datetoa2($earning->create_time); + if (!$coin) + { + if (!$showrental) continue; + + $reward = bitcoinvaluetoa($earning->amount); + $value = mbitcoinvaluetoa($earning->amount * 1000); + $percent = $block->amount ? percentvaluetoa($earning->amount * 100 / $block->amount) : 0; + + echo ''; + echo ''; + echo 'Rental (' . $block->algo . ')'; + echo '' . $reward . ' BTC'; + echo '' . $percent . '%'; + echo '' . $value . ''; + echo '' . $d . ' ago'; + echo 'Cleared'; + echo ''; + + continue; + } + + $reward = altcoinvaluetoa($earning->amount); + $percent = $block->amount ? percentvaluetoa($earning->amount * 100 / $block->amount) : 0; + $value = mbitcoinvaluetoa($earning->amount * $earning->price * 1000); + + $blockUrl = $coin->createExplorerLink($coin->name, array( + 'height' => $block->height + )); + echo ''; + echo ''; + echo '' . $blockUrl . ' (' . $coin->algo . ')'; + echo '' . $reward . ' ' . $coin->symbol_show . ''; + echo '' . $percent . '%'; + echo '' . $value . ''; + echo '' . $d . ' ago'; + echo ''; + + if ($earning->status == 0) + { + $eta = ''; + if ($coin->block_time && $coin->mature_blocks) + { + $t = (int)($coin->mature_blocks - $block->confirmations) * $coin->block_time; + $eta = "ETA: " . sprintf('%dh %02dmn', ($t / 3600) , ($t / 60) % 60); + } + echo 'Immature (' . $block->confirmations . ')'; + } + + else if ($earning->status == 1) echo '' . (YAAMP_ALLOW_EXCHANGE ? 'Exchange' : 'Confirmed') . ''; + + else if ($earning->status == 2) echo 'Cleared'; + + else if ($earning->status == - 1) echo 'Invalid'; + + echo ""; + echo ""; } echo ""; echo "

"; - - - - diff --git a/web/yaamp/modules/site/results/wallet_graphs_results.php b/web/yaamp/modules/site/results/wallet_graphs_results.php index ecd9ece05..f1a6b7705 100644 --- a/web/yaamp/modules/site/results/wallet_graphs_results.php +++ b/web/yaamp/modules/site/results/wallet_graphs_results.php @@ -1,7 +1,6 @@ @@ -9,25 +8,26 @@

end; -foreach(yaamp_get_algos() as $algo) -{ - $delay = time()-24*60*60; - $user_shares = controller()->memcache->get_database_scalar("wallet_hashuser-$user->id-$algo", - "select count(*) from hashuser where userid=$user->id and time>$delay and algo=:algo limit 1", array(':algo'=>$algo)); - - $minercount = getdbocount('db_workers', "userid=$user->id and algo=:algo limit 1", array(':algo'=>$algo)); - if(!$user_shares && !$minercount) continue; - echo <<memcache + ->get_database_scalar("wallet_hashuser-$user->id-$algo", "select count(*) from hashuser where userid=$user->id and time>$delay and algo=:algo limit 1", array( + ':algo' => $algo + )); + + $minercount = getdbocount('db_workers', "userid=$user->id and algo=:algo limit 1", array( + ':algo' => $algo + )); + if (!$user_shares && !$minercount) continue; + + echo <<

end; + } echo "

"; - - - - - - diff --git a/web/yaamp/modules/site/results/wallet_miners_results.php b/web/yaamp/modules/site/results/wallet_miners_results.php index 51f53402e..d5f69ee88 100644 --- a/web/yaamp/modules/site/results/wallet_miners_results.php +++ b/web/yaamp/modules/site/results/wallet_miners_results.php @@ -1,12 +1,12 @@ id); $coinid = intval($user->coinid); -if ($coinid) { - $coin = getdbo('db_coins', $coinid); +if ($coinid) +{ + $coin = getdbo('db_coins', $coinid); } echo "
"; @@ -24,104 +24,119 @@ echo ""; echo ""; -foreach(yaamp_get_algos() as $algo) +foreach (yaamp_get_algos() as $algo) { - if (!YAAMP_ALLOW_EXCHANGE && isset($coin) && $coin->algo != $algo) continue; - - $user_rate1 = yaamp_user_rate($userid, $algo); - $user_rate1_bad = yaamp_user_rate_bad($userid, $algo); - - $percent_bad = ($user_rate1 + $user_rate1_bad)? $user_rate1_bad * 100 / ($user_rate1 + $user_rate1_bad): 0; - $percent_bad = $percent_bad? round($percent_bad, 1).'%': ''; - - $user_rate1 = $user_rate1? Itoa2($user_rate1).'h/s': '-'; - $minercount = getdbocount('db_workers', "userid=$userid AND algo=:algo", array(':algo'=>$algo)); - - if (YAAMP_ALLOW_EXCHANGE || !$user->coinid) { - - $user_shares = controller()->memcache->get_database_scalar("wallet_user_shares-$userid-$algo", - "SELECT SUM(difficulty) FROM shares WHERE valid AND userid=$userid AND algo=:algo", array(':algo'=>$algo)); - if(!$user_shares && !$minercount) continue; - - $total_shares = controller()->memcache->get_database_scalar("wallet_total_shares-$algo", - "SELECT SUM(difficulty) FROM shares WHERE valid AND algo=:algo", array(':algo'=>$algo)); - - } else { - // we know the single currency mined if auto exchange is disabled - $user_shares = controller()->memcache->get_database_scalar("wallet_user_shares-$algo-$coinid-$userid", - "SELECT SUM(difficulty) FROM shares WHERE valid AND userid=$userid AND coinid=$coinid AND algo=:algo", array(':algo'=>$algo)); - if(!$user_shares) continue; - - $total_shares = controller()->memcache->get_database_scalar("wallet_coin_shares-$coinid", - "SELECT SUM(difficulty) FROM shares WHERE valid AND coinid=$coinid AND algo=:algo", array(':algo'=>$algo)); - } - - if(!$total_shares) continue; - $percent_shares = round($user_shares * 100 / $total_shares, 4); - - echo ''; - echo ''.$algo.''; - echo ''.$minercount.''; - echo ''.$percent_shares.'%'; - echo ''.$user_rate1.''; - echo ''.$percent_bad.''; - echo ''; + if (!YAAMP_ALLOW_EXCHANGE && isset($coin) && $coin->algo != $algo) continue; + + $user_rate1 = yaamp_user_rate($userid, $algo); + $user_rate1_bad = yaamp_user_rate_bad($userid, $algo); + + $percent_bad = ($user_rate1 + $user_rate1_bad) ? $user_rate1_bad * 100 / ($user_rate1 + $user_rate1_bad) : 0; + $percent_bad = $percent_bad ? round($percent_bad, 1) . '%' : ''; + + $user_rate1 = $user_rate1 ? Itoa2($user_rate1) . 'h/s' : '-'; + $minercount = getdbocount('db_workers', "userid=$userid AND algo=:algo", array( + ':algo' => $algo + )); + + if (YAAMP_ALLOW_EXCHANGE || !$user->coinid) + { + + $user_shares = controller() + ->memcache + ->get_database_scalar("wallet_user_shares-$userid-$algo", "SELECT SUM(difficulty) FROM shares WHERE valid AND userid=$userid AND algo=:algo", array( + ':algo' => $algo + )); + if (!$user_shares && !$minercount) continue; + + $total_shares = controller() + ->memcache + ->get_database_scalar("wallet_total_shares-$algo", "SELECT SUM(difficulty) FROM shares WHERE valid AND algo=:algo", array( + ':algo' => $algo + )); + + } + else + { + // we know the single currency mined if auto exchange is disabled + $user_shares = controller() + ->memcache + ->get_database_scalar("wallet_user_shares-$algo-$coinid-$userid", "SELECT SUM(difficulty) FROM shares WHERE valid AND userid=$userid AND coinid=$coinid AND algo=:algo", array( + ':algo' => $algo + )); + if (!$user_shares) continue; + + $total_shares = controller() + ->memcache + ->get_database_scalar("wallet_coin_shares-$coinid", "SELECT SUM(difficulty) FROM shares WHERE valid AND coinid=$coinid AND algo=:algo", array( + ':algo' => $algo + )); + } + + if (!$total_shares) continue; + $percent_shares = round($user_shares * 100 / $total_shares, 4); + + echo ''; + echo '' . $algo . ''; + echo '' . $minercount . ''; + echo '' . $percent_shares . '%'; + echo '' . $user_rate1 . ''; + echo '' . $percent_bad . ''; + echo ''; } echo ""; //////////////////////////////////////////////////////////////////////////////// - $workers = getdbolist('db_workers', "userid=$user->id order by password"); -if(count($workers)) +if (count($workers)) { - echo "
"; - echo ""; - echo ""; - echo ""; - echo ""; - if ($this->admin) echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - - foreach($workers as $worker) - { - $user_rate1 = yaamp_worker_rate($worker->id, $worker->algo); - $user_rate1_bad = yaamp_worker_rate_bad($worker->id, $worker->algo); - $user_rejects = yaamp_worker_shares_bad($worker->id, $worker->algo); - if (!$user_rejects) $user_rejects = ''; - - $percent = ($user_rate1 + $user_rate1_bad)? $user_rate1_bad * 100 / ($user_rate1 + $user_rate1_bad): 0; - $percent = $percent? round($percent, 2).'%': ''; - - $user_rate1 = $user_rate1? Itoa2($user_rate1).'h/s': ''; - - $version = substr($worker->version, 0, 20); - $password = substr($worker->password, 0, 32); - if (empty($password) && !empty($worker->worker)) - $password = substr($worker->worker, 0, 32); - - $subscribe = Booltoa($worker->subscribe); - - echo ''; - echo ''; - if ($this->admin) echo ""; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - } - - echo "
DetailsIPExtraAlgoDiffES**Hashrate*Reject*
'.$version.'{$worker->ip}'.$password.''.$worker->algo.''.$worker->difficulty.''.$subscribe.''.$user_rate1.''.$user_rejects.'
"; + echo "
"; + echo ""; + echo ""; + echo ""; + echo ""; + if ($this->admin) echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + + foreach ($workers as $worker) + { + $user_rate1 = yaamp_worker_rate($worker->id, $worker->algo); + $user_rate1_bad = yaamp_worker_rate_bad($worker->id, $worker->algo); + $user_rejects = yaamp_worker_shares_bad($worker->id, $worker->algo); + if (!$user_rejects) $user_rejects = ''; + + $percent = ($user_rate1 + $user_rate1_bad) ? $user_rate1_bad * 100 / ($user_rate1 + $user_rate1_bad) : 0; + $percent = $percent ? round($percent, 2) . '%' : ''; + + $user_rate1 = $user_rate1 ? Itoa2($user_rate1) . 'h/s' : ''; + + $version = substr($worker->version, 0, 20); + $password = substr($worker->password, 0, 32); + if (empty($password) && !empty($worker->worker)) $password = substr($worker->worker, 0, 32); + + $subscribe = Booltoa($worker->subscribe); + + echo ''; + echo ''; + if ($this->admin) echo ""; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + } + + echo "
DetailsIPExtraAlgoDiffES**Hashrate*Reject*
' . $version . '{$worker->ip}' . $password . '' . $worker->algo . '' . $worker->difficulty . '' . $subscribe . '' . $user_rate1 . '' . $user_rejects . '
"; } echo "
"; @@ -132,11 +147,3 @@

"; echo "

"; - - - - - - - - diff --git a/web/yaamp/modules/site/results/wallet_results.php b/web/yaamp/modules/site/results/wallet_results.php index f7b34ec94..419b21af6 100644 --- a/web/yaamp/modules/site/results/wallet_results.php +++ b/web/yaamp/modules/site/results/wallet_results.php @@ -1,10 +1,9 @@ "; - echo "
$title
"; - echo "
"; + echo "
"; + echo "
$title
"; + echo "
"; } $mining = getdbosql('db_mining'); @@ -13,24 +12,25 @@ function WriteBoxHeader($title) $show_details = getparam('showdetails'); $user = getuserparam(getparam('address')); -if(!$user) return; +if (!$user) return; WriteBoxHeader("Wallet: $user->username"); $refcoin = getdbo('db_coins', $user->coinid); -if(!$refcoin) +if (!$refcoin) { - if($user->coinid != null) - echo "
This wallet address is not valid. + if ($user->coinid != null) echo "
This wallet address is not valid. You will not receive payments using this address.
"; - $refcoin = getdbosql('db_coins', "symbol='BTC'"); + $refcoin = getdbosql('db_coins', "symbol='BTC'"); -} elseif (!YAAMP_ALLOW_EXCHANGE && $user->coinid == 6 && $defaultalgo != 'sha256') { +} +elseif (!YAAMP_ALLOW_EXCHANGE && $user->coinid == 6 && $defaultalgo != 'sha256') +{ - echo "
This pool does not convert/trade currencies. + echo "
This pool does not convert/trade currencies. You will not receive payments using this BTC address.
"; - return; + return; } echo ""; @@ -48,75 +48,75 @@ function WriteBoxHeader($title) $total_pending = 0; -if($show_details) +if ($show_details) { - $t1 = microtime(true); - - $list = dbolist("select coinid from earnings where userid=$user->id group by coinid"); - if(!count($list)) - echo ""; - - else - { - // sort by value - foreach($list as $item) - { - $coin = getdbo('db_coins', $item['coinid']); - if(!$coin) continue; - - $name = substr($coin->name, 0, 12); - - $confirmed = controller()->memcache->get_database_scalar("wallet_confirmed-$user->id-$coin->id", - "select sum(amount) from earnings where status=1 and userid=$user->id and coinid=$coin->id"); - - $unconfirmed = controller()->memcache->get_database_scalar("wallet_unconfirmed-$user->id-$coin->id", - "select sum(amount) from earnings where status=0 and userid=$user->id and coinid=$coin->id"); - - $total = $confirmed + $unconfirmed; - // $value = bitcoinvaluetoa($total * $coin->price / $refcoin->price); - $value = bitcoinvaluetoa(yaamp_convert_amount_user($coin, $total, $user)); - - $confirmed = altcoinvaluetoa($confirmed); - $unconfirmed = altcoinvaluetoa($unconfirmed); - $total = altcoinvaluetoa($total); - - echo ""; - echo ""; - echo ""; - - echo ""; - echo ""; - echo ""; - echo ""; - - echo ""; - } - } - - $d1 = microtime(true) - $t1; - controller()->memcache->add_monitoring_function('wallet_results-1', $d1); + $t1 = microtime(true); + + $list = dbolist("select coinid from earnings where userid=$user->id group by coinid"); + if (!count($list)) echo ""; + + else + { + // sort by value + foreach ($list as $item) + { + $coin = getdbo('db_coins', $item['coinid']); + if (!$coin) continue; + + $name = substr($coin->name, 0, 12); + + $confirmed = controller() + ->memcache + ->get_database_scalar("wallet_confirmed-$user->id-$coin->id", "select sum(amount) from earnings where status=1 and userid=$user->id and coinid=$coin->id"); + + $unconfirmed = controller() + ->memcache + ->get_database_scalar("wallet_unconfirmed-$user->id-$coin->id", "select sum(amount) from earnings where status=0 and userid=$user->id and coinid=$coin->id"); + + $total = $confirmed + $unconfirmed; + // $value = bitcoinvaluetoa($total * $coin->price / $refcoin->price); + $value = bitcoinvaluetoa(yaamp_convert_amount_user($coin, $total, $user)); + + $confirmed = altcoinvaluetoa($confirmed); + $unconfirmed = altcoinvaluetoa($unconfirmed); + $total = altcoinvaluetoa($total); + + echo ""; + echo ""; + echo ""; + + echo ""; + echo ""; + echo ""; + echo ""; + + echo ""; + } + } + + $d1 = microtime(true) - $t1; + controller() + ->memcache + ->add_monitoring_function('wallet_results-1', $d1); } ////////////////////////////////////////////////////////////////////////////// - // $confirmed = bitcoinvaluetoa(controller()->memcache->get_database_scalar("wallet_confirmed-$user->id", // "select sum(amount*price) from earnings where status=1 and userid=$user->id"))/$refcoin->price; - // $unconfirmed = bitcoinvaluetoa(controller()->memcache->get_database_scalar("wallet_unconfirmed-$user->id", // "select sum(amount*price) from earnings where status=0 and userid=$user->id"))/$refcoin->price; - $confirmed = yaamp_convert_earnings_user($user, "status=1"); $unconfirmed = yaamp_convert_earnings_user($user, "status=0"); $total_unsold = bitcoinvaluetoa($confirmed + $unconfirmed); -$confirmed = $confirmed? bitcoinvaluetoa($confirmed): ''; -$unconfirmed = $unconfirmed? bitcoinvaluetoa($unconfirmed): ''; +$confirmed = $confirmed ? bitcoinvaluetoa($confirmed) : ''; +$unconfirmed = $unconfirmed ? bitcoinvaluetoa($unconfirmed) : ''; //$total_usd = number_format($total_unsold*$mining->usdbtc*$refcoin->price, 3, '.', ' '); $total_pending = bitcoinvaluetoa($total_pending); -if(!$show_details && $total_unsold > 0) +if (!$show_details && $total_unsold > 0) { - echo ' + echo ' '; -echo ''; +echo ''; echo ''; -echo ''; -echo ''; +echo ''; +echo ''; echo ''; -echo ''; +echo ''; echo ""; // //////////////////////////////////////////////////////////////////////////// - $fees_notice = ''; -if ($user->donation > 0) { - $fees_notice = 'Currently donating '.$user->donation.' % of the rewards.'; -} else if ($user->no_fees == 1) { - $fees_notice = 'Currently mining without pool fees.'; +if ($user->donation > 0) +{ + $fees_notice = 'Currently donating ' . $user->donation . ' % of the rewards.'; } -echo ''; +else if ($user->no_fees == 1) +{ + $fees_notice = 'Currently mining without pool fees.'; +} +echo ''; // //////////////////////////////////////////////////////////////////////////// - $balance = bitcoinvaluetoa($user->balance); //$balance_usd = number_format($user->balance*$mining->usdbtc*$refcoin->price, 3, '.', ' '); - echo ""; echo ""; echo ""; @@ -167,10 +165,8 @@ function WriteBoxHeader($title) echo ""; //////////////////////////////////////////////////////////////////////////// - $total_unpaid = bitcoinvaluetoa($balance + $total_unsold); //$total_unpaid_usd = number_format($total_unpaid*$mining->usdbtc*$refcoin->price, 3, '.', ' '); - echo ""; echo ""; echo ""; @@ -179,13 +175,12 @@ function WriteBoxHeader($title) echo ""; //////////////////////////////////////////////////////////////////////////// - -$total_paid = controller()->memcache->get_database_scalar("wallet_total_paid-$user->id", - "select sum(amount) from payouts where account_id=$user->id"); +$total_paid = controller() + ->memcache + ->get_database_scalar("wallet_total_paid-$user->id", "select sum(amount) from payouts where account_id=$user->id"); $total_paid = bitcoinvaluetoa($total_paid); //$total_paid_usd = number_format($total_paid*$mining->usdbtc*$refcoin->price, 3, '.', ' '); - echo ""; echo ""; echo ""; @@ -194,12 +189,9 @@ function WriteBoxHeader($title) echo ""; //////////////////////////////////////////////////////////////////////////// - //$delay = 7*24*60*60; - $total_earned = bitcoinvaluetoa($total_unsold + $balance + $total_paid); //$total_earned_usd = number_format($total_earned*$mining->usdbtc*$refcoin->price, 3, '.', ' '); - echo ""; echo ""; echo ""; @@ -213,24 +205,26 @@ function WriteBoxHeader($title) echo '

'; echo '* approximate from current exchange rates
'; -if ($refcoin->symbol == 'BTC') { - $usd = number_format($mining->usdbtc, 2, '.', ' '); - echo '** bitstamp '.$usd.' USD/BTC'; +if ($refcoin->symbol == 'BTC') +{ + $usd = number_format($mining->usdbtc, 2, '.', ' '); + echo '** bitstamp ' . $usd . ' USD/BTC'; } echo '

'; -if ($refcoin->payout_min) { - echo '

'; - echo 'Note: Minimum payout for this wallet is '.($refcoin->payout_min).' '.$refcoin->symbol; - echo '

'; +if ($refcoin->payout_min) +{ + echo '

'; + echo 'Note: Minimum payout for this wallet is ' . ($refcoin->payout_min) . ' ' . $refcoin->symbol; + echo '

'; } echo '
'; -$header = "Last 24 Hours Payouts: ".$user->username; +$header = "Last 24 Hours Payouts: " . $user->username; WriteBoxHeader($header); -$t = time()-24*60*60; +$t = time() - 24 * 60 * 60; $list = getdbolist('db_payouts', "account_id={$user->id} AND time>$t ORDER BY time DESC"); echo "
-none-
$name ($coin->algo)$unconfirmed$confirmed$total$value $refcoin->symbol
-none-
$name ($coin->algo)$unconfirmed$confirmed$total$value $refcoin->symbol
'; -if($refcoin->symbol == 'BTC') - echo $refcoin->name; -else - echo ''.$refcoin->name.''; +if ($refcoin->symbol == 'BTC') echo $refcoin->name; +else echo '' . $refcoin->name . ''; echo '
(total pending)
'.$unconfirmed.''.$confirmed.'' . $unconfirmed . '' . $confirmed . ''.$total_unsold.' '.$refcoin->symbol.'' . $total_unsold . ' ' . $refcoin->symbol . '
'.$fees_notice.'
' . $fees_notice . '
Balance
Total Unpaid
Total Paid
Total Earned
"; @@ -243,24 +237,27 @@ function WriteBoxHeader($title) echo ""; echo ""; -$total = 0; $firstid = 999999999; -foreach($list as $payout) +$total = 0; +$firstid = 999999999; +foreach ($list as $payout) { - $d = datetoa2($payout->time); - $amount = bitcoinvaluetoa($payout->amount); - $firstid = min($firstid, (int) $payout->id); + $d = datetoa2($payout->time); + $amount = bitcoinvaluetoa($payout->amount); + $firstid = min($firstid, (int)$payout->id); - echo ''; - echo ''; - echo ''; + echo ''; + echo ''; + echo ''; - $payout_tx = substr($payout->tx, 0, 36).'...'; - $link = $refcoin->createExplorerLink($payout_tx, array('txid'=>$payout->tx), array(), true); + $payout_tx = substr($payout->tx, 0, 36) . '...'; + $link = $refcoin->createExplorerLink($payout_tx, array( + 'txid' => $payout->tx + ) , array() , true); - echo ''; - echo ''; + echo ''; + echo ''; - $total += $payout->amount; + $total += $payout->amount; } $amount = bitcoinvaluetoa($total); @@ -273,13 +270,15 @@ function WriteBoxHeader($title) end; + // Search extra Payouts which were not in the db (yiimp payout check command) // In this case, the id are greater than last 24h ones and the fee column is filled $list_extra = getdbolist('db_payouts', "account_id={$user->id} AND id>$firstid AND fee > 0.0 ORDER BY time DESC"); -if (!empty($list_extra)) { +if (!empty($list_extra)) +{ - echo << @@ -294,44 +293,41 @@ function WriteBoxHeader($title) end; - $total = 0.0; - foreach($list_extra as $payout) - { - $d = datetoa2($payout->time); - $amount = bitcoinvaluetoa($payout->amount); - echo ''; - echo ''; - echo ''; + $total = 0.0; + foreach ($list_extra as $payout) + { + $d = datetoa2($payout->time); + $amount = bitcoinvaluetoa($payout->amount); + + echo ''; + echo ''; + echo ''; - $payout_tx = substr($payout->tx, 0, 36).'...'; - $link = $refcoin->createExplorerLink($payout_tx, array('txid'=>$payout->tx), array(), true); + $payout_tx = substr($payout->tx, 0, 36) . '...'; + $link = $refcoin->createExplorerLink($payout_tx, array( + 'txid' => $payout->tx + ) , array() , true); - echo ''; - echo ''; + echo ''; + echo ''; - $total += $payout->amount; - } + $total += $payout->amount; + } - $amount = bitcoinvaluetoa($total); + $amount = bitcoinvaluetoa($total); - echo << end; -} +} echo "
'.$d.' ago'.$amount.'
' . $d . ' ago' . $amount . ''.$link.'
' . $link . '
Extra payouts detected in the last 24H to explain negative balances (buggy Wallets)
'.$d.' ago'.$amount.'
' . $d . ' ago' . $amount . ''.$link.'
' . $link . '
Total: {$amount}

"; echo "
"; echo "

"; - - - - - - diff --git a/web/yaamp/modules/site/tx.php b/web/yaamp/modules/site/tx.php index 7bc8debdb..bac0f1692 100644 --- a/web/yaamp/modules/site/tx.php +++ b/web/yaamp/modules/site/tx.php @@ -1,11 +1,10 @@ pageTitle = $user->username.' | '.YAAMP_SITE_NAME; +$this->pageTitle = $user->username . ' | ' . YAAMP_SITE_NAME; echo "
"; echo "
Transactions to $user->username
"; @@ -28,22 +27,26 @@ $coin = ($bitcoin && $user->coinid == $bitcoin->id) ? $bitcoin : getdbo('db_coins', $user->coinid); $total = 0; -foreach($list as $payout) +foreach ($list as $payout) { - $d = datetoa2($payout->time); - $amount = bitcoinvaluetoa($payout->amount); + $d = datetoa2($payout->time); + $amount = bitcoinvaluetoa($payout->amount); - echo ""; - echo ""; - echo "$d ago"; + echo ""; + echo ""; + echo "$d ago"; - echo "$amount"; + echo "$amount"; - $url = $coin->createExplorerLink($payout->tx, array('txid'=>$payout->tx), array('target'=>'_blank')); - echo ''.$url.''; + $url = $coin->createExplorerLink($payout->tx, array( + 'txid' => $payout->tx + ) , array( + 'target' => '_blank' + )); + echo '' . $url . ''; - echo ""; - $total += $payout->amount; + echo ""; + $total += $payout->amount; } $total = bitcoinvaluetoa($total); @@ -59,5 +62,3 @@ echo "
"; echo "

"; - - diff --git a/web/yaamp/modules/site/user.php b/web/yaamp/modules/site/user.php index bce83f91c..b7d9d74ed 100644 --- a/web/yaamp/modules/site/user.php +++ b/web/yaamp/modules/site/user.php @@ -1,5 +1,4 @@ -all-"; -$list = getdbolist('db_coins', "enable AND (". - "id IN (SELECT DISTINCT coinid FROM accounts WHERE balance>0.0001) ". - "OR id IN (SELECT DISTINCT coinid from earnings) ) ORDER BY symbol"); -foreach($list as $coin) +$list = getdbolist('db_coins', "enable AND (" . "id IN (SELECT DISTINCT coinid FROM accounts WHERE balance>0.0001) " . "OR id IN (SELECT DISTINCT coinid from earnings) ) ORDER BY symbol"); +foreach ($list as $coin) { - if($coin->symbol == $symbol) - $coins .= ''; - else - $coins .= ''; + if ($coin->symbol == $symbol) $coins .= ''; + else $coins .= ''; } - echo << diff --git a/web/yaamp/modules/site/user_results.php b/web/yaamp/modules/site/user_results.php index 8a3beb7b2..0cf5cd5f2 100644 --- a/web/yaamp/modules/site/user_results.php +++ b/web/yaamp/modules/site/user_results.php @@ -1,18 +1,17 @@ .001 OR id IN (SELECT DISTINCT userid FROM workers) ORDER BY balance DESC"); +if ($symbol == 'all') $users = getdbolist('db_accounts', "balance>.001 OR id IN (SELECT DISTINCT userid FROM workers) ORDER BY balance DESC"); else { - $coin = getdbosql('db_coins', "symbol=:symbol", array(':symbol'=>$symbol)); - if(!$coin) return; + $coin = getdbosql('db_coins', "symbol=:symbol", array( + ':symbol' => $symbol + )); + if (!$coin) return; - $users = getdbolist('db_accounts', "coinid={$coin->id} AND (balance>.001 OR id IN (SELECT DISTINCT userid FROM workers)) ORDER BY balance DESC"); + $users = getdbolist('db_accounts', "coinid={$coin->id} AND (balance>.001 OR id IN (SELECT DISTINCT userid FROM workers)) ORDER BY balance DESC"); } echo << end; + showTableSorter('maintable', "{ tableClass: 'dataGrid', textExtraction: { @@ -62,83 +62,89 @@ end; + $total_balance = 0; $total_paid = 0; $total_unsold = 0; -foreach($users as $user) +foreach ($users as $user) { - $target = yaamp_hashrate_constant(); - $interval = yaamp_hashrate_step(); // 300 seconds - $delay = time()-$interval; - - $user_rate = dboscalar("SELECT (sum(difficulty) * $target / $interval / 1000) FROM shares WHERE valid AND time>$delay AND userid=".$user->id); - $user_bad = yaamp_user_rate_bad($user->id);// dboscalar("SELECT (count(id) * $target / $interval / 1000) FROM shares WHERE valid=0 AND time>$delay AND userid=".$user->id); - $pct_bad = $user_rate? round($user_bad*100/$user_rate, 3): 0; - - $balance = bitcoinvaluetoa($user->balance); - $paid = dboscalar("SELECT sum(amount) FROM payouts WHERE account_id=".$user->id); - $d = datetoa2($user->last_earning); - - $miner_count = getdbocount('db_workers', "userid=".$user->id); - $block_count = getdbocount('db_blocks', "userid=".$user->id); - $block_diff = ($paid && $block_count) ? round(dboscalar("SELECT sum(difficulty) FROM blocks WHERE userid=".$user->id)/$paid, 3): '?'; - - $paid = bitcoinvaluetoa($paid); - - $user_bad = Itoa2($user_bad); - - $coinimg = ''; $coinlink = ''; - $imgopt = array('width'=>'16'); - if ($coin && $user->coinid == $coin->id) { - $coinimg = CHtml::image($coin->image, $coin->symbol, $imgopt); - $coinlink = CHtml::link($coin->symbol, '/site/coin?id='.$coin->id); - } else if ($user->coinid > 0) { - $user_coin = getdbosql('db_coins', "id=:id", array(':id'=>$user->coinid)); - if ($user_coin) { - $coinimg = CHtml::image($user_coin->image, $user_coin->symbol, $imgopt); - $coinlink = CHtml::link($user_coin->symbol, '/site/coin?id='.$user_coin->id); - } - } - - echo ''; - echo ''.$user->id.''; - echo ''.$coinimg.''; - echo ''.$coinlink.''; - echo ''.$user->username.''; - echo ''.$d.''; - echo ''.$miner_count.''; - - echo ''.($user_rate ? Itoa2($user_rate) : '').''; - echo ''; - if ($pct_bad) echo round($pct_bad,1)." %"; - echo ''; - - echo ''.$block_count.''; - echo ''.($user_rate ? $block_diff : '').''; - echo ''.$balance.''; - echo ''.$paid.''; - - echo ''; - - if ($user->logtraffic) - echo 'unwatch '; - else - echo 'watch '; - - if ($user->is_locked) - echo 'unblock '; - else - echo 'block '; - - echo 'BAN'; - - echo ''; - - echo ''; - - $total_balance += $user->balance; - $total_paid += $paid; + $target = yaamp_hashrate_constant(); + $interval = yaamp_hashrate_step(); // 300 seconds + $delay = time() - $interval; + + $user_rate = dboscalar("SELECT (sum(difficulty) * $target / $interval / 1000) FROM shares WHERE valid AND time>$delay AND userid=" . $user->id); + $user_bad = yaamp_user_rate_bad($user->id); // dboscalar("SELECT (count(id) * $target / $interval / 1000) FROM shares WHERE valid=0 AND time>$delay AND userid=".$user->id); + $pct_bad = $user_rate ? round($user_bad * 100 / $user_rate, 3) : 0; + + $balance = bitcoinvaluetoa($user->balance); + $paid = dboscalar("SELECT sum(amount) FROM payouts WHERE account_id=" . $user->id); + $d = datetoa2($user->last_earning); + + $miner_count = getdbocount('db_workers', "userid=" . $user->id); + $block_count = getdbocount('db_blocks', "userid=" . $user->id); + $block_diff = ($paid && $block_count) ? round(dboscalar("SELECT sum(difficulty) FROM blocks WHERE userid=" . $user->id) / $paid, 3) : '?'; + + $paid = bitcoinvaluetoa($paid); + + $user_bad = Itoa2($user_bad); + + $coinimg = ''; + $coinlink = ''; + $imgopt = array( + 'width' => '16' + ); + if ($coin && $user->coinid == $coin->id) + { + $coinimg = CHtml::image($coin->image, $coin->symbol, $imgopt); + $coinlink = CHtml::link($coin->symbol, '/site/coin?id=' . $coin->id); + } + else if ($user->coinid > 0) + { + $user_coin = getdbosql('db_coins', "id=:id", array( + ':id' => $user->coinid + )); + if ($user_coin) + { + $coinimg = CHtml::image($user_coin->image, $user_coin->symbol, $imgopt); + $coinlink = CHtml::link($user_coin->symbol, '/site/coin?id=' . $user_coin->id); + } + } + + echo ''; + echo '' . $user->id . ''; + echo '' . $coinimg . ''; + echo '' . $coinlink . ''; + echo '' . $user->username . ''; + echo '' . $d . ''; + echo '' . $miner_count . ''; + + echo '' . ($user_rate ? Itoa2($user_rate) : '') . ''; + echo ''; + if ($pct_bad) echo round($pct_bad, 1) . " %"; + echo ''; + + echo '' . $block_count . ''; + echo '' . ($user_rate ? $block_diff : '') . ''; + echo '' . $balance . ''; + echo '' . $paid . ''; + + echo ''; + + if ($user->logtraffic) echo 'unwatch '; + else echo 'watch '; + + if ($user->is_locked) echo 'unblock '; + else echo 'block '; + + echo 'BAN'; + + echo ''; + + echo ''; + + $total_balance += $user->balance; + $total_paid += $paid; } echo ""; @@ -151,43 +157,33 @@ $user_count = count($users); echo ''; -echo 'Users Total ('.$user_count.')'; -for ($c=0; $c<$colspan; $c++) echo ''; -echo ''.$total_balance.''; -echo ''.$total_paid.''; +echo 'Users Total (' . $user_count . ')'; +for ($c = 0;$c < $colspan;$c++) echo ''; +echo '' . $total_balance . ''; +echo '' . $total_paid . ''; echo ''; echo ''; -if($coin) +if ($coin) { - $balance = bitcoinvaluetoa($coin->balance); - $profit = bitcoinvaluetoa($balance - $total_balance); - - echo ''; - echo 'Wallet Balance'; - for ($c=0; $c<$colspan; $c++) echo ''; - echo ''.$balance.''; - echo ''; - echo ''; - - echo ''; - echo 'Wallet Profit'; - for ($c=0; $c<$colspan; $c++) echo ''; - echo ''.$profit.''; - echo ''; - echo ''; + $balance = bitcoinvaluetoa($coin->balance); + $profit = bitcoinvaluetoa($balance - $total_balance); + + echo ''; + echo 'Wallet Balance'; + for ($c = 0;$c < $colspan;$c++) echo ''; + echo '' . $balance . ''; + echo ''; + echo ''; + + echo ''; + echo 'Wallet Profit'; + for ($c = 0;$c < $colspan;$c++) echo ''; + echo '' . $profit . ''; + echo ''; + echo ''; } echo ""; //echo "

1% bonus

"; - - - - - - - - - - diff --git a/web/yaamp/modules/site/version.php b/web/yaamp/modules/site/version.php index 9fe717d2f..e224afcf5 100644 --- a/web/yaamp/modules/site/version.php +++ b/web/yaamp/modules/site/version.php @@ -4,11 +4,10 @@ $algo = user()->getState('yaamp-algo'); $algos = yaamp_get_algos(); $algo_opts = ''; -foreach($algos as $a) { - if($a == $algo) - $algo_opts .= ""; - else - $algo_opts .= ""; +foreach ($algos as $a) +{ + if ($a == $algo) $algo_opts .= ""; + else $algo_opts .= ""; } echo <<$algo_opts 
end; + ?> @@ -60,6 +60,3 @@ function main_refresh() }); - - - diff --git a/web/yaamp/modules/site/version_results.php b/web/yaamp/modules/site/version_results.php index e10096c51..8a50d4ef5 100644 --- a/web/yaamp/modules/site/version_results.php +++ b/web/yaamp/modules/site/version_results.php @@ -1,12 +1,10 @@ setState('yaamp-algo', $_GET['algo']); +if (isset($_GET['algo'])) user()->setState('yaamp-algo', $_GET['algo']); $algo = user()->getState('yaamp-algo'); $target = yaamp_hashrate_constant($algo); $interval = yaamp_hashrate_step(); -$delay = time()-$interval; +$delay = time() - $interval; echo "
"; echo ""; @@ -19,33 +17,37 @@ echo ""; echo ""; -$versions = dbolist("select version, count(*) as c from workers where algo=:algo group by version", array(':algo'=>$algo)); -foreach($versions as $item) +$versions = dbolist("select version, count(*) as c from workers where algo=:algo group by version", array( + ':algo' => $algo +)); +foreach ($versions as $item) { - $version = $item['version']; - $count = $item['c']; - - $hashrate = dboscalar("select sum(difficulty) * $target / $interval / 1000 from shares where valid and time>$delay and - workerid in (select id from workers where algo=:algo and version=:version)", array(':algo'=>$algo, ':version'=>$version)); - - $invalid = dboscalar("select sum(difficulty) * $target / $interval / 1000 from shares where not valid and time>$delay and - workerid in (select id from workers where algo=:algo and version=:version)", array(':algo'=>$algo, ':version'=>$version)); - - $percent = $hashrate? round($invalid*100/$hashrate, 3): 0; - $hashrate = Itoa2($hashrate).'h/s'; - $invalid = Itoa2($invalid).'h/s'; - - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; + $version = $item['version']; + $count = $item['c']; + + $hashrate = dboscalar("select sum(difficulty) * $target / $interval / 1000 from shares where valid and time>$delay and + workerid in (select id from workers where algo=:algo and version=:version)", array( + ':algo' => $algo, + ':version' => $version + )); + + $invalid = dboscalar("select sum(difficulty) * $target / $interval / 1000 from shares where not valid and time>$delay and + workerid in (select id from workers where algo=:algo and version=:version)", array( + ':algo' => $algo, + ':version' => $version + )); + + $percent = $hashrate ? round($invalid * 100 / $hashrate, 3) : 0; + $hashrate = Itoa2($hashrate) . 'h/s'; + $invalid = Itoa2($invalid) . 'h/s'; + + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; } echo "
$version$count$hashrate$invalid{$percent}%
$version$count$hashrate$invalid{$percent}%
"; - - - - diff --git a/web/yaamp/modules/site/wallet.php b/web/yaamp/modules/site/wallet.php index dc9e28ddf..64e664bcf 100644 --- a/web/yaamp/modules/site/wallet.php +++ b/web/yaamp/modules/site/wallet.php @@ -141,10 +141,10 @@ $balance = $balance>0? "$balance BTC": ''; echo ''.$balance.''; - + $delicon = $address == $addr ? '' : ''; echo ''.$delicon.''; - + echo ''; } @@ -416,4 +416,3 @@ function drop_cookie(el) END; - diff --git a/web/yaamp/modules/site/worker.php b/web/yaamp/modules/site/worker.php index c7932b132..cd20b2ef0 100644 --- a/web/yaamp/modules/site/worker.php +++ b/web/yaamp/modules/site/worker.php @@ -4,14 +4,14 @@ $algo = user()->getState('yaamp-algo'); $algos = yaamp_get_algos(); $algo_opts = ''; -foreach($algos as $a) { - if($a == $algo) - $algo_opts .= ""; - else - $algo_opts .= ""; +foreach ($algos as $a) +{ + if ($a == $algo) $algo_opts .= ""; + else $algo_opts .= ""; } -if (!strstr($algo_opts, 'selected') && $this->admin) { - $algo_opts = "" . $algo_opts; +if (!strstr($algo_opts, 'selected') && $this->admin) +{ + $algo_opts = "" . $algo_opts; } echo <<$algo_opts 
end; + ?>
@@ -62,6 +63,3 @@ function main_refresh() }); - - - diff --git a/web/yaamp/modules/site/worker_results.php b/web/yaamp/modules/site/worker_results.php index 2169e59e3..a993cb09e 100644 --- a/web/yaamp/modules/site/worker_results.php +++ b/web/yaamp/modules/site/worker_results.php @@ -1,7 +1,7 @@ setState('yaamp-algo', $_GET['algo']); + user()->setState('yaamp-algo', $_GET['algo']); $algo = user()->getState('yaamp-algo'); @@ -18,19 +18,19 @@ end; showTableSorter('maintable', "{ - tableClass: 'dataGrid', - textExtraction: { - 6: function(node, table, n) { return $(node).attr('data'); } - }, - widgets: ['zebra','filter','Storage','saveSort'], - widgetOptions: { - saveSort: true, - filter_saveFilters: false, - filter_external: '.search', - filter_columnFilters: false, - filter_childRows : true, - filter_ignoreCase: true - } + tableClass: 'dataGrid', + textExtraction: { + 6: function(node, table, n) { return $(node).attr('data'); } + }, + widgets: ['zebra','filter','Storage','saveSort'], + widgetOptions: { + saveSort: true, + filter_saveFilters: false, + filter_external: '.search', + filter_columnFilters: false, + filter_childRows : true, + filter_ignoreCase: true + } }"); echo << end; -$workers = getdbolist('db_workers', "algo=:algo order by name", array(':algo'=>$algo)); +$workers = getdbolist('db_workers', "algo=:algo order by name", array( + ':algo' => $algo +)); $total_rate = 0.0; -foreach($workers as $worker) -{ - $total_rate += yaamp_worker_rate($worker->id); +foreach ($workers as $worker) { + $total_rate += yaamp_worker_rate($worker->id); } -foreach($workers as $worker) -{ - $user_rate = yaamp_worker_rate($worker->id); - $percent = 0.0; - if ($total_rate) $percent = (100.0 * $user_rate) / $total_rate; - $user_bad = yaamp_worker_rate_bad($worker->id); - $pct_bad = ($user_rate+$user_bad)? round($user_bad*100/($user_rate+$user_bad), 3): 0; - $user_rate_h = $user_rate ? Itoa2($user_rate).'H' : '-'; - - $name = $worker->worker; - $user = $coin = NULL; - $coinimg = ''; $coinlink = ''; $coinsym = ''; $shares= ''; - if ($worker->userid) { - $user = getdbo('db_accounts', $worker->userid); - if ($user) { - $coin = getdbo('db_coins', $user->coinid); - $coinsym = $coin->symbol; - $coinimg = CHtml::image($coin->image, $coin->symbol, array('width'=>'16')); - $coinlink = CHtml::link($coin->name, '/site/coin?id='.$coin->id); - } - $name = empty($name) ? $user->login : $name; - $gift = $user->donation; - } - - $dns = !empty($worker->dns)? $worker->dns: $worker->ip; - if(strlen($worker->dns) > 40) - $dns = '...'.substr($worker->dns, strlen($worker->dns) - 40); - - echo ""; - echo ''.$coinimg.''; - echo ''.$coinlink.''.($coinsym ? ' ('.$coinsym.')':'-').''; - echo "$worker->name"; - echo "$worker->password"; - echo "$dns"; - echo "$worker->version"; - echo "$user_rate_h"; - echo "$worker->difficulty"; - - $shares = dboscalar("SELECT COUNT(id) as shares FROM shares WHERE workerid=:worker AND algo=:algo", array( - ':worker'=> $worker->id, - ':algo'=> $algo - )); - echo "$shares"; - - echo ""; - if ($user_bad > 0) { - if ($pct_bad > 50) - echo " {$pct_bad}%"; - else - echo " {$pct_bad}%"; - } - echo ""; - - $worker_blocs = dboscalar("SELECT COUNT(id) as blocs FROM blocks WHERE workerid=:worker AND algo=:algo", array( - ':worker'=> $worker->id, - ':algo'=> $algo - )); - $user_blocs = dboscalar("SELECT COUNT(id) as blocs FROM blocks WHERE userid=:user AND algo=:algo - AND time > (SELECT min(time) FROM workers WHERE algo=:algo)", array( - ':user'=> $worker->userid, - ':algo'=> $algo - )); - echo ''.number_format($percent,1,'.','').'%'; - - echo ''.$worker_blocs.' / '.$user_blocs.''; - echo ''.$name.''; - echo ''.(isset($gift) && $gift ? "$gift %" : '').''; - echo ''; +foreach ($workers as $worker) { + $user_rate = yaamp_worker_rate($worker->id); + $percent = 0.0; + if ($total_rate) + $percent = (100.0 * $user_rate) / $total_rate; + $user_bad = yaamp_worker_rate_bad($worker->id); + $pct_bad = ($user_rate + $user_bad) ? round($user_bad * 100 / ($user_rate + $user_bad), 3) : 0; + $user_rate_h = $user_rate ? Itoa2($user_rate) . 'H' : '-'; + + $name = $worker->worker; + $user = $coin = NULL; + $coinimg = ''; + $coinlink = ''; + $coinsym = ''; + $shares = ''; + if ($worker->userid) { + $user = getdbo('db_accounts', $worker->userid); + if ($user) { + $coin = getdbo('db_coins', $user->coinid); + $coinsym = $coin->symbol; + $coinimg = CHtml::image($coin->image, $coin->symbol, array( + 'width' => '16' + )); + $coinlink = CHtml::link($coin->name, '/site/coin?id=' . $coin->id); + } + $name = empty($name) ? $user->login : $name; + $gift = $user->donation; + } + + $dns = !empty($worker->dns) ? $worker->dns : $worker->ip; + if (strlen($worker->dns) > 40) + $dns = '...' . substr($worker->dns, strlen($worker->dns) - 40); + + echo ""; + echo '' . $coinimg . ''; + echo '' . $coinlink . '' . ($coinsym ? ' (' . $coinsym . ')' : '-') . ''; + echo "$worker->name"; + echo "$worker->password"; + echo "$dns"; + echo "$worker->version"; + echo "$user_rate_h"; + echo "$worker->difficulty"; + + $shares = dboscalar("SELECT COUNT(id) as shares FROM shares WHERE workerid=:worker AND algo=:algo", array( + ':worker' => $worker->id, + ':algo' => $algo + )); + echo "$shares"; + + echo ""; + if ($user_bad > 0) { + if ($pct_bad > 50) + echo " {$pct_bad}%"; + else + echo " {$pct_bad}%"; + } + echo ""; + + $worker_blocs = dboscalar("SELECT COUNT(id) as blocs FROM blocks WHERE workerid=:worker AND algo=:algo", array( + ':worker' => $worker->id, + ':algo' => $algo + )); + $user_blocs = dboscalar("SELECT COUNT(id) as blocs FROM blocks WHERE userid=:user AND algo=:algo + AND time > (SELECT min(time) FROM workers WHERE algo=:algo)", array( + ':user' => $worker->userid, + ':algo' => $algo + )); + echo '' . number_format($percent, 1, '.', '') . '%'; + + echo '' . $worker_blocs . ' / ' . $user_blocs . ''; + echo '' . $name . ''; + echo '' . (isset($gift) && $gift ? "$gift %" : '') . ''; + echo ''; } echo ""; - - - - diff --git a/web/yaamp/modules/stats/StatsController.php b/web/yaamp/modules/stats/StatsController.php index a4eb5faef..9273f7928 100644 --- a/web/yaamp/modules/stats/StatsController.php +++ b/web/yaamp/modules/stats/StatsController.php @@ -1,65 +1,57 @@ render('index'); - } - - public function actionGraph_results_1() - { - $this->renderPartial('graph_results_1'); - } - - public function actionGraph_results_2() - { - $this->renderPartial('graph_results_2'); - } - - public function actionGraph_results_3() - { - $this->renderPartial('graph_results_3'); - } - - public function actionGraph_results_4() - { - $this->renderPartial('graph_results_4'); - } - - public function actionGraph_results_5() - { - $this->renderPartial('graph_results_5'); - } - - public function actionGraph_results_6() - { - $this->renderPartial('graph_results_6'); - } - - public function actionGraph_results_7() - { - $this->renderPartial('graph_results_7'); - } - - public function actionGraph_results_8() - { - $this->renderPartial('graph_results_8'); - } - - public function actionGraph_results_9() - { - $this->renderPartial('graph_results_9'); - } - + public $defaultAction = 'index'; + + ///////////////////////////////////////////////// + public function actionIndex() + { + $this->render('index'); + } + + public function actionGraph_results_1() + { + $this->renderPartial('graph_results_1'); + } + + public function actionGraph_results_2() + { + $this->renderPartial('graph_results_2'); + } + + public function actionGraph_results_3() + { + $this->renderPartial('graph_results_3'); + } + + public function actionGraph_results_4() + { + $this->renderPartial('graph_results_4'); + } + + public function actionGraph_results_5() + { + $this->renderPartial('graph_results_5'); + } + + public function actionGraph_results_6() + { + $this->renderPartial('graph_results_6'); + } + + public function actionGraph_results_7() + { + $this->renderPartial('graph_results_7'); + } + + public function actionGraph_results_8() + { + $this->renderPartial('graph_results_8'); + } + + public function actionGraph_results_9() + { + $this->renderPartial('graph_results_9'); + } } - - - - - diff --git a/web/yaamp/modules/stats/index.php b/web/yaamp/modules/stats/index.php index 866e242dd..3e0441629 100644 --- a/web/yaamp/modules/stats/index.php +++ b/web/yaamp/modules/stats/index.php @@ -1,5 +1,4 @@ getState('yaamp-algo'); $algo_unit = 'Mh'; $algo_factor = yaamp_algo_mBTC_factor($algo); @@ -14,36 +13,49 @@ $hour = 60 * 60; $days = 24 * $hour; -$dbMax = (int) controller()->memcache->get_database_scalar("stats_maxt-$algo", - "SELECT (MAX(time)-30*60) FROM hashstats WHERE time>:t AND algo=:algo", array(':t'=>time()-2*$hour,':algo'=>$algo)); -$dtMax = max(time()-$hour, $dbMax); - -$t1 = $dtMax - 2*$days; -$t2 = $dtMax - 7*$days; -$t3 = $dtMax - 30*$days; - -$row1 = controller()->memcache->get_database_row("stats_col1-$algo", - "SELECT AVG(hashrate) as a, SUM(earnings) as b FROM hashstats WHERE time>$t1 AND algo=:algo", array(':algo'=>$algo)); -$row2 = controller()->memcache->get_database_row("stats_col2-$algo", - "SELECT AVG(hashrate) as a, SUM(earnings) as b FROM hashstats WHERE time>$t2 AND algo=:algo", array(':algo'=>$algo)); -$row3 = controller()->memcache->get_database_row("stats_col3-$algo", - "SELECT AVG(hashrate) as a, SUM(earnings) as b FROM hashstats WHERE time>$t3 AND algo=:algo", array(':algo'=>$algo)); - -if($row1['a']>0 && $row2['a']>0 && $row3['a']>0) +$dbMax = (int)controller() + ->memcache + ->get_database_scalar("stats_maxt-$algo", "SELECT (MAX(time)-30*60) FROM hashstats WHERE time>:t AND algo=:algo", array( + ':t' => time() - 2 * $hour, + ':algo' => $algo +)); +$dtMax = max(time() - $hour, $dbMax); + +$t1 = $dtMax - 2 * $days; +$t2 = $dtMax - 7 * $days; +$t3 = $dtMax - 30 * $days; + +$row1 = controller() + ->memcache + ->get_database_row("stats_col1-$algo", "SELECT AVG(hashrate) as a, SUM(earnings) as b FROM hashstats WHERE time>$t1 AND algo=:algo", array( + ':algo' => $algo +)); +$row2 = controller() + ->memcache + ->get_database_row("stats_col2-$algo", "SELECT AVG(hashrate) as a, SUM(earnings) as b FROM hashstats WHERE time>$t2 AND algo=:algo", array( + ':algo' => $algo +)); +$row3 = controller() + ->memcache + ->get_database_row("stats_col3-$algo", "SELECT AVG(hashrate) as a, SUM(earnings) as b FROM hashstats WHERE time>$t3 AND algo=:algo", array( + ':algo' => $algo +)); + +if ($row1['a'] > 0 && $row2['a'] > 0 && $row3['a'] > 0) { - $a1 = max(1., (double) $row1['a']); - $a2 = max(1., (double) $row2['a']); - $a3 = max(1., (double) $row3['a']); + $a1 = max(1., (double)$row1['a']); + $a2 = max(1., (double)$row2['a']); + $a3 = max(1., (double)$row3['a']); - $btcmhday1 = bitcoinvaluetoa(($row1['b'] / 2) * $algo_factor * (1000000 / $a1)); - $btcmhday2 = bitcoinvaluetoa(($row2['b'] / 7) * $algo_factor * (1000000 / $a2)); - $btcmhday3 = bitcoinvaluetoa(($row3['b'] / 30) * $algo_factor * (1000000 / $a3)); + $btcmhday1 = bitcoinvaluetoa(($row1['b'] / 2) * $algo_factor * (1000000 / $a1)); + $btcmhday2 = bitcoinvaluetoa(($row2['b'] / 7) * $algo_factor * (1000000 / $a2)); + $btcmhday3 = bitcoinvaluetoa(($row3['b'] / 30) * $algo_factor * (1000000 / $a3)); } else { - $btcmhday1 = 0; - $btcmhday2 = 0; - $btcmhday3 = 0; + $btcmhday1 = 0; + $btcmhday2 = 0; + $btcmhday3 = 0; } $hashrate1 = Itoa2($row1['a']); @@ -59,28 +71,27 @@ //$algos = yaamp_get_algos(); $algos = array(); $enabled = dbolist("SELECT algo, count(id) as count FROM coins WHERE enable AND visible GROUP BY algo ORDER BY algo"); -foreach ($enabled as $row) { - $algos[$row['algo']] = $row['count']; +foreach ($enabled as $row) +{ + $algos[$row['algo']] = $row['count']; } $string = ''; -foreach($algos as $a => $count) +foreach ($algos as $a => $count) { - if($a == $algo) - $string .= ""; - else - $string .= ""; + if ($a == $algo) $string .= ""; + else $string .= ""; } // to fill the graphs on right edges (big tick interval of 4 days) $dtMin1 = $t1 + $hour; $dtMax1 = $dtMax; -$dtMin2 = $t2 - 2*$hour; +$dtMin2 = $t2 - 2 * $hour; $dtMax2 = $dtMin2 + 7 * $days; -$dtMin3 = $dtMax1 - (8*4+1)*$days; -$dtMax3 = $dtMin3 + (8*4) * $days; +$dtMin3 = $dtMax1 - (8 * 4 + 1) * $days; +$dtMax3 = $dtMin3 + (8 * 4) * $days; echo << end; - - diff --git a/web/yaamp/modules/thread/CronjobController.php b/web/yaamp/modules/thread/CronjobController.php index 302b9f63f..6197ef8d9 100644 --- a/web/yaamp/modules/thread/CronjobController.php +++ b/web/yaamp/modules/thread/CronjobController.php @@ -1,222 +1,243 @@ memcache->memcache, 'apache_locked'); - if($apache_locked) return; - - $b = preg_match('/load average: (.*)$/', $uptime, $m); - if(!$b) return; - - $e = explode(', ', $m[1]); - - $webserver = 'nginx'; - $res = exec("pgrep $webserver"); - $webserver_running = !empty($res); - - if($e[0] > 4 && $webserver_running) - { - debuglog('server overload!'); - // debuglog('stopping webserver'); - // system("service $webserver stop"); - sleep(1); - } - - else if(!$webserver_running) - { - debuglog('starting webserver'); - system("service $webserver start"); - } - } - - public function actionRunBlocks() - { -// screenlog(__FUNCTION__); - set_time_limit(0); - - $this->monitorApache(); - - $last_complete = memcache_get($this->memcache->memcache, "cronjob_block_time_start"); - if($last_complete+(5*60) < time()) - dborun("update jobs set active=false"); - BackendBlockFind1(); - if(!memcache_get($this->memcache->memcache, 'balances_locked')) { - BackendClearEarnings(); - } - BackendRentingUpdate(); - BackendProcessList(); - BackendBlocksUpdate(); - - memcache_set($this->memcache->memcache, "cronjob_block_time_start", time()); -// screenlog(__FUNCTION__.' done'); - } - - public function actionRunLoop2() - { -// screenlog(__FUNCTION__); - set_time_limit(0); - - $this->monitorApache(); - - BackendCoinsUpdate(); - BackendStatsUpdate(); - BackendUsersUpdate(); - - BackendUpdateServices(); - BackendUpdateDeposit(); - - MonitorBTC(); - - $last = memcache_get($this->memcache->memcache, 'last_renting_payout2'); - if($last + 5*60 < time() && !memcache_get($this->memcache->memcache, 'balances_locked')) - { - memcache_set($this->memcache->memcache, 'last_renting_payout2', time()); - BackendRentingPayout(); - } - - $last = memcache_get($this->memcache->memcache, 'last_stats2'); - if($last + 5*60 < time()) - { - memcache_set($this->memcache->memcache, 'last_stats2', time()); - BackendStatsUpdate2(); - } - - memcache_set($this->memcache->memcache, "cronjob_loop2_time_start", time()); -// screenlog(__FUNCTION__.' done'); - } - - public function actionRun() - { -// debuglog(__METHOD__); - set_time_limit(0); - -// BackendRunCoinActions(); - - $state = memcache_get($this->memcache->memcache, 'cronjob_main_state'); - if(!$state) $state = 0; - - memcache_set($this->memcache->memcache, 'cronjob_main_state', $state+1); - memcache_set($this->memcache->memcache, "cronjob_main_state_$state", 1); - - switch($state) - { - case 0: - updateRawcoins(); - - $btcusd = bitstamp_btcusd(); - if($btcusd) { - $mining = getdbosql('db_mining'); - if (!$mining) $mining = new db_mining; - $mining->usdbtc = $btcusd; - $mining->save(); - } - - break; - - case 1: - if(!YAAMP_PRODUCTION) break; - - getBitstampBalances(); - getCexIoBalances(); - doBittrexTrading(); - doCrex24Trading(); - doCryptopiaTrading(); - doKrakenTrading(); - doLiveCoinTrading(); - doPoloniexTrading(); - break; - - case 2: - if(!YAAMP_PRODUCTION) break; - - doBinanceTrading(); - doCCexTrading(); - doBterTrading(); - doBleutradeTrading(); - doKuCoinTrading(); - doNovaTrading(); - doYobitTrading(); - doCoinsMarketsTrading(); - break; - - case 3: - BackendPricesUpdate(); - BackendWatchMarkets(); - break; - - case 4: - BackendBlocksUpdate(); - break; - - case 5: - TradingSellCoins(); - break; - - case 6: - BackendBlockFind2(); - BackendUpdatePoolBalances(); - break; - - case 7: - NotifyCheckRules(); - BenchUpdateChips(); - break; - - default: - memcache_set($this->memcache->memcache, 'cronjob_main_state', 0); - BackendQuickClean(); - - $t = memcache_get($this->memcache->memcache, "cronjob_main_start_time"); - $n = time(); - - memcache_set($this->memcache->memcache, "cronjob_main_time", $n-$t); - memcache_set($this->memcache->memcache, "cronjob_main_start_time", $n); - } - - debuglog(__METHOD__." $state"); - memcache_set($this->memcache->memcache, "cronjob_main_state_$state", 0); - - memcache_set($this->memcache->memcache, "cronjob_main_time_start", time()); - if(!YAAMP_PRODUCTION) return; - - /////////////////////////////////////////////////////////////////// - - $mining = getdbosql('db_mining'); - if($mining->last_payout + YAAMP_PAYMENTS_FREQ > time()) return; - - debuglog("--------------------------------------------------------"); - - $mining->last_payout = time(); - $mining->save(); - - memcache_set($this->memcache->memcache, 'apache_locked', true); - if(YAAMP_USE_NGINX) - system("service nginx stop"); - - sleep(10); - BackendDoBackup(); - memcache_set($this->memcache->memcache, 'apache_locked', false); - - // prevent user balances changes during payments (blocks thread) - memcache_set($this->memcache->memcache, 'balances_locked', true, 0, 300); - BackendPayments(); - memcache_set($this->memcache->memcache, 'balances_locked', false); - - BackendCleanDatabase(); - - // BackendOptimizeTables(); - debuglog('payments sequence done'); - } - -} - + private function monitorApache() + { + if (!YAAMP_PRODUCTION) return; + if (!YAAMP_USE_NGINX) return; + + $uptime = exec('uptime'); + + $apache_locked = memcache_get($this + ->memcache->memcache, 'apache_locked'); + if ($apache_locked) return; + + $b = preg_match('/load average: (.*)$/', $uptime, $m); + if (!$b) return; + + $e = explode(', ', $m[1]); + + $webserver = 'nginx'; + $res = exec("pgrep $webserver"); + $webserver_running = !empty($res); + + if ($e[0] > 4 && $webserver_running) + { + debuglog('server overload!'); + // debuglog('stopping webserver'); + // system("service $webserver stop"); + sleep(1); + } + + else if (!$webserver_running) + { + debuglog('starting webserver'); + system("service $webserver start"); + } + } + + public function actionRunBlocks() + { + // screenlog(__FUNCTION__); + set_time_limit(0); + + $this->monitorApache(); + + $last_complete = memcache_get($this + ->memcache->memcache, "cronjob_block_time_start"); + if ($last_complete + (5 * 60) < time()) dborun("update jobs set active=false"); + BackendBlockFind1(); + if (!memcache_get($this + ->memcache->memcache, 'balances_locked')) + { + BackendClearEarnings(); + } + BackendRentingUpdate(); + BackendProcessList(); + BackendBlocksUpdate(); + + memcache_set($this + ->memcache->memcache, "cronjob_block_time_start", time()); + // screenlog(__FUNCTION__.' done'); + + } + + public function actionRunLoop2() + { + // screenlog(__FUNCTION__); + set_time_limit(0); + + $this->monitorApache(); + + BackendCoinsUpdate(); + BackendStatsUpdate(); + BackendUsersUpdate(); + + BackendUpdateServices(); + BackendUpdateDeposit(); + + MonitorBTC(); + + $last = memcache_get($this + ->memcache->memcache, 'last_renting_payout2'); + if ($last + 5 * 60 < time() && !memcache_get($this + ->memcache->memcache, 'balances_locked')) + { + memcache_set($this + ->memcache->memcache, 'last_renting_payout2', time()); + BackendRentingPayout(); + } + + $last = memcache_get($this + ->memcache->memcache, 'last_stats2'); + if ($last + 5 * 60 < time()) + { + memcache_set($this + ->memcache->memcache, 'last_stats2', time()); + BackendStatsUpdate2(); + } + + memcache_set($this + ->memcache->memcache, "cronjob_loop2_time_start", time()); + // screenlog(__FUNCTION__.' done'); + + } + + public function actionRun() + { + // debuglog(__METHOD__); + set_time_limit(0); + + // BackendRunCoinActions(); + $state = memcache_get($this + ->memcache->memcache, 'cronjob_main_state'); + if (!$state) $state = 0; + + memcache_set($this + ->memcache->memcache, 'cronjob_main_state', $state + 1); + memcache_set($this + ->memcache->memcache, "cronjob_main_state_$state", 1); + + switch ($state) + { + case 0: + updateRawcoins(); + + $btcusd = bitstamp_btcusd(); + if ($btcusd) + { + $mining = getdbosql('db_mining'); + if (!$mining) $mining = new db_mining; + $mining->usdbtc = $btcusd; + $mining->save(); + } + + break; + + case 1: + if (!YAAMP_PRODUCTION) break; + + getBitstampBalances(); + getCexIoBalances(); + doBittrexTrading(); + doCrex24Trading(); + doCryptopiaTrading(); + doKrakenTrading(); + doLiveCoinTrading(); + doPoloniexTrading(); + break; + + case 2: + if (!YAAMP_PRODUCTION) break; + + doBinanceTrading(); + doCCexTrading(); + doBleutradeTrading(); + doCryptobridgeTrading(); + doKuCoinTrading(); + doNovaTrading(); + doYobitTrading(); + doCoinsMarketsTrading(); + break; + + case 3: + BackendPricesUpdate(); + BackendWatchMarkets(); + break; + + case 4: + BackendBlocksUpdate(); + break; + + case 5: + TradingSellCoins(); + break; + + case 6: + BackendBlockFind2(); + BackendUpdatePoolBalances(); + break; + + case 7: + NotifyCheckRules(); + BenchUpdateChips(); + break; + + default: + memcache_set($this + ->memcache->memcache, 'cronjob_main_state', 0); + BackendQuickClean(); + + $t = memcache_get($this + ->memcache->memcache, "cronjob_main_start_time"); + $n = time(); + + memcache_set($this + ->memcache->memcache, "cronjob_main_time", $n - $t); + memcache_set($this + ->memcache->memcache, "cronjob_main_start_time", $n); + } + + debuglog(__METHOD__ . " $state"); + memcache_set($this + ->memcache->memcache, "cronjob_main_state_$state", 0); + + memcache_set($this + ->memcache->memcache, "cronjob_main_time_start", time()); + if (!YAAMP_PRODUCTION) return; + + /////////////////////////////////////////////////////////////////// + $mining = getdbosql('db_mining'); + if ($mining->last_payout + YAAMP_PAYMENTS_FREQ > time()) return; + + debuglog("--------------------------------------------------------"); + + $mining->last_payout = time(); + $mining->save(); + + memcache_set($this + ->memcache->memcache, 'apache_locked', true); + if (YAAMP_USE_NGINX) system("service nginx stop"); + + sleep(10); + BackendDoBackup(); + memcache_set($this + ->memcache->memcache, 'apache_locked', false); + + // prevent user balances changes during payments (blocks thread) + memcache_set($this + ->memcache->memcache, 'balances_locked', true, 0, 300); + BackendPayments(); + memcache_set($this + ->memcache->memcache, 'balances_locked', false); + + BackendCleanDatabase(); + + // BackendOptimizeTables(); + debuglog('payments sequence done'); + } + + } diff --git a/web/yaamp/modules/trading/TradingController.php b/web/yaamp/modules/trading/TradingController.php index 2f4100762..221f99195 100644 --- a/web/yaamp/modules/trading/TradingController.php +++ b/web/yaamp/modules/trading/TradingController.php @@ -1,59 +1,44 @@ admin) return; - $this->render('index'); - } - - public function actionMining_results() - { - if(!$this->admin) return; - $this->renderPartial('mining_results'); - } - - -// public function actionCreate() -// { -// if(!$this->admin) return; -// $coin = new db_coins; - -// if(isset($_POST['db_coins'])) -// { -// $coin->setAttributes($_POST['db_coins'], false); -// if($coin->save()) -// $this->redirect(array('index')); -// } - -// $this->render('_form', array('coin'=>$coin, 'update'=>false)); -// } - -// public function actionUpdate() -// { -// if(!$this->admin) return; -// $coin = getdbo('db_coins', getiparam('id')); - -// if(isset($_POST['db_coins'])) -// { -// $coin->setAttributes($_POST['db_coins'], false); -// if($coin->save()) -// $this->redirect(array('index')); -// } - -// $this->render('_form', array('coin'=>$coin, 'update'=>true)); -// } + public $defaultAction = 'index'; + + ///////////////////////////////////////////////// + public function actionIndex() + { + if (!$this->admin) return; + $this->render('index'); + } + + public function actionMining_results() + { + if (!$this->admin) return; + $this->renderPartial('mining_results'); + } + + // public function actionCreate() + // { + // if(!$this->admin) return; + // $coin = new db_coins; + // if(isset($_POST['db_coins'])) + // { + // $coin->setAttributes($_POST['db_coins'], false); + // if($coin->save()) + // $this->redirect(array('index')); + // } + // $this->render('_form', array('coin'=>$coin, 'update'=>false)); + // } + // public function actionUpdate() + // { + // if(!$this->admin) return; + // $coin = getdbo('db_coins', getiparam('id')); + // if(isset($_POST['db_coins'])) + // { + // $coin->setAttributes($_POST['db_coins'], false); + // if($coin->save()) + // $this->redirect(array('index')); + // } + // $this->render('_form', array('coin'=>$coin, 'update'=>true)); + // } } - - - - - - - diff --git a/web/yaamp/modules/trading/index.php b/web/yaamp/modules/trading/index.php index d510b071a..b1bb1d751 100644 --- a/web/yaamp/modules/trading/index.php +++ b/web/yaamp/modules/trading/index.php @@ -1,5 +1,4 @@ getState('yaamp-algo'); JavascriptFile("/extensions/jqplot/jquery.jqplot.js"); @@ -10,8 +9,9 @@ $height = '240px'; $wallet = user()->getState('yaamp-wallet'); -if (!empty($wallet) && preg_match('/[^A-Za-z0-9]/', $wallet)) { - die; +if (!empty($wallet) && preg_match('/[^A-Za-z0-9]/', $wallet)) +{ + die; } $user = getuserparam($wallet); @@ -270,8 +270,3 @@ function user_hashrate_graph_init(data) end; - - - - - diff --git a/web/yaamp/modules/trading/mining_results.php b/web/yaamp/modules/trading/mining_results.php index 192c949f6..356d78ae8 100644 --- a/web/yaamp/modules/trading/mining_results.php +++ b/web/yaamp/modules/trading/mining_results.php @@ -1,97 +1,100 @@ "; - echo "
$title
"; - echo "
"; + echo "
"; + echo "
$title
"; + echo "
"; } $algo = user()->getState('yaamp-algo'); $total_rate = Itoa2(yaamp_pool_rate()); -$list = getdbolist('db_coins', "enable and algo=:algo order by index_avg desc", array(':algo'=>$algo)); +$list = getdbolist('db_coins', "enable and algo=:algo order by index_avg desc", array( + ':algo' => $algo +)); $count = count($list); -$worker = getdbocount('db_workers', "algo=:algo", array(':algo'=>$algo)); -$services = getdbolist('db_services', "algo=:algo order by price desc", array(':algo'=>$algo)); +$worker = getdbocount('db_workers', "algo=:algo", array( + ':algo' => $algo +)); +$services = getdbolist('db_services', "algo=:algo order by price desc", array( + ':algo' => $algo +)); //////////// - $table = array( - 'scrypt'=>0, - 'sha256'=>1, - 'scryptn'=>2, - 'x11'=>3, - 'x13'=>4, - 'x15'=>6, - 'nist5'=>7, - 'neoscrypt'=>8, - 'lyra2'=>9, + 'scrypt' => 0, + 'sha256' => 1, + 'scryptn' => 2, + 'x11' => 3, + 'x13' => 4, + 'x15' => 6, + 'nist5' => 7, + 'neoscrypt' => 8, + 'lyra2' => 9, ); $res = false; -if (isset($table[$algo]) && YAAMP_USE_NICEHASH_API) - $res = fetch_url("https://api.nicehash.com/api?method=orders.get&algo={$table[$algo]}"); +if (isset($table[$algo]) && YAAMP_USE_NICEHASH_API) $res = fetch_url("https://api.nicehash.com/api?method=orders.get&algo={$table[$algo]}"); -if(!$res) return; +if (!$res) return; $a = json_decode($res); -$niceorders = $a->result->orders; +$niceorders = $a + ->result->orders; $allorders = array(); -$nicehash = getdbosql('db_nicehash', "algo=:algo and orderid!=0", array(':algo'=>$algo)); -if($nicehash) +$nicehash = getdbosql('db_nicehash', "algo=:algo and orderid!=0", array( + ':algo' => $algo +)); +if ($nicehash) { - $index = $nicehash->price*1000+1; - - $allorders[$index] = array(); - $allorders[$index]['speed'] = $nicehash->accepted; - $allorders[$index]['price'] = $nicehash->price; - $allorders[$index]['workers'] = $nicehash->workers; - $allorders[$index]['btc'] = $nicehash->btc; - $allorders[$index]['limit'] = $nicehash->speed; - $allorders[$index]['me'] = true; + $index = $nicehash->price * 1000 + 1; + + $allorders[$index] = array(); + $allorders[$index]['speed'] = $nicehash->accepted; + $allorders[$index]['price'] = $nicehash->price; + $allorders[$index]['workers'] = $nicehash->workers; + $allorders[$index]['btc'] = $nicehash->btc; + $allorders[$index]['limit'] = $nicehash->speed; + $allorders[$index]['me'] = true; } -foreach($niceorders as $order) +foreach ($niceorders as $order) { - if(!$order->alive) continue; - if(!$order->workers) continue; - if(!$order->type == 0) continue; - - $index = $order->price*1000; - if(!isset($allorders[$index])) - { - $allorders[$index] = array(); - - $allorders[$index]['price'] = $order->price; - $allorders[$index]['speed'] = 0; - $allorders[$index]['workers'] = 0; - $allorders[$index]['btc'] = 0; - $allorders[$index]['limit'] = 0; - } - - $allorders[$index]['speed'] += $order->accepted_speed; - $allorders[$index]['workers'] += $order->workers; - //$allorders[$index]['btc'] += $order->btc_avail; - $allorders[$index]['limit'] += $order->limit_speed; + if (!$order->alive) continue; + if (!$order->workers) continue; + if (!$order->type == 0) continue; + + $index = $order->price * 1000; + if (!isset($allorders[$index])) + { + $allorders[$index] = array(); + + $allorders[$index]['price'] = $order->price; + $allorders[$index]['speed'] = 0; + $allorders[$index]['workers'] = 0; + $allorders[$index]['btc'] = 0; + $allorders[$index]['limit'] = 0; + } + + $allorders[$index]['speed'] += $order->accepted_speed; + $allorders[$index]['workers'] += $order->workers; + //$allorders[$index]['btc'] += $order->btc_avail; + $allorders[$index]['limit'] += $order->limit_speed; } $total_nicehash = 0; -foreach($allorders as $i=>$order) - $total_nicehash += $order['speed']; +foreach ($allorders as $i => $order) $total_nicehash += $order['speed']; function cmp($a, $b) { - return $a['price'] < $b['price']; + return $a['price'] < $b['price']; } usort($allorders, 'cmp'); - /////// - WriteBoxHeader("Mining $count coins at {$total_rate}h/s * with $worker miners ($algo)"); echo ""; @@ -108,43 +111,39 @@ function cmp($a, $b) echo ""; echo ""; -foreach($list as $coin) +foreach ($list as $coin) { - $name = substr($coin->name, 0, 12); - $difficulty = Itoa2($coin->difficulty, 3); - $price = bitcoinvaluetoa($coin->price); - $height = number_format($coin->block_height, 0, '.', ' '); - $pool_ttf = $coin->pool_ttf? sectoa2($coin->pool_ttf): ''; - $reward = round($coin->reward, 3); - $btcmhd = mbitcoinvaluetoa(yaamp_profitability($coin)); + $name = substr($coin->name, 0, 12); + $difficulty = Itoa2($coin->difficulty, 3); + $price = bitcoinvaluetoa($coin->price); + $height = number_format($coin->block_height, 0, '.', ' '); + $pool_ttf = $coin->pool_ttf ? sectoa2($coin->pool_ttf) : ''; + $reward = round($coin->reward, 3); + $btcmhd = mbitcoinvaluetoa(yaamp_profitability($coin)); - $pool_hash = yaamp_coin_rate($coin->id); - $pool_hash = $pool_hash? Itoa2($pool_hash).'h/s': ''; + $pool_hash = yaamp_coin_rate($coin->id); + $pool_hash = $pool_hash ? Itoa2($pool_hash) . 'h/s' : ''; - show_orders($allorders, $services, $btcmhd); - show_services($services, $btcmhd); + show_orders($allorders, $services, $btcmhd); + show_services($services, $btcmhd); - if(!$coin->auto_ready) - echo ""; - else - echo ""; + if (!$coin->auto_ready) echo ""; + else echo ""; - echo ""; - echo ""; + echo ""; + echo ""; - echo ""; - echo ""; + echo ""; + echo ""; - if(!empty($coin->errors)) - echo ""; - else - echo ""; + if (!empty($coin->errors)) echo ""; + else echo ""; - echo ""; + echo ""; - echo ""; - echo ""; - echo ""; + echo ""; + echo ""; + echo ""; } show_orders($allorders, $services); @@ -153,23 +152,28 @@ function cmp($a, $b) echo "
$name$name$reward $coin->symbol$difficulty$reward $coin->symbol$difficulty$height$height$height$height$pool_ttf$pool_ttf$pool_hash$btcmhd
$pool_hash$btcmhd

"; ///////////////////////////////////////////////////////////////////////////////////////////// - $target = yaamp_hashrate_constant($algo); $interval = yaamp_hashrate_step(); -$delay = time()-$interval; +$delay = time() - $interval; $version = 'NiceHash/1.0.0'; $hashrate = dboscalar("select sum(difficulty) * $target / $interval / 1000 from shares where valid and time>$delay and - workerid in (select id from workers where algo=:algo and version='$version')", array(':algo'=>$algo)); + workerid in (select id from workers where algo=:algo and version='$version')", array( + ':algo' => $algo +)); $invalid = dboscalar("select sum(difficulty) * $target / $interval / 1000 from shares where not valid and time>$delay and - workerid in (select id from workers where algo=:algo and version='$version')", array(':algo'=>$algo)); + workerid in (select id from workers where algo=:algo and version='$version')", array( + ':algo' => $algo +)); -$count = getdbocount('db_workers', "algo=:algo and version='$version'", array(':algo'=>$algo)); +$count = getdbocount('db_workers', "algo=:algo and version='$version'", array( + ':algo' => $algo +)); -$percent = $total_nicehash&&$hashrate? round($hashrate * 100 / $total_nicehash / 1000000000, 2).'%': ''; +$percent = $total_nicehash && $hashrate ? round($hashrate * 100 / $total_nicehash / 1000000000, 2) . '%' : ''; -$hashrate = $hashrate? Itoa2($hashrate).'h/s': ''; +$hashrate = $hashrate ? Itoa2($hashrate) . 'h/s' : ''; $version = substr($version, 0, 30); $total_nicehash = round($total_nicehash, 3); @@ -181,68 +185,65 @@ function cmp($a, $b) echo "

"; ////////////////////////////////////////////////////////////////////////////////////////////////// - -function show_services(&$services, $btcmhd=0) +function show_services(&$services, $btcmhd = 0) { - if(!controller()->admin || !$services) return; - foreach($services as $i=>$service) - { - if($service->price*1000 < $btcmhd) continue; - $service_btcmhd = mbitcoinvaluetoa($service->price*1000); - - echo ""; - echo ""; - echo "$service->name"; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo "$service_btcmhd"; - echo ""; - - unset($services[$i]); - } + if (!controller()->admin || !$services) return; + foreach ($services as $i => $service) + { + if ($service->price * 1000 < $btcmhd) continue; + $service_btcmhd = mbitcoinvaluetoa($service->price * 1000); + + echo ""; + echo ""; + echo "$service->name"; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo "$service_btcmhd"; + echo ""; + + unset($services[$i]); + } } -function show_orders(&$allorders, &$services, $btcmhd=0) +function show_orders(&$allorders, &$services, $btcmhd = 0) { - $algo = user()->getState('yaamp-algo'); - $price = controller()->memcache->get_database_scalar("current_price-$algo", - "select price from hashrate where algo=:algo order by time desc limit 1", array(':algo'=>$algo)); - - foreach($allorders as $i=>$order) - { - if($order['price'] < $btcmhd) continue; - if($order['workers'] <= 0 && !isset($order['me'])) continue; - if($order['speed'] <= 0 && !isset($order['me'])) continue; - - $service_btcmhd = mbitcoinvaluetoa($order['price']); - $hash = Itoa2($order['speed']*1000000000).'h/s'; - $limit = Itoa2($order['limit']*1000000000).'h/s'; - $btc = round($order['btc']*1000, 1); - $profit = $price>$service_btcmhd? round(($price-$service_btcmhd)/$service_btcmhd*100).'%': ''; - - show_services($services, $service_btcmhd); - - if(isset($order['me'])) - echo ""; - else - echo ""; - - echo ""; - echo "$hash ({$order['workers']})"; - echo "$limit"; - echo "$btc"; - echo "$profit"; - echo ""; - echo ""; - echo "$service_btcmhd"; - echo ""; - - unset($allorders[$i]); - } + $algo = user()->getState('yaamp-algo'); + $price = controller() + ->memcache + ->get_database_scalar("current_price-$algo", "select price from hashrate where algo=:algo order by time desc limit 1", array( + ':algo' => $algo + )); + + foreach ($allorders as $i => $order) + { + if ($order['price'] < $btcmhd) continue; + if ($order['workers'] <= 0 && !isset($order['me'])) continue; + if ($order['speed'] <= 0 && !isset($order['me'])) continue; + + $service_btcmhd = mbitcoinvaluetoa($order['price']); + $hash = Itoa2($order['speed'] * 1000000000) . 'h/s'; + $limit = Itoa2($order['limit'] * 1000000000) . 'h/s'; + $btc = round($order['btc'] * 1000, 1); + $profit = $price > $service_btcmhd ? round(($price - $service_btcmhd) / $service_btcmhd * 100) . '%' : ''; + + show_services($services, $service_btcmhd); + + if (isset($order['me'])) echo ""; + else echo ""; + + echo ""; + echo "$hash ({$order['workers']})"; + echo "$limit"; + echo "$btc"; + echo "$profit"; + echo ""; + echo ""; + echo "$service_btcmhd"; + echo ""; + + unset($allorders[$i]); + } } - - - diff --git a/web/yaamp/ui/css/main.css b/web/yaamp/ui/css/main.css index 747860ee9..0737f4933 100644 --- a/web/yaamp/ui/css/main.css +++ b/web/yaamp/ui/css/main.css @@ -225,3 +225,21 @@ hr color: blue; } + +.social-icons { + text-align: center; + } +.social-icons li { + display:inline-block; + list-style-type:none; + -webkit-user-select:none; + -moz-user-select:none; + } +.social-icons li a { + border-bottom: none; + } +.social-icons li img { + width:70px; + height:70px; + margin-right: 20px; +} diff --git a/web/yaamp/ui/lib/pageheader.php b/web/yaamp/ui/lib/pageheader.php index 4b7c3dd7a..09138d883 100644 --- a/web/yaamp/ui/lib/pageheader.php +++ b/web/yaamp/ui/lib/pageheader.php @@ -1,20 +1,20 @@ - - - + + + - - - + + + - - + + pageTitle) ? YAAMP_SITE_NAME : YAAMP_SITE_NAME." - ".$this->pageTitle; -echo ''.$pageTitle.''; + +$pageTitle = empty($this->pageTitle) ? YAAMP_SITE_NAME : YAAMP_SITE_NAME . " - " . $this->pageTitle; +echo '' . $pageTitle . ''; echo CHtml::cssFile("/extensions/jquery/themes/ui-lightness/jquery-ui.css"); echo CHtml::cssFile('/yaamp/ui/css/main.css'); diff --git a/web/yaamp/ui/main.php b/web/yaamp/ui/main.php index 693791d2f..b7c4f0542 100644 --- a/web/yaamp/ui/main.php +++ b/web/yaamp/ui/main.php @@ -4,9 +4,9 @@ echo << - - - + + + @@ -15,14 +15,14 @@ - - + + END; -$pageTitle = empty($this->pageTitle) ? YAAMP_SITE_NAME : YAAMP_SITE_NAME." - ".$this->pageTitle; +$pageTitle = empty($this->pageTitle) ? YAAMP_SITE_NAME : YAAMP_SITE_NAME . " - " . $this->pageTitle; -echo ''.$pageTitle.''; +echo '' . $pageTitle . ''; echo CHtml::cssFile("/extensions/jquery/themes/ui-lightness/jquery-ui.css"); echo CHtml::cssFile('/yaamp/ui/css/main.css'); @@ -71,79 +71,82 @@ function showItemHeader($selected, $url, $name) { - if($selected) $selected_text = "class='selected'"; - else $selected_text = ''; + if ($selected) + $selected_text = "class='selected'"; + else + $selected_text = ''; - echo "$name"; - echo " "; + echo "$name"; + echo " "; } function showPageHeader() { - echo '
'; - echo '
'; + echo '
'; + echo '
'; - echo '  '.YAAMP_SITE_NAME.''; + echo '  ' . YAAMP_SITE_NAME . ''; - $action = controller()->action->id; - $wallet = user()->getState('yaamp-wallet'); - $ad = isset($_GET['address']); + $action = controller()->action->id; + $wallet = user()->getState('yaamp-wallet'); + $ad = isset($_GET['address']); - showItemHeader(controller()->id=='site' && $action=='index' && !$ad, '/', 'Home'); - showItemHeader($action=='mining', '/site/mining', 'Pool'); - showItemHeader(controller()->id=='site'&&($action=='index' || $action=='wallet') && $ad, "/?address=$wallet", 'Wallet'); - showItemHeader(controller()->id=='stats', '/stats', 'Graphs'); - showItemHeader($action=='miners', '/site/miners', 'Miners'); - if (YIIMP_PUBLIC_EXPLORER) - showItemHeader(controller()->id=='explorer', '/explorer', 'Explorers'); + showItemHeader(controller()->id == 'site' && $action == 'index' && !$ad, '/', 'Home'); + showItemHeader($action == 'mining', '/site/mining', 'Pool'); + showItemHeader(controller()->id == 'site' && ($action == 'index' || $action == 'wallet') && $ad, "/?address=$wallet", 'Wallet'); + showItemHeader(controller()->id == 'stats', '/stats', 'Graphs'); + showItemHeader($action == 'miners', '/site/miners', 'Miners'); + if (YIIMP_PUBLIC_EXPLORER) + showItemHeader(controller()->id == 'explorer', '/explorer', 'Explorers'); - if (YIIMP_PUBLIC_BENCHMARK) - showItemHeader(controller()->id=='bench', '/bench', 'Benchs'); + if (YIIMP_PUBLIC_BENCHMARK) + showItemHeader(controller()->id == 'bench', '/bench', 'Benchs'); - if (YAAMP_RENTAL) - showItemHeader(controller()->id=='renting', '/renting', 'Rental'); + if (YAAMP_RENTAL) + showItemHeader(controller()->id == 'renting', '/renting', 'Rental'); - if(controller()->admin) - { - if (isAdminIP($_SERVER['REMOTE_ADDR']) === false) - debuglog("admin {$_SERVER['REMOTE_ADDR']}"); + if (controller()->admin) { + if (isAdminIP($_SERVER['REMOTE_ADDR']) === false) + debuglog("admin {$_SERVER['REMOTE_ADDR']}"); - showItemHeader(controller()->id=='coin', '/coin', 'Coins'); - showItemHeader($action=='common', '/site/common', 'Dashboard'); - showItemHeader(controller()->id=='site'&&$action=='admin', "/site/admin", 'Wallets'); + showItemHeader(controller()->id == 'coin', '/coin', 'Coins'); + showItemHeader($action == 'common', '/site/common', 'Dashboard'); + showItemHeader(controller()->id == 'site' && $action == 'admin', "/site/admin", 'Wallets'); - if (YAAMP_RENTAL) - showItemHeader(controller()->id=='renting' && $action=='admin', '/renting/admin', 'Jobs'); + if (YAAMP_RENTAL) + showItemHeader(controller()->id == 'renting' && $action == 'admin', '/renting/admin', 'Jobs'); - if (YAAMP_ALLOW_EXCHANGE) - showItemHeader(controller()->id=='trading', '/trading', 'Trading'); + if (YAAMP_ALLOW_EXCHANGE) + showItemHeader(controller()->id == 'trading', '/trading', 'Trading'); - if (YAAMP_USE_NICEHASH_API) - showItemHeader(controller()->id=='nicehash', '/nicehash', 'Nicehash'); - } + if (YAAMP_USE_NICEHASH_API) + showItemHeader(controller()->id == 'nicehash', '/nicehash', 'Nicehash'); + } - echo ''; + echo ''; - $mining = getdbosql('db_mining'); - $nextpayment = date('H:i T', $mining->last_payout+YAAMP_PAYMENTS_FREQ); - $eta = ($mining->last_payout+YAAMP_PAYMENTS_FREQ) - time(); - $eta_mn = 'in '.round($eta / 60).' minutes'; + $mining = getdbosql('db_mining'); + $nextpayment = date('H:i T', $mining->last_payout + YAAMP_PAYMENTS_FREQ); + // $nextpayment = date('H:i', $mining->last_payout+YAAMP_PAYMENTS_FREQ) . ' UTC (US)'; + // define('UTCEUR', 7200); + // $nextpaymentEUR = date('H:i', $mining->last_payout+YAAMP_PAYMENTS_FREQ+UTCEUR); // . ' UTC+2 (EUR)'; + $eta = ($mining->last_payout + YAAMP_PAYMENTS_FREQ) - time(); + $eta_mn = 'in ' . round($eta / 60) . ' minutes'; - echo 'Next Payout: '.$nextpayment.''; + echo 'Next Payout: ' . $nextpayment . ''; + // echo 'Next Payout: '.$nextpayment.' / '.$nextpaymentEUR.''; + // echo 'Next Payout: '.$nextpayment.' UTC (US) / '.$nextpaymentEUR.' UTC+2 (EUR)'; - echo "
"; - echo "
"; + echo "
"; + echo "
"; } function showPageFooter() { - echo ''; } - -