From c0d9d74729ffd35c25e52a755d4103e8ce3416e6 Mon Sep 17 00:00:00 2001 From: djm34 Date: Thu, 11 Dec 2014 23:11:42 +0100 Subject: [PATCH 01/27] Lyra2RE lyra2/skein256/keccak256/groestl256/blake256 (+ logic for precalulation) --- algorithm.c | 56 +++- algorithm/Lyra2.c | 208 ++++++++++++ algorithm/Lyra2.h | 50 +++ algorithm/Lyra2RE.c | 169 ++++++++++ algorithm/Lyra2RE.h | 10 + algorithm/Sponge.c | 742 +++++++++++++++++++++++++++++++++++++++++++ algorithm/Sponge.h | 108 +++++++ driver-opencl.c | 8 +- example.bat | 9 + findnonce.c | 139 ++++++++ findnonce.h | 2 +- kernel/Lyra2.cl | 145 +++++++++ kernel/Lyra2RE.cl | 392 +++++++++++++++++++++++ kernel/blake256.cl | 96 ++++++ kernel/groestl256.cl | 415 ++++++++++++++++++++++++ kernel/keccak1600.cl | 84 +++++ kernel/skein256.cl | 107 +++++++ miner.h | 1 + sgminer.c | 2 + 19 files changed, 2738 insertions(+), 5 deletions(-) create mode 100644 algorithm/Lyra2.c create mode 100644 algorithm/Lyra2.h create mode 100644 algorithm/Lyra2RE.c create mode 100644 algorithm/Lyra2RE.h create mode 100644 algorithm/Sponge.c create mode 100644 algorithm/Sponge.h create mode 100644 example.bat create mode 100644 kernel/Lyra2.cl create mode 100644 kernel/Lyra2RE.cl create mode 100644 kernel/blake256.cl create mode 100644 kernel/groestl256.cl create mode 100644 kernel/keccak1600.cl create mode 100644 kernel/skein256.cl diff --git a/algorithm.c b/algorithm.c index 2f5494969..eba19f6f6 100644 --- a/algorithm.c +++ b/algorithm.c @@ -31,12 +31,13 @@ #include "algorithm/fresh.h" #include "algorithm/whirlcoin.h" #include "algorithm/neoscrypt.h" +#include "algorithm/Lyra2RE.h" #include "compat.h" #include #include - +bool opt_lyra; const char *algorithm_type_str[] = { "Unknown", "Scrypt", @@ -52,7 +53,8 @@ const char *algorithm_type_str[] = { "NIST", "Fresh", "Whirlcoin", - "Neoscrypt" + "Neoscrypt", + "Lyra2RE" }; void sha256(const unsigned char *message, unsigned int len, unsigned char *digest) @@ -211,6 +213,52 @@ static cl_int queue_sph_kernel(struct __clState *clState, struct _dev_blk_ctx *b return status; } +static cl_int queue_lyra2RE_kernel(struct __clState *clState, struct _dev_blk_ctx *blk, __maybe_unused cl_uint threads) +{ + cl_kernel *kernel; + unsigned int num; + cl_int status = 0; + cl_uint le_target; + + le_target = *(cl_uint *)(blk->work->device_target + 28); +// le_target = *(cl_ulong *)(blk->work->device_target + 24); + flip80(clState->cldata, blk->work->data); + status = clEnqueueWriteBuffer(clState->commandQueue, clState->CLbuffer0, true, 0, 80, clState->cldata, 0, NULL, NULL); + + // blake - search + kernel = &clState->kernel; + num = 0; +// CL_SET_ARG(clState->CLbuffer0); + CL_SET_ARG(clState->padbuffer8); + CL_SET_ARG(blk->work->blk.ctx_a); + CL_SET_ARG(blk->work->blk.ctx_b); + CL_SET_ARG(blk->work->blk.ctx_c); + CL_SET_ARG(blk->work->blk.ctx_d); + CL_SET_ARG(blk->work->blk.ctx_e); + CL_SET_ARG(blk->work->blk.ctx_f); + CL_SET_ARG(blk->work->blk.ctx_g); + CL_SET_ARG(blk->work->blk.ctx_h); + CL_SET_ARG(blk->work->blk.cty_a); + CL_SET_ARG(blk->work->blk.cty_b); + CL_SET_ARG(blk->work->blk.cty_c); + + // bmw - search1 + kernel = clState->extra_kernels; + CL_SET_ARG_0(clState->padbuffer8); + // groestl - search2 + CL_NEXTKERNEL_SET_ARG_0(clState->padbuffer8); + // skein - search3 + CL_NEXTKERNEL_SET_ARG_0(clState->padbuffer8); + // jh - search4 + num = 0; + CL_NEXTKERNEL_SET_ARG(clState->padbuffer8); + CL_SET_ARG(clState->outputBuffer); + CL_SET_ARG(le_target); + + return status; +} + + static cl_int queue_darkcoin_mod_kernel(struct __clState *clState, struct _dev_blk_ctx *blk, __maybe_unused cl_uint threads) { cl_kernel *kernel; @@ -705,6 +753,8 @@ static algorithm_settings_t algos[] = { { "fresh", ALGO_FRESH, "", 1, 256, 256, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 4, 4 * 16 * 4194304, 0, fresh_regenhash, queue_fresh_kernel, gen_hash, NULL}, + { "Lyra2RE", ALGO_LYRA2RE, "", 1, 64, 64, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 4,2 * 8 * 4194304 , 0, lyra2re_regenhash, queue_lyra2RE_kernel, gen_hash, NULL}, + // kernels starting from this will have difficulty calculated by using fuguecoin algorithm #define A_FUGUE(a, b, c) \ { a, ALGO_FUGUE, "", 1, 256, 256, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 0, 0, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, b, queue_sph_kernel, c, NULL} @@ -811,7 +861,7 @@ void set_algorithm(algorithm_t* algo, const char* newname_alias) // use old nfactor if it was previously set and is different than the one set by alias if ((old_nfactor > 0) && (old_nfactor != nfactor)) nfactor = old_nfactor; - + if (algo->type == ALGO_LYRA2RE) {opt_lyra = true;} set_algorithm_nfactor(algo, nfactor); //reapply kernelfile if was set diff --git a/algorithm/Lyra2.c b/algorithm/Lyra2.c new file mode 100644 index 000000000..412aa1f68 --- /dev/null +++ b/algorithm/Lyra2.c @@ -0,0 +1,208 @@ +/** + * Implementation of 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. + */ +#include +#include +#include +#include +#include "Lyra2.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 LYRA2(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 + 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_BYTES; //goes to next block of pad(pwd || salt || basil) + } + + //Initializes M[0] and M[1] + reducedSqueezeRow0(state, memMatrix[0]); //The locally copied password is most likely overwritten here + reducedDuplexRow1(state, memMatrix[0], memMatrix[1]); + + do { + //M[row] = rand; //M[row*] = M[row*] XOR rotW(rand) + reducedDuplexRowSetup(state, memMatrix[prev], memMatrix[rowa], memMatrix[row]); + + + //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]); + + //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/algorithm/Lyra2.h b/algorithm/Lyra2.h new file mode 100644 index 000000000..13c7dbd3b --- /dev/null +++ b/algorithm/Lyra2.h @@ -0,0 +1,50 @@ +/** + * 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 LYRA2_H_ +#define LYRA2_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 8 //512 bits (=64 bytes, =8 uint64_t) +#define BLOCK_LEN_BLAKE2_SAFE_BYTES (BLOCK_LEN_BLAKE2_SAFE_INT64 * 8) //same as above, in bytes + + +#ifdef BLOCK_LEN_BITS + #define BLOCK_LEN_INT64 (BLOCK_LEN_BITS/64) //Block length: 768 bits (=96 bytes, =12 uint64_t) + #define BLOCK_LEN_BYTES (BLOCK_LEN_BITS/8) //Block length, in bytes +#else //default block lenght: 768 bits + #define BLOCK_LEN_INT64 12 //Block length: 768 bits (=96 bytes, =12 uint64_t) + #define BLOCK_LEN_BYTES (BLOCK_LEN_INT64 * 8) //Block length, in bytes +#endif + +#ifndef N_COLS + #define N_COLS 8 //Number of columns in the memory matrix: fixed to 64 by default +#endif + +#define ROW_LEN_INT64 (BLOCK_LEN_INT64 * N_COLS) //Total length of a row: N_COLS blocks +#define ROW_LEN_BYTES (ROW_LEN_INT64 * 8) //Number of bytes per row + + +int LYRA2(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); + +#endif /* LYRA2_H_ */ diff --git a/algorithm/Lyra2RE.c b/algorithm/Lyra2RE.c new file mode 100644 index 000000000..24b8210c6 --- /dev/null +++ b/algorithm/Lyra2RE.c @@ -0,0 +1,169 @@ +/*- + * Copyright 2014 James Lovejoy + * Copyright 2014 phm + * 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 "config.h" +#include "miner.h" + +#include +#include +#include + +#include "sph/sph_blake.h" +#include "sph/sph_groestl.h" +#include "sph/sph_skein.h" +#include "sph/sph_keccak.h" +#include "Lyra2.h" + +/* + * Encode a length len/4 vector of (uint32_t) into a length len vector of + * (unsigned char) in big-endian form. Assumes len is a multiple of 4. + */ +static inline void +be32enc_vect(uint32_t *dst, const uint32_t *src, uint32_t len) +{ + uint32_t i; + + for (i = 0; i < len; i++) + dst[i] = htobe32(src[i]); +} + + +inline void lyra2rehash(void *state, const void *input) +{ + sph_blake256_context ctx_blake; + sph_groestl256_context ctx_groestl; + sph_keccak256_context ctx_keccak; + sph_skein256_context ctx_skein; + + uint32_t hashA[8], hashB[8]; + + sph_blake256_init(&ctx_blake); + sph_blake256 (&ctx_blake, input, 80); + sph_blake256_close (&ctx_blake, hashA); + + + + + sph_keccak256_init(&ctx_keccak); + sph_keccak256 (&ctx_keccak,hashA, 32); + sph_keccak256_close(&ctx_keccak, hashB); + + LYRA2(hashA, 32, hashB, 32, hashB, 32, 1, 8, 8); + + + sph_skein256_init(&ctx_skein); + sph_skein256 (&ctx_skein, hashA, 32); + sph_skein256_close(&ctx_skein, hashB); + + + sph_groestl256_init(&ctx_groestl); + sph_groestl256 (&ctx_groestl, hashB, 32); + sph_groestl256_close(&ctx_groestl, hashA); + +//printf("cpu hash %08x %08x %08x %08x\n",hashA[0],hashA[1],hashA[2],hashA[3]); + + memcpy(state, hashA, 32); +} + +static const uint32_t diff1targ = 0x0000ffff; + + +/* Used externally as confirmation of correct OCL code */ +int lyra2re_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t nonce) +{ + uint32_t tmp_hash7, Htarg = le32toh(((const uint32_t *)ptarget)[7]); + uint32_t data[20], ohash[8]; + + be32enc_vect(data, (const uint32_t *)pdata, 19); + data[19] = htobe32(nonce); + lyra2rehash(ohash, data); + tmp_hash7 = be32toh(ohash[7]); + + applog(LOG_DEBUG, "htarget %08lx diff1 %08lx hash %08lx", + (long unsigned int)Htarg, + (long unsigned int)diff1targ, + (long unsigned int)tmp_hash7); + if (tmp_hash7 > diff1targ) + return -1; + if (tmp_hash7 > Htarg) + return 0; + return 1; +} + +void lyra2re_regenhash(struct work *work) +{ + uint32_t data[20]; + uint32_t *nonce = (uint32_t *)(work->data + 76); + uint32_t *ohash = (uint32_t *)(work->hash); + + be32enc_vect(data, (const uint32_t *)work->data, 19); + data[19] = htobe32(*nonce); + lyra2rehash(ohash, data); +} + +bool scanhash_lyra2re(struct thr_info *thr, const unsigned char __maybe_unused *pmidstate, + unsigned char *pdata, unsigned char __maybe_unused *phash1, + unsigned char __maybe_unused *phash, const unsigned char *ptarget, + uint32_t max_nonce, uint32_t *last_nonce, uint32_t n) +{ + uint32_t *nonce = (uint32_t *)(pdata + 76); + uint32_t data[20]; + uint32_t tmp_hash7; + uint32_t Htarg = le32toh(((const uint32_t *)ptarget)[7]); + bool ret = false; + + be32enc_vect(data, (const uint32_t *)pdata, 19); + + while(1) { + uint32_t ostate[8]; + + *nonce = ++n; + data[19] = (n); + lyra2rehash(ostate, data); + tmp_hash7 = (ostate[7]); + + applog(LOG_INFO, "data7 %08lx", + (long unsigned int)data[7]); + + if (unlikely(tmp_hash7 <= Htarg)) { + ((uint32_t *)pdata)[19] = htobe32(n); + *last_nonce = n; + ret = true; + break; + } + + if (unlikely((n >= max_nonce) || thr->work_restart)) { + *last_nonce = n; + break; + } + } + + return ret; +} + + + diff --git a/algorithm/Lyra2RE.h b/algorithm/Lyra2RE.h new file mode 100644 index 000000000..8a58e7471 --- /dev/null +++ b/algorithm/Lyra2RE.h @@ -0,0 +1,10 @@ +#ifndef LYRA2RE_H +#define LYRA2RE_H + +#include "miner.h" + +extern int lyra2re_test(unsigned char *pdata, const unsigned char *ptarget, + uint32_t nonce); +extern void lyra2re_regenhash(struct work *work); + +#endif /* LYRA2RE_H */ diff --git a/algorithm/Sponge.c b/algorithm/Sponge.c new file mode 100644 index 000000000..0aa5aace3 --- /dev/null +++ b/algorithm/Sponge.c @@ -0,0 +1,742 @@ +/** + * A simple implementation of Blake2b's internal permutation + * in the form of a sponge. + * + * 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. + */ +#include +#include +#include +#include "Sponge.h" +#include "Lyra2.h" + + + +/** + * Initializes the Sponge State. The first 512 bits are set to zeros and the remainder + * receive Blake2b's IV as per Blake2b's specification. Note: Even though sponges + * typically have their internal state initialized with zeros, Blake2b's G function + * has a fixed point: if the internal state and message are both filled with zeros. the + * resulting permutation will always be a block filled with zeros; this happens because + * Blake2b does not use the constants originally employed in Blake2 inside its G function, + * relying on the IV for avoiding possible fixed points. + * + * @param state The 1024-bit array to be initialized + */ +inline void initState(uint64_t state[/*16*/]) { + //First 512 bis are zeros + memset(state, 0, 64); + //Remainder BLOCK_LEN_BLAKE2_SAFE_BYTES are reserved to the IV + state[8] = blake2b_IV[0]; + state[9] = blake2b_IV[1]; + state[10] = blake2b_IV[2]; + state[11] = blake2b_IV[3]; + state[12] = blake2b_IV[4]; + state[13] = blake2b_IV[5]; + state[14] = blake2b_IV[6]; + state[15] = blake2b_IV[7]; +} + +/** + * Execute Blake2b's G function, with all 12 rounds. + * + * @param v A 1024-bit (16 uint64_t) array to be processed by Blake2b's G function + */ +inline static void blake2bLyra(uint64_t *v) { + ROUND_LYRA(0); + ROUND_LYRA(1); + ROUND_LYRA(2); + ROUND_LYRA(3); + ROUND_LYRA(4); + ROUND_LYRA(5); + ROUND_LYRA(6); + ROUND_LYRA(7); + ROUND_LYRA(8); + ROUND_LYRA(9); + ROUND_LYRA(10); + ROUND_LYRA(11); +} + +/** + * Executes a reduced version of Blake2b's G function with only one round + * @param v A 1024-bit (16 uint64_t) array to be processed by Blake2b's G function + */ +inline static void reducedBlake2bLyra(uint64_t *v) { + ROUND_LYRA(0); +} + +/** + * Performs a squeeze operation, using Blake2b's G function as the + * internal permutation + * + * @param state The current state of the sponge + * @param out Array that will receive the data squeezed + * @param len The number of bytes to be squeezed into the "out" array + */ +inline void squeeze(uint64_t *state, byte *out, unsigned int len) { + int fullBlocks = len / BLOCK_LEN_BYTES; + byte *ptr = out; + int i; + //Squeezes full blocks + for (i = 0; i < fullBlocks; i++) { + memcpy(ptr, state, BLOCK_LEN_BYTES); + blake2bLyra(state); + ptr += BLOCK_LEN_BYTES; + } + + //Squeezes remaining bytes + memcpy(ptr, state, (len % BLOCK_LEN_BYTES)); +} + +/** + * Performs an absorb operation for a single block (BLOCK_LEN_INT64 words + * of type uint64_t), using Blake2b's G function as the internal permutation + * + * @param state The current state of the sponge + * @param in The block to be absorbed (BLOCK_LEN_INT64 words) + */ +inline void absorbBlock(uint64_t *state, const uint64_t *in) { + //XORs the first BLOCK_LEN_INT64 words of "in" with the current state + state[0] ^= in[0]; + state[1] ^= in[1]; + state[2] ^= in[2]; + state[3] ^= in[3]; + state[4] ^= in[4]; + state[5] ^= in[5]; + state[6] ^= in[6]; + state[7] ^= in[7]; + state[8] ^= in[8]; + state[9] ^= in[9]; + state[10] ^= in[10]; + state[11] ^= in[11]; + + //Applies the transformation f to the sponge's state + blake2bLyra(state); +} + +/** + * Performs an absorb operation for a single block (BLOCK_LEN_BLAKE2_SAFE_INT64 + * words of type uint64_t), using Blake2b's G function as the internal permutation + * + * @param state The current state of the sponge + * @param in The block to be absorbed (BLOCK_LEN_BLAKE2_SAFE_INT64 words) + */ +inline void absorbBlockBlake2Safe(uint64_t *state, const uint64_t *in) { + //XORs the first BLOCK_LEN_BLAKE2_SAFE_INT64 words of "in" with the current state + state[0] ^= in[0]; + state[1] ^= in[1]; + state[2] ^= in[2]; + state[3] ^= in[3]; + state[4] ^= in[4]; + state[5] ^= in[5]; + state[6] ^= in[6]; + state[7] ^= in[7]; + + //Applies the transformation f to the sponge's state + blake2bLyra(state); +} + +/** + * Performs a reduced squeeze operation for a single row, from the highest to + * the lowest index, using the reduced-round Blake2b's G function as the + * internal permutation + * + * @param state The current state of the sponge + * @param rowOut Row to receive the data squeezed + */ +inline void reducedSqueezeRow0(uint64_t* state, uint64_t* rowOut) { + uint64_t* ptrWord = rowOut + (N_COLS-1)*BLOCK_LEN_INT64; //In Lyra2: pointer to M[0][C-1] + int i; + //M[row][C-1-col] = H.reduced_squeeze() + for (i = 0; i < N_COLS; i++) { + ptrWord[0] = state[0]; + ptrWord[1] = state[1]; + ptrWord[2] = state[2]; + ptrWord[3] = state[3]; + ptrWord[4] = state[4]; + ptrWord[5] = state[5]; + ptrWord[6] = state[6]; + ptrWord[7] = state[7]; + ptrWord[8] = state[8]; + ptrWord[9] = state[9]; + ptrWord[10] = state[10]; + ptrWord[11] = state[11]; + + //Goes to next block (column) that will receive the squeezed data + ptrWord -= BLOCK_LEN_INT64; + + //Applies the reduced-round transformation f to the sponge's state + reducedBlake2bLyra(state); + } +} + +/** + * Performs a reduced duplex operation for a single row, from the highest to + * the lowest index, using the reduced-round Blake2b's G function as the + * internal permutation + * + * @param state The current state of the sponge + * @param rowIn Row to feed the sponge + * @param rowOut Row to receive the sponge's output + */ +inline void reducedDuplexRow1(uint64_t *state, uint64_t *rowIn, uint64_t *rowOut) { + uint64_t* ptrWordIn = rowIn; //In Lyra2: pointer to prev + uint64_t* ptrWordOut = rowOut + (N_COLS-1)*BLOCK_LEN_INT64; //In Lyra2: pointer to row + int i; + + for (i = 0; i < N_COLS; i++) { + + //Absorbing "M[prev][col]" + state[0] ^= (ptrWordIn[0]); + state[1] ^= (ptrWordIn[1]); + state[2] ^= (ptrWordIn[2]); + state[3] ^= (ptrWordIn[3]); + state[4] ^= (ptrWordIn[4]); + state[5] ^= (ptrWordIn[5]); + state[6] ^= (ptrWordIn[6]); + state[7] ^= (ptrWordIn[7]); + state[8] ^= (ptrWordIn[8]); + state[9] ^= (ptrWordIn[9]); + state[10] ^= (ptrWordIn[10]); + state[11] ^= (ptrWordIn[11]); + + //Applies the reduced-round transformation f to the sponge's state + reducedBlake2bLyra(state); + + //M[row][C-1-col] = M[prev][col] XOR rand + ptrWordOut[0] = ptrWordIn[0] ^ state[0]; + ptrWordOut[1] = ptrWordIn[1] ^ state[1]; + ptrWordOut[2] = ptrWordIn[2] ^ state[2]; + ptrWordOut[3] = ptrWordIn[3] ^ state[3]; + ptrWordOut[4] = ptrWordIn[4] ^ state[4]; + ptrWordOut[5] = ptrWordIn[5] ^ state[5]; + ptrWordOut[6] = ptrWordIn[6] ^ state[6]; + ptrWordOut[7] = ptrWordIn[7] ^ state[7]; + ptrWordOut[8] = ptrWordIn[8] ^ state[8]; + ptrWordOut[9] = ptrWordIn[9] ^ state[9]; + ptrWordOut[10] = ptrWordIn[10] ^ state[10]; + ptrWordOut[11] = ptrWordIn[11] ^ state[11]; + + + //Input: next column (i.e., next block in sequence) + ptrWordIn += BLOCK_LEN_INT64; + //Output: goes to previous column + ptrWordOut -= BLOCK_LEN_INT64; + } +} + +/** + * Performs a duplexing operation over "M[rowInOut][col] [+] M[rowIn][col]" (i.e., + * the wordwise addition of two columns, ignoring carries between words). The + * output of this operation, "rand", is then used to make + * "M[rowOut][(N_COLS-1)-col] = M[rowIn][col] XOR rand" and + * "M[rowInOut][col] = M[rowInOut][col] XOR rotW(rand)", where rotW is a 64-bit + * rotation to the left and N_COLS is a system parameter. + * + * @param state The current state of the sponge + * @param rowIn Row used only as input + * @param rowInOut Row used as input and to receive output after rotation + * @param rowOut Row receiving the output + * + */ +inline void reducedDuplexRowSetup(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOut, uint64_t *rowOut) { + uint64_t* ptrWordIn = rowIn; //In Lyra2: pointer to prev + uint64_t* ptrWordInOut = rowInOut; //In Lyra2: pointer to row* + uint64_t* ptrWordOut = rowOut + (N_COLS-1)*BLOCK_LEN_INT64; //In Lyra2: pointer to row + int i; + + for (i = 0; i < N_COLS; i++) { + //Absorbing "M[prev] [+] M[row*]" + state[0] ^= (ptrWordIn[0] + ptrWordInOut[0]); + state[1] ^= (ptrWordIn[1] + ptrWordInOut[1]); + state[2] ^= (ptrWordIn[2] + ptrWordInOut[2]); + state[3] ^= (ptrWordIn[3] + ptrWordInOut[3]); + state[4] ^= (ptrWordIn[4] + ptrWordInOut[4]); + state[5] ^= (ptrWordIn[5] + ptrWordInOut[5]); + state[6] ^= (ptrWordIn[6] + ptrWordInOut[6]); + state[7] ^= (ptrWordIn[7] + ptrWordInOut[7]); + state[8] ^= (ptrWordIn[8] + ptrWordInOut[8]); + state[9] ^= (ptrWordIn[9] + ptrWordInOut[9]); + state[10] ^= (ptrWordIn[10] + ptrWordInOut[10]); + state[11] ^= (ptrWordIn[11] + ptrWordInOut[11]); + + //Applies the reduced-round transformation f to the sponge's state + reducedBlake2bLyra(state); + + //M[row][col] = M[prev][col] XOR rand + ptrWordOut[0] = ptrWordIn[0] ^ state[0]; + ptrWordOut[1] = ptrWordIn[1] ^ state[1]; + ptrWordOut[2] = ptrWordIn[2] ^ state[2]; + ptrWordOut[3] = ptrWordIn[3] ^ state[3]; + ptrWordOut[4] = ptrWordIn[4] ^ state[4]; + ptrWordOut[5] = ptrWordIn[5] ^ state[5]; + ptrWordOut[6] = ptrWordIn[6] ^ state[6]; + ptrWordOut[7] = ptrWordIn[7] ^ state[7]; + ptrWordOut[8] = ptrWordIn[8] ^ state[8]; + ptrWordOut[9] = ptrWordIn[9] ^ state[9]; + ptrWordOut[10] = ptrWordIn[10] ^ state[10]; + ptrWordOut[11] = ptrWordIn[11] ^ state[11]; + + //M[row*][col] = M[row*][col] XOR rotW(rand) + ptrWordInOut[0] ^= state[11]; + ptrWordInOut[1] ^= state[0]; + ptrWordInOut[2] ^= state[1]; + ptrWordInOut[3] ^= state[2]; + ptrWordInOut[4] ^= state[3]; + ptrWordInOut[5] ^= state[4]; + ptrWordInOut[6] ^= state[5]; + ptrWordInOut[7] ^= state[6]; + ptrWordInOut[8] ^= state[7]; + ptrWordInOut[9] ^= state[8]; + ptrWordInOut[10] ^= state[9]; + ptrWordInOut[11] ^= state[10]; + + //Inputs: next column (i.e., next block in sequence) + ptrWordInOut += BLOCK_LEN_INT64; + ptrWordIn += BLOCK_LEN_INT64; + //Output: goes to previous column + ptrWordOut -= BLOCK_LEN_INT64; + } +} + +/** + * Performs a duplexing operation over "M[rowInOut][col] [+] M[rowIn][col]" (i.e., + * the wordwise addition of two columns, ignoring carries between words). The + * output of this operation, "rand", is then used to make + * "M[rowOut][col] = M[rowOut][col] XOR rand" and + * "M[rowInOut][col] = M[rowInOut][col] XOR rotW(rand)", where rotW is a 64-bit + * rotation to the left. + * + * @param state The current state of the sponge + * @param rowIn Row used only as input + * @param rowInOut Row used as input and to receive output after rotation + * @param rowOut Row receiving the output + * + */ +inline void reducedDuplexRow(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOut, uint64_t *rowOut) { + uint64_t* ptrWordInOut = rowInOut; //In Lyra2: pointer to row* + uint64_t* ptrWordIn = rowIn; //In Lyra2: pointer to prev + uint64_t* ptrWordOut = rowOut; //In Lyra2: pointer to row + int i; + + for (i = 0; i < N_COLS; i++) { + + //Absorbing "M[prev] [+] M[row*]" + state[0] ^= (ptrWordIn[0] + ptrWordInOut[0]); + state[1] ^= (ptrWordIn[1] + ptrWordInOut[1]); + state[2] ^= (ptrWordIn[2] + ptrWordInOut[2]); + state[3] ^= (ptrWordIn[3] + ptrWordInOut[3]); + state[4] ^= (ptrWordIn[4] + ptrWordInOut[4]); + state[5] ^= (ptrWordIn[5] + ptrWordInOut[5]); + state[6] ^= (ptrWordIn[6] + ptrWordInOut[6]); + state[7] ^= (ptrWordIn[7] + ptrWordInOut[7]); + state[8] ^= (ptrWordIn[8] + ptrWordInOut[8]); + state[9] ^= (ptrWordIn[9] + ptrWordInOut[9]); + state[10] ^= (ptrWordIn[10] + ptrWordInOut[10]); + state[11] ^= (ptrWordIn[11] + ptrWordInOut[11]); + + //Applies the reduced-round transformation f to the sponge's state + reducedBlake2bLyra(state); + + //M[rowOut][col] = M[rowOut][col] XOR rand + ptrWordOut[0] ^= state[0]; + ptrWordOut[1] ^= state[1]; + ptrWordOut[2] ^= state[2]; + ptrWordOut[3] ^= state[3]; + ptrWordOut[4] ^= state[4]; + ptrWordOut[5] ^= state[5]; + ptrWordOut[6] ^= state[6]; + ptrWordOut[7] ^= state[7]; + ptrWordOut[8] ^= state[8]; + ptrWordOut[9] ^= state[9]; + ptrWordOut[10] ^= state[10]; + ptrWordOut[11] ^= state[11]; + + //M[rowInOut][col] = M[rowInOut][col] XOR rotW(rand) + ptrWordInOut[0] ^= state[11]; + ptrWordInOut[1] ^= state[0]; + ptrWordInOut[2] ^= state[1]; + ptrWordInOut[3] ^= state[2]; + ptrWordInOut[4] ^= state[3]; + ptrWordInOut[5] ^= state[4]; + ptrWordInOut[6] ^= state[5]; + ptrWordInOut[7] ^= state[6]; + ptrWordInOut[8] ^= state[7]; + ptrWordInOut[9] ^= state[8]; + ptrWordInOut[10] ^= state[9]; + ptrWordInOut[11] ^= state[10]; + + //Goes to next block + ptrWordOut += BLOCK_LEN_INT64; + ptrWordInOut += BLOCK_LEN_INT64; + ptrWordIn += BLOCK_LEN_INT64; + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Performs a duplex operation over "M[rowInOut] [+] M[rowIn]", writing the output "rand" + * on M[rowOut] and making "M[rowInOut] = M[rowInOut] XOR rotW(rand)", where rotW is a 64-bit + * rotation to the left. + * + * @param state The current state of the sponge + * @param rowIn Row used only as input + * @param rowInOut Row used as input and to receive output after rotation + * @param rowOut Row receiving the output + * + */ +/* +inline void reducedDuplexRowSetupOLD(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOut, uint64_t *rowOut) { + uint64_t* ptrWordIn = rowIn; //In Lyra2: pointer to prev + uint64_t* ptrWordInOut = rowInOut; //In Lyra2: pointer to row* + uint64_t* ptrWordOut = rowOut; //In Lyra2: pointer to row + int i; + for (i = 0; i < N_COLS; i++) { + + //Absorbing "M[rowInOut] XOR M[rowIn]" + state[0] ^= ptrWordInOut[0] ^ ptrWordIn[0]; + state[1] ^= ptrWordInOut[1] ^ ptrWordIn[1]; + state[2] ^= ptrWordInOut[2] ^ ptrWordIn[2]; + state[3] ^= ptrWordInOut[3] ^ ptrWordIn[3]; + state[4] ^= ptrWordInOut[4] ^ ptrWordIn[4]; + state[5] ^= ptrWordInOut[5] ^ ptrWordIn[5]; + state[6] ^= ptrWordInOut[6] ^ ptrWordIn[6]; + state[7] ^= ptrWordInOut[7] ^ ptrWordIn[7]; + state[8] ^= ptrWordInOut[8] ^ ptrWordIn[8]; + state[9] ^= ptrWordInOut[9] ^ ptrWordIn[9]; + state[10] ^= ptrWordInOut[10] ^ ptrWordIn[10]; + state[11] ^= ptrWordInOut[11] ^ ptrWordIn[11]; + + //Applies the reduced-round transformation f to the sponge's state + reducedBlake2bLyra(state); + + //M[row][col] = rand + ptrWordOut[0] = state[0]; + ptrWordOut[1] = state[1]; + ptrWordOut[2] = state[2]; + ptrWordOut[3] = state[3]; + ptrWordOut[4] = state[4]; + ptrWordOut[5] = state[5]; + ptrWordOut[6] = state[6]; + ptrWordOut[7] = state[7]; + ptrWordOut[8] = state[8]; + ptrWordOut[9] = state[9]; + ptrWordOut[10] = state[10]; + ptrWordOut[11] = state[11]; + + + //M[row*][col] = M[row*][col] XOR rotW(rand) + ptrWordInOut[0] ^= state[10]; + ptrWordInOut[1] ^= state[11]; + ptrWordInOut[2] ^= state[0]; + ptrWordInOut[3] ^= state[1]; + ptrWordInOut[4] ^= state[2]; + ptrWordInOut[5] ^= state[3]; + ptrWordInOut[6] ^= state[4]; + ptrWordInOut[7] ^= state[5]; + ptrWordInOut[8] ^= state[6]; + ptrWordInOut[9] ^= state[7]; + ptrWordInOut[10] ^= state[8]; + ptrWordInOut[11] ^= state[9]; + + //Goes to next column (i.e., next block in sequence) + ptrWordInOut += BLOCK_LEN_INT64; + ptrWordIn += BLOCK_LEN_INT64; + ptrWordOut += BLOCK_LEN_INT64; + } +} +*/ + +/** + * Performs a duplex operation over "M[rowInOut] XOR M[rowIn]", writing the output "rand" + * on M[rowOut] and making "M[rowInOut] = M[rowInOut] XOR rotW(rand)", where rotW is a 64-bit + * rotation to the left. + * + * @param state The current state of the sponge + * @param rowIn Row used only as input + * @param rowInOut Row used as input and to receive output after rotation + * @param rowOut Row receiving the output + * + */ +/* +inline void reducedDuplexRowSetupv5(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOut, uint64_t *rowOut) { + uint64_t* ptrWordIn = rowIn; //In Lyra2: pointer to prev + uint64_t* ptrWordInOut = rowInOut; //In Lyra2: pointer to row* + uint64_t* ptrWordOut = rowOut; //In Lyra2: pointer to row + int i; + for (i = 0; i < N_COLS; i++) { + + //Absorbing "M[rowInOut] XOR M[rowIn]" + state[0] ^= ptrWordInOut[0] + ptrWordIn[0]; + state[1] ^= ptrWordInOut[1] + ptrWordIn[1]; + state[2] ^= ptrWordInOut[2] + ptrWordIn[2]; + state[3] ^= ptrWordInOut[3] + ptrWordIn[3]; + state[4] ^= ptrWordInOut[4] + ptrWordIn[4]; + state[5] ^= ptrWordInOut[5] + ptrWordIn[5]; + state[6] ^= ptrWordInOut[6] + ptrWordIn[6]; + state[7] ^= ptrWordInOut[7] + ptrWordIn[7]; + state[8] ^= ptrWordInOut[8] + ptrWordIn[8]; + state[9] ^= ptrWordInOut[9] + ptrWordIn[9]; + state[10] ^= ptrWordInOut[10] + ptrWordIn[10]; + state[11] ^= ptrWordInOut[11] + ptrWordIn[11]; + + //Applies the reduced-round transformation f to the sponge's state + reducedBlake2bLyra(state); + + + //M[row*][col] = M[row*][col] XOR rotW(rand) + ptrWordInOut[0] ^= state[10]; + ptrWordInOut[1] ^= state[11]; + ptrWordInOut[2] ^= state[0]; + ptrWordInOut[3] ^= state[1]; + ptrWordInOut[4] ^= state[2]; + ptrWordInOut[5] ^= state[3]; + ptrWordInOut[6] ^= state[4]; + ptrWordInOut[7] ^= state[5]; + ptrWordInOut[8] ^= state[6]; + ptrWordInOut[9] ^= state[7]; + ptrWordInOut[10] ^= state[8]; + ptrWordInOut[11] ^= state[9]; + + + //M[row][col] = rand + ptrWordOut[0] = state[0] ^ ptrWordIn[0]; + ptrWordOut[1] = state[1] ^ ptrWordIn[1]; + ptrWordOut[2] = state[2] ^ ptrWordIn[2]; + ptrWordOut[3] = state[3] ^ ptrWordIn[3]; + ptrWordOut[4] = state[4] ^ ptrWordIn[4]; + ptrWordOut[5] = state[5] ^ ptrWordIn[5]; + ptrWordOut[6] = state[6] ^ ptrWordIn[6]; + ptrWordOut[7] = state[7] ^ ptrWordIn[7]; + ptrWordOut[8] = state[8] ^ ptrWordIn[8]; + ptrWordOut[9] = state[9] ^ ptrWordIn[9]; + ptrWordOut[10] = state[10] ^ ptrWordIn[10]; + ptrWordOut[11] = state[11] ^ ptrWordIn[11]; + + //Goes to next column (i.e., next block in sequence) + ptrWordInOut += BLOCK_LEN_INT64; + ptrWordIn += BLOCK_LEN_INT64; + ptrWordOut += BLOCK_LEN_INT64; + } +} +*/ + +/** + * Performs a duplex operation over "M[rowInOut] XOR M[rowIn]", writing the output "rand" + * on M[rowOut] and making "M[rowInOut] = M[rowInOut] XOR rotW(rand)", where rotW is a 64-bit + * rotation to the left. + * + * @param state The current state of the sponge + * @param rowIn Row used only as input + * @param rowInOut Row used as input and to receive output after rotation + * @param rowOut Row receiving the output + * + */ +/* +inline void reducedDuplexRowSetupv5c(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOut, uint64_t *rowOut) { + uint64_t* ptrWordIn = rowIn; //In Lyra2: pointer to prev + uint64_t* ptrWordInOut = rowInOut; //In Lyra2: pointer to row* + uint64_t* ptrWordOut = rowOut; + int i; + + for (i = 0; i < N_COLS / 2; i++) { + //Absorbing "M[rowInOut] XOR M[rowIn]" + state[0] ^= ptrWordInOut[0] + ptrWordIn[0]; + state[1] ^= ptrWordInOut[1] + ptrWordIn[1]; + state[2] ^= ptrWordInOut[2] + ptrWordIn[2]; + state[3] ^= ptrWordInOut[3] + ptrWordIn[3]; + state[4] ^= ptrWordInOut[4] + ptrWordIn[4]; + state[5] ^= ptrWordInOut[5] + ptrWordIn[5]; + state[6] ^= ptrWordInOut[6] + ptrWordIn[6]; + state[7] ^= ptrWordInOut[7] + ptrWordIn[7]; + state[8] ^= ptrWordInOut[8] + ptrWordIn[8]; + state[9] ^= ptrWordInOut[9] + ptrWordIn[9]; + state[10] ^= ptrWordInOut[10] + ptrWordIn[10]; + state[11] ^= ptrWordInOut[11] + ptrWordIn[11]; + + //Applies the reduced-round transformation f to the sponge's state + reducedBlake2bLyra(state); + + + //M[row*][col] = M[row*][col] XOR rotW(rand) + ptrWordInOut[0] ^= state[10]; + ptrWordInOut[1] ^= state[11]; + ptrWordInOut[2] ^= state[0]; + ptrWordInOut[3] ^= state[1]; + ptrWordInOut[4] ^= state[2]; + ptrWordInOut[5] ^= state[3]; + ptrWordInOut[6] ^= state[4]; + ptrWordInOut[7] ^= state[5]; + ptrWordInOut[8] ^= state[6]; + ptrWordInOut[9] ^= state[7]; + ptrWordInOut[10] ^= state[8]; + ptrWordInOut[11] ^= state[9]; + + + //M[row][col] = rand + ptrWordOut[0] = state[0] ^ ptrWordIn[0]; + ptrWordOut[1] = state[1] ^ ptrWordIn[1]; + ptrWordOut[2] = state[2] ^ ptrWordIn[2]; + ptrWordOut[3] = state[3] ^ ptrWordIn[3]; + ptrWordOut[4] = state[4] ^ ptrWordIn[4]; + ptrWordOut[5] = state[5] ^ ptrWordIn[5]; + ptrWordOut[6] = state[6] ^ ptrWordIn[6]; + ptrWordOut[7] = state[7] ^ ptrWordIn[7]; + ptrWordOut[8] = state[8] ^ ptrWordIn[8]; + ptrWordOut[9] = state[9] ^ ptrWordIn[9]; + ptrWordOut[10] = state[10] ^ ptrWordIn[10]; + ptrWordOut[11] = state[11] ^ ptrWordIn[11]; + + //Goes to next column (i.e., next block in sequence) + ptrWordInOut += BLOCK_LEN_INT64; + ptrWordIn += BLOCK_LEN_INT64; + ptrWordOut += 2 * BLOCK_LEN_INT64; + } + + ptrWordOut = rowOut + BLOCK_LEN_INT64; + for (i = 0; i < N_COLS / 2; i++) { + //Absorbing "M[rowInOut] XOR M[rowIn]" + state[0] ^= ptrWordInOut[0] + ptrWordIn[0]; + state[1] ^= ptrWordInOut[1] + ptrWordIn[1]; + state[2] ^= ptrWordInOut[2] + ptrWordIn[2]; + state[3] ^= ptrWordInOut[3] + ptrWordIn[3]; + state[4] ^= ptrWordInOut[4] + ptrWordIn[4]; + state[5] ^= ptrWordInOut[5] + ptrWordIn[5]; + state[6] ^= ptrWordInOut[6] + ptrWordIn[6]; + state[7] ^= ptrWordInOut[7] + ptrWordIn[7]; + state[8] ^= ptrWordInOut[8] + ptrWordIn[8]; + state[9] ^= ptrWordInOut[9] + ptrWordIn[9]; + state[10] ^= ptrWordInOut[10] + ptrWordIn[10]; + state[11] ^= ptrWordInOut[11] + ptrWordIn[11]; + + //Applies the reduced-round transformation f to the sponge's state + reducedBlake2bLyra(state); + + + //M[row*][col] = M[row*][col] XOR rotW(rand) + ptrWordInOut[0] ^= state[10]; + ptrWordInOut[1] ^= state[11]; + ptrWordInOut[2] ^= state[0]; + ptrWordInOut[3] ^= state[1]; + ptrWordInOut[4] ^= state[2]; + ptrWordInOut[5] ^= state[3]; + ptrWordInOut[6] ^= state[4]; + ptrWordInOut[7] ^= state[5]; + ptrWordInOut[8] ^= state[6]; + ptrWordInOut[9] ^= state[7]; + ptrWordInOut[10] ^= state[8]; + ptrWordInOut[11] ^= state[9]; + + + //M[row][col] = rand + ptrWordOut[0] = state[0] ^ ptrWordIn[0]; + ptrWordOut[1] = state[1] ^ ptrWordIn[1]; + ptrWordOut[2] = state[2] ^ ptrWordIn[2]; + ptrWordOut[3] = state[3] ^ ptrWordIn[3]; + ptrWordOut[4] = state[4] ^ ptrWordIn[4]; + ptrWordOut[5] = state[5] ^ ptrWordIn[5]; + ptrWordOut[6] = state[6] ^ ptrWordIn[6]; + ptrWordOut[7] = state[7] ^ ptrWordIn[7]; + ptrWordOut[8] = state[8] ^ ptrWordIn[8]; + ptrWordOut[9] = state[9] ^ ptrWordIn[9]; + ptrWordOut[10] = state[10] ^ ptrWordIn[10]; + ptrWordOut[11] = state[11] ^ ptrWordIn[11]; + + //Goes to next column (i.e., next block in sequence) + ptrWordInOut += BLOCK_LEN_INT64; + ptrWordIn += BLOCK_LEN_INT64; + ptrWordOut += 2 * BLOCK_LEN_INT64; + } +} +*/ + +/** + * Performs a duplex operation over "M[rowInOut] XOR M[rowIn]", using the output "rand" + * to make "M[rowOut][col] = M[rowOut][col] XOR rand" and "M[rowInOut] = M[rowInOut] XOR rotW(rand)", + * where rotW is a 64-bit rotation to the left. + * + * @param state The current state of the sponge + * @param rowIn Row used only as input + * @param rowInOut Row used as input and to receive output after rotation + * @param rowOut Row receiving the output + * + */ +/* +inline void reducedDuplexRowd(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOut, uint64_t *rowOut) { + uint64_t* ptrWordInOut = rowInOut; //In Lyra2: pointer to row* + uint64_t* ptrWordIn = rowIn; //In Lyra2: pointer to prev + uint64_t* ptrWordOut = rowOut; //In Lyra2: pointer to row + int i; + for (i = 0; i < N_COLS; i++) { + + //Absorbing "M[rowInOut] XOR M[rowIn]" + state[0] ^= ptrWordInOut[0] + ptrWordIn[0]; + state[1] ^= ptrWordInOut[1] + ptrWordIn[1]; + state[2] ^= ptrWordInOut[2] + ptrWordIn[2]; + state[3] ^= ptrWordInOut[3] + ptrWordIn[3]; + state[4] ^= ptrWordInOut[4] + ptrWordIn[4]; + state[5] ^= ptrWordInOut[5] + ptrWordIn[5]; + state[6] ^= ptrWordInOut[6] + ptrWordIn[6]; + state[7] ^= ptrWordInOut[7] + ptrWordIn[7]; + state[8] ^= ptrWordInOut[8] + ptrWordIn[8]; + state[9] ^= ptrWordInOut[9] + ptrWordIn[9]; + state[10] ^= ptrWordInOut[10] + ptrWordIn[10]; + state[11] ^= ptrWordInOut[11] + ptrWordIn[11]; + + //Applies the reduced-round transformation f to the sponge's state + reducedBlake2bLyra(state); + + //M[rowOut][col] = M[rowOut][col] XOR rand + ptrWordOut[0] ^= state[0]; + ptrWordOut[1] ^= state[1]; + ptrWordOut[2] ^= state[2]; + ptrWordOut[3] ^= state[3]; + ptrWordOut[4] ^= state[4]; + ptrWordOut[5] ^= state[5]; + ptrWordOut[6] ^= state[6]; + ptrWordOut[7] ^= state[7]; + ptrWordOut[8] ^= state[8]; + ptrWordOut[9] ^= state[9]; + ptrWordOut[10] ^= state[10]; + ptrWordOut[11] ^= state[11]; + + //M[rowInOut][col] = M[rowInOut][col] XOR rotW(rand) + + + //Goes to next block + ptrWordOut += BLOCK_LEN_INT64; + ptrWordInOut += BLOCK_LEN_INT64; + ptrWordIn += BLOCK_LEN_INT64; + } +} +*/ + +/** + Prints an array of unsigned chars + */ +void printArray(unsigned char *array, unsigned int size, char *name) { + int i; + printf("%s: ", name); + for (i = 0; i < size; i++) { + printf("%2x|", array[i]); + } + printf("\n"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/algorithm/Sponge.h b/algorithm/Sponge.h new file mode 100644 index 000000000..3fcff0d7e --- /dev/null +++ b/algorithm/Sponge.h @@ -0,0 +1,108 @@ +/** + * Header file for Blake2b's internal permutation in the form of a sponge. + * This code is based on the original Blake2b's implementation provided by + * Samuel Neves (https://blake2.net/) + * + * 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 SPONGE_H_ +#define SPONGE_H_ + +#include + +#if defined(__GNUC__) +#define ALIGN __attribute__ ((aligned(32))) +#elif defined(_MSC_VER) +#define ALIGN __declspec(align(32)) +#else +#define ALIGN +#endif + + +/*Blake2b IV Array*/ +static const uint64_t blake2b_IV[8] = +{ + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, + 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, + 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL +}; + +/*Blake2b's rotation*/ +static inline uint64_t rotr64( const uint64_t w, const unsigned c ){ + return ( w >> c ) | ( w << ( 64 - c ) ); +} + +/*Blake2b's G function*/ +#define G(r,i,a,b,c,d) \ + do { \ + a = a + b; \ + d = rotr64(d ^ a, 32); \ + c = c + d; \ + b = rotr64(b ^ c, 24); \ + a = a + b; \ + d = rotr64(d ^ a, 16); \ + c = c + d; \ + b = rotr64(b ^ c, 63); \ + } while(0) + + +/*One Round of the Blake2b's compression function*/ +#define ROUND_LYRA(r) \ + 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]); + + +//---- Housekeeping +void initState(uint64_t state[/*16*/]); + +//---- Squeezes +void squeeze(uint64_t *state, unsigned char *out, unsigned int len); +void reducedSqueezeRow0(uint64_t* state, uint64_t* row); + +//---- Absorbs +void absorbBlock(uint64_t *state, const uint64_t *in); +void absorbBlockBlake2Safe(uint64_t *state, const uint64_t *in); + +//---- Duplexes +void reducedDuplexRow1(uint64_t *state, uint64_t *rowIn, uint64_t *rowOut); +void reducedDuplexRowSetup(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOut, uint64_t *rowOut); +void reducedDuplexRow(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOut, uint64_t *rowOut); + +//---- Misc +void printArray(unsigned char *array, unsigned int size, char *name); + +//////////////////////////////////////////////////////////////////////////////////////////////// + + +////TESTS//// +//void reducedDuplexRowc(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOut, uint64_t *rowOut); +//void reducedDuplexRowd(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOut, uint64_t *rowOut); +//void reducedDuplexRowSetupv4(uint64_t *state, uint64_t *rowIn1, uint64_t *rowIn2, uint64_t *rowOut1, uint64_t *rowOut2); +//void reducedDuplexRowSetupv5(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOut, uint64_t *rowOut); +//void reducedDuplexRowSetupv5c(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOut, uint64_t *rowOut); +//void reducedDuplexRowSetupv5d(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOut, uint64_t *rowOut); +///////////// + + +#endif /* SPONGE_H_ */ diff --git a/driver-opencl.c b/driver-opencl.c index 48ffc517d..aa56d1d36 100644 --- a/driver-opencl.c +++ b/driver-opencl.c @@ -49,6 +49,7 @@ extern bool opt_loginput; extern char *opt_kernel_path; extern int gpur_thr_id; extern bool opt_noadl; +extern bool opt_lyra; extern void *miner_thread(void *userdata); extern int dev_from_id(int thr_id); @@ -1357,7 +1358,12 @@ static bool opencl_thread_init(struct thr_info *thr) static bool opencl_prepare_work(struct thr_info __maybe_unused *thr, struct work *work) { - work->blk.work = work; + + if (opt_lyra) { + work->blk.work = work; + precalc_hash_blake256(&work->blk, 0, (uint32_t *)(work->data)); + } + else {work->blk.work = work;} thr->pool_no = work->pool->pool_no; return true; } diff --git a/example.bat b/example.bat new file mode 100644 index 000000000..605501dad --- /dev/null +++ b/example.bat @@ -0,0 +1,9 @@ +setx GPU_FORCE_64BIT_PTR 0 +setx GPU_MAX_HEAP_SIZE 100 +setx GPU_USE_SYNC_OBJECTS 1 +setx GPU_MAX_ALLOC_PERCENT 100 +del *.bin + +sgminer.exe --no-submit-stale --kernel Lyra2RE -o stratum+tcp://92.27.201.170:9174 -u m -p 1 --gpu-platform 2 -I 19 --shaders 2816 -w 64 -g 2 + +pause \ No newline at end of file diff --git a/findnonce.c b/findnonce.c index be9ba0dfd..5ef19a510 100644 --- a/findnonce.c +++ b/findnonce.c @@ -234,3 +234,142 @@ void postcalc_hash_async(struct thr_info *thr, struct work *work, uint32_t *res) free(pcd); } } + +// BLAKE 256 14 rounds (standard) + +typedef struct +{ + uint32_t h[8]; + uint32_t t; +} blake_state256; + +#define NB_ROUNDS32 14 + +const uint8_t blake_sigma[][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 }, + { 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 } +}; + +const uint32_t blake_u256[16] = +{ + 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, + 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, + 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, + 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917 +}; + +#define ROT32(x,n) (((x)<<(32-n))|( (x)>>(n))) +//#define ROT32(x,n) (rotate((uint)x, (uint)32-n)) +#define ADD32(x,y) ((uint32_t)((x) + (y))) +#define XOR32(x,y) ((uint32_t)((x) ^ (y))) + +#define G(a,b,c,d,i) \ +do {\ + v[a] += XOR32(m[blake_sigma[r][i]], blake_u256[blake_sigma[r][i+1]]) + v[b];\ + v[d] = ROT32(XOR32(v[d],v[a]),16);\ + v[c] += v[d];\ + v[b] = ROT32(XOR32(v[b],v[c]),12);\ + v[a] += XOR32(m[blake_sigma[r][i+1]], blake_u256[blake_sigma[r][i]]) + v[b]; \ + v[d] = ROT32(XOR32(v[d],v[a]), 8);\ + v[c] += v[d];\ + v[b] = ROT32(XOR32(v[b],v[c]), 7);\ + } while (0) + + +// compress a block +void blake256_compress_block(blake_state256 *S, uint32_t *m) +{ + uint32_t v[16]; + int i, r; + for (i = 0; i < 8; ++i) v[i] = S->h[i]; + + v[8] = blake_u256[0]; + v[9] = blake_u256[1]; + v[10] = blake_u256[2]; + v[11] = blake_u256[3]; + v[12] = blake_u256[4]; + v[13] = blake_u256[5]; + v[14] = blake_u256[6]; + v[15] = blake_u256[7]; + + v[12] ^= S->t; + v[13] ^= S->t; + + for (r = 0; r < NB_ROUNDS32; ++r) + { + /* column step */ + G(0, 4, 8, 12, 0); + G(1, 5, 9, 13, 2); + G(2, 6, 10, 14, 4); + G(3, 7, 11, 15, 6); + /* diagonal step */ + G(0, 5, 10, 15, 8); + G(1, 6, 11, 12, 10); + G(2, 7, 8, 13, 12); + G(3, 4, 9, 14, 14); + } + + for (i = 0; i < 16; ++i) S->h[i & 7] ^= v[i]; +} + + +void blake256_init(blake_state256 *S) +{ + S->h[0] = 0x6a09e667; + S->h[1] = 0xbb67ae85; + S->h[2] = 0x3c6ef372; + S->h[3] = 0xa54ff53a; + S->h[4] = 0x510e527f; + S->h[5] = 0x9b05688c; + S->h[6] = 0x1f83d9ab; + S->h[7] = 0x5be0cd19; + S->t = 0; +} + + +void blake256_update(blake_state256 *S, const uint32_t *in) +{ + uint32_t m[16]; + int i; + S->t = 512; + for (i = 0; i < 16; ++i) m[i] = in[i]; + blake256_compress_block(S, m); +} + + + +void precalc_hash_blake256(dev_blk_ctx *blk, uint32_t *state, uint32_t *data) +{ +blake_state256 S; +blake256_init(&S); +blake256_update(&S, data); + +blk->ctx_a = S.h[0]; +blk->ctx_b = S.h[1]; +blk->ctx_c = S.h[2]; +blk->ctx_d = S.h[3]; +blk->ctx_e = S.h[4]; +blk->ctx_f = S.h[5]; +blk->ctx_g = S.h[6]; +blk->ctx_h = S.h[7]; + +blk->cty_a = data[16]; +blk->cty_b = data[17]; +blk->cty_c = data[18]; + +} diff --git a/findnonce.h b/findnonce.h index 9376a57be..354cbf017 100644 --- a/findnonce.h +++ b/findnonce.h @@ -10,5 +10,5 @@ extern void precalc_hash(dev_blk_ctx *blk, uint32_t *state, uint32_t *data); extern void postcalc_hash_async(struct thr_info *thr, struct work *work, uint32_t *res); - +extern void precalc_hash_blake256(dev_blk_ctx *blk, uint32_t *state, uint32_t *data); #endif /*FINDNONCE_H*/ diff --git a/kernel/Lyra2.cl b/kernel/Lyra2.cl new file mode 100644 index 000000000..24aa5eb85 --- /dev/null +++ b/kernel/Lyra2.cl @@ -0,0 +1,145 @@ +/* +* Lyra2 kernel implementation. +* +* ==========================(LICENSE BEGIN)============================ +* Copyright (c) 2014 djm34 +* +* +* 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 djm34 +*/ + +/*Blake2b IV Array*/ +__constant static const sph_u64 blake2b_IV[8] = +{ + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, + 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, + 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL +}; + +/*Blake2b's rotation*/ +static inline sph_u64 rotr64( const sph_u64 w, const unsigned c ){ + return rotate(w, (ulong)(64-c)); +} + +/*Blake2b's G function*/ +#define G(a,b,c,d) \ + do { \ +a += b; d ^= a; d = SPH_ROTR64(d, 32); \ +c += d; b ^= c; b = SPH_ROTR64(b, 24); \ +a += b; d ^= a; d = SPH_ROTR64(d, 16); \ +c += d; b ^= c; b = SPH_ROTR64(b, 63); \ + } while(0) + + +/*One Round of the Blake2b's compression function*/ +#define round_lyra(v) \ + do { \ + G(v[ 0],v[ 4],v[ 8],v[12]); \ + G(v[ 1],v[ 5],v[ 9],v[13]); \ + G(v[ 2],v[ 6],v[10],v[14]); \ + G(v[ 3],v[ 7],v[11],v[15]); \ + G(v[ 0],v[ 5],v[10],v[15]); \ + G(v[ 1],v[ 6],v[11],v[12]); \ + G(v[ 2],v[ 7],v[ 8],v[13]); \ + G(v[ 3],v[ 4],v[ 9],v[14]); \ + } while(0) + + +#define reduceDuplexRowSetup(rowIn, rowInOut, rowOut) \ + { \ + for (int i = 0; i < 8; i++) \ + { \ +\ + for (int j = 0; j < 12; j++) {state[j] ^= Matrix[12 * i + j][rowIn] + Matrix[12 * i + j][rowInOut];} \ + round_lyra(state); \ + for (int j = 0; j < 12; j++) {Matrix[j + 84 - 12 * i][rowOut] = Matrix[12 * i + j][rowIn] ^ state[j];} \ +\ + Matrix[0 + 12 * i][rowInOut] ^= state[11]; \ + Matrix[1 + 12 * i][rowInOut] ^= state[0]; \ + Matrix[2 + 12 * i][rowInOut] ^= state[1]; \ + Matrix[3 + 12 * i][rowInOut] ^= state[2]; \ + Matrix[4 + 12 * i][rowInOut] ^= state[3]; \ + Matrix[5 + 12 * i][rowInOut] ^= state[4]; \ + Matrix[6 + 12 * i][rowInOut] ^= state[5]; \ + Matrix[7 + 12 * i][rowInOut] ^= state[6]; \ + Matrix[8 + 12 * i][rowInOut] ^= state[7]; \ + Matrix[9 + 12 * i][rowInOut] ^= state[8]; \ + Matrix[10 + 12 * i][rowInOut] ^= state[9]; \ + Matrix[11 + 12 * i][rowInOut] ^= state[10]; \ + } \ + \ + } + +#define reduceDuplexRow(rowIn, rowInOut, rowOut) \ + { \ + for (int i = 0; i < 8; i++) \ + { \ + for (int j = 0; j < 12; j++) \ + state[j] ^= Matrix[12 * i + j][rowIn] + Matrix[12 * i + j][rowInOut]; \ + \ + round_lyra(state); \ + for (int j = 0; j < 12; j++) {Matrix[j + 12 * i][rowOut] ^= state[j];} \ +\ + Matrix[0 + 12 * i][rowInOut] ^= state[11]; \ + Matrix[1 + 12 * i][rowInOut] ^= state[0]; \ + Matrix[2 + 12 * i][rowInOut] ^= state[1]; \ + Matrix[3 + 12 * i][rowInOut] ^= state[2]; \ + Matrix[4 + 12 * i][rowInOut] ^= state[3]; \ + Matrix[5 + 12 * i][rowInOut] ^= state[4]; \ + Matrix[6 + 12 * i][rowInOut] ^= state[5]; \ + Matrix[7 + 12 * i][rowInOut] ^= state[6]; \ + Matrix[8 + 12 * i][rowInOut] ^= state[7]; \ + Matrix[9 + 12 * i][rowInOut] ^= state[8]; \ + Matrix[10 + 12 * i][rowInOut] ^= state[9]; \ + Matrix[11 + 12 * i][rowInOut] ^= state[10]; \ + } \ + \ + } +#define absorbblock(in) { \ + state[0] ^= Matrix[0][in]; \ + state[1] ^= Matrix[1][in]; \ + state[2] ^= Matrix[2][in]; \ + state[3] ^= Matrix[3][in]; \ + state[4] ^= Matrix[4][in]; \ + state[5] ^= Matrix[5][in]; \ + state[6] ^= Matrix[6][in]; \ + state[7] ^= Matrix[7][in]; \ + state[8] ^= Matrix[8][in]; \ + state[9] ^= Matrix[9][in]; \ + state[10] ^= Matrix[10][in]; \ + state[11] ^= Matrix[11][in]; \ + round_lyra(state); \ + round_lyra(state); \ + round_lyra(state); \ + round_lyra(state); \ + round_lyra(state); \ + round_lyra(state); \ + round_lyra(state); \ + round_lyra(state); \ + round_lyra(state); \ + round_lyra(state); \ + round_lyra(state); \ + round_lyra(state); \ + } \ No newline at end of file diff --git a/kernel/Lyra2RE.cl b/kernel/Lyra2RE.cl new file mode 100644 index 000000000..03ddc15ed --- /dev/null +++ b/kernel/Lyra2RE.cl @@ -0,0 +1,392 @@ +/* + * Lyra2RE kernel implementation. + * + * ==========================(LICENSE BEGIN)============================ + * Copyright (c) 2014 djm34 + * Copyright (c) 2014 James Lovejoy + * + * 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 djm34 + */ + +#pragma OPENCL EXTENSION cl_amd_printf : enable + +#ifndef LYRA2RE_CL +#define LYRA2RE_CL + +#if __ENDIAN_LITTLE__ +#define SPH_LITTLE_ENDIAN 1 +#else +#define SPH_BIG_ENDIAN 1 +#endif + +#define SPH_UPTR sph_u64 + +typedef unsigned int sph_u32; +typedef int sph_s32; +#ifndef __OPENCL_VERSION__ +typedef unsigned long long sph_u64; +typedef long long sph_s64; +#else +typedef unsigned long sph_u64; +typedef long sph_s64; +#endif + + +#define SPH_64 1 +#define SPH_64_TRUE 1 + +#define SPH_C32(x) ((sph_u32)(x ## U)) +#define SPH_T32(x) ((x) & SPH_C32(0xFFFFFFFF)) + +#define SPH_C64(x) ((sph_u64)(x ## UL)) +#define SPH_T64(x) ((x) & SPH_C64(0xFFFFFFFFFFFFFFFF)) + +//#define SPH_ROTL32(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) +//#define SPH_ROTR32(x, n) (((x) >> (n)) | ((x) << (32 - (n)))) +//#define SPH_ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n)))) +//#define SPH_ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n)))) + +#define SPH_ROTL32(x,n) rotate(x,(uint)n) //faster with driver 14.6 +#define SPH_ROTR32(x,n) rotate(x,(uint)(32-n)) +#define SPH_ROTL64(x,n) rotate(x,(ulong)n) +#define SPH_ROTR64(x,n) rotate(x,(ulong)(64-n)) + + +#include "blake256.cl" +#include "groestl256.cl" +#include "Lyra2.cl" +#include "keccak1600.cl" +#include "skein256.cl" + +#define SWAP4(x) as_uint(as_uchar4(x).wzyx) +#define SWAP8(x) as_ulong(as_uchar8(x).s76543210) + +#if SPH_BIG_ENDIAN + #define DEC64E(x) (x) + #define DEC64BE(x) (*(const __global sph_u64 *) (x)); + #define DEC64LE(x) SWAP8(*(const __global sph_u64 *) (x)); + #define DEC32LE(x) (*(const __global sph_u32 *) (x)); +#else + #define DEC64E(x) SWAP8(x) + #define DEC64BE(x) SWAP8(*(const __global sph_u64 *) (x)); + #define DEC64LE(x) (*(const __global sph_u64 *) (x)); +#define DEC32LE(x) SWAP4(*(const __global sph_u32 *) (x)); +#endif + +typedef union { + unsigned char h1[64]; + uint h4[16]; + ulong h8[8]; +} hash_t; + +__attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) +__kernel void search( + __global hash_t* hashes, + // precalc hash from fisrt part of message + const uint h0, + const uint h1, + const uint h2, + const uint h3, + const uint h4, + const uint h5, + const uint h6, + const uint h7, + // last 12 bytes of original message + const uint in16, + const uint in17, + const uint in18 +) +{ + uint gid = get_global_id(0); + __global hash_t *hash = &(hashes[gid-get_global_offset(0)]); + + sph_u32 h[8]; + sph_u32 m[16]; + sph_u32 v[16]; + + +h[0]=h0; +h[1]=h1; +h[2]=h2; +h[3]=h3; +h[4]=h4; +h[5]=h5; +h[6]=h6; +h[7]=h7; +// compress 2nd round + m[0] = in16; + m[1] = in17; + m[2] = in18; + m[3] = SWAP4(gid); + + for (int i = 4; i < 16; i++) {m[i] = c_Padding[i];} + + for (int i = 0; i < 8; i++) {v[i] = h[i];} + + v[8] = c_u256[0]; + v[9] = c_u256[1]; + v[10] = c_u256[2]; + v[11] = c_u256[3]; + v[12] = c_u256[4] ^ 640; + v[13] = c_u256[5] ^ 640; + v[14] = c_u256[6]; + v[15] = c_u256[7]; + + for (int r = 0; r < 14; r++) { + GS(0, 4, 0x8, 0xC, 0x0); + GS(1, 5, 0x9, 0xD, 0x2); + GS(2, 6, 0xA, 0xE, 0x4); + GS(3, 7, 0xB, 0xF, 0x6); + GS(0, 5, 0xA, 0xF, 0x8); + GS(1, 6, 0xB, 0xC, 0xA); + GS(2, 7, 0x8, 0xD, 0xC); + GS(3, 4, 0x9, 0xE, 0xE); + } + + for (int i = 0; i < 16; i++) { + int j = i & 7; + h[j] ^= v[i];} + +for (int i=0;i<8;i++) {hash->h4[i]=SWAP4(h[i]);} + + barrier(CLK_GLOBAL_MEM_FENCE); + +} + +// keccak256 + + +__attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) +__kernel void search1(__global hash_t* hashes) +{ + uint gid = get_global_id(0); + __global hash_t *hash = &(hashes[gid-get_global_offset(0)]); + + sph_u64 keccak_gpu_state[25]; + + for (int i = 0; i<25; i++) { + if (i<4) { keccak_gpu_state[i] = hash->h8[i]; } + else { keccak_gpu_state[i] = 0; } + } + keccak_gpu_state[4] = 0x0000000000000001; + keccak_gpu_state[16] = 0x8000000000000000; + + keccak_block(keccak_gpu_state); + for (int i = 0; i<4; i++) { hash->h8[i] = keccak_gpu_state[i]; } + + barrier(CLK_GLOBAL_MEM_FENCE); + + +} + +/// lyra2 algo + + +__attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) +__kernel void search2(__global hash_t* hashes) +{ + uint gid = get_global_id(0); + __global hash_t *hash = &(hashes[gid-get_global_offset(0)]); + + + + sph_u64 state[16]; + + for (int i = 0; i<4; i++) { state[i] = hash->h8[i];} //password + for (int i = 0; i<4; i++) { state[i + 4] = state[i]; } //salt + + for (int i = 0; i<8; i++) { state[i + 8] = blake2b_IV[i]; } + + // blake2blyra x2 + + for (int i = 0; i<24; i++) { round_lyra(state); } //because 12 is not enough + + sph_u64 Matrix[96][8]; // very uncool + /// reducedSqueezeRow0 + + for (int i = 0; i < 8; i++) + { + for (int j = 0; j<12; j++) { Matrix[j + 84 - 12 * i][0] = state[j]; } + round_lyra(state); + } + + /// reducedSqueezeRow1 + + for (int i = 0; i < 8; i++) + { + for (int j = 0; j<12; j++) { state[j] ^= Matrix[j + 12 * i][0]; } + round_lyra(state); + for (int j = 0; j<12; j++) { Matrix[j + 84 - 12 * i][1] = Matrix[j + 12 * i][0] ^ state[j]; } + } + + + reduceDuplexRowSetup(1, 0, 2); + reduceDuplexRowSetup(2, 1, 3); + reduceDuplexRowSetup(3, 0, 4); + reduceDuplexRowSetup(4, 3, 5); + reduceDuplexRowSetup(5, 2, 6); + reduceDuplexRowSetup(6, 1, 7); + + sph_u64 rowa; + rowa = state[0] & 7; + + reduceDuplexRow(7, rowa, 0); + rowa = state[0] & 7; + reduceDuplexRow(0, rowa, 3); + rowa = state[0] & 7; + reduceDuplexRow(3, rowa, 6); + rowa = state[0] & 7; + reduceDuplexRow(6, rowa, 1); + rowa = state[0] & 7; + reduceDuplexRow(1, rowa, 4); + rowa = state[0] & 7; + reduceDuplexRow(4, rowa, 7); + rowa = state[0] & 7; + reduceDuplexRow(7, rowa, 2); + rowa = state[0] & 7; + reduceDuplexRow(2, rowa, 5); + + absorbblock(rowa); + + for (int i = 0; i<4; i++) {hash->h8[i] = state[i];} + + barrier(CLK_GLOBAL_MEM_FENCE); + +} + +//skein256 + +__attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) +__kernel void search3(__global hash_t* hashes) +{ + uint gid = get_global_id(0); + __global hash_t *hash = &(hashes[gid-get_global_offset(0)]); + + + sph_u64 h[9]; + sph_u64 t[3]; + sph_u64 dt0,dt1,dt2,dt3; + sph_u64 p0, p1, p2, p3, p4, p5, p6, p7; + h[8] = skein_ks_parity; + + for (int i = 0; i<8; i++) { + h[i] = SKEIN_IV512_256[i]; + h[8] ^= h[i];} + + t[0]=t12[0]; + t[1]=t12[1]; + t[2]=t12[2]; + + dt0=hash->h8[0]; + dt1=hash->h8[1]; + dt2=hash->h8[2]; + dt3=hash->h8[3]; + + p0 = h[0] + dt0; + p1 = h[1] + dt1; + p2 = h[2] + dt2; + p3 = h[3] + dt3; + p4 = h[4]; + p5 = h[5] + t[0]; + p6 = h[6] + t[1]; + p7 = h[7]; + + #pragma unroll + for (int i = 1; i<19; i+=2) {Round_8_512(p0,p1,p2,p3,p4,p5,p6,p7,i);} + p0 ^= dt0; + p1 ^= dt1; + p2 ^= dt2; + p3 ^= dt3; + + h[0] = p0; + h[1] = p1; + h[2] = p2; + h[3] = p3; + h[4] = p4; + h[5] = p5; + h[6] = p6; + h[7] = p7; + h[8] = skein_ks_parity; + + for (int i = 0; i<8; i++) { h[8] ^= h[i]; } + + t[0] = t12[3]; + t[1] = t12[4]; + t[2] = t12[5]; + p5 += t[0]; //p5 already equal h[5] + p6 += t[1]; + + #pragma unroll + for (int i = 1; i<19; i+=2) { Round_8_512(p0, p1, p2, p3, p4, p5, p6, p7, i); } + + hash->h8[0] = p0; + hash->h8[1] = p1; + hash->h8[2] = p2; + hash->h8[3] = p3; + + + + barrier(CLK_GLOBAL_MEM_FENCE); + +} + +__attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) +__kernel void search4(__global hash_t* hashes, __global uint* output, const uint target) +{ + uint gid = get_global_id(0); + __global hash_t *hash = &(hashes[gid - get_global_offset(0)]); + + sph_u64 message[8], state[8]; + sph_u64 t[8]; + for (int k = 0; k<4; k++) { message[k] = hash->h8[k]; } + + message[4] = 0x80UL; + message[5] = 0UL; + message[6] = 0UL; + message[7] = 0x0100000000000000UL; + + for (int u = 0; u<8; u++) { state[u] = message[u]; } + state[7] ^= 0x0001000000000000UL; + + PERM_SMALL_P(state); + state[7] ^= 0x0001000000000000UL; + PERM_SMALL_Q(message); + + for (int u = 0; u<8; u++) { state[u] ^= message[u]; } + message[7] = state[7]; + + PERM_SMALL_Pf(state); + + state[7] ^= message[7]; + barrier(CLK_GLOBAL_MEM_FENCE); + + bool result = ( as_uint2(state[7]).y <= target); + if (result) { + output[atomic_inc(output + 0xFF)] = SWAP4(gid); + } + +} + + +#endif // LYRA2RE_CL \ No newline at end of file diff --git a/kernel/blake256.cl b/kernel/blake256.cl new file mode 100644 index 000000000..012285a5e --- /dev/null +++ b/kernel/blake256.cl @@ -0,0 +1,96 @@ +/* +* blake256 kernel implementation. +* +* ==========================(LICENSE BEGIN)============================ +* Copyright (c) 2014 djm34 +* Copyright (c) 2014 tpruvot +* 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 djm34 +*/ +__constant static const int sigma[16][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 }, + { 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 } +}; + + +__constant static const sph_u32 c_IV256[8] = { + 0x6A09E667, 0xBB67AE85, + 0x3C6EF372, 0xA54FF53A, + 0x510E527F, 0x9B05688C, + 0x1F83D9AB, 0x5BE0CD19 +}; + +/* Second part (64-80) msg never change, store it */ +__constant static const sph_u32 c_Padding[16] = { + 0, 0, 0, 0, + 0x80000000, 0, 0, 0, + 0, 0, 0, 0, + 0, 1, 0, 640, +}; +__constant static const sph_u32 c_u256[16] = { + 0x243F6A88, 0x85A308D3, + 0x13198A2E, 0x03707344, + 0xA4093822, 0x299F31D0, + 0x082EFA98, 0xEC4E6C89, + 0x452821E6, 0x38D01377, + 0xBE5466CF, 0x34E90C6C, + 0xC0AC29B7, 0xC97C50DD, + 0x3F84D5B5, 0xB5470917 +}; + +#define GS(a,b,c,d,x) { \ + const sph_u32 idx1 = sigma[r][x]; \ + const sph_u32 idx2 = sigma[r][x+1]; \ + v[a] += (m[idx1] ^ c_u256[idx2]) + v[b]; \ + v[d] ^= v[a]; \ + v[d] = SPH_ROTR32(v[d], 16); \ + v[c] += v[d]; \ + v[b] ^= v[c]; \ + v[b] = SPH_ROTR32(v[b], 12); \ +\ + v[a] += (m[idx2] ^ c_u256[idx1]) + v[b]; \ + v[d] ^= v[a]; \ + v[d] = SPH_ROTR32(v[d], 8); \ + v[c] += v[d]; \ + v[b] ^= v[c]; \ + v[b] = SPH_ROTR32(v[b], 7); \ +} + + + + + diff --git a/kernel/groestl256.cl b/kernel/groestl256.cl new file mode 100644 index 000000000..824910a35 --- /dev/null +++ b/kernel/groestl256.cl @@ -0,0 +1,415 @@ +/* $Id: groestl.c 260 2011-07-21 01:02:38Z tp $ */ +/* + * Groestl256 + * + * ==========================(LICENSE BEGIN)============================ + * Copyright (c) 2014 djm34 + * 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 + */ + +/* + * Apparently, the 32-bit-only version is not faster than the 64-bit + * version unless using the "small footprint" code on a 32-bit machine. + */ + +#define C64e(x) ((SPH_C64(x) >> 56) \ + | ((SPH_C64(x) >> 40) & SPH_C64(0x000000000000FF00)) \ + | ((SPH_C64(x) >> 24) & SPH_C64(0x0000000000FF0000)) \ + | ((SPH_C64(x) >> 8) & SPH_C64(0x00000000FF000000)) \ + | ((SPH_C64(x) << 8) & SPH_C64(0x000000FF00000000)) \ + | ((SPH_C64(x) << 24) & SPH_C64(0x0000FF0000000000)) \ + | ((SPH_C64(x) << 40) & SPH_C64(0x00FF000000000000)) \ + | ((SPH_C64(x) << 56) & SPH_C64(0xFF00000000000000))) +#define dec64e_aligned sph_dec64le_aligned +#define enc64e sph_enc64le +#define B64_0(x) ((x) & 0xFF) +#define B64_1(x) (((x) >> 8) & 0xFF) +#define B64_2(x) (((x) >> 16) & 0xFF) +#define B64_3(x) (((x) >> 24) & 0xFF) +#define B64_4(x) (((x) >> 32) & 0xFF) +#define B64_5(x) (((x) >> 40) & 0xFF) +#define B64_6(x) (((x) >> 48) & 0xFF) +#define B64_7(x) ((x) >> 56) +#define R64 SPH_ROTL64 +#define PC64(j, r) ((sph_u64)((j) + (r))) +#define QC64(j, r) (((sph_u64)(r) << 56) ^ SPH_T64(~((sph_u64)(j) << 56))) + +__constant static const sph_u64 T0[] = { + C64e(0xc632f4a5f497a5c6), C64e(0xf86f978497eb84f8), + C64e(0xee5eb099b0c799ee), C64e(0xf67a8c8d8cf78df6), + C64e(0xffe8170d17e50dff), C64e(0xd60adcbddcb7bdd6), + C64e(0xde16c8b1c8a7b1de), C64e(0x916dfc54fc395491), + C64e(0x6090f050f0c05060), C64e(0x0207050305040302), + C64e(0xce2ee0a9e087a9ce), C64e(0x56d1877d87ac7d56), + C64e(0xe7cc2b192bd519e7), C64e(0xb513a662a67162b5), + C64e(0x4d7c31e6319ae64d), C64e(0xec59b59ab5c39aec), + C64e(0x8f40cf45cf05458f), C64e(0x1fa3bc9dbc3e9d1f), + C64e(0x8949c040c0094089), C64e(0xfa68928792ef87fa), + C64e(0xefd03f153fc515ef), C64e(0xb29426eb267febb2), + C64e(0x8ece40c94007c98e), C64e(0xfbe61d0b1ded0bfb), + C64e(0x416e2fec2f82ec41), C64e(0xb31aa967a97d67b3), + C64e(0x5f431cfd1cbefd5f), C64e(0x456025ea258aea45), + C64e(0x23f9dabfda46bf23), C64e(0x535102f702a6f753), + C64e(0xe445a196a1d396e4), C64e(0x9b76ed5bed2d5b9b), + C64e(0x75285dc25deac275), C64e(0xe1c5241c24d91ce1), + C64e(0x3dd4e9aee97aae3d), C64e(0x4cf2be6abe986a4c), + C64e(0x6c82ee5aeed85a6c), C64e(0x7ebdc341c3fc417e), + C64e(0xf5f3060206f102f5), C64e(0x8352d14fd11d4f83), + C64e(0x688ce45ce4d05c68), C64e(0x515607f407a2f451), + C64e(0xd18d5c345cb934d1), C64e(0xf9e1180818e908f9), + C64e(0xe24cae93aedf93e2), C64e(0xab3e9573954d73ab), + C64e(0x6297f553f5c45362), C64e(0x2a6b413f41543f2a), + C64e(0x081c140c14100c08), C64e(0x9563f652f6315295), + C64e(0x46e9af65af8c6546), C64e(0x9d7fe25ee2215e9d), + C64e(0x3048782878602830), C64e(0x37cff8a1f86ea137), + C64e(0x0a1b110f11140f0a), C64e(0x2febc4b5c45eb52f), + C64e(0x0e151b091b1c090e), C64e(0x247e5a365a483624), + C64e(0x1badb69bb6369b1b), C64e(0xdf98473d47a53ddf), + C64e(0xcda76a266a8126cd), C64e(0x4ef5bb69bb9c694e), + C64e(0x7f334ccd4cfecd7f), C64e(0xea50ba9fbacf9fea), + C64e(0x123f2d1b2d241b12), C64e(0x1da4b99eb93a9e1d), + C64e(0x58c49c749cb07458), C64e(0x3446722e72682e34), + C64e(0x3641772d776c2d36), C64e(0xdc11cdb2cda3b2dc), + C64e(0xb49d29ee2973eeb4), C64e(0x5b4d16fb16b6fb5b), + C64e(0xa4a501f60153f6a4), C64e(0x76a1d74dd7ec4d76), + C64e(0xb714a361a37561b7), C64e(0x7d3449ce49face7d), + C64e(0x52df8d7b8da47b52), C64e(0xdd9f423e42a13edd), + C64e(0x5ecd937193bc715e), C64e(0x13b1a297a2269713), + C64e(0xa6a204f50457f5a6), C64e(0xb901b868b86968b9), + C64e(0x0000000000000000), C64e(0xc1b5742c74992cc1), + C64e(0x40e0a060a0806040), C64e(0xe3c2211f21dd1fe3), + C64e(0x793a43c843f2c879), C64e(0xb69a2ced2c77edb6), + C64e(0xd40dd9bed9b3bed4), C64e(0x8d47ca46ca01468d), + C64e(0x671770d970ced967), C64e(0x72afdd4bdde44b72), + C64e(0x94ed79de7933de94), C64e(0x98ff67d4672bd498), + C64e(0xb09323e8237be8b0), C64e(0x855bde4ade114a85), + C64e(0xbb06bd6bbd6d6bbb), C64e(0xc5bb7e2a7e912ac5), + C64e(0x4f7b34e5349ee54f), C64e(0xedd73a163ac116ed), + C64e(0x86d254c55417c586), C64e(0x9af862d7622fd79a), + C64e(0x6699ff55ffcc5566), C64e(0x11b6a794a7229411), + C64e(0x8ac04acf4a0fcf8a), C64e(0xe9d9301030c910e9), + C64e(0x040e0a060a080604), C64e(0xfe66988198e781fe), + C64e(0xa0ab0bf00b5bf0a0), C64e(0x78b4cc44ccf04478), + C64e(0x25f0d5bad54aba25), C64e(0x4b753ee33e96e34b), + C64e(0xa2ac0ef30e5ff3a2), C64e(0x5d4419fe19bafe5d), + C64e(0x80db5bc05b1bc080), C64e(0x0580858a850a8a05), + C64e(0x3fd3ecadec7ead3f), C64e(0x21fedfbcdf42bc21), + C64e(0x70a8d848d8e04870), C64e(0xf1fd0c040cf904f1), + C64e(0x63197adf7ac6df63), C64e(0x772f58c158eec177), + C64e(0xaf309f759f4575af), C64e(0x42e7a563a5846342), + C64e(0x2070503050403020), C64e(0xe5cb2e1a2ed11ae5), + C64e(0xfdef120e12e10efd), C64e(0xbf08b76db7656dbf), + C64e(0x8155d44cd4194c81), C64e(0x18243c143c301418), + C64e(0x26795f355f4c3526), C64e(0xc3b2712f719d2fc3), + C64e(0xbe8638e13867e1be), C64e(0x35c8fda2fd6aa235), + C64e(0x88c74fcc4f0bcc88), C64e(0x2e654b394b5c392e), + C64e(0x936af957f93d5793), C64e(0x55580df20daaf255), + C64e(0xfc619d829de382fc), C64e(0x7ab3c947c9f4477a), + C64e(0xc827efacef8bacc8), C64e(0xba8832e7326fe7ba), + C64e(0x324f7d2b7d642b32), C64e(0xe642a495a4d795e6), + C64e(0xc03bfba0fb9ba0c0), C64e(0x19aab398b3329819), + C64e(0x9ef668d16827d19e), C64e(0xa322817f815d7fa3), + C64e(0x44eeaa66aa886644), C64e(0x54d6827e82a87e54), + C64e(0x3bdde6abe676ab3b), C64e(0x0b959e839e16830b), + C64e(0x8cc945ca4503ca8c), C64e(0xc7bc7b297b9529c7), + C64e(0x6b056ed36ed6d36b), C64e(0x286c443c44503c28), + C64e(0xa72c8b798b5579a7), C64e(0xbc813de23d63e2bc), + C64e(0x1631271d272c1d16), C64e(0xad379a769a4176ad), + C64e(0xdb964d3b4dad3bdb), C64e(0x649efa56fac85664), + C64e(0x74a6d24ed2e84e74), C64e(0x1436221e22281e14), + C64e(0x92e476db763fdb92), C64e(0x0c121e0a1e180a0c), + C64e(0x48fcb46cb4906c48), C64e(0xb88f37e4376be4b8), + C64e(0x9f78e75de7255d9f), C64e(0xbd0fb26eb2616ebd), + C64e(0x43692aef2a86ef43), C64e(0xc435f1a6f193a6c4), + C64e(0x39dae3a8e372a839), C64e(0x31c6f7a4f762a431), + C64e(0xd38a593759bd37d3), C64e(0xf274868b86ff8bf2), + C64e(0xd583563256b132d5), C64e(0x8b4ec543c50d438b), + C64e(0x6e85eb59ebdc596e), C64e(0xda18c2b7c2afb7da), + C64e(0x018e8f8c8f028c01), C64e(0xb11dac64ac7964b1), + C64e(0x9cf16dd26d23d29c), C64e(0x49723be03b92e049), + C64e(0xd81fc7b4c7abb4d8), C64e(0xacb915fa1543faac), + C64e(0xf3fa090709fd07f3), C64e(0xcfa06f256f8525cf), + C64e(0xca20eaafea8fafca), C64e(0xf47d898e89f38ef4), + C64e(0x476720e9208ee947), C64e(0x1038281828201810), + C64e(0x6f0b64d564ded56f), C64e(0xf073838883fb88f0), + C64e(0x4afbb16fb1946f4a), C64e(0x5cca967296b8725c), + C64e(0x38546c246c702438), C64e(0x575f08f108aef157), + C64e(0x732152c752e6c773), C64e(0x9764f351f3355197), + C64e(0xcbae6523658d23cb), C64e(0xa125847c84597ca1), + C64e(0xe857bf9cbfcb9ce8), C64e(0x3e5d6321637c213e), + C64e(0x96ea7cdd7c37dd96), C64e(0x611e7fdc7fc2dc61), + C64e(0x0d9c9186911a860d), C64e(0x0f9b9485941e850f), + C64e(0xe04bab90abdb90e0), C64e(0x7cbac642c6f8427c), + C64e(0x712657c457e2c471), C64e(0xcc29e5aae583aacc), + C64e(0x90e373d8733bd890), C64e(0x06090f050f0c0506), + C64e(0xf7f4030103f501f7), C64e(0x1c2a36123638121c), + C64e(0xc23cfea3fe9fa3c2), C64e(0x6a8be15fe1d45f6a), + C64e(0xaebe10f91047f9ae), C64e(0x69026bd06bd2d069), + C64e(0x17bfa891a82e9117), C64e(0x9971e858e8295899), + C64e(0x3a5369276974273a), C64e(0x27f7d0b9d04eb927), + C64e(0xd991483848a938d9), C64e(0xebde351335cd13eb), + C64e(0x2be5ceb3ce56b32b), C64e(0x2277553355443322), + C64e(0xd204d6bbd6bfbbd2), C64e(0xa9399070904970a9), + C64e(0x07878089800e8907), C64e(0x33c1f2a7f266a733), + C64e(0x2decc1b6c15ab62d), C64e(0x3c5a66226678223c), + C64e(0x15b8ad92ad2a9215), C64e(0xc9a96020608920c9), + C64e(0x875cdb49db154987), C64e(0xaab01aff1a4fffaa), + C64e(0x50d8887888a07850), C64e(0xa52b8e7a8e517aa5), + C64e(0x03898a8f8a068f03), C64e(0x594a13f813b2f859), + C64e(0x09929b809b128009), C64e(0x1a2339173934171a), + C64e(0x651075da75cada65), C64e(0xd784533153b531d7), + C64e(0x84d551c65113c684), C64e(0xd003d3b8d3bbb8d0), + C64e(0x82dc5ec35e1fc382), C64e(0x29e2cbb0cb52b029), + C64e(0x5ac3997799b4775a), C64e(0x1e2d3311333c111e), + C64e(0x7b3d46cb46f6cb7b), C64e(0xa8b71ffc1f4bfca8), + C64e(0x6d0c61d661dad66d), C64e(0x2c624e3a4e583a2c) +}; + +__constant static const sph_u64 T4[] = { + C64e(0xf497a5c6c632f4a5), C64e(0x97eb84f8f86f9784), + C64e(0xb0c799eeee5eb099), C64e(0x8cf78df6f67a8c8d), + C64e(0x17e50dffffe8170d), C64e(0xdcb7bdd6d60adcbd), + C64e(0xc8a7b1dede16c8b1), C64e(0xfc395491916dfc54), + C64e(0xf0c050606090f050), C64e(0x0504030202070503), + C64e(0xe087a9cece2ee0a9), C64e(0x87ac7d5656d1877d), + C64e(0x2bd519e7e7cc2b19), C64e(0xa67162b5b513a662), + C64e(0x319ae64d4d7c31e6), C64e(0xb5c39aecec59b59a), + C64e(0xcf05458f8f40cf45), C64e(0xbc3e9d1f1fa3bc9d), + C64e(0xc00940898949c040), C64e(0x92ef87fafa689287), + C64e(0x3fc515efefd03f15), C64e(0x267febb2b29426eb), + C64e(0x4007c98e8ece40c9), C64e(0x1ded0bfbfbe61d0b), + C64e(0x2f82ec41416e2fec), C64e(0xa97d67b3b31aa967), + C64e(0x1cbefd5f5f431cfd), C64e(0x258aea45456025ea), + C64e(0xda46bf2323f9dabf), C64e(0x02a6f753535102f7), + C64e(0xa1d396e4e445a196), C64e(0xed2d5b9b9b76ed5b), + C64e(0x5deac27575285dc2), C64e(0x24d91ce1e1c5241c), + C64e(0xe97aae3d3dd4e9ae), C64e(0xbe986a4c4cf2be6a), + C64e(0xeed85a6c6c82ee5a), C64e(0xc3fc417e7ebdc341), + C64e(0x06f102f5f5f30602), C64e(0xd11d4f838352d14f), + C64e(0xe4d05c68688ce45c), C64e(0x07a2f451515607f4), + C64e(0x5cb934d1d18d5c34), C64e(0x18e908f9f9e11808), + C64e(0xaedf93e2e24cae93), C64e(0x954d73abab3e9573), + C64e(0xf5c453626297f553), C64e(0x41543f2a2a6b413f), + C64e(0x14100c08081c140c), C64e(0xf63152959563f652), + C64e(0xaf8c654646e9af65), C64e(0xe2215e9d9d7fe25e), + C64e(0x7860283030487828), C64e(0xf86ea13737cff8a1), + C64e(0x11140f0a0a1b110f), C64e(0xc45eb52f2febc4b5), + C64e(0x1b1c090e0e151b09), C64e(0x5a483624247e5a36), + C64e(0xb6369b1b1badb69b), C64e(0x47a53ddfdf98473d), + C64e(0x6a8126cdcda76a26), C64e(0xbb9c694e4ef5bb69), + C64e(0x4cfecd7f7f334ccd), C64e(0xbacf9feaea50ba9f), + C64e(0x2d241b12123f2d1b), C64e(0xb93a9e1d1da4b99e), + C64e(0x9cb0745858c49c74), C64e(0x72682e343446722e), + C64e(0x776c2d363641772d), C64e(0xcda3b2dcdc11cdb2), + C64e(0x2973eeb4b49d29ee), C64e(0x16b6fb5b5b4d16fb), + C64e(0x0153f6a4a4a501f6), C64e(0xd7ec4d7676a1d74d), + C64e(0xa37561b7b714a361), C64e(0x49face7d7d3449ce), + C64e(0x8da47b5252df8d7b), C64e(0x42a13edddd9f423e), + C64e(0x93bc715e5ecd9371), C64e(0xa226971313b1a297), + C64e(0x0457f5a6a6a204f5), C64e(0xb86968b9b901b868), + C64e(0x0000000000000000), C64e(0x74992cc1c1b5742c), + C64e(0xa080604040e0a060), C64e(0x21dd1fe3e3c2211f), + C64e(0x43f2c879793a43c8), C64e(0x2c77edb6b69a2ced), + C64e(0xd9b3bed4d40dd9be), C64e(0xca01468d8d47ca46), + C64e(0x70ced967671770d9), C64e(0xdde44b7272afdd4b), + C64e(0x7933de9494ed79de), C64e(0x672bd49898ff67d4), + C64e(0x237be8b0b09323e8), C64e(0xde114a85855bde4a), + C64e(0xbd6d6bbbbb06bd6b), C64e(0x7e912ac5c5bb7e2a), + C64e(0x349ee54f4f7b34e5), C64e(0x3ac116ededd73a16), + C64e(0x5417c58686d254c5), C64e(0x622fd79a9af862d7), + C64e(0xffcc55666699ff55), C64e(0xa722941111b6a794), + C64e(0x4a0fcf8a8ac04acf), C64e(0x30c910e9e9d93010), + C64e(0x0a080604040e0a06), C64e(0x98e781fefe669881), + C64e(0x0b5bf0a0a0ab0bf0), C64e(0xccf0447878b4cc44), + C64e(0xd54aba2525f0d5ba), C64e(0x3e96e34b4b753ee3), + C64e(0x0e5ff3a2a2ac0ef3), C64e(0x19bafe5d5d4419fe), + C64e(0x5b1bc08080db5bc0), C64e(0x850a8a050580858a), + C64e(0xec7ead3f3fd3ecad), C64e(0xdf42bc2121fedfbc), + C64e(0xd8e0487070a8d848), C64e(0x0cf904f1f1fd0c04), + C64e(0x7ac6df6363197adf), C64e(0x58eec177772f58c1), + C64e(0x9f4575afaf309f75), C64e(0xa584634242e7a563), + C64e(0x5040302020705030), C64e(0x2ed11ae5e5cb2e1a), + C64e(0x12e10efdfdef120e), C64e(0xb7656dbfbf08b76d), + C64e(0xd4194c818155d44c), C64e(0x3c30141818243c14), + C64e(0x5f4c352626795f35), C64e(0x719d2fc3c3b2712f), + C64e(0x3867e1bebe8638e1), C64e(0xfd6aa23535c8fda2), + C64e(0x4f0bcc8888c74fcc), C64e(0x4b5c392e2e654b39), + C64e(0xf93d5793936af957), C64e(0x0daaf25555580df2), + C64e(0x9de382fcfc619d82), C64e(0xc9f4477a7ab3c947), + C64e(0xef8bacc8c827efac), C64e(0x326fe7baba8832e7), + C64e(0x7d642b32324f7d2b), C64e(0xa4d795e6e642a495), + C64e(0xfb9ba0c0c03bfba0), C64e(0xb332981919aab398), + C64e(0x6827d19e9ef668d1), C64e(0x815d7fa3a322817f), + C64e(0xaa88664444eeaa66), C64e(0x82a87e5454d6827e), + C64e(0xe676ab3b3bdde6ab), C64e(0x9e16830b0b959e83), + C64e(0x4503ca8c8cc945ca), C64e(0x7b9529c7c7bc7b29), + C64e(0x6ed6d36b6b056ed3), C64e(0x44503c28286c443c), + C64e(0x8b5579a7a72c8b79), C64e(0x3d63e2bcbc813de2), + C64e(0x272c1d161631271d), C64e(0x9a4176adad379a76), + C64e(0x4dad3bdbdb964d3b), C64e(0xfac85664649efa56), + C64e(0xd2e84e7474a6d24e), C64e(0x22281e141436221e), + C64e(0x763fdb9292e476db), C64e(0x1e180a0c0c121e0a), + C64e(0xb4906c4848fcb46c), C64e(0x376be4b8b88f37e4), + C64e(0xe7255d9f9f78e75d), C64e(0xb2616ebdbd0fb26e), + C64e(0x2a86ef4343692aef), C64e(0xf193a6c4c435f1a6), + C64e(0xe372a83939dae3a8), C64e(0xf762a43131c6f7a4), + C64e(0x59bd37d3d38a5937), C64e(0x86ff8bf2f274868b), + C64e(0x56b132d5d5835632), C64e(0xc50d438b8b4ec543), + C64e(0xebdc596e6e85eb59), C64e(0xc2afb7dada18c2b7), + C64e(0x8f028c01018e8f8c), C64e(0xac7964b1b11dac64), + C64e(0x6d23d29c9cf16dd2), C64e(0x3b92e04949723be0), + C64e(0xc7abb4d8d81fc7b4), C64e(0x1543faacacb915fa), + C64e(0x09fd07f3f3fa0907), C64e(0x6f8525cfcfa06f25), + C64e(0xea8fafcaca20eaaf), C64e(0x89f38ef4f47d898e), + C64e(0x208ee947476720e9), C64e(0x2820181010382818), + C64e(0x64ded56f6f0b64d5), C64e(0x83fb88f0f0738388), + C64e(0xb1946f4a4afbb16f), C64e(0x96b8725c5cca9672), + C64e(0x6c70243838546c24), C64e(0x08aef157575f08f1), + C64e(0x52e6c773732152c7), C64e(0xf33551979764f351), + C64e(0x658d23cbcbae6523), C64e(0x84597ca1a125847c), + C64e(0xbfcb9ce8e857bf9c), C64e(0x637c213e3e5d6321), + C64e(0x7c37dd9696ea7cdd), C64e(0x7fc2dc61611e7fdc), + C64e(0x911a860d0d9c9186), C64e(0x941e850f0f9b9485), + C64e(0xabdb90e0e04bab90), C64e(0xc6f8427c7cbac642), + C64e(0x57e2c471712657c4), C64e(0xe583aacccc29e5aa), + C64e(0x733bd89090e373d8), C64e(0x0f0c050606090f05), + C64e(0x03f501f7f7f40301), C64e(0x3638121c1c2a3612), + C64e(0xfe9fa3c2c23cfea3), C64e(0xe1d45f6a6a8be15f), + C64e(0x1047f9aeaebe10f9), C64e(0x6bd2d06969026bd0), + C64e(0xa82e911717bfa891), C64e(0xe82958999971e858), + C64e(0x6974273a3a536927), C64e(0xd04eb92727f7d0b9), + C64e(0x48a938d9d9914838), C64e(0x35cd13ebebde3513), + C64e(0xce56b32b2be5ceb3), C64e(0x5544332222775533), + C64e(0xd6bfbbd2d204d6bb), C64e(0x904970a9a9399070), + C64e(0x800e890707878089), C64e(0xf266a73333c1f2a7), + C64e(0xc15ab62d2decc1b6), C64e(0x6678223c3c5a6622), + C64e(0xad2a921515b8ad92), C64e(0x608920c9c9a96020), + C64e(0xdb154987875cdb49), C64e(0x1a4fffaaaab01aff), + C64e(0x88a0785050d88878), C64e(0x8e517aa5a52b8e7a), + C64e(0x8a068f0303898a8f), C64e(0x13b2f859594a13f8), + C64e(0x9b12800909929b80), C64e(0x3934171a1a233917), + C64e(0x75cada65651075da), C64e(0x53b531d7d7845331), + C64e(0x5113c68484d551c6), C64e(0xd3bbb8d0d003d3b8), + C64e(0x5e1fc38282dc5ec3), C64e(0xcb52b02929e2cbb0), + C64e(0x99b4775a5ac39977), C64e(0x333c111e1e2d3311), + C64e(0x46f6cb7b7b3d46cb), C64e(0x1f4bfca8a8b71ffc), + C64e(0x61dad66d6d0c61d6), C64e(0x4e583a2c2c624e3a) +}; + +#define RSTT(d, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ + t[d] = T0[B64_0(a[b0])] \ + ^ R64(T0[B64_1(a[b1])], 8) \ + ^ R64(T0[B64_2(a[b2])], 16) \ + ^ R64(T0[B64_3(a[b3])], 24) \ + ^ T4[B64_4(a[b4])] \ + ^ R64(T4[B64_5(a[b5])], 8) \ + ^ R64(T4[B64_6(a[b6])], 16) \ + ^ R64(T4[B64_7(a[b7])], 24); \ + } while (0) + +#define ROUND_SMALL_P(a, r) do { \ + a[0] ^= PC64(0x00, r); \ + a[1] ^= PC64(0x10, r); \ + a[2] ^= PC64(0x20, r); \ + a[3] ^= PC64(0x30, r); \ + a[4] ^= PC64(0x40, r); \ + a[5] ^= PC64(0x50, r); \ + a[6] ^= PC64(0x60, r); \ + a[7] ^= PC64(0x70, r); \ + RSTT(0, a, 0, 1, 2, 3, 4, 5, 6, 7); \ + RSTT(1, a, 1, 2, 3, 4, 5, 6, 7, 0); \ + RSTT(2, a, 2, 3, 4, 5, 6, 7, 0, 1); \ + RSTT(3, a, 3, 4, 5, 6, 7, 0, 1, 2); \ + RSTT(4, a, 4, 5, 6, 7, 0, 1, 2, 3); \ + RSTT(5, a, 5, 6, 7, 0, 1, 2, 3, 4); \ + RSTT(6, a, 6, 7, 0, 1, 2, 3, 4, 5); \ + RSTT(7, a, 7, 0, 1, 2, 3, 4, 5, 6); \ + a[0] = t[0]; \ + a[1] = t[1]; \ + a[2] = t[2]; \ + a[3] = t[3]; \ + a[4] = t[4]; \ + a[5] = t[5]; \ + a[6] = t[6]; \ + a[7] = t[7]; \ + } while (0) + +#define ROUND_SMALL_Pf(a, r) do { \ + a[0] ^= PC64(0x00, r); \ + a[1] ^= PC64(0x10, r); \ + a[2] ^= PC64(0x20, r); \ + a[3] ^= PC64(0x30, r); \ + a[4] ^= PC64(0x40, r); \ + a[5] ^= PC64(0x50, r); \ + a[6] ^= PC64(0x60, r); \ + a[7] ^= PC64(0x70, r); \ + RSTT(7, a, 7, 0, 1, 2, 3, 4, 5, 6); \ + a[7] = t[7]; \ + } while (0) + +#define ROUND_SMALL_Q(a, r) do { \ + a[0] ^= QC64(0x00, r); \ + a[1] ^= QC64(0x10, r); \ + a[2] ^= QC64(0x20, r); \ + a[3] ^= QC64(0x30, r); \ + a[4] ^= QC64(0x40, r); \ + a[5] ^= QC64(0x50, r); \ + a[6] ^= QC64(0x60, r); \ + a[7] ^= QC64(0x70, r); \ + RSTT(0, a, 1, 3, 5, 7, 0, 2, 4, 6); \ + RSTT(1, a, 2, 4, 6, 0, 1, 3, 5, 7); \ + RSTT(2, a, 3, 5, 7, 1, 2, 4, 6, 0); \ + RSTT(3, a, 4, 6, 0, 2, 3, 5, 7, 1); \ + RSTT(4, a, 5, 7, 1, 3, 4, 6, 0, 2); \ + RSTT(5, a, 6, 0, 2, 4, 5, 7, 1, 3); \ + RSTT(6, a, 7, 1, 3, 5, 6, 0, 2, 4); \ + RSTT(7, a, 0, 2, 4, 6, 7, 1, 3, 5); \ + a[0] = t[0]; \ + a[1] = t[1]; \ + a[2] = t[2]; \ + a[3] = t[3]; \ + a[4] = t[4]; \ + a[5] = t[5]; \ + a[6] = t[6]; \ + a[7] = t[7]; \ + } while (0) + +#define PERM_SMALL_P(a) do { \ + for (int r = 0; r < 10; r ++) \ + ROUND_SMALL_P(a, r); \ + } while (0) + +#define PERM_SMALL_Pf(a) do { \ + for (int r = 0; r < 9; r ++) { \ + ROUND_SMALL_P(a, r);} \ + ROUND_SMALL_Pf(a,9); \ + } while (0) + +#define PERM_SMALL_Q(a) do { \ + for (int r = 0; r < 10; r ++) \ + ROUND_SMALL_Q(a, r); \ + } while (0) + diff --git a/kernel/keccak1600.cl b/kernel/keccak1600.cl new file mode 100644 index 000000000..d870a155e --- /dev/null +++ b/kernel/keccak1600.cl @@ -0,0 +1,84 @@ +/* + * keccak_1600 function + * C. Buchner 2014 + * + */ + +__constant static const sph_u64 RC[] = { + SPH_C64(0x0000000000000001), SPH_C64(0x0000000000008082), + SPH_C64(0x800000000000808A), SPH_C64(0x8000000080008000), + SPH_C64(0x000000000000808B), SPH_C64(0x0000000080000001), + SPH_C64(0x8000000080008081), SPH_C64(0x8000000000008009), + SPH_C64(0x000000000000008A), SPH_C64(0x0000000000000088), + SPH_C64(0x0000000080008009), SPH_C64(0x000000008000000A), + SPH_C64(0x000000008000808B), SPH_C64(0x800000000000008B), + SPH_C64(0x8000000000008089), SPH_C64(0x8000000000008003), + SPH_C64(0x8000000000008002), SPH_C64(0x8000000000000080), + SPH_C64(0x000000000000800A), SPH_C64(0x800000008000000A), + SPH_C64(0x8000000080008081), SPH_C64(0x8000000000008080), + SPH_C64(0x0000000080000001), SPH_C64(0x8000000080008008) +}; + + +inline void keccak_block(ulong *s) { + size_t i; + ulong t[5], u[5], v, w; + + for (i = 0; i < 24; i++) { + /* theta: c = a[0,i] ^ a[1,i] ^ .. a[4,i] */ + t[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20]; + t[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21]; + t[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22]; + t[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23]; + t[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24]; + + /* theta: d[i] = c[i+4] ^ rotl(c[i+1],1) */ + u[0] = t[4] ^ SPH_ROTL64(t[1], 1); + u[1] = t[0] ^ SPH_ROTL64(t[2], 1); + u[2] = t[1] ^ SPH_ROTL64(t[3], 1); + u[3] = t[2] ^ SPH_ROTL64(t[4], 1); + u[4] = t[3] ^ SPH_ROTL64(t[0], 1); + + /* theta: a[0,i], a[1,i], .. a[4,i] ^= d[i] */ + s[0] ^= u[0]; s[5] ^= u[0]; s[10] ^= u[0]; s[15] ^= u[0]; s[20] ^= u[0]; + s[1] ^= u[1]; s[6] ^= u[1]; s[11] ^= u[1]; s[16] ^= u[1]; s[21] ^= u[1]; + s[2] ^= u[2]; s[7] ^= u[2]; s[12] ^= u[2]; s[17] ^= u[2]; s[22] ^= u[2]; + s[3] ^= u[3]; s[8] ^= u[3]; s[13] ^= u[3]; s[18] ^= u[3]; s[23] ^= u[3]; + s[4] ^= u[4]; s[9] ^= u[4]; s[14] ^= u[4]; s[19] ^= u[4]; s[24] ^= u[4]; + + /* rho pi: b[..] = rotl(a[..], ..) */ + v = s[1]; + s[1] = SPH_ROTL64(s[6], 44); + s[6] = SPH_ROTL64(s[9], 20); + s[9] = SPH_ROTL64(s[22], 61); + s[22] = SPH_ROTL64(s[14], 39); + s[14] = SPH_ROTL64(s[20], 18); + s[20] = SPH_ROTL64(s[2], 62); + s[2] = SPH_ROTL64(s[12], 43); + s[12] = SPH_ROTL64(s[13], 25); + s[13] = SPH_ROTL64(s[19], 8); + s[19] = SPH_ROTL64(s[23], 56); + s[23] = SPH_ROTL64(s[15], 41); + s[15] = SPH_ROTL64(s[4], 27); + s[4] = SPH_ROTL64(s[24], 14); + s[24] = SPH_ROTL64(s[21], 2); + s[21] = SPH_ROTL64(s[8], 55); + s[8] = SPH_ROTL64(s[16], 45); + s[16] = SPH_ROTL64(s[5], 36); + s[5] = SPH_ROTL64(s[3], 28); + s[3] = SPH_ROTL64(s[18], 21); + s[18] = SPH_ROTL64(s[17], 15); + s[17] = SPH_ROTL64(s[11], 10); + s[11] = SPH_ROTL64(s[7], 6); + s[7] = SPH_ROTL64(s[10], 3); + s[10] = SPH_ROTL64(v, 1); + + v = s[0]; w = s[1]; s[0] ^= (~w) & s[2]; s[1] ^= (~s[2]) & s[3]; s[2] ^= (~s[3]) & s[4]; s[3] ^= (~s[4]) & v; s[4] ^= (~v) & w; + v = s[5]; w = s[6]; s[5] ^= (~w) & s[7]; s[6] ^= (~s[7]) & s[8]; s[7] ^= (~s[8]) & s[9]; s[8] ^= (~s[9]) & v; s[9] ^= (~v) & w; + v = s[10]; w = s[11]; s[10] ^= (~w) & s[12]; s[11] ^= (~s[12]) & s[13]; s[12] ^= (~s[13]) & s[14]; s[13] ^= (~s[14]) & v; s[14] ^= (~v) & w; + v = s[15]; w = s[16]; s[15] ^= (~w) & s[17]; s[16] ^= (~s[17]) & s[18]; s[17] ^= (~s[18]) & s[19]; s[18] ^= (~s[19]) & v; s[19] ^= (~v) & w; + v = s[20]; w = s[21]; s[20] ^= (~w) & s[22]; s[21] ^= (~s[22]) & s[23]; s[22] ^= (~s[23]) & s[24]; s[23] ^= (~s[24]) & v; s[24] ^= (~v) & w; + + s[0] ^= RC[i]; + } +}; \ No newline at end of file diff --git a/kernel/skein256.cl b/kernel/skein256.cl new file mode 100644 index 000000000..8a5e8481f --- /dev/null +++ b/kernel/skein256.cl @@ -0,0 +1,107 @@ + +/* +* skein256 kernel implementation. +* +* ==========================(LICENSE BEGIN)============================ +* Copyright (c) 2014 djm34 +* +* 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 djm34 +*/ + + +__constant static const sph_u64 SKEIN_IV512[] = { + SPH_C64(0x4903ADFF749C51CE), SPH_C64(0x0D95DE399746DF03), + SPH_C64(0x8FD1934127C79BCE), SPH_C64(0x9A255629FF352CB1), + SPH_C64(0x5DB62599DF6CA7B0), SPH_C64(0xEABE394CA9D5C3F4), + SPH_C64(0x991112C71A75B523), SPH_C64(0xAE18A40B660FCC33) +}; + +__constant static const sph_u64 SKEIN_IV512_256[8] = { + 0xCCD044A12FDB3E13UL, 0xE83590301A79A9EBUL, + 0x55AEA0614F816E6FUL, 0x2A2767A4AE9B94DBUL, + 0xEC06025E74DD7683UL, 0xE7A436CDC4746251UL, + 0xC36FBAF9393AD185UL, 0x3EEDBA1833EDFC13UL +}; + + + +__constant static const int ROT256[8][4] = +{ + 46, 36, 19, 37, + 33, 27, 14, 42, + 17, 49, 36, 39, + 44, 9, 54, 56, + 39, 30, 34, 24, + 13, 50, 10, 17, + 25, 29, 39, 43, + 8, 35, 56, 22, +}; + +__constant static const sph_u64 skein_ks_parity = 0x1BD11BDAA9FC1A22; + +__constant static const sph_u64 t12[6] = +{ 0x20UL, +0xf000000000000000UL, +0xf000000000000020UL, +0x08UL, +0xff00000000000000UL, +0xff00000000000008UL +}; +static inline ulong ROTL64(const ulong v, const ulong n){ + return rotate(v,n); +} + +#define Round512(p0,p1,p2,p3,p4,p5,p6,p7,ROT) { \ +p0 += p1; p1 = SPH_ROTL64(p1, ROT256[ROT][0]); p1 ^= p0; \ +p2 += p3; p3 = SPH_ROTL64(p3, ROT256[ROT][1]); p3 ^= p2; \ +p4 += p5; p5 = SPH_ROTL64(p5, ROT256[ROT][2]); p5 ^= p4; \ +p6 += p7; p7 = SPH_ROTL64(p7, ROT256[ROT][3]); p7 ^= p6; \ +} + +#define Round_8_512(p0, p1, p2, p3, p4, p5, p6, p7, R) { \ + Round512(p0, p1, p2, p3, p4, p5, p6, p7, 0); \ + Round512(p2, p1, p4, p7, p6, p5, p0, p3, 1); \ + Round512(p4, p1, p6, p3, p0, p5, p2, p7, 2); \ + Round512(p6, p1, p0, p7, p2, p5, p4, p3, 3); \ + p0 += h[((R)+0) % 9]; \ + p1 += h[((R)+1) % 9]; \ + p2 += h[((R)+2) % 9]; \ + p3 += h[((R)+3) % 9]; \ + p4 += h[((R)+4) % 9]; \ + p5 += h[((R)+5) % 9] + t[((R)+0) % 3]; \ + p6 += h[((R)+6) % 9] + t[((R)+1) % 3]; \ + p7 += h[((R)+7) % 9] + R; \ + Round512(p0, p1, p2, p3, p4, p5, p6, p7, 4); \ + Round512(p2, p1, p4, p7, p6, p5, p0, p3, 5); \ + Round512(p4, p1, p6, p3, p0, p5, p2, p7, 6); \ + Round512(p6, p1, p0, p7, p2, p5, p4, p3, 7); \ + p0 += h[((R)+1) % 9]; \ + p1 += h[((R)+2) % 9]; \ + p2 += h[((R)+3) % 9]; \ + p3 += h[((R)+4) % 9]; \ + p4 += h[((R)+5) % 9]; \ + p5 += h[((R)+6) % 9] + t[((R)+1) % 3]; \ + p6 += h[((R)+7) % 9] + t[((R)+2) % 3]; \ + p7 += h[((R)+8) % 9] + (R+1); \ +} \ No newline at end of file diff --git a/miner.h b/miner.h index 206d2763f..9917fdeb3 100644 --- a/miner.h +++ b/miner.h @@ -1013,6 +1013,7 @@ extern bool opt_protocol; extern bool have_longpoll; extern char *opt_kernel_path; extern char *opt_socks_proxy; +extern bool opt_lyra; #if defined(unix) || defined(__APPLE__) extern char *opt_stderr_cmd; diff --git a/sgminer.c b/sgminer.c index f3e409334..97f4fae33 100644 --- a/sgminer.c +++ b/sgminer.c @@ -48,6 +48,7 @@ char *curly = ":D"; #endif #include #include "sph/sph_sha2.h" +#include "sph/sph_blake.h" #include "compat.h" #include "miner.h" @@ -1922,6 +1923,7 @@ static void calc_midstate(struct work *work) endian_flip32(work->midstate, work->midstate); } + static struct work *make_work(void) { struct work *w = (struct work *)calloc(1, sizeof(struct work)); From d53f3cfa5cf8646439b9f8ac568ad2a6919d4920 Mon Sep 17 00:00:00 2001 From: djm34 Date: Thu, 11 Dec 2014 23:43:54 +0100 Subject: [PATCH 02/27] lyra2re missing file --- algorithm.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/algorithm.h b/algorithm.h index bbe63beb3..a121be198 100644 --- a/algorithm.h +++ b/algorithm.h @@ -25,7 +25,8 @@ typedef enum { ALGO_NIST, ALGO_FRESH, ALGO_WHIRL, - ALGO_NEOSCRYPT + ALGO_NEOSCRYPT, + ALGO_LYRA2RE } algorithm_type_t; extern const char *algorithm_type_str[]; From fbbe09a938c45bdd1d89cbc21d36276c19e31f36 Mon Sep 17 00:00:00 2001 From: djm34 Date: Fri, 12 Dec 2014 00:13:39 +0100 Subject: [PATCH 03/27] lyra2re --- Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.am b/Makefile.am index f0e63de9b..f70986b5b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -68,6 +68,7 @@ sgminer_SOURCES += algorithm/x14.c algorithm/x14.h sgminer_SOURCES += algorithm/fresh.c algorithm/fresh.h sgminer_SOURCES += algorithm/whirlcoin.c algorithm/whirlcoin.h sgminer_SOURCES += algorithm/neoscrypt.c algorithm/neoscrypt.h +sgminer_SOURCES += algorithm/Lyra2RE.c algorithm/Lyra2RE.h algorithm/Lyra2.c algorithm/Lyra2.h algorithm/Sponge.c algorithm/Sponge.h bin_SCRIPTS = $(top_srcdir)/kernel/*.cl From 5a522ee1edc06fb4d82061c3e65cd921e7d99f51 Mon Sep 17 00:00:00 2001 From: djm34 Date: Sat, 13 Dec 2014 04:44:06 +0100 Subject: [PATCH 04/27] lyra2re change in difficulty no difficulty adjustment --- algorithm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/algorithm.c b/algorithm.c index eba19f6f6..2dbb6ea66 100644 --- a/algorithm.c +++ b/algorithm.c @@ -753,7 +753,7 @@ static algorithm_settings_t algos[] = { { "fresh", ALGO_FRESH, "", 1, 256, 256, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 4, 4 * 16 * 4194304, 0, fresh_regenhash, queue_fresh_kernel, gen_hash, NULL}, - { "Lyra2RE", ALGO_LYRA2RE, "", 1, 64, 64, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 4,2 * 8 * 4194304 , 0, lyra2re_regenhash, queue_lyra2RE_kernel, gen_hash, NULL}, + { "Lyra2RE", ALGO_LYRA2RE, "", 1, 1, 1, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 4,2 * 8 * 4194304 , 0, lyra2re_regenhash, queue_lyra2RE_kernel, gen_hash, NULL}, // kernels starting from this will have difficulty calculated by using fuguecoin algorithm #define A_FUGUE(a, b, c) \ From 084dbc98f6ed35f27552d565a85243ecb3370067 Mon Sep 17 00:00:00 2001 From: djm34 Date: Sat, 13 Dec 2014 15:52:47 +0100 Subject: [PATCH 05/27] change back difficulty adjustment to 128 --- algorithm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/algorithm.c b/algorithm.c index 2dbb6ea66..6ea4b3501 100644 --- a/algorithm.c +++ b/algorithm.c @@ -753,7 +753,7 @@ static algorithm_settings_t algos[] = { { "fresh", ALGO_FRESH, "", 1, 256, 256, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 4, 4 * 16 * 4194304, 0, fresh_regenhash, queue_fresh_kernel, gen_hash, NULL}, - { "Lyra2RE", ALGO_LYRA2RE, "", 1, 1, 1, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 4,2 * 8 * 4194304 , 0, lyra2re_regenhash, queue_lyra2RE_kernel, gen_hash, NULL}, + { "Lyra2RE", ALGO_LYRA2RE, "", 1, 128, 128, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 4,2 * 8 * 4194304 , 0, lyra2re_regenhash, queue_lyra2RE_kernel, gen_hash, NULL}, // kernels starting from this will have difficulty calculated by using fuguecoin algorithm #define A_FUGUE(a, b, c) \ From 87d7abef81b2f084453e5f26809446021e4cb9b3 Mon Sep 17 00:00:00 2001 From: djm34 Date: Thu, 18 Dec 2014 19:11:01 +0100 Subject: [PATCH 06/27] change in target uint type --- algorithm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/algorithm.c b/algorithm.c index 6ea4b3501..2e2241529 100644 --- a/algorithm.c +++ b/algorithm.c @@ -218,10 +218,10 @@ static cl_int queue_lyra2RE_kernel(struct __clState *clState, struct _dev_blk_ct cl_kernel *kernel; unsigned int num; cl_int status = 0; - cl_uint le_target; + cl_ulong le_target; - le_target = *(cl_uint *)(blk->work->device_target + 28); -// le_target = *(cl_ulong *)(blk->work->device_target + 24); +// le_target = *(cl_uint *)(blk->work->device_target + 28); + le_target = *(cl_ulong *)(blk->work->device_target + 24); flip80(clState->cldata, blk->work->data); status = clEnqueueWriteBuffer(clState->commandQueue, clState->CLbuffer0, true, 0, 80, clState->cldata, 0, NULL, NULL); @@ -753,7 +753,7 @@ static algorithm_settings_t algos[] = { { "fresh", ALGO_FRESH, "", 1, 256, 256, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 4, 4 * 16 * 4194304, 0, fresh_regenhash, queue_fresh_kernel, gen_hash, NULL}, - { "Lyra2RE", ALGO_LYRA2RE, "", 1, 128, 128, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 4,2 * 8 * 4194304 , 0, lyra2re_regenhash, queue_lyra2RE_kernel, gen_hash, NULL}, + { "Lyra2RE", ALGO_LYRA2RE, "", 1, 256, 256, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 4,2 * 8 * 4194304 , 0, lyra2re_regenhash, queue_lyra2RE_kernel, gen_hash, NULL}, // kernels starting from this will have difficulty calculated by using fuguecoin algorithm #define A_FUGUE(a, b, c) \ From 67046b3e82d5b72c0faa5a51dc90ef3e39fdcb33 Mon Sep 17 00:00:00 2001 From: djm34 Date: Thu, 18 Dec 2014 19:35:22 +0100 Subject: [PATCH 07/27] new kernels (faster) --- kernel/Lyra2.cl | 55 +- kernel/Lyra2RE.cl | 173 +++- kernel/groestl.cl | 133 ++- kernel/groestl256.cl | 1116 ++++++++++++++++++++--- kernel/groestlcoin-v1.cl | 1854 ++++++++++++++++++++++++++++++++++++++ kernel/skein256.cl | 4 +- 6 files changed, 3140 insertions(+), 195 deletions(-) create mode 100644 kernel/groestlcoin-v1.cl diff --git a/kernel/Lyra2.cl b/kernel/Lyra2.cl index 24aa5eb85..276e0c4e5 100644 --- a/kernel/Lyra2.cl +++ b/kernel/Lyra2.cl @@ -39,18 +39,51 @@ __constant static const sph_u64 blake2b_IV[8] = }; /*Blake2b's rotation*/ -static inline sph_u64 rotr64( const sph_u64 w, const unsigned c ){ - return rotate(w, (ulong)(64-c)); -} -/*Blake2b's G function*/ + +static inline uint2 ror2(uint2 v, unsigned a) { + uint2 result; + unsigned n = 64 - a; + if (n == 32) { return (uint2)(v.y,v.x); } + if (n < 32) { + result.y = ((v.y << (n)) | (v.x >> (32 - n))); + result.x = ((v.x << (n)) | (v.y >> (32 - n))); + } + else { + result.y = ((v.x << (n - 32)) | (v.y >> (64 - n))); + result.x = ((v.y << (n - 32)) | (v.x >> (64 - n))); + } + return result; +} +static inline uint2 ror2l(uint2 v, unsigned a) { + uint2 result; + result.y = ((v.x << (32-a)) | (v.y >> (a))); + result.x = ((v.y << (32-a)) | (v.x >> (a))); + return result; +} +static inline uint2 ror2r(uint2 v, unsigned a) { + uint2 result; + result.y = ((v.y << (64-a)) | (v.x >> (a-32))); + result.x = ((v.x << (64-a)) | (v.y >> (a-32))); + return result; +} +/* #define G(a,b,c,d) \ do { \ -a += b; d ^= a; d = SPH_ROTR64(d, 32); \ -c += d; b ^= c; b = SPH_ROTR64(b, 24); \ -a += b; d ^= a; d = SPH_ROTR64(d, 16); \ -c += d; b ^= c; b = SPH_ROTR64(b, 63); \ - } while(0) +a = as_uint2(as_ulong(a)+as_ulong(b)); d ^= a; d = d.yx; \ +c = as_uint2(as_ulong(c)+as_ulong(d)); b ^= c; b = ror2l(b, 24); \ +a = as_uint2(as_ulong(a)+as_ulong(b)); d ^= a; d = ror2l(d, 16); \ +c = as_uint2(as_ulong(c)+as_ulong(d)); b ^= c; b = ror2r(b, 63); \ + } while(0) +*/ +#define G(a,b,c,d) \ + do { \ +a = as_uint2(as_ulong(a)+as_ulong(b)); d ^= a; d = d.yx; \ +c = as_uint2(as_ulong(c)+as_ulong(d)); b ^= c; b = as_uint2(as_uchar8(b).s34567012); \ +a = as_uint2(as_ulong(a)+as_ulong(b)); d ^= a; d = ror2l(d, 16); \ +c = as_uint2(as_ulong(c)+as_ulong(d)); b ^= c; b = ror2r(b, 63); \ + } while(0) + /*One Round of the Blake2b's compression function*/ @@ -72,7 +105,7 @@ c += d; b ^= c; b = SPH_ROTR64(b, 63); \ for (int i = 0; i < 8; i++) \ { \ \ - for (int j = 0; j < 12; j++) {state[j] ^= Matrix[12 * i + j][rowIn] + Matrix[12 * i + j][rowInOut];} \ + for (int j = 0; j < 12; j++) {state[j] ^= as_uint2(as_ulong(Matrix[12 * i + j][rowIn]) + as_ulong(Matrix[12 * i + j][rowInOut]));} \ round_lyra(state); \ for (int j = 0; j < 12; j++) {Matrix[j + 84 - 12 * i][rowOut] = Matrix[12 * i + j][rowIn] ^ state[j];} \ \ @@ -97,7 +130,7 @@ c += d; b ^= c; b = SPH_ROTR64(b, 63); \ for (int i = 0; i < 8; i++) \ { \ for (int j = 0; j < 12; j++) \ - state[j] ^= Matrix[12 * i + j][rowIn] + Matrix[12 * i + j][rowInOut]; \ + state[j] ^= as_uint2(as_ulong(Matrix[12 * i + j][rowIn]) + as_ulong(Matrix[12 * i + j][rowInOut])); \ \ round_lyra(state); \ for (int j = 0; j < 12; j++) {Matrix[j + 12 * i][rowOut] ^= state[j];} \ diff --git a/kernel/Lyra2RE.cl b/kernel/Lyra2RE.cl index 03ddc15ed..1283867ff 100644 --- a/kernel/Lyra2RE.cl +++ b/kernel/Lyra2RE.cl @@ -70,7 +70,56 @@ typedef long sph_s64; #define SPH_ROTL32(x,n) rotate(x,(uint)n) //faster with driver 14.6 #define SPH_ROTR32(x,n) rotate(x,(uint)(32-n)) #define SPH_ROTL64(x,n) rotate(x,(ulong)n) -#define SPH_ROTR64(x,n) rotate(x,(ulong)(64-n)) +//#define SPH_ROTR64(x,n) rotate(x,(ulong)(64-n)) + +/* +inline ulong rol64 (ulong l,ulong n) +{ +if (n<=32) { +uint2 t = rotate(as_uint2(l), (n)); +return as_ulong((uint2)(bitselect(t.s0, t.s1, (uint)(1 << (n)) - 1), bitselect(t.s0, t.s1, (uint)(~((1 << (n)) - 1))))); } +else { +uint2 t = rotate(as_uint2(l), (n - 32)); +return as_ulong((uint2)(bitselect(t.s1, t.s0, (uint)(1 << (n - 32)) - 1), bitselect(t.s1, t.s0, (uint)(~((1 << (n - 32)) - 1))))); +}} +*/ + + +/* +static inline ulong rol64(const ulong vw, unsigned n) { + uint2 result; + uint2 v=as_uint2(vw); + if (n == 32) { return as_ulong((uint2)(v.y,v.x)); } + if (n < 32) { + result.y = ( (v.y << (n)) | (v.x >> (32 - n)) ); + result.x = ( (v.x << (n)) | (v.y >> (32 - n)) ); + } + else { + result.y = ( (v.x << (n - 32)) | (v.y >> (64 - n)) ); + result.x = ( (v.y << (n - 32)) | (v.x >> (64 - n)) ); + } + return as_ulong(result); +} +*/ + +static inline sph_u64 ror64(sph_u64 vw, unsigned a) { + uint2 result; + uint2 v = as_uint2(vw); + unsigned n = (unsigned)(64 - a); + if (n == 32) { return as_ulong((uint2)(v.y,v.x)); } + if (n < 32) { + result.y = ((v.y << (n)) | (v.x >> (32 - n))); + result.x = ((v.x << (n)) | (v.y >> (32 - n))); + } + else { + result.y = ((v.x << (n - 32)) | (v.y >> (64 - n))); + result.x = ((v.y << (n - 32)) | (v.x >> (64 - n))); + } + return as_ulong(result); +} + +#define SPH_ROTR64(l,n) ror64(l,n) + #include "blake256.cl" @@ -170,7 +219,7 @@ h[7]=h7; for (int i=0;i<8;i++) {hash->h4[i]=SWAP4(h[i]);} - barrier(CLK_GLOBAL_MEM_FENCE); +barrier(CLK_LOCAL_MEM_FENCE); } @@ -194,8 +243,8 @@ __kernel void search1(__global hash_t* hashes) keccak_block(keccak_gpu_state); for (int i = 0; i<4; i++) { hash->h8[i] = keccak_gpu_state[i]; } +barrier(CLK_LOCAL_MEM_FENCE); - barrier(CLK_GLOBAL_MEM_FENCE); } @@ -211,18 +260,18 @@ __kernel void search2(__global hash_t* hashes) - sph_u64 state[16]; + uint2 state[16]; - for (int i = 0; i<4; i++) { state[i] = hash->h8[i];} //password + for (int i = 0; i<4; i++) { state[i] = as_uint2(hash->h8[i]);} //password for (int i = 0; i<4; i++) { state[i + 4] = state[i]; } //salt - for (int i = 0; i<8; i++) { state[i + 8] = blake2b_IV[i]; } + for (int i = 0; i<8; i++) { state[i + 8] = as_uint2(blake2b_IV[i]); } // blake2blyra x2 for (int i = 0; i<24; i++) { round_lyra(state); } //because 12 is not enough - sph_u64 Matrix[96][8]; // very uncool + __private uint2 Matrix[96][8]; // very uncool /// reducedSqueezeRow0 for (int i = 0; i < 8; i++) @@ -248,30 +297,31 @@ __kernel void search2(__global hash_t* hashes) reduceDuplexRowSetup(5, 2, 6); reduceDuplexRowSetup(6, 1, 7); - sph_u64 rowa; - rowa = state[0] & 7; + sph_u32 rowa; + rowa = state[0].x & 7; reduceDuplexRow(7, rowa, 0); - rowa = state[0] & 7; + rowa = state[0].x & 7; reduceDuplexRow(0, rowa, 3); - rowa = state[0] & 7; + rowa = state[0].x & 7; reduceDuplexRow(3, rowa, 6); - rowa = state[0] & 7; + rowa = state[0].x & 7; reduceDuplexRow(6, rowa, 1); - rowa = state[0] & 7; + rowa = state[0].x & 7; reduceDuplexRow(1, rowa, 4); - rowa = state[0] & 7; + rowa = state[0].x & 7; reduceDuplexRow(4, rowa, 7); - rowa = state[0] & 7; + rowa = state[0].x & 7; reduceDuplexRow(7, rowa, 2); - rowa = state[0] & 7; + rowa = state[0].x & 7; reduceDuplexRow(2, rowa, 5); absorbblock(rowa); - for (int i = 0; i<4; i++) {hash->h8[i] = state[i];} + for (int i = 0; i<4; i++) {hash->h8[i] = as_ulong(state[i]);} +barrier(CLK_LOCAL_MEM_FENCE); - barrier(CLK_GLOBAL_MEM_FENCE); + } @@ -344,44 +394,99 @@ __kernel void search3(__global hash_t* hashes) hash->h8[1] = p1; hash->h8[2] = p2; hash->h8[3] = p3; - - - - barrier(CLK_GLOBAL_MEM_FENCE); + barrier(CLK_LOCAL_MEM_FENCE); } __attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) -__kernel void search4(__global hash_t* hashes, __global uint* output, const uint target) +__kernel void search4(__global hash_t* hashes, __global uint* output, const ulong target) { +// __local ulong T0[256], T1[256], T2[256], T3[256], T4[256], T5[256], T6[256], T7[256]; + // uint u = get_local_id(0); +/* +for (uint u = get_local_id(0); u < 256; u += get_local_size(0)) { + + + T0[u] = T0_G[u]; + T1[u] = T1_G[u]; + T2[u] = T2_G[u]; + T3[u] = T3_G[u]; + T4[u] = T4_G[u]; + T5[u] = T5_G[u]; + T6[u] = T6_G[u]; + T7[u] = T7_G[u]; + } +barrier(CLK_LOCAL_MEM_FENCE); + + T1[u] = SPH_ROTL64(T0[u], 8UL); + T2[u] = SPH_ROTL64(T0[u], 16UL); + T3[u] = SPH_ROTL64(T0[u], 24UL); + T4[u] = SPH_ROTL64(T0[u], 32UL); + T5[u] = SPH_ROTL64(T0[u], 40UL); + T6[u] = SPH_ROTL64(T0[u], 48UL); + T7[u] = SPH_ROTL64(T0[u], 56UL); + +*/ uint gid = get_global_id(0); + __global hash_t *hash = &(hashes[gid - get_global_offset(0)]); - sph_u64 message[8], state[8]; - sph_u64 t[8]; - for (int k = 0; k<4; k++) { message[k] = hash->h8[k]; } + + + __private ulong message[8], state[8]; + __private ulong t[8]; + + + for (int u = 0; u<4; u++) { message[u] = hash->h8[u]; } message[4] = 0x80UL; message[5] = 0UL; message[6] = 0UL; message[7] = 0x0100000000000000UL; + for (int u = 0; u<8; u++) { state[u] = message[u]; } state[7] ^= 0x0001000000000000UL; - PERM_SMALL_P(state); + + + for (int r = 0; r < 10; r ++) {ROUND_SMALL_P(state, r); } + state[7] ^= 0x0001000000000000UL; - PERM_SMALL_Q(message); - for (int u = 0; u<8; u++) { state[u] ^= message[u]; } - message[7] = state[7]; + + for (int r = 0; r < 10; r ++) {ROUND_SMALL_Q(message, r); } - PERM_SMALL_Pf(state); - state[7] ^= message[7]; - barrier(CLK_GLOBAL_MEM_FENCE); + for (int u = 0; u<8; u++) { state[u] ^= message[u]; } + message[7] = state[7]; - bool result = ( as_uint2(state[7]).y <= target); + for (int r = 0; r < 9; r ++) {ROUND_SMALL_P(state, r); } + uchar8 State; + State.s0 =as_uchar8(state[7]^0x79).s0; + State.s1 =as_uchar8(state[0]^0x09).s1; + State.s2 =as_uchar8(state[1]^0x19).s2; + State.s3 =as_uchar8(state[2]^0x29).s3; + State.s4 =as_uchar8(state[3]^0x39).s4; + State.s5 =as_uchar8(state[4]^0x49).s5; + State.s6 =as_uchar8(state[5]^0x59).s6; + State.s7 =as_uchar8(state[6]^0x69).s7; + + + state[7] =T0_G[State.s0] + ^ R64(T0_G[State.s1], 8) + ^ R64(T0_G[State.s2], 16) + ^ R64(T0_G[State.s3], 24) + ^ T4_G[State.s4] + ^ R64(T4_G[State.s5], 8) + ^ R64(T4_G[State.s6], 16) + ^ R64(T4_G[State.s7], 24) ^message[7]; + +// t[7] ^= message[7]; + barrier(CLK_LOCAL_MEM_FENCE); + + + bool result = ( state[7] <= target); if (result) { output[atomic_inc(output + 0xFF)] = SWAP4(gid); } diff --git a/kernel/groestl.cl b/kernel/groestl.cl index bf93cd0ba..a81633cc3 100644 --- a/kernel/groestl.cl +++ b/kernel/groestl.cl @@ -57,8 +57,8 @@ #define USE_LE 1 #endif -#if USE_LE +#if USE_LE #if SPH_64 #define C64e(x) ((SPH_C64(x) >> 56) \ | ((SPH_C64(x) >> 40) & SPH_C64(0x000000000000FF00)) \ @@ -1173,6 +1173,8 @@ __constant static const sph_u64 T7[] = { ^ R64(T4[B64_7(a[b7])], 24); \ } while (0) + + #else #define RBTT(d, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ @@ -1186,6 +1188,9 @@ __constant static const sph_u64 T7[] = { ^ T7[B64_7(a[b7])]; \ } while (0) + + + #endif #if SPH_SMALL_FOOTPRINT_GROESTL @@ -1417,6 +1422,9 @@ __constant static const sph_u64 T7[] = { } while (0) */ + + + #define PERM_BIG_P(a) do { \ int r; \ for (r = 0; r < 14; ++r) { \ @@ -1429,4 +1437,125 @@ __constant static const sph_u64 T7[] = { for (r = 0; r < 14; ++r) { \ ROUND_BIG_Q(a, r); \ } \ - } while (0) \ No newline at end of file + } while (0) + +#if SPH_SMALL_FOOTPRINT_GROESTL + +#define RSTT(d, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ + t[d] = T0[B64_0(a[b0])] \ + ^ R64(T0[B64_1(a[b1])], 8) \ + ^ R64(T0[B64_2(a[b2])], 16) \ + ^ R64(T0[B64_3(a[b3])], 24) \ + ^ T4[B64_4(a[b4])] \ + ^ R64(T4[B64_5(a[b5])], 8) \ + ^ R64(T4[B64_6(a[b6])], 16) \ + ^ R64(T4[B64_7(a[b7])], 24); \ + } while (0) + +#else + +#define RSTT(d, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ + t[d] = T0[B64_0(a[b0])] \ + ^ T1[B64_1(a[b1])] \ + ^ T2[B64_2(a[b2])] \ + ^ T3[B64_3(a[b3])] \ + ^ T4[B64_4(a[b4])] \ + ^ T5[B64_5(a[b5])] \ + ^ T6[B64_6(a[b6])] \ + ^ T7[B64_7(a[b7])]; \ + } while (0) + +#endif +#define ROUND_SMALL_P(a, r) do { \ + sph_u64 t[8]; \ + a[0] ^= PC64(0x00, r); \ + a[1] ^= PC64(0x10, r); \ + a[2] ^= PC64(0x20, r); \ + a[3] ^= PC64(0x30, r); \ + a[4] ^= PC64(0x40, r); \ + a[5] ^= PC64(0x50, r); \ + a[6] ^= PC64(0x60, r); \ + a[7] ^= PC64(0x70, r); \ + RSTT(0, a, 0, 1, 2, 3, 4, 5, 6, 7); \ + RSTT(1, a, 1, 2, 3, 4, 5, 6, 7, 0); \ + RSTT(2, a, 2, 3, 4, 5, 6, 7, 0, 1); \ + RSTT(3, a, 3, 4, 5, 6, 7, 0, 1, 2); \ + RSTT(4, a, 4, 5, 6, 7, 0, 1, 2, 3); \ + RSTT(5, a, 5, 6, 7, 0, 1, 2, 3, 4); \ + RSTT(6, a, 6, 7, 0, 1, 2, 3, 4, 5); \ + RSTT(7, a, 7, 0, 1, 2, 3, 4, 5, 6); \ + a[0] = t[0]; \ + a[1] = t[1]; \ + a[2] = t[2]; \ + a[3] = t[3]; \ + a[4] = t[4]; \ + a[5] = t[5]; \ + a[6] = t[6]; \ + a[7] = t[7]; \ + } while (0) + +#define ROUND_SMALL_Q(a, r) do { \ + sph_u64 t[8]; \ + a[0] ^= QC64(0x00, r); \ + a[1] ^= QC64(0x10, r); \ + a[2] ^= QC64(0x20, r); \ + a[3] ^= QC64(0x30, r); \ + a[4] ^= QC64(0x40, r); \ + a[5] ^= QC64(0x50, r); \ + a[6] ^= QC64(0x60, r); \ + a[7] ^= QC64(0x70, r); \ + RSTT(0, a, 1, 3, 5, 7, 0, 2, 4, 6); \ + RSTT(1, a, 2, 4, 6, 0, 1, 3, 5, 7); \ + RSTT(2, a, 3, 5, 7, 1, 2, 4, 6, 0); \ + RSTT(3, a, 4, 6, 0, 2, 3, 5, 7, 1); \ + RSTT(4, a, 5, 7, 1, 3, 4, 6, 0, 2); \ + RSTT(5, a, 6, 0, 2, 4, 5, 7, 1, 3); \ + RSTT(6, a, 7, 1, 3, 5, 6, 0, 2, 4); \ + RSTT(7, a, 0, 2, 4, 6, 7, 1, 3, 5); \ + a[0] = t[0]; \ + a[1] = t[1]; \ + a[2] = t[2]; \ + a[3] = t[3]; \ + a[4] = t[4]; \ + a[5] = t[5]; \ + a[6] = t[6]; \ + a[7] = t[7]; \ + } while (0) + +#if SPH_SMALL_FOOTPRINT_GROESTL + +#define PERM_SMALL_P(a) do { \ + int r; \ + for (r = 0; r < 10; r ++) \ + ROUND_SMALL_P(a, r); \ + } while (0) + +#define PERM_SMALL_Q(a) do { \ + int r; \ + for (r = 0; r < 10; r ++) \ + ROUND_SMALL_Q(a, r); \ + } while (0) + +#else + +/* + * Apparently, unrolling more than that confuses GCC, resulting in + * lower performance, even though L1 cache would be no problem. + */ +#define PERM_SMALL_P(a) do { \ + int r; \ + for (r = 0; r < 10; r += 2) { \ + ROUND_SMALL_P(a, r + 0); \ + ROUND_SMALL_P(a, r + 1); \ + } \ + } while (0) + +#define PERM_SMALL_Q(a) do { \ + int r; \ + for (r = 0; r < 10; r += 2) { \ + ROUND_SMALL_Q(a, r + 0); \ + ROUND_SMALL_Q(a, r + 1); \ + } \ + } while (0) + +#endif diff --git a/kernel/groestl256.cl b/kernel/groestl256.cl index 824910a35..e083e7ce3 100644 --- a/kernel/groestl256.cl +++ b/kernel/groestl256.cl @@ -30,10 +30,6 @@ * @author Thomas Pornin */ -/* - * Apparently, the 32-bit-only version is not faster than the 64-bit - * version unless using the "small footprint" code on a 32-bit machine. - */ #define C64e(x) ((SPH_C64(x) >> 56) \ | ((SPH_C64(x) >> 40) & SPH_C64(0x000000000000FF00)) \ @@ -43,8 +39,7 @@ | ((SPH_C64(x) << 24) & SPH_C64(0x0000FF0000000000)) \ | ((SPH_C64(x) << 40) & SPH_C64(0x00FF000000000000)) \ | ((SPH_C64(x) << 56) & SPH_C64(0xFF00000000000000))) -#define dec64e_aligned sph_dec64le_aligned -#define enc64e sph_enc64le + #define B64_0(x) ((x) & 0xFF) #define B64_1(x) (((x) >> 8) & 0xFF) #define B64_2(x) (((x) >> 16) & 0xFF) @@ -55,9 +50,9 @@ #define B64_7(x) ((x) >> 56) #define R64 SPH_ROTL64 #define PC64(j, r) ((sph_u64)((j) + (r))) -#define QC64(j, r) (((sph_u64)(r) << 56) ^ SPH_T64(~((sph_u64)(j) << 56))) +#define QC64(j, r) (((sph_u64)(r) << 56) ^ (~((sph_u64)(j) << 56))) -__constant static const sph_u64 T0[] = { +__constant static const sph_u64 T0_G[] = { C64e(0xc632f4a5f497a5c6), C64e(0xf86f978497eb84f8), C64e(0xee5eb099b0c799ee), C64e(0xf67a8c8d8cf78df6), C64e(0xffe8170d17e50dff), C64e(0xd60adcbddcb7bdd6), @@ -188,148 +183,979 @@ __constant static const sph_u64 T0[] = { C64e(0x6d0c61d661dad66d), C64e(0x2c624e3a4e583a2c) }; -__constant static const sph_u64 T4[] = { - C64e(0xf497a5c6c632f4a5), C64e(0x97eb84f8f86f9784), - C64e(0xb0c799eeee5eb099), C64e(0x8cf78df6f67a8c8d), - C64e(0x17e50dffffe8170d), C64e(0xdcb7bdd6d60adcbd), - C64e(0xc8a7b1dede16c8b1), C64e(0xfc395491916dfc54), - C64e(0xf0c050606090f050), C64e(0x0504030202070503), - C64e(0xe087a9cece2ee0a9), C64e(0x87ac7d5656d1877d), - C64e(0x2bd519e7e7cc2b19), C64e(0xa67162b5b513a662), - C64e(0x319ae64d4d7c31e6), C64e(0xb5c39aecec59b59a), - C64e(0xcf05458f8f40cf45), C64e(0xbc3e9d1f1fa3bc9d), - C64e(0xc00940898949c040), C64e(0x92ef87fafa689287), - C64e(0x3fc515efefd03f15), C64e(0x267febb2b29426eb), - C64e(0x4007c98e8ece40c9), C64e(0x1ded0bfbfbe61d0b), - C64e(0x2f82ec41416e2fec), C64e(0xa97d67b3b31aa967), - C64e(0x1cbefd5f5f431cfd), C64e(0x258aea45456025ea), - C64e(0xda46bf2323f9dabf), C64e(0x02a6f753535102f7), - C64e(0xa1d396e4e445a196), C64e(0xed2d5b9b9b76ed5b), - C64e(0x5deac27575285dc2), C64e(0x24d91ce1e1c5241c), - C64e(0xe97aae3d3dd4e9ae), C64e(0xbe986a4c4cf2be6a), - C64e(0xeed85a6c6c82ee5a), C64e(0xc3fc417e7ebdc341), - C64e(0x06f102f5f5f30602), C64e(0xd11d4f838352d14f), - C64e(0xe4d05c68688ce45c), C64e(0x07a2f451515607f4), - C64e(0x5cb934d1d18d5c34), C64e(0x18e908f9f9e11808), - C64e(0xaedf93e2e24cae93), C64e(0x954d73abab3e9573), - C64e(0xf5c453626297f553), C64e(0x41543f2a2a6b413f), - C64e(0x14100c08081c140c), C64e(0xf63152959563f652), - C64e(0xaf8c654646e9af65), C64e(0xe2215e9d9d7fe25e), - C64e(0x7860283030487828), C64e(0xf86ea13737cff8a1), - C64e(0x11140f0a0a1b110f), C64e(0xc45eb52f2febc4b5), - C64e(0x1b1c090e0e151b09), C64e(0x5a483624247e5a36), - C64e(0xb6369b1b1badb69b), C64e(0x47a53ddfdf98473d), - C64e(0x6a8126cdcda76a26), C64e(0xbb9c694e4ef5bb69), - C64e(0x4cfecd7f7f334ccd), C64e(0xbacf9feaea50ba9f), - C64e(0x2d241b12123f2d1b), C64e(0xb93a9e1d1da4b99e), - C64e(0x9cb0745858c49c74), C64e(0x72682e343446722e), - C64e(0x776c2d363641772d), C64e(0xcda3b2dcdc11cdb2), - C64e(0x2973eeb4b49d29ee), C64e(0x16b6fb5b5b4d16fb), - C64e(0x0153f6a4a4a501f6), C64e(0xd7ec4d7676a1d74d), - C64e(0xa37561b7b714a361), C64e(0x49face7d7d3449ce), - C64e(0x8da47b5252df8d7b), C64e(0x42a13edddd9f423e), - C64e(0x93bc715e5ecd9371), C64e(0xa226971313b1a297), - C64e(0x0457f5a6a6a204f5), C64e(0xb86968b9b901b868), - C64e(0x0000000000000000), C64e(0x74992cc1c1b5742c), - C64e(0xa080604040e0a060), C64e(0x21dd1fe3e3c2211f), - C64e(0x43f2c879793a43c8), C64e(0x2c77edb6b69a2ced), - C64e(0xd9b3bed4d40dd9be), C64e(0xca01468d8d47ca46), - C64e(0x70ced967671770d9), C64e(0xdde44b7272afdd4b), - C64e(0x7933de9494ed79de), C64e(0x672bd49898ff67d4), - C64e(0x237be8b0b09323e8), C64e(0xde114a85855bde4a), - C64e(0xbd6d6bbbbb06bd6b), C64e(0x7e912ac5c5bb7e2a), - C64e(0x349ee54f4f7b34e5), C64e(0x3ac116ededd73a16), - C64e(0x5417c58686d254c5), C64e(0x622fd79a9af862d7), - C64e(0xffcc55666699ff55), C64e(0xa722941111b6a794), - C64e(0x4a0fcf8a8ac04acf), C64e(0x30c910e9e9d93010), - C64e(0x0a080604040e0a06), C64e(0x98e781fefe669881), - C64e(0x0b5bf0a0a0ab0bf0), C64e(0xccf0447878b4cc44), - C64e(0xd54aba2525f0d5ba), C64e(0x3e96e34b4b753ee3), - C64e(0x0e5ff3a2a2ac0ef3), C64e(0x19bafe5d5d4419fe), - C64e(0x5b1bc08080db5bc0), C64e(0x850a8a050580858a), - C64e(0xec7ead3f3fd3ecad), C64e(0xdf42bc2121fedfbc), - C64e(0xd8e0487070a8d848), C64e(0x0cf904f1f1fd0c04), - C64e(0x7ac6df6363197adf), C64e(0x58eec177772f58c1), - C64e(0x9f4575afaf309f75), C64e(0xa584634242e7a563), - C64e(0x5040302020705030), C64e(0x2ed11ae5e5cb2e1a), - C64e(0x12e10efdfdef120e), C64e(0xb7656dbfbf08b76d), - C64e(0xd4194c818155d44c), C64e(0x3c30141818243c14), - C64e(0x5f4c352626795f35), C64e(0x719d2fc3c3b2712f), - C64e(0x3867e1bebe8638e1), C64e(0xfd6aa23535c8fda2), - C64e(0x4f0bcc8888c74fcc), C64e(0x4b5c392e2e654b39), - C64e(0xf93d5793936af957), C64e(0x0daaf25555580df2), - C64e(0x9de382fcfc619d82), C64e(0xc9f4477a7ab3c947), - C64e(0xef8bacc8c827efac), C64e(0x326fe7baba8832e7), - C64e(0x7d642b32324f7d2b), C64e(0xa4d795e6e642a495), - C64e(0xfb9ba0c0c03bfba0), C64e(0xb332981919aab398), - C64e(0x6827d19e9ef668d1), C64e(0x815d7fa3a322817f), - C64e(0xaa88664444eeaa66), C64e(0x82a87e5454d6827e), - C64e(0xe676ab3b3bdde6ab), C64e(0x9e16830b0b959e83), - C64e(0x4503ca8c8cc945ca), C64e(0x7b9529c7c7bc7b29), - C64e(0x6ed6d36b6b056ed3), C64e(0x44503c28286c443c), - C64e(0x8b5579a7a72c8b79), C64e(0x3d63e2bcbc813de2), - C64e(0x272c1d161631271d), C64e(0x9a4176adad379a76), - C64e(0x4dad3bdbdb964d3b), C64e(0xfac85664649efa56), - C64e(0xd2e84e7474a6d24e), C64e(0x22281e141436221e), - C64e(0x763fdb9292e476db), C64e(0x1e180a0c0c121e0a), - C64e(0xb4906c4848fcb46c), C64e(0x376be4b8b88f37e4), - C64e(0xe7255d9f9f78e75d), C64e(0xb2616ebdbd0fb26e), - C64e(0x2a86ef4343692aef), C64e(0xf193a6c4c435f1a6), - C64e(0xe372a83939dae3a8), C64e(0xf762a43131c6f7a4), - C64e(0x59bd37d3d38a5937), C64e(0x86ff8bf2f274868b), - C64e(0x56b132d5d5835632), C64e(0xc50d438b8b4ec543), - C64e(0xebdc596e6e85eb59), C64e(0xc2afb7dada18c2b7), - C64e(0x8f028c01018e8f8c), C64e(0xac7964b1b11dac64), - C64e(0x6d23d29c9cf16dd2), C64e(0x3b92e04949723be0), - C64e(0xc7abb4d8d81fc7b4), C64e(0x1543faacacb915fa), - C64e(0x09fd07f3f3fa0907), C64e(0x6f8525cfcfa06f25), - C64e(0xea8fafcaca20eaaf), C64e(0x89f38ef4f47d898e), - C64e(0x208ee947476720e9), C64e(0x2820181010382818), - C64e(0x64ded56f6f0b64d5), C64e(0x83fb88f0f0738388), - C64e(0xb1946f4a4afbb16f), C64e(0x96b8725c5cca9672), - C64e(0x6c70243838546c24), C64e(0x08aef157575f08f1), - C64e(0x52e6c773732152c7), C64e(0xf33551979764f351), - C64e(0x658d23cbcbae6523), C64e(0x84597ca1a125847c), - C64e(0xbfcb9ce8e857bf9c), C64e(0x637c213e3e5d6321), - C64e(0x7c37dd9696ea7cdd), C64e(0x7fc2dc61611e7fdc), - C64e(0x911a860d0d9c9186), C64e(0x941e850f0f9b9485), - C64e(0xabdb90e0e04bab90), C64e(0xc6f8427c7cbac642), - C64e(0x57e2c471712657c4), C64e(0xe583aacccc29e5aa), - C64e(0x733bd89090e373d8), C64e(0x0f0c050606090f05), - C64e(0x03f501f7f7f40301), C64e(0x3638121c1c2a3612), - C64e(0xfe9fa3c2c23cfea3), C64e(0xe1d45f6a6a8be15f), - C64e(0x1047f9aeaebe10f9), C64e(0x6bd2d06969026bd0), - C64e(0xa82e911717bfa891), C64e(0xe82958999971e858), - C64e(0x6974273a3a536927), C64e(0xd04eb92727f7d0b9), - C64e(0x48a938d9d9914838), C64e(0x35cd13ebebde3513), - C64e(0xce56b32b2be5ceb3), C64e(0x5544332222775533), - C64e(0xd6bfbbd2d204d6bb), C64e(0x904970a9a9399070), - C64e(0x800e890707878089), C64e(0xf266a73333c1f2a7), - C64e(0xc15ab62d2decc1b6), C64e(0x6678223c3c5a6622), - C64e(0xad2a921515b8ad92), C64e(0x608920c9c9a96020), - C64e(0xdb154987875cdb49), C64e(0x1a4fffaaaab01aff), - C64e(0x88a0785050d88878), C64e(0x8e517aa5a52b8e7a), - C64e(0x8a068f0303898a8f), C64e(0x13b2f859594a13f8), - C64e(0x9b12800909929b80), C64e(0x3934171a1a233917), - C64e(0x75cada65651075da), C64e(0x53b531d7d7845331), - C64e(0x5113c68484d551c6), C64e(0xd3bbb8d0d003d3b8), - C64e(0x5e1fc38282dc5ec3), C64e(0xcb52b02929e2cbb0), - C64e(0x99b4775a5ac39977), C64e(0x333c111e1e2d3311), - C64e(0x46f6cb7b7b3d46cb), C64e(0x1f4bfca8a8b71ffc), - C64e(0x61dad66d6d0c61d6), C64e(0x4e583a2c2c624e3a) +/* +__constant static const ulong T1_G[] = { + C64e(0xc6c632f4a5f497a5), C64e(0xf8f86f978497eb84), + C64e(0xeeee5eb099b0c799), C64e(0xf6f67a8c8d8cf78d), + C64e(0xffffe8170d17e50d), C64e(0xd6d60adcbddcb7bd), + C64e(0xdede16c8b1c8a7b1), C64e(0x91916dfc54fc3954), + C64e(0x606090f050f0c050), C64e(0x0202070503050403), + C64e(0xcece2ee0a9e087a9), C64e(0x5656d1877d87ac7d), + C64e(0xe7e7cc2b192bd519), C64e(0xb5b513a662a67162), + C64e(0x4d4d7c31e6319ae6), C64e(0xecec59b59ab5c39a), + C64e(0x8f8f40cf45cf0545), C64e(0x1f1fa3bc9dbc3e9d), + C64e(0x898949c040c00940), C64e(0xfafa68928792ef87), + C64e(0xefefd03f153fc515), C64e(0xb2b29426eb267feb), + C64e(0x8e8ece40c94007c9), C64e(0xfbfbe61d0b1ded0b), + C64e(0x41416e2fec2f82ec), C64e(0xb3b31aa967a97d67), + C64e(0x5f5f431cfd1cbefd), C64e(0x45456025ea258aea), + C64e(0x2323f9dabfda46bf), C64e(0x53535102f702a6f7), + C64e(0xe4e445a196a1d396), C64e(0x9b9b76ed5bed2d5b), + C64e(0x7575285dc25deac2), C64e(0xe1e1c5241c24d91c), + C64e(0x3d3dd4e9aee97aae), C64e(0x4c4cf2be6abe986a), + C64e(0x6c6c82ee5aeed85a), C64e(0x7e7ebdc341c3fc41), + C64e(0xf5f5f3060206f102), C64e(0x838352d14fd11d4f), + C64e(0x68688ce45ce4d05c), C64e(0x51515607f407a2f4), + C64e(0xd1d18d5c345cb934), C64e(0xf9f9e1180818e908), + C64e(0xe2e24cae93aedf93), C64e(0xabab3e9573954d73), + C64e(0x626297f553f5c453), C64e(0x2a2a6b413f41543f), + C64e(0x08081c140c14100c), C64e(0x959563f652f63152), + C64e(0x4646e9af65af8c65), C64e(0x9d9d7fe25ee2215e), + C64e(0x3030487828786028), C64e(0x3737cff8a1f86ea1), + C64e(0x0a0a1b110f11140f), C64e(0x2f2febc4b5c45eb5), + C64e(0x0e0e151b091b1c09), C64e(0x24247e5a365a4836), + C64e(0x1b1badb69bb6369b), C64e(0xdfdf98473d47a53d), + C64e(0xcdcda76a266a8126), C64e(0x4e4ef5bb69bb9c69), + C64e(0x7f7f334ccd4cfecd), C64e(0xeaea50ba9fbacf9f), + C64e(0x12123f2d1b2d241b), C64e(0x1d1da4b99eb93a9e), + C64e(0x5858c49c749cb074), C64e(0x343446722e72682e), + C64e(0x363641772d776c2d), C64e(0xdcdc11cdb2cda3b2), + C64e(0xb4b49d29ee2973ee), C64e(0x5b5b4d16fb16b6fb), + C64e(0xa4a4a501f60153f6), C64e(0x7676a1d74dd7ec4d), + C64e(0xb7b714a361a37561), C64e(0x7d7d3449ce49face), + C64e(0x5252df8d7b8da47b), C64e(0xdddd9f423e42a13e), + C64e(0x5e5ecd937193bc71), C64e(0x1313b1a297a22697), + C64e(0xa6a6a204f50457f5), C64e(0xb9b901b868b86968), + C64e(0x0000000000000000), C64e(0xc1c1b5742c74992c), + C64e(0x4040e0a060a08060), C64e(0xe3e3c2211f21dd1f), + C64e(0x79793a43c843f2c8), C64e(0xb6b69a2ced2c77ed), + C64e(0xd4d40dd9bed9b3be), C64e(0x8d8d47ca46ca0146), + C64e(0x67671770d970ced9), C64e(0x7272afdd4bdde44b), + C64e(0x9494ed79de7933de), C64e(0x9898ff67d4672bd4), + C64e(0xb0b09323e8237be8), C64e(0x85855bde4ade114a), + C64e(0xbbbb06bd6bbd6d6b), C64e(0xc5c5bb7e2a7e912a), + C64e(0x4f4f7b34e5349ee5), C64e(0xededd73a163ac116), + C64e(0x8686d254c55417c5), C64e(0x9a9af862d7622fd7), + C64e(0x666699ff55ffcc55), C64e(0x1111b6a794a72294), + C64e(0x8a8ac04acf4a0fcf), C64e(0xe9e9d9301030c910), + C64e(0x04040e0a060a0806), C64e(0xfefe66988198e781), + C64e(0xa0a0ab0bf00b5bf0), C64e(0x7878b4cc44ccf044), + C64e(0x2525f0d5bad54aba), C64e(0x4b4b753ee33e96e3), + C64e(0xa2a2ac0ef30e5ff3), C64e(0x5d5d4419fe19bafe), + C64e(0x8080db5bc05b1bc0), C64e(0x050580858a850a8a), + C64e(0x3f3fd3ecadec7ead), C64e(0x2121fedfbcdf42bc), + C64e(0x7070a8d848d8e048), C64e(0xf1f1fd0c040cf904), + C64e(0x6363197adf7ac6df), C64e(0x77772f58c158eec1), + C64e(0xafaf309f759f4575), C64e(0x4242e7a563a58463), + C64e(0x2020705030504030), C64e(0xe5e5cb2e1a2ed11a), + C64e(0xfdfdef120e12e10e), C64e(0xbfbf08b76db7656d), + C64e(0x818155d44cd4194c), C64e(0x1818243c143c3014), + C64e(0x2626795f355f4c35), C64e(0xc3c3b2712f719d2f), + C64e(0xbebe8638e13867e1), C64e(0x3535c8fda2fd6aa2), + C64e(0x8888c74fcc4f0bcc), C64e(0x2e2e654b394b5c39), + C64e(0x93936af957f93d57), C64e(0x5555580df20daaf2), + C64e(0xfcfc619d829de382), C64e(0x7a7ab3c947c9f447), + C64e(0xc8c827efacef8bac), C64e(0xbaba8832e7326fe7), + C64e(0x32324f7d2b7d642b), C64e(0xe6e642a495a4d795), + C64e(0xc0c03bfba0fb9ba0), C64e(0x1919aab398b33298), + C64e(0x9e9ef668d16827d1), C64e(0xa3a322817f815d7f), + C64e(0x4444eeaa66aa8866), C64e(0x5454d6827e82a87e), + C64e(0x3b3bdde6abe676ab), C64e(0x0b0b959e839e1683), + C64e(0x8c8cc945ca4503ca), C64e(0xc7c7bc7b297b9529), + C64e(0x6b6b056ed36ed6d3), C64e(0x28286c443c44503c), + C64e(0xa7a72c8b798b5579), C64e(0xbcbc813de23d63e2), + C64e(0x161631271d272c1d), C64e(0xadad379a769a4176), + C64e(0xdbdb964d3b4dad3b), C64e(0x64649efa56fac856), + C64e(0x7474a6d24ed2e84e), C64e(0x141436221e22281e), + C64e(0x9292e476db763fdb), C64e(0x0c0c121e0a1e180a), + C64e(0x4848fcb46cb4906c), C64e(0xb8b88f37e4376be4), + C64e(0x9f9f78e75de7255d), C64e(0xbdbd0fb26eb2616e), + C64e(0x4343692aef2a86ef), C64e(0xc4c435f1a6f193a6), + C64e(0x3939dae3a8e372a8), C64e(0x3131c6f7a4f762a4), + C64e(0xd3d38a593759bd37), C64e(0xf2f274868b86ff8b), + C64e(0xd5d583563256b132), C64e(0x8b8b4ec543c50d43), + C64e(0x6e6e85eb59ebdc59), C64e(0xdada18c2b7c2afb7), + C64e(0x01018e8f8c8f028c), C64e(0xb1b11dac64ac7964), + C64e(0x9c9cf16dd26d23d2), C64e(0x4949723be03b92e0), + C64e(0xd8d81fc7b4c7abb4), C64e(0xacacb915fa1543fa), + C64e(0xf3f3fa090709fd07), C64e(0xcfcfa06f256f8525), + C64e(0xcaca20eaafea8faf), C64e(0xf4f47d898e89f38e), + C64e(0x47476720e9208ee9), C64e(0x1010382818282018), + C64e(0x6f6f0b64d564ded5), C64e(0xf0f073838883fb88), + C64e(0x4a4afbb16fb1946f), C64e(0x5c5cca967296b872), + C64e(0x3838546c246c7024), C64e(0x57575f08f108aef1), + C64e(0x73732152c752e6c7), C64e(0x979764f351f33551), + C64e(0xcbcbae6523658d23), C64e(0xa1a125847c84597c), + C64e(0xe8e857bf9cbfcb9c), C64e(0x3e3e5d6321637c21), + C64e(0x9696ea7cdd7c37dd), C64e(0x61611e7fdc7fc2dc), + C64e(0x0d0d9c9186911a86), C64e(0x0f0f9b9485941e85), + C64e(0xe0e04bab90abdb90), C64e(0x7c7cbac642c6f842), + C64e(0x71712657c457e2c4), C64e(0xcccc29e5aae583aa), + C64e(0x9090e373d8733bd8), C64e(0x0606090f050f0c05), + C64e(0xf7f7f4030103f501), C64e(0x1c1c2a3612363812), + C64e(0xc2c23cfea3fe9fa3), C64e(0x6a6a8be15fe1d45f), + C64e(0xaeaebe10f91047f9), C64e(0x6969026bd06bd2d0), + C64e(0x1717bfa891a82e91), C64e(0x999971e858e82958), + C64e(0x3a3a536927697427), C64e(0x2727f7d0b9d04eb9), + C64e(0xd9d991483848a938), C64e(0xebebde351335cd13), + C64e(0x2b2be5ceb3ce56b3), C64e(0x2222775533554433), + C64e(0xd2d204d6bbd6bfbb), C64e(0xa9a9399070904970), + C64e(0x0707878089800e89), C64e(0x3333c1f2a7f266a7), + C64e(0x2d2decc1b6c15ab6), C64e(0x3c3c5a6622667822), + C64e(0x1515b8ad92ad2a92), C64e(0xc9c9a96020608920), + C64e(0x87875cdb49db1549), C64e(0xaaaab01aff1a4fff), + C64e(0x5050d8887888a078), C64e(0xa5a52b8e7a8e517a), + C64e(0x0303898a8f8a068f), C64e(0x59594a13f813b2f8), + C64e(0x0909929b809b1280), C64e(0x1a1a233917393417), + C64e(0x65651075da75cada), C64e(0xd7d784533153b531), + C64e(0x8484d551c65113c6), C64e(0xd0d003d3b8d3bbb8), + C64e(0x8282dc5ec35e1fc3), C64e(0x2929e2cbb0cb52b0), + C64e(0x5a5ac3997799b477), C64e(0x1e1e2d3311333c11), + C64e(0x7b7b3d46cb46f6cb), C64e(0xa8a8b71ffc1f4bfc), + C64e(0x6d6d0c61d661dad6), C64e(0x2c2c624e3a4e583a) +}; + +__constant static const ulong T2_G[] = { +C64e(0xa5c6c632f4a5f497), C64e(0x84f8f86f978497eb), +C64e(0x99eeee5eb099b0c7), C64e(0x8df6f67a8c8d8cf7), +C64e(0x0dffffe8170d17e5), C64e(0xbdd6d60adcbddcb7), +C64e(0xb1dede16c8b1c8a7), C64e(0x5491916dfc54fc39), +C64e(0x50606090f050f0c0), C64e(0x0302020705030504), +C64e(0xa9cece2ee0a9e087), C64e(0x7d5656d1877d87ac), +C64e(0x19e7e7cc2b192bd5), C64e(0x62b5b513a662a671), +C64e(0xe64d4d7c31e6319a), C64e(0x9aecec59b59ab5c3), +C64e(0x458f8f40cf45cf05), C64e(0x9d1f1fa3bc9dbc3e), +C64e(0x40898949c040c009), C64e(0x87fafa68928792ef), +C64e(0x15efefd03f153fc5), C64e(0xebb2b29426eb267f), +C64e(0xc98e8ece40c94007), C64e(0x0bfbfbe61d0b1ded), +C64e(0xec41416e2fec2f82), C64e(0x67b3b31aa967a97d), +C64e(0xfd5f5f431cfd1cbe), C64e(0xea45456025ea258a), +C64e(0xbf2323f9dabfda46), C64e(0xf753535102f702a6), +C64e(0x96e4e445a196a1d3), C64e(0x5b9b9b76ed5bed2d), +C64e(0xc27575285dc25dea), C64e(0x1ce1e1c5241c24d9), +C64e(0xae3d3dd4e9aee97a), C64e(0x6a4c4cf2be6abe98), +C64e(0x5a6c6c82ee5aeed8), C64e(0x417e7ebdc341c3fc), +C64e(0x02f5f5f3060206f1), C64e(0x4f838352d14fd11d), +C64e(0x5c68688ce45ce4d0), C64e(0xf451515607f407a2), +C64e(0x34d1d18d5c345cb9), C64e(0x08f9f9e1180818e9), +C64e(0x93e2e24cae93aedf), C64e(0x73abab3e9573954d), +C64e(0x53626297f553f5c4), C64e(0x3f2a2a6b413f4154), +C64e(0x0c08081c140c1410), C64e(0x52959563f652f631), +C64e(0x654646e9af65af8c), C64e(0x5e9d9d7fe25ee221), +C64e(0x2830304878287860), C64e(0xa13737cff8a1f86e), +C64e(0x0f0a0a1b110f1114), C64e(0xb52f2febc4b5c45e), +C64e(0x090e0e151b091b1c), C64e(0x3624247e5a365a48), +C64e(0x9b1b1badb69bb636), C64e(0x3ddfdf98473d47a5), +C64e(0x26cdcda76a266a81), C64e(0x694e4ef5bb69bb9c), +C64e(0xcd7f7f334ccd4cfe), C64e(0x9feaea50ba9fbacf), +C64e(0x1b12123f2d1b2d24), C64e(0x9e1d1da4b99eb93a), +C64e(0x745858c49c749cb0), C64e(0x2e343446722e7268), +C64e(0x2d363641772d776c), C64e(0xb2dcdc11cdb2cda3), +C64e(0xeeb4b49d29ee2973), C64e(0xfb5b5b4d16fb16b6), +C64e(0xf6a4a4a501f60153), C64e(0x4d7676a1d74dd7ec), +C64e(0x61b7b714a361a375), C64e(0xce7d7d3449ce49fa), +C64e(0x7b5252df8d7b8da4), C64e(0x3edddd9f423e42a1), +C64e(0x715e5ecd937193bc), C64e(0x971313b1a297a226), +C64e(0xf5a6a6a204f50457), C64e(0x68b9b901b868b869), +C64e(0x0000000000000000), C64e(0x2cc1c1b5742c7499), +C64e(0x604040e0a060a080), C64e(0x1fe3e3c2211f21dd), +C64e(0xc879793a43c843f2), C64e(0xedb6b69a2ced2c77), +C64e(0xbed4d40dd9bed9b3), C64e(0x468d8d47ca46ca01), +C64e(0xd967671770d970ce), C64e(0x4b7272afdd4bdde4), +C64e(0xde9494ed79de7933), C64e(0xd49898ff67d4672b), +C64e(0xe8b0b09323e8237b), C64e(0x4a85855bde4ade11), +C64e(0x6bbbbb06bd6bbd6d), C64e(0x2ac5c5bb7e2a7e91), +C64e(0xe54f4f7b34e5349e), C64e(0x16ededd73a163ac1), +C64e(0xc58686d254c55417), C64e(0xd79a9af862d7622f), +C64e(0x55666699ff55ffcc), C64e(0x941111b6a794a722), +C64e(0xcf8a8ac04acf4a0f), C64e(0x10e9e9d9301030c9), +C64e(0x0604040e0a060a08), C64e(0x81fefe66988198e7), +C64e(0xf0a0a0ab0bf00b5b), C64e(0x447878b4cc44ccf0), +C64e(0xba2525f0d5bad54a), C64e(0xe34b4b753ee33e96), +C64e(0xf3a2a2ac0ef30e5f), C64e(0xfe5d5d4419fe19ba), +C64e(0xc08080db5bc05b1b), C64e(0x8a050580858a850a), +C64e(0xad3f3fd3ecadec7e), C64e(0xbc2121fedfbcdf42), +C64e(0x487070a8d848d8e0), C64e(0x04f1f1fd0c040cf9), +C64e(0xdf6363197adf7ac6), C64e(0xc177772f58c158ee), +C64e(0x75afaf309f759f45), C64e(0x634242e7a563a584), +C64e(0x3020207050305040), C64e(0x1ae5e5cb2e1a2ed1), +C64e(0x0efdfdef120e12e1), C64e(0x6dbfbf08b76db765), +C64e(0x4c818155d44cd419), C64e(0x141818243c143c30), +C64e(0x352626795f355f4c), C64e(0x2fc3c3b2712f719d), +C64e(0xe1bebe8638e13867), C64e(0xa23535c8fda2fd6a), +C64e(0xcc8888c74fcc4f0b), C64e(0x392e2e654b394b5c), +C64e(0x5793936af957f93d), C64e(0xf25555580df20daa), +C64e(0x82fcfc619d829de3), C64e(0x477a7ab3c947c9f4), +C64e(0xacc8c827efacef8b), C64e(0xe7baba8832e7326f), +C64e(0x2b32324f7d2b7d64), C64e(0x95e6e642a495a4d7), +C64e(0xa0c0c03bfba0fb9b), C64e(0x981919aab398b332), +C64e(0xd19e9ef668d16827), C64e(0x7fa3a322817f815d), +C64e(0x664444eeaa66aa88), C64e(0x7e5454d6827e82a8), +C64e(0xab3b3bdde6abe676), C64e(0x830b0b959e839e16), +C64e(0xca8c8cc945ca4503), C64e(0x29c7c7bc7b297b95), +C64e(0xd36b6b056ed36ed6), C64e(0x3c28286c443c4450), +C64e(0x79a7a72c8b798b55), C64e(0xe2bcbc813de23d63), +C64e(0x1d161631271d272c), C64e(0x76adad379a769a41), +C64e(0x3bdbdb964d3b4dad), C64e(0x5664649efa56fac8), +C64e(0x4e7474a6d24ed2e8), C64e(0x1e141436221e2228), +C64e(0xdb9292e476db763f), C64e(0x0a0c0c121e0a1e18), +C64e(0x6c4848fcb46cb490), C64e(0xe4b8b88f37e4376b), +C64e(0x5d9f9f78e75de725), C64e(0x6ebdbd0fb26eb261), +C64e(0xef4343692aef2a86), C64e(0xa6c4c435f1a6f193), +C64e(0xa83939dae3a8e372), C64e(0xa43131c6f7a4f762), +C64e(0x37d3d38a593759bd), C64e(0x8bf2f274868b86ff), +C64e(0x32d5d583563256b1), C64e(0x438b8b4ec543c50d), +C64e(0x596e6e85eb59ebdc), C64e(0xb7dada18c2b7c2af), +C64e(0x8c01018e8f8c8f02), C64e(0x64b1b11dac64ac79), +C64e(0xd29c9cf16dd26d23), C64e(0xe04949723be03b92), +C64e(0xb4d8d81fc7b4c7ab), C64e(0xfaacacb915fa1543), +C64e(0x07f3f3fa090709fd), C64e(0x25cfcfa06f256f85), +C64e(0xafcaca20eaafea8f), C64e(0x8ef4f47d898e89f3), +C64e(0xe947476720e9208e), C64e(0x1810103828182820), +C64e(0xd56f6f0b64d564de), C64e(0x88f0f073838883fb), +C64e(0x6f4a4afbb16fb194), C64e(0x725c5cca967296b8), +C64e(0x243838546c246c70), C64e(0xf157575f08f108ae), +C64e(0xc773732152c752e6), C64e(0x51979764f351f335), +C64e(0x23cbcbae6523658d), C64e(0x7ca1a125847c8459), +C64e(0x9ce8e857bf9cbfcb), C64e(0x213e3e5d6321637c), +C64e(0xdd9696ea7cdd7c37), C64e(0xdc61611e7fdc7fc2), +C64e(0x860d0d9c9186911a), C64e(0x850f0f9b9485941e), +C64e(0x90e0e04bab90abdb), C64e(0x427c7cbac642c6f8), +C64e(0xc471712657c457e2), C64e(0xaacccc29e5aae583), +C64e(0xd89090e373d8733b), C64e(0x050606090f050f0c), +C64e(0x01f7f7f4030103f5), C64e(0x121c1c2a36123638), +C64e(0xa3c2c23cfea3fe9f), C64e(0x5f6a6a8be15fe1d4), +C64e(0xf9aeaebe10f91047), C64e(0xd06969026bd06bd2), +C64e(0x911717bfa891a82e), C64e(0x58999971e858e829), +C64e(0x273a3a5369276974), C64e(0xb92727f7d0b9d04e), +C64e(0x38d9d991483848a9), C64e(0x13ebebde351335cd), +C64e(0xb32b2be5ceb3ce56), C64e(0x3322227755335544), +C64e(0xbbd2d204d6bbd6bf), C64e(0x70a9a93990709049), +C64e(0x890707878089800e), C64e(0xa73333c1f2a7f266), +C64e(0xb62d2decc1b6c15a), C64e(0x223c3c5a66226678), +C64e(0x921515b8ad92ad2a), C64e(0x20c9c9a960206089), +C64e(0x4987875cdb49db15), C64e(0xffaaaab01aff1a4f), +C64e(0x785050d8887888a0), C64e(0x7aa5a52b8e7a8e51), +C64e(0x8f0303898a8f8a06), C64e(0xf859594a13f813b2), +C64e(0x800909929b809b12), C64e(0x171a1a2339173934), +C64e(0xda65651075da75ca), C64e(0x31d7d784533153b5), +C64e(0xc68484d551c65113), C64e(0xb8d0d003d3b8d3bb), +C64e(0xc38282dc5ec35e1f), C64e(0xb02929e2cbb0cb52), +C64e(0x775a5ac3997799b4), C64e(0x111e1e2d3311333c), +C64e(0xcb7b7b3d46cb46f6), C64e(0xfca8a8b71ffc1f4b), +C64e(0xd66d6d0c61d661da), C64e(0x3a2c2c624e3a4e58) +}; + +__constant static const ulong T3_G[] = { +C64e(0x97a5c6c632f4a5f4), C64e(0xeb84f8f86f978497), +C64e(0xc799eeee5eb099b0), C64e(0xf78df6f67a8c8d8c), +C64e(0xe50dffffe8170d17), C64e(0xb7bdd6d60adcbddc), +C64e(0xa7b1dede16c8b1c8), C64e(0x395491916dfc54fc), +C64e(0xc050606090f050f0), C64e(0x0403020207050305), +C64e(0x87a9cece2ee0a9e0), C64e(0xac7d5656d1877d87), +C64e(0xd519e7e7cc2b192b), C64e(0x7162b5b513a662a6), +C64e(0x9ae64d4d7c31e631), C64e(0xc39aecec59b59ab5), +C64e(0x05458f8f40cf45cf), C64e(0x3e9d1f1fa3bc9dbc), +C64e(0x0940898949c040c0), C64e(0xef87fafa68928792), +C64e(0xc515efefd03f153f), C64e(0x7febb2b29426eb26), +C64e(0x07c98e8ece40c940), C64e(0xed0bfbfbe61d0b1d), +C64e(0x82ec41416e2fec2f), C64e(0x7d67b3b31aa967a9), +C64e(0xbefd5f5f431cfd1c), C64e(0x8aea45456025ea25), +C64e(0x46bf2323f9dabfda), C64e(0xa6f753535102f702), +C64e(0xd396e4e445a196a1), C64e(0x2d5b9b9b76ed5bed), +C64e(0xeac27575285dc25d), C64e(0xd91ce1e1c5241c24), +C64e(0x7aae3d3dd4e9aee9), C64e(0x986a4c4cf2be6abe), +C64e(0xd85a6c6c82ee5aee), C64e(0xfc417e7ebdc341c3), +C64e(0xf102f5f5f3060206), C64e(0x1d4f838352d14fd1), +C64e(0xd05c68688ce45ce4), C64e(0xa2f451515607f407), +C64e(0xb934d1d18d5c345c), C64e(0xe908f9f9e1180818), +C64e(0xdf93e2e24cae93ae), C64e(0x4d73abab3e957395), +C64e(0xc453626297f553f5), C64e(0x543f2a2a6b413f41), +C64e(0x100c08081c140c14), C64e(0x3152959563f652f6), +C64e(0x8c654646e9af65af), C64e(0x215e9d9d7fe25ee2), +C64e(0x6028303048782878), C64e(0x6ea13737cff8a1f8), +C64e(0x140f0a0a1b110f11), C64e(0x5eb52f2febc4b5c4), +C64e(0x1c090e0e151b091b), C64e(0x483624247e5a365a), +C64e(0x369b1b1badb69bb6), C64e(0xa53ddfdf98473d47), +C64e(0x8126cdcda76a266a), C64e(0x9c694e4ef5bb69bb), +C64e(0xfecd7f7f334ccd4c), C64e(0xcf9feaea50ba9fba), +C64e(0x241b12123f2d1b2d), C64e(0x3a9e1d1da4b99eb9), +C64e(0xb0745858c49c749c), C64e(0x682e343446722e72), +C64e(0x6c2d363641772d77), C64e(0xa3b2dcdc11cdb2cd), +C64e(0x73eeb4b49d29ee29), C64e(0xb6fb5b5b4d16fb16), +C64e(0x53f6a4a4a501f601), C64e(0xec4d7676a1d74dd7), +C64e(0x7561b7b714a361a3), C64e(0xface7d7d3449ce49), +C64e(0xa47b5252df8d7b8d), C64e(0xa13edddd9f423e42), +C64e(0xbc715e5ecd937193), C64e(0x26971313b1a297a2), +C64e(0x57f5a6a6a204f504), C64e(0x6968b9b901b868b8), +C64e(0x0000000000000000), C64e(0x992cc1c1b5742c74), +C64e(0x80604040e0a060a0), C64e(0xdd1fe3e3c2211f21), +C64e(0xf2c879793a43c843), C64e(0x77edb6b69a2ced2c), +C64e(0xb3bed4d40dd9bed9), C64e(0x01468d8d47ca46ca), +C64e(0xced967671770d970), C64e(0xe44b7272afdd4bdd), +C64e(0x33de9494ed79de79), C64e(0x2bd49898ff67d467), +C64e(0x7be8b0b09323e823), C64e(0x114a85855bde4ade), +C64e(0x6d6bbbbb06bd6bbd), C64e(0x912ac5c5bb7e2a7e), +C64e(0x9ee54f4f7b34e534), C64e(0xc116ededd73a163a), +C64e(0x17c58686d254c554), C64e(0x2fd79a9af862d762), +C64e(0xcc55666699ff55ff), C64e(0x22941111b6a794a7), +C64e(0x0fcf8a8ac04acf4a), C64e(0xc910e9e9d9301030), +C64e(0x080604040e0a060a), C64e(0xe781fefe66988198), +C64e(0x5bf0a0a0ab0bf00b), C64e(0xf0447878b4cc44cc), +C64e(0x4aba2525f0d5bad5), C64e(0x96e34b4b753ee33e), +C64e(0x5ff3a2a2ac0ef30e), C64e(0xbafe5d5d4419fe19), +C64e(0x1bc08080db5bc05b), C64e(0x0a8a050580858a85), +C64e(0x7ead3f3fd3ecadec), C64e(0x42bc2121fedfbcdf), +C64e(0xe0487070a8d848d8), C64e(0xf904f1f1fd0c040c), +C64e(0xc6df6363197adf7a), C64e(0xeec177772f58c158), +C64e(0x4575afaf309f759f), C64e(0x84634242e7a563a5), +C64e(0x4030202070503050), C64e(0xd11ae5e5cb2e1a2e), +C64e(0xe10efdfdef120e12), C64e(0x656dbfbf08b76db7), +C64e(0x194c818155d44cd4), C64e(0x30141818243c143c), +C64e(0x4c352626795f355f), C64e(0x9d2fc3c3b2712f71), +C64e(0x67e1bebe8638e138), C64e(0x6aa23535c8fda2fd), +C64e(0x0bcc8888c74fcc4f), C64e(0x5c392e2e654b394b), +C64e(0x3d5793936af957f9), C64e(0xaaf25555580df20d), +C64e(0xe382fcfc619d829d), C64e(0xf4477a7ab3c947c9), +C64e(0x8bacc8c827efacef), C64e(0x6fe7baba8832e732), +C64e(0x642b32324f7d2b7d), C64e(0xd795e6e642a495a4), +C64e(0x9ba0c0c03bfba0fb), C64e(0x32981919aab398b3), +C64e(0x27d19e9ef668d168), C64e(0x5d7fa3a322817f81), +C64e(0x88664444eeaa66aa), C64e(0xa87e5454d6827e82), +C64e(0x76ab3b3bdde6abe6), C64e(0x16830b0b959e839e), +C64e(0x03ca8c8cc945ca45), C64e(0x9529c7c7bc7b297b), +C64e(0xd6d36b6b056ed36e), C64e(0x503c28286c443c44), +C64e(0x5579a7a72c8b798b), C64e(0x63e2bcbc813de23d), +C64e(0x2c1d161631271d27), C64e(0x4176adad379a769a), +C64e(0xad3bdbdb964d3b4d), C64e(0xc85664649efa56fa), +C64e(0xe84e7474a6d24ed2), C64e(0x281e141436221e22), +C64e(0x3fdb9292e476db76), C64e(0x180a0c0c121e0a1e), +C64e(0x906c4848fcb46cb4), C64e(0x6be4b8b88f37e437), +C64e(0x255d9f9f78e75de7), C64e(0x616ebdbd0fb26eb2), +C64e(0x86ef4343692aef2a), C64e(0x93a6c4c435f1a6f1), +C64e(0x72a83939dae3a8e3), C64e(0x62a43131c6f7a4f7), +C64e(0xbd37d3d38a593759), C64e(0xff8bf2f274868b86), +C64e(0xb132d5d583563256), C64e(0x0d438b8b4ec543c5), +C64e(0xdc596e6e85eb59eb), C64e(0xafb7dada18c2b7c2), +C64e(0x028c01018e8f8c8f), C64e(0x7964b1b11dac64ac), +C64e(0x23d29c9cf16dd26d), C64e(0x92e04949723be03b), +C64e(0xabb4d8d81fc7b4c7), C64e(0x43faacacb915fa15), +C64e(0xfd07f3f3fa090709), C64e(0x8525cfcfa06f256f), +C64e(0x8fafcaca20eaafea), C64e(0xf38ef4f47d898e89), +C64e(0x8ee947476720e920), C64e(0x2018101038281828), +C64e(0xded56f6f0b64d564), C64e(0xfb88f0f073838883), +C64e(0x946f4a4afbb16fb1), C64e(0xb8725c5cca967296), +C64e(0x70243838546c246c), C64e(0xaef157575f08f108), +C64e(0xe6c773732152c752), C64e(0x3551979764f351f3), +C64e(0x8d23cbcbae652365), C64e(0x597ca1a125847c84), +C64e(0xcb9ce8e857bf9cbf), C64e(0x7c213e3e5d632163), +C64e(0x37dd9696ea7cdd7c), C64e(0xc2dc61611e7fdc7f), +C64e(0x1a860d0d9c918691), C64e(0x1e850f0f9b948594), +C64e(0xdb90e0e04bab90ab), C64e(0xf8427c7cbac642c6), +C64e(0xe2c471712657c457), C64e(0x83aacccc29e5aae5), +C64e(0x3bd89090e373d873), C64e(0x0c050606090f050f), +C64e(0xf501f7f7f4030103), C64e(0x38121c1c2a361236), +C64e(0x9fa3c2c23cfea3fe), C64e(0xd45f6a6a8be15fe1), +C64e(0x47f9aeaebe10f910), C64e(0xd2d06969026bd06b), +C64e(0x2e911717bfa891a8), C64e(0x2958999971e858e8), +C64e(0x74273a3a53692769), C64e(0x4eb92727f7d0b9d0), +C64e(0xa938d9d991483848), C64e(0xcd13ebebde351335), +C64e(0x56b32b2be5ceb3ce), C64e(0x4433222277553355), +C64e(0xbfbbd2d204d6bbd6), C64e(0x4970a9a939907090), +C64e(0x0e89070787808980), C64e(0x66a73333c1f2a7f2), +C64e(0x5ab62d2decc1b6c1), C64e(0x78223c3c5a662266), +C64e(0x2a921515b8ad92ad), C64e(0x8920c9c9a9602060), +C64e(0x154987875cdb49db), C64e(0x4fffaaaab01aff1a), +C64e(0xa0785050d8887888), C64e(0x517aa5a52b8e7a8e), +C64e(0x068f0303898a8f8a), C64e(0xb2f859594a13f813), +C64e(0x12800909929b809b), C64e(0x34171a1a23391739), +C64e(0xcada65651075da75), C64e(0xb531d7d784533153), +C64e(0x13c68484d551c651), C64e(0xbbb8d0d003d3b8d3), +C64e(0x1fc38282dc5ec35e), C64e(0x52b02929e2cbb0cb), +C64e(0xb4775a5ac3997799), C64e(0x3c111e1e2d331133), +C64e(0xf6cb7b7b3d46cb46), C64e(0x4bfca8a8b71ffc1f), +C64e(0xdad66d6d0c61d661), C64e(0x583a2c2c624e3a4e) +}; +*/ +__constant static const ulong T4_G[] = { +C64e(0xf497a5c6c632f4a5), C64e(0x97eb84f8f86f9784), +C64e(0xb0c799eeee5eb099), C64e(0x8cf78df6f67a8c8d), +C64e(0x17e50dffffe8170d), C64e(0xdcb7bdd6d60adcbd), +C64e(0xc8a7b1dede16c8b1), C64e(0xfc395491916dfc54), +C64e(0xf0c050606090f050), C64e(0x0504030202070503), +C64e(0xe087a9cece2ee0a9), C64e(0x87ac7d5656d1877d), +C64e(0x2bd519e7e7cc2b19), C64e(0xa67162b5b513a662), +C64e(0x319ae64d4d7c31e6), C64e(0xb5c39aecec59b59a), +C64e(0xcf05458f8f40cf45), C64e(0xbc3e9d1f1fa3bc9d), +C64e(0xc00940898949c040), C64e(0x92ef87fafa689287), +C64e(0x3fc515efefd03f15), C64e(0x267febb2b29426eb), +C64e(0x4007c98e8ece40c9), C64e(0x1ded0bfbfbe61d0b), +C64e(0x2f82ec41416e2fec), C64e(0xa97d67b3b31aa967), +C64e(0x1cbefd5f5f431cfd), C64e(0x258aea45456025ea), +C64e(0xda46bf2323f9dabf), C64e(0x02a6f753535102f7), +C64e(0xa1d396e4e445a196), C64e(0xed2d5b9b9b76ed5b), +C64e(0x5deac27575285dc2), C64e(0x24d91ce1e1c5241c), +C64e(0xe97aae3d3dd4e9ae), C64e(0xbe986a4c4cf2be6a), +C64e(0xeed85a6c6c82ee5a), C64e(0xc3fc417e7ebdc341), +C64e(0x06f102f5f5f30602), C64e(0xd11d4f838352d14f), +C64e(0xe4d05c68688ce45c), C64e(0x07a2f451515607f4), +C64e(0x5cb934d1d18d5c34), C64e(0x18e908f9f9e11808), +C64e(0xaedf93e2e24cae93), C64e(0x954d73abab3e9573), +C64e(0xf5c453626297f553), C64e(0x41543f2a2a6b413f), +C64e(0x14100c08081c140c), C64e(0xf63152959563f652), +C64e(0xaf8c654646e9af65), C64e(0xe2215e9d9d7fe25e), +C64e(0x7860283030487828), C64e(0xf86ea13737cff8a1), +C64e(0x11140f0a0a1b110f), C64e(0xc45eb52f2febc4b5), +C64e(0x1b1c090e0e151b09), C64e(0x5a483624247e5a36), +C64e(0xb6369b1b1badb69b), C64e(0x47a53ddfdf98473d), +C64e(0x6a8126cdcda76a26), C64e(0xbb9c694e4ef5bb69), +C64e(0x4cfecd7f7f334ccd), C64e(0xbacf9feaea50ba9f), +C64e(0x2d241b12123f2d1b), C64e(0xb93a9e1d1da4b99e), +C64e(0x9cb0745858c49c74), C64e(0x72682e343446722e), +C64e(0x776c2d363641772d), C64e(0xcda3b2dcdc11cdb2), +C64e(0x2973eeb4b49d29ee), C64e(0x16b6fb5b5b4d16fb), +C64e(0x0153f6a4a4a501f6), C64e(0xd7ec4d7676a1d74d), +C64e(0xa37561b7b714a361), C64e(0x49face7d7d3449ce), +C64e(0x8da47b5252df8d7b), C64e(0x42a13edddd9f423e), +C64e(0x93bc715e5ecd9371), C64e(0xa226971313b1a297), +C64e(0x0457f5a6a6a204f5), C64e(0xb86968b9b901b868), +C64e(0x0000000000000000), C64e(0x74992cc1c1b5742c), +C64e(0xa080604040e0a060), C64e(0x21dd1fe3e3c2211f), +C64e(0x43f2c879793a43c8), C64e(0x2c77edb6b69a2ced), +C64e(0xd9b3bed4d40dd9be), C64e(0xca01468d8d47ca46), +C64e(0x70ced967671770d9), C64e(0xdde44b7272afdd4b), +C64e(0x7933de9494ed79de), C64e(0x672bd49898ff67d4), +C64e(0x237be8b0b09323e8), C64e(0xde114a85855bde4a), +C64e(0xbd6d6bbbbb06bd6b), C64e(0x7e912ac5c5bb7e2a), +C64e(0x349ee54f4f7b34e5), C64e(0x3ac116ededd73a16), +C64e(0x5417c58686d254c5), C64e(0x622fd79a9af862d7), +C64e(0xffcc55666699ff55), C64e(0xa722941111b6a794), +C64e(0x4a0fcf8a8ac04acf), C64e(0x30c910e9e9d93010), +C64e(0x0a080604040e0a06), C64e(0x98e781fefe669881), +C64e(0x0b5bf0a0a0ab0bf0), C64e(0xccf0447878b4cc44), +C64e(0xd54aba2525f0d5ba), C64e(0x3e96e34b4b753ee3), +C64e(0x0e5ff3a2a2ac0ef3), C64e(0x19bafe5d5d4419fe), +C64e(0x5b1bc08080db5bc0), C64e(0x850a8a050580858a), +C64e(0xec7ead3f3fd3ecad), C64e(0xdf42bc2121fedfbc), +C64e(0xd8e0487070a8d848), C64e(0x0cf904f1f1fd0c04), +C64e(0x7ac6df6363197adf), C64e(0x58eec177772f58c1), +C64e(0x9f4575afaf309f75), C64e(0xa584634242e7a563), +C64e(0x5040302020705030), C64e(0x2ed11ae5e5cb2e1a), +C64e(0x12e10efdfdef120e), C64e(0xb7656dbfbf08b76d), +C64e(0xd4194c818155d44c), C64e(0x3c30141818243c14), +C64e(0x5f4c352626795f35), C64e(0x719d2fc3c3b2712f), +C64e(0x3867e1bebe8638e1), C64e(0xfd6aa23535c8fda2), +C64e(0x4f0bcc8888c74fcc), C64e(0x4b5c392e2e654b39), +C64e(0xf93d5793936af957), C64e(0x0daaf25555580df2), +C64e(0x9de382fcfc619d82), C64e(0xc9f4477a7ab3c947), +C64e(0xef8bacc8c827efac), C64e(0x326fe7baba8832e7), +C64e(0x7d642b32324f7d2b), C64e(0xa4d795e6e642a495), +C64e(0xfb9ba0c0c03bfba0), C64e(0xb332981919aab398), +C64e(0x6827d19e9ef668d1), C64e(0x815d7fa3a322817f), +C64e(0xaa88664444eeaa66), C64e(0x82a87e5454d6827e), +C64e(0xe676ab3b3bdde6ab), C64e(0x9e16830b0b959e83), +C64e(0x4503ca8c8cc945ca), C64e(0x7b9529c7c7bc7b29), +C64e(0x6ed6d36b6b056ed3), C64e(0x44503c28286c443c), +C64e(0x8b5579a7a72c8b79), C64e(0x3d63e2bcbc813de2), +C64e(0x272c1d161631271d), C64e(0x9a4176adad379a76), +C64e(0x4dad3bdbdb964d3b), C64e(0xfac85664649efa56), +C64e(0xd2e84e7474a6d24e), C64e(0x22281e141436221e), +C64e(0x763fdb9292e476db), C64e(0x1e180a0c0c121e0a), +C64e(0xb4906c4848fcb46c), C64e(0x376be4b8b88f37e4), +C64e(0xe7255d9f9f78e75d), C64e(0xb2616ebdbd0fb26e), +C64e(0x2a86ef4343692aef), C64e(0xf193a6c4c435f1a6), +C64e(0xe372a83939dae3a8), C64e(0xf762a43131c6f7a4), +C64e(0x59bd37d3d38a5937), C64e(0x86ff8bf2f274868b), +C64e(0x56b132d5d5835632), C64e(0xc50d438b8b4ec543), +C64e(0xebdc596e6e85eb59), C64e(0xc2afb7dada18c2b7), +C64e(0x8f028c01018e8f8c), C64e(0xac7964b1b11dac64), +C64e(0x6d23d29c9cf16dd2), C64e(0x3b92e04949723be0), +C64e(0xc7abb4d8d81fc7b4), C64e(0x1543faacacb915fa), +C64e(0x09fd07f3f3fa0907), C64e(0x6f8525cfcfa06f25), +C64e(0xea8fafcaca20eaaf), C64e(0x89f38ef4f47d898e), +C64e(0x208ee947476720e9), C64e(0x2820181010382818), +C64e(0x64ded56f6f0b64d5), C64e(0x83fb88f0f0738388), +C64e(0xb1946f4a4afbb16f), C64e(0x96b8725c5cca9672), +C64e(0x6c70243838546c24), C64e(0x08aef157575f08f1), +C64e(0x52e6c773732152c7), C64e(0xf33551979764f351), +C64e(0x658d23cbcbae6523), C64e(0x84597ca1a125847c), +C64e(0xbfcb9ce8e857bf9c), C64e(0x637c213e3e5d6321), +C64e(0x7c37dd9696ea7cdd), C64e(0x7fc2dc61611e7fdc), +C64e(0x911a860d0d9c9186), C64e(0x941e850f0f9b9485), +C64e(0xabdb90e0e04bab90), C64e(0xc6f8427c7cbac642), +C64e(0x57e2c471712657c4), C64e(0xe583aacccc29e5aa), +C64e(0x733bd89090e373d8), C64e(0x0f0c050606090f05), +C64e(0x03f501f7f7f40301), C64e(0x3638121c1c2a3612), +C64e(0xfe9fa3c2c23cfea3), C64e(0xe1d45f6a6a8be15f), +C64e(0x1047f9aeaebe10f9), C64e(0x6bd2d06969026bd0), +C64e(0xa82e911717bfa891), C64e(0xe82958999971e858), +C64e(0x6974273a3a536927), C64e(0xd04eb92727f7d0b9), +C64e(0x48a938d9d9914838), C64e(0x35cd13ebebde3513), +C64e(0xce56b32b2be5ceb3), C64e(0x5544332222775533), +C64e(0xd6bfbbd2d204d6bb), C64e(0x904970a9a9399070), +C64e(0x800e890707878089), C64e(0xf266a73333c1f2a7), +C64e(0xc15ab62d2decc1b6), C64e(0x6678223c3c5a6622), +C64e(0xad2a921515b8ad92), C64e(0x608920c9c9a96020), +C64e(0xdb154987875cdb49), C64e(0x1a4fffaaaab01aff), +C64e(0x88a0785050d88878), C64e(0x8e517aa5a52b8e7a), +C64e(0x8a068f0303898a8f), C64e(0x13b2f859594a13f8), +C64e(0x9b12800909929b80), C64e(0x3934171a1a233917), +C64e(0x75cada65651075da), C64e(0x53b531d7d7845331), +C64e(0x5113c68484d551c6), C64e(0xd3bbb8d0d003d3b8), +C64e(0x5e1fc38282dc5ec3), C64e(0xcb52b02929e2cbb0), +C64e(0x99b4775a5ac39977), C64e(0x333c111e1e2d3311), +C64e(0x46f6cb7b7b3d46cb), C64e(0x1f4bfca8a8b71ffc), +C64e(0x61dad66d6d0c61d6), C64e(0x4e583a2c2c624e3a) +}; + +/* +__constant static const ulong T5_G[] = { +C64e(0xa5f497a5c6c632f4), C64e(0x8497eb84f8f86f97), +C64e(0x99b0c799eeee5eb0), C64e(0x8d8cf78df6f67a8c), +C64e(0x0d17e50dffffe817), C64e(0xbddcb7bdd6d60adc), +C64e(0xb1c8a7b1dede16c8), C64e(0x54fc395491916dfc), +C64e(0x50f0c050606090f0), C64e(0x0305040302020705), +C64e(0xa9e087a9cece2ee0), C64e(0x7d87ac7d5656d187), +C64e(0x192bd519e7e7cc2b), C64e(0x62a67162b5b513a6), +C64e(0xe6319ae64d4d7c31), C64e(0x9ab5c39aecec59b5), +C64e(0x45cf05458f8f40cf), C64e(0x9dbc3e9d1f1fa3bc), +C64e(0x40c00940898949c0), C64e(0x8792ef87fafa6892), +C64e(0x153fc515efefd03f), C64e(0xeb267febb2b29426), +C64e(0xc94007c98e8ece40), C64e(0x0b1ded0bfbfbe61d), +C64e(0xec2f82ec41416e2f), C64e(0x67a97d67b3b31aa9), +C64e(0xfd1cbefd5f5f431c), C64e(0xea258aea45456025), +C64e(0xbfda46bf2323f9da), C64e(0xf702a6f753535102), +C64e(0x96a1d396e4e445a1), C64e(0x5bed2d5b9b9b76ed), +C64e(0xc25deac27575285d), C64e(0x1c24d91ce1e1c524), +C64e(0xaee97aae3d3dd4e9), C64e(0x6abe986a4c4cf2be), +C64e(0x5aeed85a6c6c82ee), C64e(0x41c3fc417e7ebdc3), +C64e(0x0206f102f5f5f306), C64e(0x4fd11d4f838352d1), +C64e(0x5ce4d05c68688ce4), C64e(0xf407a2f451515607), +C64e(0x345cb934d1d18d5c), C64e(0x0818e908f9f9e118), +C64e(0x93aedf93e2e24cae), C64e(0x73954d73abab3e95), +C64e(0x53f5c453626297f5), C64e(0x3f41543f2a2a6b41), +C64e(0x0c14100c08081c14), C64e(0x52f63152959563f6), +C64e(0x65af8c654646e9af), C64e(0x5ee2215e9d9d7fe2), +C64e(0x2878602830304878), C64e(0xa1f86ea13737cff8), +C64e(0x0f11140f0a0a1b11), C64e(0xb5c45eb52f2febc4), +C64e(0x091b1c090e0e151b), C64e(0x365a483624247e5a), +C64e(0x9bb6369b1b1badb6), C64e(0x3d47a53ddfdf9847), +C64e(0x266a8126cdcda76a), C64e(0x69bb9c694e4ef5bb), +C64e(0xcd4cfecd7f7f334c), C64e(0x9fbacf9feaea50ba), +C64e(0x1b2d241b12123f2d), C64e(0x9eb93a9e1d1da4b9), +C64e(0x749cb0745858c49c), C64e(0x2e72682e34344672), +C64e(0x2d776c2d36364177), C64e(0xb2cda3b2dcdc11cd), +C64e(0xee2973eeb4b49d29), C64e(0xfb16b6fb5b5b4d16), +C64e(0xf60153f6a4a4a501), C64e(0x4dd7ec4d7676a1d7), +C64e(0x61a37561b7b714a3), C64e(0xce49face7d7d3449), +C64e(0x7b8da47b5252df8d), C64e(0x3e42a13edddd9f42), +C64e(0x7193bc715e5ecd93), C64e(0x97a226971313b1a2), +C64e(0xf50457f5a6a6a204), C64e(0x68b86968b9b901b8), +C64e(0x0000000000000000), C64e(0x2c74992cc1c1b574), +C64e(0x60a080604040e0a0), C64e(0x1f21dd1fe3e3c221), +C64e(0xc843f2c879793a43), C64e(0xed2c77edb6b69a2c), +C64e(0xbed9b3bed4d40dd9), C64e(0x46ca01468d8d47ca), +C64e(0xd970ced967671770), C64e(0x4bdde44b7272afdd), +C64e(0xde7933de9494ed79), C64e(0xd4672bd49898ff67), +C64e(0xe8237be8b0b09323), C64e(0x4ade114a85855bde), +C64e(0x6bbd6d6bbbbb06bd), C64e(0x2a7e912ac5c5bb7e), +C64e(0xe5349ee54f4f7b34), C64e(0x163ac116ededd73a), +C64e(0xc55417c58686d254), C64e(0xd7622fd79a9af862), +C64e(0x55ffcc55666699ff), C64e(0x94a722941111b6a7), +C64e(0xcf4a0fcf8a8ac04a), C64e(0x1030c910e9e9d930), +C64e(0x060a080604040e0a), C64e(0x8198e781fefe6698), +C64e(0xf00b5bf0a0a0ab0b), C64e(0x44ccf0447878b4cc), +C64e(0xbad54aba2525f0d5), C64e(0xe33e96e34b4b753e), +C64e(0xf30e5ff3a2a2ac0e), C64e(0xfe19bafe5d5d4419), +C64e(0xc05b1bc08080db5b), C64e(0x8a850a8a05058085), +C64e(0xadec7ead3f3fd3ec), C64e(0xbcdf42bc2121fedf), +C64e(0x48d8e0487070a8d8), C64e(0x040cf904f1f1fd0c), +C64e(0xdf7ac6df6363197a), C64e(0xc158eec177772f58), +C64e(0x759f4575afaf309f), C64e(0x63a584634242e7a5), +C64e(0x3050403020207050), C64e(0x1a2ed11ae5e5cb2e), +C64e(0x0e12e10efdfdef12), C64e(0x6db7656dbfbf08b7), +C64e(0x4cd4194c818155d4), C64e(0x143c30141818243c), +C64e(0x355f4c352626795f), C64e(0x2f719d2fc3c3b271), +C64e(0xe13867e1bebe8638), C64e(0xa2fd6aa23535c8fd), +C64e(0xcc4f0bcc8888c74f), C64e(0x394b5c392e2e654b), +C64e(0x57f93d5793936af9), C64e(0xf20daaf25555580d), +C64e(0x829de382fcfc619d), C64e(0x47c9f4477a7ab3c9), +C64e(0xacef8bacc8c827ef), C64e(0xe7326fe7baba8832), +C64e(0x2b7d642b32324f7d), C64e(0x95a4d795e6e642a4), +C64e(0xa0fb9ba0c0c03bfb), C64e(0x98b332981919aab3), +C64e(0xd16827d19e9ef668), C64e(0x7f815d7fa3a32281), +C64e(0x66aa88664444eeaa), C64e(0x7e82a87e5454d682), +C64e(0xabe676ab3b3bdde6), C64e(0x839e16830b0b959e), +C64e(0xca4503ca8c8cc945), C64e(0x297b9529c7c7bc7b), +C64e(0xd36ed6d36b6b056e), C64e(0x3c44503c28286c44), +C64e(0x798b5579a7a72c8b), C64e(0xe23d63e2bcbc813d), +C64e(0x1d272c1d16163127), C64e(0x769a4176adad379a), +C64e(0x3b4dad3bdbdb964d), C64e(0x56fac85664649efa), +C64e(0x4ed2e84e7474a6d2), C64e(0x1e22281e14143622), +C64e(0xdb763fdb9292e476), C64e(0x0a1e180a0c0c121e), +C64e(0x6cb4906c4848fcb4), C64e(0xe4376be4b8b88f37), +C64e(0x5de7255d9f9f78e7), C64e(0x6eb2616ebdbd0fb2), +C64e(0xef2a86ef4343692a), C64e(0xa6f193a6c4c435f1), +C64e(0xa8e372a83939dae3), C64e(0xa4f762a43131c6f7), +C64e(0x3759bd37d3d38a59), C64e(0x8b86ff8bf2f27486), +C64e(0x3256b132d5d58356), C64e(0x43c50d438b8b4ec5), +C64e(0x59ebdc596e6e85eb), C64e(0xb7c2afb7dada18c2), +C64e(0x8c8f028c01018e8f), C64e(0x64ac7964b1b11dac), +C64e(0xd26d23d29c9cf16d), C64e(0xe03b92e04949723b), +C64e(0xb4c7abb4d8d81fc7), C64e(0xfa1543faacacb915), +C64e(0x0709fd07f3f3fa09), C64e(0x256f8525cfcfa06f), +C64e(0xafea8fafcaca20ea), C64e(0x8e89f38ef4f47d89), +C64e(0xe9208ee947476720), C64e(0x1828201810103828), +C64e(0xd564ded56f6f0b64), C64e(0x8883fb88f0f07383), +C64e(0x6fb1946f4a4afbb1), C64e(0x7296b8725c5cca96), +C64e(0x246c70243838546c), C64e(0xf108aef157575f08), +C64e(0xc752e6c773732152), C64e(0x51f33551979764f3), +C64e(0x23658d23cbcbae65), C64e(0x7c84597ca1a12584), +C64e(0x9cbfcb9ce8e857bf), C64e(0x21637c213e3e5d63), +C64e(0xdd7c37dd9696ea7c), C64e(0xdc7fc2dc61611e7f), +C64e(0x86911a860d0d9c91), C64e(0x85941e850f0f9b94), +C64e(0x90abdb90e0e04bab), C64e(0x42c6f8427c7cbac6), +C64e(0xc457e2c471712657), C64e(0xaae583aacccc29e5), +C64e(0xd8733bd89090e373), C64e(0x050f0c050606090f), +C64e(0x0103f501f7f7f403), C64e(0x123638121c1c2a36), +C64e(0xa3fe9fa3c2c23cfe), C64e(0x5fe1d45f6a6a8be1), +C64e(0xf91047f9aeaebe10), C64e(0xd06bd2d06969026b), +C64e(0x91a82e911717bfa8), C64e(0x58e82958999971e8), +C64e(0x276974273a3a5369), C64e(0xb9d04eb92727f7d0), +C64e(0x3848a938d9d99148), C64e(0x1335cd13ebebde35), +C64e(0xb3ce56b32b2be5ce), C64e(0x3355443322227755), +C64e(0xbbd6bfbbd2d204d6), C64e(0x70904970a9a93990), +C64e(0x89800e8907078780), C64e(0xa7f266a73333c1f2), +C64e(0xb6c15ab62d2decc1), C64e(0x226678223c3c5a66), +C64e(0x92ad2a921515b8ad), C64e(0x20608920c9c9a960), +C64e(0x49db154987875cdb), C64e(0xff1a4fffaaaab01a), +C64e(0x7888a0785050d888), C64e(0x7a8e517aa5a52b8e), +C64e(0x8f8a068f0303898a), C64e(0xf813b2f859594a13), +C64e(0x809b12800909929b), C64e(0x173934171a1a2339), +C64e(0xda75cada65651075), C64e(0x3153b531d7d78453), +C64e(0xc65113c68484d551), C64e(0xb8d3bbb8d0d003d3), +C64e(0xc35e1fc38282dc5e), C64e(0xb0cb52b02929e2cb), +C64e(0x7799b4775a5ac399), C64e(0x11333c111e1e2d33), +C64e(0xcb46f6cb7b7b3d46), C64e(0xfc1f4bfca8a8b71f), +C64e(0xd661dad66d6d0c61), C64e(0x3a4e583a2c2c624e) +}; + +__constant static const ulong T6_G[] = { +C64e(0xf4a5f497a5c6c632), C64e(0x978497eb84f8f86f), +C64e(0xb099b0c799eeee5e), C64e(0x8c8d8cf78df6f67a), +C64e(0x170d17e50dffffe8), C64e(0xdcbddcb7bdd6d60a), +C64e(0xc8b1c8a7b1dede16), C64e(0xfc54fc395491916d), +C64e(0xf050f0c050606090), C64e(0x0503050403020207), +C64e(0xe0a9e087a9cece2e), C64e(0x877d87ac7d5656d1), +C64e(0x2b192bd519e7e7cc), C64e(0xa662a67162b5b513), +C64e(0x31e6319ae64d4d7c), C64e(0xb59ab5c39aecec59), +C64e(0xcf45cf05458f8f40), C64e(0xbc9dbc3e9d1f1fa3), +C64e(0xc040c00940898949), C64e(0x928792ef87fafa68), +C64e(0x3f153fc515efefd0), C64e(0x26eb267febb2b294), +C64e(0x40c94007c98e8ece), C64e(0x1d0b1ded0bfbfbe6), +C64e(0x2fec2f82ec41416e), C64e(0xa967a97d67b3b31a), +C64e(0x1cfd1cbefd5f5f43), C64e(0x25ea258aea454560), +C64e(0xdabfda46bf2323f9), C64e(0x02f702a6f7535351), +C64e(0xa196a1d396e4e445), C64e(0xed5bed2d5b9b9b76), +C64e(0x5dc25deac2757528), C64e(0x241c24d91ce1e1c5), +C64e(0xe9aee97aae3d3dd4), C64e(0xbe6abe986a4c4cf2), +C64e(0xee5aeed85a6c6c82), C64e(0xc341c3fc417e7ebd), +C64e(0x060206f102f5f5f3), C64e(0xd14fd11d4f838352), +C64e(0xe45ce4d05c68688c), C64e(0x07f407a2f4515156), +C64e(0x5c345cb934d1d18d), C64e(0x180818e908f9f9e1), +C64e(0xae93aedf93e2e24c), C64e(0x9573954d73abab3e), +C64e(0xf553f5c453626297), C64e(0x413f41543f2a2a6b), +C64e(0x140c14100c08081c), C64e(0xf652f63152959563), +C64e(0xaf65af8c654646e9), C64e(0xe25ee2215e9d9d7f), +C64e(0x7828786028303048), C64e(0xf8a1f86ea13737cf), +C64e(0x110f11140f0a0a1b), C64e(0xc4b5c45eb52f2feb), +C64e(0x1b091b1c090e0e15), C64e(0x5a365a483624247e), +C64e(0xb69bb6369b1b1bad), C64e(0x473d47a53ddfdf98), +C64e(0x6a266a8126cdcda7), C64e(0xbb69bb9c694e4ef5), +C64e(0x4ccd4cfecd7f7f33), C64e(0xba9fbacf9feaea50), +C64e(0x2d1b2d241b12123f), C64e(0xb99eb93a9e1d1da4), +C64e(0x9c749cb0745858c4), C64e(0x722e72682e343446), +C64e(0x772d776c2d363641), C64e(0xcdb2cda3b2dcdc11), +C64e(0x29ee2973eeb4b49d), C64e(0x16fb16b6fb5b5b4d), +C64e(0x01f60153f6a4a4a5), C64e(0xd74dd7ec4d7676a1), +C64e(0xa361a37561b7b714), C64e(0x49ce49face7d7d34), +C64e(0x8d7b8da47b5252df), C64e(0x423e42a13edddd9f), +C64e(0x937193bc715e5ecd), C64e(0xa297a226971313b1), +C64e(0x04f50457f5a6a6a2), C64e(0xb868b86968b9b901), +C64e(0x0000000000000000), C64e(0x742c74992cc1c1b5), +C64e(0xa060a080604040e0), C64e(0x211f21dd1fe3e3c2), +C64e(0x43c843f2c879793a), C64e(0x2ced2c77edb6b69a), +C64e(0xd9bed9b3bed4d40d), C64e(0xca46ca01468d8d47), +C64e(0x70d970ced9676717), C64e(0xdd4bdde44b7272af), +C64e(0x79de7933de9494ed), C64e(0x67d4672bd49898ff), +C64e(0x23e8237be8b0b093), C64e(0xde4ade114a85855b), +C64e(0xbd6bbd6d6bbbbb06), C64e(0x7e2a7e912ac5c5bb), +C64e(0x34e5349ee54f4f7b), C64e(0x3a163ac116ededd7), +C64e(0x54c55417c58686d2), C64e(0x62d7622fd79a9af8), +C64e(0xff55ffcc55666699), C64e(0xa794a722941111b6), +C64e(0x4acf4a0fcf8a8ac0), C64e(0x301030c910e9e9d9), +C64e(0x0a060a080604040e), C64e(0x988198e781fefe66), +C64e(0x0bf00b5bf0a0a0ab), C64e(0xcc44ccf0447878b4), +C64e(0xd5bad54aba2525f0), C64e(0x3ee33e96e34b4b75), +C64e(0x0ef30e5ff3a2a2ac), C64e(0x19fe19bafe5d5d44), +C64e(0x5bc05b1bc08080db), C64e(0x858a850a8a050580), +C64e(0xecadec7ead3f3fd3), C64e(0xdfbcdf42bc2121fe), +C64e(0xd848d8e0487070a8), C64e(0x0c040cf904f1f1fd), +C64e(0x7adf7ac6df636319), C64e(0x58c158eec177772f), +C64e(0x9f759f4575afaf30), C64e(0xa563a584634242e7), +C64e(0x5030504030202070), C64e(0x2e1a2ed11ae5e5cb), +C64e(0x120e12e10efdfdef), C64e(0xb76db7656dbfbf08), +C64e(0xd44cd4194c818155), C64e(0x3c143c3014181824), +C64e(0x5f355f4c35262679), C64e(0x712f719d2fc3c3b2), +C64e(0x38e13867e1bebe86), C64e(0xfda2fd6aa23535c8), +C64e(0x4fcc4f0bcc8888c7), C64e(0x4b394b5c392e2e65), +C64e(0xf957f93d5793936a), C64e(0x0df20daaf2555558), +C64e(0x9d829de382fcfc61), C64e(0xc947c9f4477a7ab3), +C64e(0xefacef8bacc8c827), C64e(0x32e7326fe7baba88), +C64e(0x7d2b7d642b32324f), C64e(0xa495a4d795e6e642), +C64e(0xfba0fb9ba0c0c03b), C64e(0xb398b332981919aa), +C64e(0x68d16827d19e9ef6), C64e(0x817f815d7fa3a322), +C64e(0xaa66aa88664444ee), C64e(0x827e82a87e5454d6), +C64e(0xe6abe676ab3b3bdd), C64e(0x9e839e16830b0b95), +C64e(0x45ca4503ca8c8cc9), C64e(0x7b297b9529c7c7bc), +C64e(0x6ed36ed6d36b6b05), C64e(0x443c44503c28286c), +C64e(0x8b798b5579a7a72c), C64e(0x3de23d63e2bcbc81), +C64e(0x271d272c1d161631), C64e(0x9a769a4176adad37), +C64e(0x4d3b4dad3bdbdb96), C64e(0xfa56fac85664649e), +C64e(0xd24ed2e84e7474a6), C64e(0x221e22281e141436), +C64e(0x76db763fdb9292e4), C64e(0x1e0a1e180a0c0c12), +C64e(0xb46cb4906c4848fc), C64e(0x37e4376be4b8b88f), +C64e(0xe75de7255d9f9f78), C64e(0xb26eb2616ebdbd0f), +C64e(0x2aef2a86ef434369), C64e(0xf1a6f193a6c4c435), +C64e(0xe3a8e372a83939da), C64e(0xf7a4f762a43131c6), +C64e(0x593759bd37d3d38a), C64e(0x868b86ff8bf2f274), +C64e(0x563256b132d5d583), C64e(0xc543c50d438b8b4e), +C64e(0xeb59ebdc596e6e85), C64e(0xc2b7c2afb7dada18), +C64e(0x8f8c8f028c01018e), C64e(0xac64ac7964b1b11d), +C64e(0x6dd26d23d29c9cf1), C64e(0x3be03b92e0494972), +C64e(0xc7b4c7abb4d8d81f), C64e(0x15fa1543faacacb9), +C64e(0x090709fd07f3f3fa), C64e(0x6f256f8525cfcfa0), +C64e(0xeaafea8fafcaca20), C64e(0x898e89f38ef4f47d), +C64e(0x20e9208ee9474767), C64e(0x2818282018101038), +C64e(0x64d564ded56f6f0b), C64e(0x838883fb88f0f073), +C64e(0xb16fb1946f4a4afb), C64e(0x967296b8725c5cca), +C64e(0x6c246c7024383854), C64e(0x08f108aef157575f), +C64e(0x52c752e6c7737321), C64e(0xf351f33551979764), +C64e(0x6523658d23cbcbae), C64e(0x847c84597ca1a125), +C64e(0xbf9cbfcb9ce8e857), C64e(0x6321637c213e3e5d), +C64e(0x7cdd7c37dd9696ea), C64e(0x7fdc7fc2dc61611e), +C64e(0x9186911a860d0d9c), C64e(0x9485941e850f0f9b), +C64e(0xab90abdb90e0e04b), C64e(0xc642c6f8427c7cba), +C64e(0x57c457e2c4717126), C64e(0xe5aae583aacccc29), +C64e(0x73d8733bd89090e3), C64e(0x0f050f0c05060609), +C64e(0x030103f501f7f7f4), C64e(0x36123638121c1c2a), +C64e(0xfea3fe9fa3c2c23c), C64e(0xe15fe1d45f6a6a8b), +C64e(0x10f91047f9aeaebe), C64e(0x6bd06bd2d0696902), +C64e(0xa891a82e911717bf), C64e(0xe858e82958999971), +C64e(0x69276974273a3a53), C64e(0xd0b9d04eb92727f7), +C64e(0x483848a938d9d991), C64e(0x351335cd13ebebde), +C64e(0xceb3ce56b32b2be5), C64e(0x5533554433222277), +C64e(0xd6bbd6bfbbd2d204), C64e(0x9070904970a9a939), +C64e(0x8089800e89070787), C64e(0xf2a7f266a73333c1), +C64e(0xc1b6c15ab62d2dec), C64e(0x66226678223c3c5a), +C64e(0xad92ad2a921515b8), C64e(0x6020608920c9c9a9), +C64e(0xdb49db154987875c), C64e(0x1aff1a4fffaaaab0), +C64e(0x887888a0785050d8), C64e(0x8e7a8e517aa5a52b), +C64e(0x8a8f8a068f030389), C64e(0x13f813b2f859594a), +C64e(0x9b809b1280090992), C64e(0x39173934171a1a23), +C64e(0x75da75cada656510), C64e(0x533153b531d7d784), +C64e(0x51c65113c68484d5), C64e(0xd3b8d3bbb8d0d003), +C64e(0x5ec35e1fc38282dc), C64e(0xcbb0cb52b02929e2), +C64e(0x997799b4775a5ac3), C64e(0x3311333c111e1e2d), +C64e(0x46cb46f6cb7b7b3d), C64e(0x1ffc1f4bfca8a8b7), +C64e(0x61d661dad66d6d0c), C64e(0x4e3a4e583a2c2c62) }; +__constant static const ulong T7_G[] = { +C64e(0x32f4a5f497a5c6c6), C64e(0x6f978497eb84f8f8), +C64e(0x5eb099b0c799eeee), C64e(0x7a8c8d8cf78df6f6), +C64e(0xe8170d17e50dffff), C64e(0x0adcbddcb7bdd6d6), +C64e(0x16c8b1c8a7b1dede), C64e(0x6dfc54fc39549191), +C64e(0x90f050f0c0506060), C64e(0x0705030504030202), +C64e(0x2ee0a9e087a9cece), C64e(0xd1877d87ac7d5656), +C64e(0xcc2b192bd519e7e7), C64e(0x13a662a67162b5b5), +C64e(0x7c31e6319ae64d4d), C64e(0x59b59ab5c39aecec), +C64e(0x40cf45cf05458f8f), C64e(0xa3bc9dbc3e9d1f1f), +C64e(0x49c040c009408989), C64e(0x68928792ef87fafa), +C64e(0xd03f153fc515efef), C64e(0x9426eb267febb2b2), +C64e(0xce40c94007c98e8e), C64e(0xe61d0b1ded0bfbfb), +C64e(0x6e2fec2f82ec4141), C64e(0x1aa967a97d67b3b3), +C64e(0x431cfd1cbefd5f5f), C64e(0x6025ea258aea4545), +C64e(0xf9dabfda46bf2323), C64e(0x5102f702a6f75353), +C64e(0x45a196a1d396e4e4), C64e(0x76ed5bed2d5b9b9b), +C64e(0x285dc25deac27575), C64e(0xc5241c24d91ce1e1), +C64e(0xd4e9aee97aae3d3d), C64e(0xf2be6abe986a4c4c), +C64e(0x82ee5aeed85a6c6c), C64e(0xbdc341c3fc417e7e), +C64e(0xf3060206f102f5f5), C64e(0x52d14fd11d4f8383), +C64e(0x8ce45ce4d05c6868), C64e(0x5607f407a2f45151), +C64e(0x8d5c345cb934d1d1), C64e(0xe1180818e908f9f9), +C64e(0x4cae93aedf93e2e2), C64e(0x3e9573954d73abab), +C64e(0x97f553f5c4536262), C64e(0x6b413f41543f2a2a), +C64e(0x1c140c14100c0808), C64e(0x63f652f631529595), +C64e(0xe9af65af8c654646), C64e(0x7fe25ee2215e9d9d), +C64e(0x4878287860283030), C64e(0xcff8a1f86ea13737), +C64e(0x1b110f11140f0a0a), C64e(0xebc4b5c45eb52f2f), +C64e(0x151b091b1c090e0e), C64e(0x7e5a365a48362424), +C64e(0xadb69bb6369b1b1b), C64e(0x98473d47a53ddfdf), +C64e(0xa76a266a8126cdcd), C64e(0xf5bb69bb9c694e4e), +C64e(0x334ccd4cfecd7f7f), C64e(0x50ba9fbacf9feaea), +C64e(0x3f2d1b2d241b1212), C64e(0xa4b99eb93a9e1d1d), +C64e(0xc49c749cb0745858), C64e(0x46722e72682e3434), +C64e(0x41772d776c2d3636), C64e(0x11cdb2cda3b2dcdc), +C64e(0x9d29ee2973eeb4b4), C64e(0x4d16fb16b6fb5b5b), +C64e(0xa501f60153f6a4a4), C64e(0xa1d74dd7ec4d7676), +C64e(0x14a361a37561b7b7), C64e(0x3449ce49face7d7d), +C64e(0xdf8d7b8da47b5252), C64e(0x9f423e42a13edddd), +C64e(0xcd937193bc715e5e), C64e(0xb1a297a226971313), +C64e(0xa204f50457f5a6a6), C64e(0x01b868b86968b9b9), +C64e(0x0000000000000000), C64e(0xb5742c74992cc1c1), +C64e(0xe0a060a080604040), C64e(0xc2211f21dd1fe3e3), +C64e(0x3a43c843f2c87979), C64e(0x9a2ced2c77edb6b6), +C64e(0x0dd9bed9b3bed4d4), C64e(0x47ca46ca01468d8d), +C64e(0x1770d970ced96767), C64e(0xafdd4bdde44b7272), +C64e(0xed79de7933de9494), C64e(0xff67d4672bd49898), +C64e(0x9323e8237be8b0b0), C64e(0x5bde4ade114a8585), +C64e(0x06bd6bbd6d6bbbbb), C64e(0xbb7e2a7e912ac5c5), +C64e(0x7b34e5349ee54f4f), C64e(0xd73a163ac116eded), +C64e(0xd254c55417c58686), C64e(0xf862d7622fd79a9a), +C64e(0x99ff55ffcc556666), C64e(0xb6a794a722941111), +C64e(0xc04acf4a0fcf8a8a), C64e(0xd9301030c910e9e9), +C64e(0x0e0a060a08060404), C64e(0x66988198e781fefe), +C64e(0xab0bf00b5bf0a0a0), C64e(0xb4cc44ccf0447878), +C64e(0xf0d5bad54aba2525), C64e(0x753ee33e96e34b4b), +C64e(0xac0ef30e5ff3a2a2), C64e(0x4419fe19bafe5d5d), +C64e(0xdb5bc05b1bc08080), C64e(0x80858a850a8a0505), +C64e(0xd3ecadec7ead3f3f), C64e(0xfedfbcdf42bc2121), +C64e(0xa8d848d8e0487070), C64e(0xfd0c040cf904f1f1), +C64e(0x197adf7ac6df6363), C64e(0x2f58c158eec17777), +C64e(0x309f759f4575afaf), C64e(0xe7a563a584634242), +C64e(0x7050305040302020), C64e(0xcb2e1a2ed11ae5e5), +C64e(0xef120e12e10efdfd), C64e(0x08b76db7656dbfbf), +C64e(0x55d44cd4194c8181), C64e(0x243c143c30141818), +C64e(0x795f355f4c352626), C64e(0xb2712f719d2fc3c3), +C64e(0x8638e13867e1bebe), C64e(0xc8fda2fd6aa23535), +C64e(0xc74fcc4f0bcc8888), C64e(0x654b394b5c392e2e), +C64e(0x6af957f93d579393), C64e(0x580df20daaf25555), +C64e(0x619d829de382fcfc), C64e(0xb3c947c9f4477a7a), +C64e(0x27efacef8bacc8c8), C64e(0x8832e7326fe7baba), +C64e(0x4f7d2b7d642b3232), C64e(0x42a495a4d795e6e6), +C64e(0x3bfba0fb9ba0c0c0), C64e(0xaab398b332981919), +C64e(0xf668d16827d19e9e), C64e(0x22817f815d7fa3a3), +C64e(0xeeaa66aa88664444), C64e(0xd6827e82a87e5454), +C64e(0xdde6abe676ab3b3b), C64e(0x959e839e16830b0b), +C64e(0xc945ca4503ca8c8c), C64e(0xbc7b297b9529c7c7), +C64e(0x056ed36ed6d36b6b), C64e(0x6c443c44503c2828), +C64e(0x2c8b798b5579a7a7), C64e(0x813de23d63e2bcbc), +C64e(0x31271d272c1d1616), C64e(0x379a769a4176adad), +C64e(0x964d3b4dad3bdbdb), C64e(0x9efa56fac8566464), +C64e(0xa6d24ed2e84e7474), C64e(0x36221e22281e1414), +C64e(0xe476db763fdb9292), C64e(0x121e0a1e180a0c0c), +C64e(0xfcb46cb4906c4848), C64e(0x8f37e4376be4b8b8), +C64e(0x78e75de7255d9f9f), C64e(0x0fb26eb2616ebdbd), +C64e(0x692aef2a86ef4343), C64e(0x35f1a6f193a6c4c4), +C64e(0xdae3a8e372a83939), C64e(0xc6f7a4f762a43131), +C64e(0x8a593759bd37d3d3), C64e(0x74868b86ff8bf2f2), +C64e(0x83563256b132d5d5), C64e(0x4ec543c50d438b8b), +C64e(0x85eb59ebdc596e6e), C64e(0x18c2b7c2afb7dada), +C64e(0x8e8f8c8f028c0101), C64e(0x1dac64ac7964b1b1), +C64e(0xf16dd26d23d29c9c), C64e(0x723be03b92e04949), +C64e(0x1fc7b4c7abb4d8d8), C64e(0xb915fa1543faacac), +C64e(0xfa090709fd07f3f3), C64e(0xa06f256f8525cfcf), +C64e(0x20eaafea8fafcaca), C64e(0x7d898e89f38ef4f4), +C64e(0x6720e9208ee94747), C64e(0x3828182820181010), +C64e(0x0b64d564ded56f6f), C64e(0x73838883fb88f0f0), +C64e(0xfbb16fb1946f4a4a), C64e(0xca967296b8725c5c), +C64e(0x546c246c70243838), C64e(0x5f08f108aef15757), +C64e(0x2152c752e6c77373), C64e(0x64f351f335519797), +C64e(0xae6523658d23cbcb), C64e(0x25847c84597ca1a1), +C64e(0x57bf9cbfcb9ce8e8), C64e(0x5d6321637c213e3e), +C64e(0xea7cdd7c37dd9696), C64e(0x1e7fdc7fc2dc6161), +C64e(0x9c9186911a860d0d), C64e(0x9b9485941e850f0f), +C64e(0x4bab90abdb90e0e0), C64e(0xbac642c6f8427c7c), +C64e(0x2657c457e2c47171), C64e(0x29e5aae583aacccc), +C64e(0xe373d8733bd89090), C64e(0x090f050f0c050606), +C64e(0xf4030103f501f7f7), C64e(0x2a36123638121c1c), +C64e(0x3cfea3fe9fa3c2c2), C64e(0x8be15fe1d45f6a6a), +C64e(0xbe10f91047f9aeae), C64e(0x026bd06bd2d06969), +C64e(0xbfa891a82e911717), C64e(0x71e858e829589999), +C64e(0x5369276974273a3a), C64e(0xf7d0b9d04eb92727), +C64e(0x91483848a938d9d9), C64e(0xde351335cd13ebeb), +C64e(0xe5ceb3ce56b32b2b), C64e(0x7755335544332222), +C64e(0x04d6bbd6bfbbd2d2), C64e(0x399070904970a9a9), +C64e(0x878089800e890707), C64e(0xc1f2a7f266a73333), +C64e(0xecc1b6c15ab62d2d), C64e(0x5a66226678223c3c), +C64e(0xb8ad92ad2a921515), C64e(0xa96020608920c9c9), +C64e(0x5cdb49db15498787), C64e(0xb01aff1a4fffaaaa), +C64e(0xd8887888a0785050), C64e(0x2b8e7a8e517aa5a5), +C64e(0x898a8f8a068f0303), C64e(0x4a13f813b2f85959), +C64e(0x929b809b12800909), C64e(0x2339173934171a1a), +C64e(0x1075da75cada6565), C64e(0x84533153b531d7d7), +C64e(0xd551c65113c68484), C64e(0x03d3b8d3bbb8d0d0), +C64e(0xdc5ec35e1fc38282), C64e(0xe2cbb0cb52b02929), +C64e(0xc3997799b4775a5a), C64e(0x2d3311333c111e1e), +C64e(0x3d46cb46f6cb7b7b), C64e(0xb71ffc1f4bfca8a8), +C64e(0x0c61d661dad66d6d), C64e(0x624e3a4e583a2c2c) +}; + +*/ + + + + + #define RSTT(d, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ - t[d] = T0[B64_0(a[b0])] \ + t[d] = T0_G[B64_0(a[b0])] \ + ^ R64(T0_G[B64_1(a[b1])], 8) \ + ^ R64(T0_G[B64_2(a[b2])], 16) \ + ^ R64(T0_G[B64_3(a[b3])], 24) \ + ^ T4_G[B64_4(a[b4])] \ + ^ R64(T4_G[B64_5(a[b5])], 8) \ + ^ R64(T4_G[B64_6(a[b6])], 16) \ + ^ R64(T4_G[B64_7(a[b7])], 24); \ + } while (0) +/* +#define RSTT(d, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ + t[d] = T0_G[B64_0(a[b0])] \ + ^ as_ulong(as_uchar8(T0_G[B64_1(a[b1])]).s70123456) \ + ^ as_ulong(as_uchar8(T0_G[B64_2(a[b2])]).s67012345) \ + ^ as_ulong(as_uchar8(T0_G[B64_3(a[b3])]).s56701234) \ + ^ T4_G[B64_4(a[b4])] \ + ^ as_ulong(as_uchar8(T4_G[B64_5(a[b5])]).s70123456) \ + ^ as_ulong(as_uchar8(T4_G[B64_6(a[b6])]).s67012345) \ + ^ as_ulong(as_uchar8(T4_G[B64_7(a[b7])]).s56701234); \ + } while (0) +*/ + + +/* +#define RSTT(d, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ + t[d] = T0[B64_0(a[b0])] \ ^ R64(T0[B64_1(a[b1])], 8) \ - ^ R64(T0[B64_2(a[b2])], 16) \ - ^ R64(T0[B64_3(a[b3])], 24) \ + ^ T2[B64_2(a[b2])] \ + ^ R64(T2[B64_3(a[b3])], 8) \ ^ T4[B64_4(a[b4])] \ - ^ R64(T4[B64_5(a[b5])], 8) \ - ^ R64(T4[B64_6(a[b6])], 16) \ - ^ R64(T4[B64_7(a[b7])], 24); \ - } while (0) + ^ R64(T4[B64_5(a[b5])], 8) \ + ^ T6[B64_6(a[b6])] \ + ^ R64(T6[B64_7(a[b7])], 8); \ + } while (0) + +#define RSTT(d, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ + t[d] = T0[B64_0(a[b0])] \ + ^ T1[B64_1(a[b1])] \ + ^ T2[B64_2(a[b2])] \ + ^ T3[B64_3(a[b3])] \ + ^ T4[B64_4(a[b4])] \ + ^ T5[B64_5(a[b5])] \ + ^ T6[B64_6(a[b6])] \ + ^ T7[B64_7(a[b7])]; \ + } while (0) +*/ #define ROUND_SMALL_P(a, r) do { \ a[0] ^= PC64(0x00, r); \ a[1] ^= PC64(0x10, r); \ @@ -357,7 +1183,7 @@ __constant static const sph_u64 T4[] = { a[7] = t[7]; \ } while (0) -#define ROUND_SMALL_Pf(a, r) do { \ +#define ROUND_SMALL_Pf(a,r) do { \ a[0] ^= PC64(0x00, r); \ a[1] ^= PC64(0x10, r); \ a[2] ^= PC64(0x20, r); \ diff --git a/kernel/groestlcoin-v1.cl b/kernel/groestlcoin-v1.cl new file mode 100644 index 000000000..c8382d581 --- /dev/null +++ b/kernel/groestlcoin-v1.cl @@ -0,0 +1,1854 @@ +/* + * ==========================(LICENSE BEGIN)============================ + * + * GroestlCoin kernel implementation: Copyright (c) 2014 pallas + * + * 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)============================= + * + * GroestlCoin kernel implementation: @author pallas + * Forum thread: http://bitcointalk.org/index.php?topic=779598 + * Donations to: BTC 1H7qC5uHuGX2d5s9Kuw3k7Wm7xMQzL16SN + */ + +#ifndef GROESTLCOIN_CL +#define GROESTLCOIN_CL + +#define DC64(x) ((ulong)(x ## UL)) +#define DEC64E(x) (*(const __global ulong *) (x)); +#define H15 (((ulong)(512 & 0xFF) << 56) | ((ulong)(512 & 0xFF00) << 40)) +#define M15 0x100000000000000 +#define ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n)))) // rotate + +#define C64e(x) ((DC64(x) >> 56) \ + | ((DC64(x) >> 40) & DC64(0x000000000000FF00)) \ + | ((DC64(x) >> 24) & DC64(0x0000000000FF0000)) \ + | ((DC64(x) >> 8) & DC64(0x00000000FF000000)) \ + | ((DC64(x) << 8) & DC64(0x000000FF00000000)) \ + | ((DC64(x) << 24) & DC64(0x0000FF0000000000)) \ + | ((DC64(x) << 40) & DC64(0x00FF000000000000)) \ + | ((DC64(x) << 56))) +#define B64_0(x) ((x) & 0xFF) +#define B64_1(x) (((x) >> 8) & 0xFF) +#define B64_2(x) (((x) >> 16) & 0xFF) +#define B64_3(x) (((x) >> 24) & 0xFF) +#define B64_4(x) (((x) >> 32) & 0xFF) +#define B64_5(x) (((x) >> 40) & 0xFF) +#define B64_6(x) (((x) >> 48) & 0xFF) +#define B64_7(x) ((x) >> 56) +#define PC64(j, r) ((ulong)((j) + (r))) +#define QC64(j, r) (((ulong)(r) << 56) ^ ~((ulong)(j) << 56)) + +__constant static const ulong T0[] = { + C64e(0xc632f4a5f497a5c6), C64e(0xf86f978497eb84f8), + C64e(0xee5eb099b0c799ee), C64e(0xf67a8c8d8cf78df6), + C64e(0xffe8170d17e50dff), C64e(0xd60adcbddcb7bdd6), + C64e(0xde16c8b1c8a7b1de), C64e(0x916dfc54fc395491), + C64e(0x6090f050f0c05060), C64e(0x0207050305040302), + C64e(0xce2ee0a9e087a9ce), C64e(0x56d1877d87ac7d56), + C64e(0xe7cc2b192bd519e7), C64e(0xb513a662a67162b5), + C64e(0x4d7c31e6319ae64d), C64e(0xec59b59ab5c39aec), + C64e(0x8f40cf45cf05458f), C64e(0x1fa3bc9dbc3e9d1f), + C64e(0x8949c040c0094089), C64e(0xfa68928792ef87fa), + C64e(0xefd03f153fc515ef), C64e(0xb29426eb267febb2), + C64e(0x8ece40c94007c98e), C64e(0xfbe61d0b1ded0bfb), + C64e(0x416e2fec2f82ec41), C64e(0xb31aa967a97d67b3), + C64e(0x5f431cfd1cbefd5f), C64e(0x456025ea258aea45), + C64e(0x23f9dabfda46bf23), C64e(0x535102f702a6f753), + C64e(0xe445a196a1d396e4), C64e(0x9b76ed5bed2d5b9b), + C64e(0x75285dc25deac275), C64e(0xe1c5241c24d91ce1), + C64e(0x3dd4e9aee97aae3d), C64e(0x4cf2be6abe986a4c), + C64e(0x6c82ee5aeed85a6c), C64e(0x7ebdc341c3fc417e), + C64e(0xf5f3060206f102f5), C64e(0x8352d14fd11d4f83), + C64e(0x688ce45ce4d05c68), C64e(0x515607f407a2f451), + C64e(0xd18d5c345cb934d1), C64e(0xf9e1180818e908f9), + C64e(0xe24cae93aedf93e2), C64e(0xab3e9573954d73ab), + C64e(0x6297f553f5c45362), C64e(0x2a6b413f41543f2a), + C64e(0x081c140c14100c08), C64e(0x9563f652f6315295), + C64e(0x46e9af65af8c6546), C64e(0x9d7fe25ee2215e9d), + C64e(0x3048782878602830), C64e(0x37cff8a1f86ea137), + C64e(0x0a1b110f11140f0a), C64e(0x2febc4b5c45eb52f), + C64e(0x0e151b091b1c090e), C64e(0x247e5a365a483624), + C64e(0x1badb69bb6369b1b), C64e(0xdf98473d47a53ddf), + C64e(0xcda76a266a8126cd), C64e(0x4ef5bb69bb9c694e), + C64e(0x7f334ccd4cfecd7f), C64e(0xea50ba9fbacf9fea), + C64e(0x123f2d1b2d241b12), C64e(0x1da4b99eb93a9e1d), + C64e(0x58c49c749cb07458), C64e(0x3446722e72682e34), + C64e(0x3641772d776c2d36), C64e(0xdc11cdb2cda3b2dc), + C64e(0xb49d29ee2973eeb4), C64e(0x5b4d16fb16b6fb5b), + C64e(0xa4a501f60153f6a4), C64e(0x76a1d74dd7ec4d76), + C64e(0xb714a361a37561b7), C64e(0x7d3449ce49face7d), + C64e(0x52df8d7b8da47b52), C64e(0xdd9f423e42a13edd), + C64e(0x5ecd937193bc715e), C64e(0x13b1a297a2269713), + C64e(0xa6a204f50457f5a6), C64e(0xb901b868b86968b9), + C64e(0x0000000000000000), C64e(0xc1b5742c74992cc1), + C64e(0x40e0a060a0806040), C64e(0xe3c2211f21dd1fe3), + C64e(0x793a43c843f2c879), C64e(0xb69a2ced2c77edb6), + C64e(0xd40dd9bed9b3bed4), C64e(0x8d47ca46ca01468d), + C64e(0x671770d970ced967), C64e(0x72afdd4bdde44b72), + C64e(0x94ed79de7933de94), C64e(0x98ff67d4672bd498), + C64e(0xb09323e8237be8b0), C64e(0x855bde4ade114a85), + C64e(0xbb06bd6bbd6d6bbb), C64e(0xc5bb7e2a7e912ac5), + C64e(0x4f7b34e5349ee54f), C64e(0xedd73a163ac116ed), + C64e(0x86d254c55417c586), C64e(0x9af862d7622fd79a), + C64e(0x6699ff55ffcc5566), C64e(0x11b6a794a7229411), + C64e(0x8ac04acf4a0fcf8a), C64e(0xe9d9301030c910e9), + C64e(0x040e0a060a080604), C64e(0xfe66988198e781fe), + C64e(0xa0ab0bf00b5bf0a0), C64e(0x78b4cc44ccf04478), + C64e(0x25f0d5bad54aba25), C64e(0x4b753ee33e96e34b), + C64e(0xa2ac0ef30e5ff3a2), C64e(0x5d4419fe19bafe5d), + C64e(0x80db5bc05b1bc080), C64e(0x0580858a850a8a05), + C64e(0x3fd3ecadec7ead3f), C64e(0x21fedfbcdf42bc21), + C64e(0x70a8d848d8e04870), C64e(0xf1fd0c040cf904f1), + C64e(0x63197adf7ac6df63), C64e(0x772f58c158eec177), + C64e(0xaf309f759f4575af), C64e(0x42e7a563a5846342), + C64e(0x2070503050403020), C64e(0xe5cb2e1a2ed11ae5), + C64e(0xfdef120e12e10efd), C64e(0xbf08b76db7656dbf), + C64e(0x8155d44cd4194c81), C64e(0x18243c143c301418), + C64e(0x26795f355f4c3526), C64e(0xc3b2712f719d2fc3), + C64e(0xbe8638e13867e1be), C64e(0x35c8fda2fd6aa235), + C64e(0x88c74fcc4f0bcc88), C64e(0x2e654b394b5c392e), + C64e(0x936af957f93d5793), C64e(0x55580df20daaf255), + C64e(0xfc619d829de382fc), C64e(0x7ab3c947c9f4477a), + C64e(0xc827efacef8bacc8), C64e(0xba8832e7326fe7ba), + C64e(0x324f7d2b7d642b32), C64e(0xe642a495a4d795e6), + C64e(0xc03bfba0fb9ba0c0), C64e(0x19aab398b3329819), + C64e(0x9ef668d16827d19e), C64e(0xa322817f815d7fa3), + C64e(0x44eeaa66aa886644), C64e(0x54d6827e82a87e54), + C64e(0x3bdde6abe676ab3b), C64e(0x0b959e839e16830b), + C64e(0x8cc945ca4503ca8c), C64e(0xc7bc7b297b9529c7), + C64e(0x6b056ed36ed6d36b), C64e(0x286c443c44503c28), + C64e(0xa72c8b798b5579a7), C64e(0xbc813de23d63e2bc), + C64e(0x1631271d272c1d16), C64e(0xad379a769a4176ad), + C64e(0xdb964d3b4dad3bdb), C64e(0x649efa56fac85664), + C64e(0x74a6d24ed2e84e74), C64e(0x1436221e22281e14), + C64e(0x92e476db763fdb92), C64e(0x0c121e0a1e180a0c), + C64e(0x48fcb46cb4906c48), C64e(0xb88f37e4376be4b8), + C64e(0x9f78e75de7255d9f), C64e(0xbd0fb26eb2616ebd), + C64e(0x43692aef2a86ef43), C64e(0xc435f1a6f193a6c4), + C64e(0x39dae3a8e372a839), C64e(0x31c6f7a4f762a431), + C64e(0xd38a593759bd37d3), C64e(0xf274868b86ff8bf2), + C64e(0xd583563256b132d5), C64e(0x8b4ec543c50d438b), + C64e(0x6e85eb59ebdc596e), C64e(0xda18c2b7c2afb7da), + C64e(0x018e8f8c8f028c01), C64e(0xb11dac64ac7964b1), + C64e(0x9cf16dd26d23d29c), C64e(0x49723be03b92e049), + C64e(0xd81fc7b4c7abb4d8), C64e(0xacb915fa1543faac), + C64e(0xf3fa090709fd07f3), C64e(0xcfa06f256f8525cf), + C64e(0xca20eaafea8fafca), C64e(0xf47d898e89f38ef4), + C64e(0x476720e9208ee947), C64e(0x1038281828201810), + C64e(0x6f0b64d564ded56f), C64e(0xf073838883fb88f0), + C64e(0x4afbb16fb1946f4a), C64e(0x5cca967296b8725c), + C64e(0x38546c246c702438), C64e(0x575f08f108aef157), + C64e(0x732152c752e6c773), C64e(0x9764f351f3355197), + C64e(0xcbae6523658d23cb), C64e(0xa125847c84597ca1), + C64e(0xe857bf9cbfcb9ce8), C64e(0x3e5d6321637c213e), + C64e(0x96ea7cdd7c37dd96), C64e(0x611e7fdc7fc2dc61), + C64e(0x0d9c9186911a860d), C64e(0x0f9b9485941e850f), + C64e(0xe04bab90abdb90e0), C64e(0x7cbac642c6f8427c), + C64e(0x712657c457e2c471), C64e(0xcc29e5aae583aacc), + C64e(0x90e373d8733bd890), C64e(0x06090f050f0c0506), + C64e(0xf7f4030103f501f7), C64e(0x1c2a36123638121c), + C64e(0xc23cfea3fe9fa3c2), C64e(0x6a8be15fe1d45f6a), + C64e(0xaebe10f91047f9ae), C64e(0x69026bd06bd2d069), + C64e(0x17bfa891a82e9117), C64e(0x9971e858e8295899), + C64e(0x3a5369276974273a), C64e(0x27f7d0b9d04eb927), + C64e(0xd991483848a938d9), C64e(0xebde351335cd13eb), + C64e(0x2be5ceb3ce56b32b), C64e(0x2277553355443322), + C64e(0xd204d6bbd6bfbbd2), C64e(0xa9399070904970a9), + C64e(0x07878089800e8907), C64e(0x33c1f2a7f266a733), + C64e(0x2decc1b6c15ab62d), C64e(0x3c5a66226678223c), + C64e(0x15b8ad92ad2a9215), C64e(0xc9a96020608920c9), + C64e(0x875cdb49db154987), C64e(0xaab01aff1a4fffaa), + C64e(0x50d8887888a07850), C64e(0xa52b8e7a8e517aa5), + C64e(0x03898a8f8a068f03), C64e(0x594a13f813b2f859), + C64e(0x09929b809b128009), C64e(0x1a2339173934171a), + C64e(0x651075da75cada65), C64e(0xd784533153b531d7), + C64e(0x84d551c65113c684), C64e(0xd003d3b8d3bbb8d0), + C64e(0x82dc5ec35e1fc382), C64e(0x29e2cbb0cb52b029), + C64e(0x5ac3997799b4775a), C64e(0x1e2d3311333c111e), + C64e(0x7b3d46cb46f6cb7b), C64e(0xa8b71ffc1f4bfca8), + C64e(0x6d0c61d661dad66d), C64e(0x2c624e3a4e583a2c) +}; + +__constant static const ulong T1[] = { + C64e(0xc6c632f4a5f497a5), C64e(0xf8f86f978497eb84), + C64e(0xeeee5eb099b0c799), C64e(0xf6f67a8c8d8cf78d), + C64e(0xffffe8170d17e50d), C64e(0xd6d60adcbddcb7bd), + C64e(0xdede16c8b1c8a7b1), C64e(0x91916dfc54fc3954), + C64e(0x606090f050f0c050), C64e(0x0202070503050403), + C64e(0xcece2ee0a9e087a9), C64e(0x5656d1877d87ac7d), + C64e(0xe7e7cc2b192bd519), C64e(0xb5b513a662a67162), + C64e(0x4d4d7c31e6319ae6), C64e(0xecec59b59ab5c39a), + C64e(0x8f8f40cf45cf0545), C64e(0x1f1fa3bc9dbc3e9d), + C64e(0x898949c040c00940), C64e(0xfafa68928792ef87), + C64e(0xefefd03f153fc515), C64e(0xb2b29426eb267feb), + C64e(0x8e8ece40c94007c9), C64e(0xfbfbe61d0b1ded0b), + C64e(0x41416e2fec2f82ec), C64e(0xb3b31aa967a97d67), + C64e(0x5f5f431cfd1cbefd), C64e(0x45456025ea258aea), + C64e(0x2323f9dabfda46bf), C64e(0x53535102f702a6f7), + C64e(0xe4e445a196a1d396), C64e(0x9b9b76ed5bed2d5b), + C64e(0x7575285dc25deac2), C64e(0xe1e1c5241c24d91c), + C64e(0x3d3dd4e9aee97aae), C64e(0x4c4cf2be6abe986a), + C64e(0x6c6c82ee5aeed85a), C64e(0x7e7ebdc341c3fc41), + C64e(0xf5f5f3060206f102), C64e(0x838352d14fd11d4f), + C64e(0x68688ce45ce4d05c), C64e(0x51515607f407a2f4), + C64e(0xd1d18d5c345cb934), C64e(0xf9f9e1180818e908), + C64e(0xe2e24cae93aedf93), C64e(0xabab3e9573954d73), + C64e(0x626297f553f5c453), C64e(0x2a2a6b413f41543f), + C64e(0x08081c140c14100c), C64e(0x959563f652f63152), + C64e(0x4646e9af65af8c65), C64e(0x9d9d7fe25ee2215e), + C64e(0x3030487828786028), C64e(0x3737cff8a1f86ea1), + C64e(0x0a0a1b110f11140f), C64e(0x2f2febc4b5c45eb5), + C64e(0x0e0e151b091b1c09), C64e(0x24247e5a365a4836), + C64e(0x1b1badb69bb6369b), C64e(0xdfdf98473d47a53d), + C64e(0xcdcda76a266a8126), C64e(0x4e4ef5bb69bb9c69), + C64e(0x7f7f334ccd4cfecd), C64e(0xeaea50ba9fbacf9f), + C64e(0x12123f2d1b2d241b), C64e(0x1d1da4b99eb93a9e), + C64e(0x5858c49c749cb074), C64e(0x343446722e72682e), + C64e(0x363641772d776c2d), C64e(0xdcdc11cdb2cda3b2), + C64e(0xb4b49d29ee2973ee), C64e(0x5b5b4d16fb16b6fb), + C64e(0xa4a4a501f60153f6), C64e(0x7676a1d74dd7ec4d), + C64e(0xb7b714a361a37561), C64e(0x7d7d3449ce49face), + C64e(0x5252df8d7b8da47b), C64e(0xdddd9f423e42a13e), + C64e(0x5e5ecd937193bc71), C64e(0x1313b1a297a22697), + C64e(0xa6a6a204f50457f5), C64e(0xb9b901b868b86968), + C64e(0x0000000000000000), C64e(0xc1c1b5742c74992c), + C64e(0x4040e0a060a08060), C64e(0xe3e3c2211f21dd1f), + C64e(0x79793a43c843f2c8), C64e(0xb6b69a2ced2c77ed), + C64e(0xd4d40dd9bed9b3be), C64e(0x8d8d47ca46ca0146), + C64e(0x67671770d970ced9), C64e(0x7272afdd4bdde44b), + C64e(0x9494ed79de7933de), C64e(0x9898ff67d4672bd4), + C64e(0xb0b09323e8237be8), C64e(0x85855bde4ade114a), + C64e(0xbbbb06bd6bbd6d6b), C64e(0xc5c5bb7e2a7e912a), + C64e(0x4f4f7b34e5349ee5), C64e(0xededd73a163ac116), + C64e(0x8686d254c55417c5), C64e(0x9a9af862d7622fd7), + C64e(0x666699ff55ffcc55), C64e(0x1111b6a794a72294), + C64e(0x8a8ac04acf4a0fcf), C64e(0xe9e9d9301030c910), + C64e(0x04040e0a060a0806), C64e(0xfefe66988198e781), + C64e(0xa0a0ab0bf00b5bf0), C64e(0x7878b4cc44ccf044), + C64e(0x2525f0d5bad54aba), C64e(0x4b4b753ee33e96e3), + C64e(0xa2a2ac0ef30e5ff3), C64e(0x5d5d4419fe19bafe), + C64e(0x8080db5bc05b1bc0), C64e(0x050580858a850a8a), + C64e(0x3f3fd3ecadec7ead), C64e(0x2121fedfbcdf42bc), + C64e(0x7070a8d848d8e048), C64e(0xf1f1fd0c040cf904), + C64e(0x6363197adf7ac6df), C64e(0x77772f58c158eec1), + C64e(0xafaf309f759f4575), C64e(0x4242e7a563a58463), + C64e(0x2020705030504030), C64e(0xe5e5cb2e1a2ed11a), + C64e(0xfdfdef120e12e10e), C64e(0xbfbf08b76db7656d), + C64e(0x818155d44cd4194c), C64e(0x1818243c143c3014), + C64e(0x2626795f355f4c35), C64e(0xc3c3b2712f719d2f), + C64e(0xbebe8638e13867e1), C64e(0x3535c8fda2fd6aa2), + C64e(0x8888c74fcc4f0bcc), C64e(0x2e2e654b394b5c39), + C64e(0x93936af957f93d57), C64e(0x5555580df20daaf2), + C64e(0xfcfc619d829de382), C64e(0x7a7ab3c947c9f447), + C64e(0xc8c827efacef8bac), C64e(0xbaba8832e7326fe7), + C64e(0x32324f7d2b7d642b), C64e(0xe6e642a495a4d795), + C64e(0xc0c03bfba0fb9ba0), C64e(0x1919aab398b33298), + C64e(0x9e9ef668d16827d1), C64e(0xa3a322817f815d7f), + C64e(0x4444eeaa66aa8866), C64e(0x5454d6827e82a87e), + C64e(0x3b3bdde6abe676ab), C64e(0x0b0b959e839e1683), + C64e(0x8c8cc945ca4503ca), C64e(0xc7c7bc7b297b9529), + C64e(0x6b6b056ed36ed6d3), C64e(0x28286c443c44503c), + C64e(0xa7a72c8b798b5579), C64e(0xbcbc813de23d63e2), + C64e(0x161631271d272c1d), C64e(0xadad379a769a4176), + C64e(0xdbdb964d3b4dad3b), C64e(0x64649efa56fac856), + C64e(0x7474a6d24ed2e84e), C64e(0x141436221e22281e), + C64e(0x9292e476db763fdb), C64e(0x0c0c121e0a1e180a), + C64e(0x4848fcb46cb4906c), C64e(0xb8b88f37e4376be4), + C64e(0x9f9f78e75de7255d), C64e(0xbdbd0fb26eb2616e), + C64e(0x4343692aef2a86ef), C64e(0xc4c435f1a6f193a6), + C64e(0x3939dae3a8e372a8), C64e(0x3131c6f7a4f762a4), + C64e(0xd3d38a593759bd37), C64e(0xf2f274868b86ff8b), + C64e(0xd5d583563256b132), C64e(0x8b8b4ec543c50d43), + C64e(0x6e6e85eb59ebdc59), C64e(0xdada18c2b7c2afb7), + C64e(0x01018e8f8c8f028c), C64e(0xb1b11dac64ac7964), + C64e(0x9c9cf16dd26d23d2), C64e(0x4949723be03b92e0), + C64e(0xd8d81fc7b4c7abb4), C64e(0xacacb915fa1543fa), + C64e(0xf3f3fa090709fd07), C64e(0xcfcfa06f256f8525), + C64e(0xcaca20eaafea8faf), C64e(0xf4f47d898e89f38e), + C64e(0x47476720e9208ee9), C64e(0x1010382818282018), + C64e(0x6f6f0b64d564ded5), C64e(0xf0f073838883fb88), + C64e(0x4a4afbb16fb1946f), C64e(0x5c5cca967296b872), + C64e(0x3838546c246c7024), C64e(0x57575f08f108aef1), + C64e(0x73732152c752e6c7), C64e(0x979764f351f33551), + C64e(0xcbcbae6523658d23), C64e(0xa1a125847c84597c), + C64e(0xe8e857bf9cbfcb9c), C64e(0x3e3e5d6321637c21), + C64e(0x9696ea7cdd7c37dd), C64e(0x61611e7fdc7fc2dc), + C64e(0x0d0d9c9186911a86), C64e(0x0f0f9b9485941e85), + C64e(0xe0e04bab90abdb90), C64e(0x7c7cbac642c6f842), + C64e(0x71712657c457e2c4), C64e(0xcccc29e5aae583aa), + C64e(0x9090e373d8733bd8), C64e(0x0606090f050f0c05), + C64e(0xf7f7f4030103f501), C64e(0x1c1c2a3612363812), + C64e(0xc2c23cfea3fe9fa3), C64e(0x6a6a8be15fe1d45f), + C64e(0xaeaebe10f91047f9), C64e(0x6969026bd06bd2d0), + C64e(0x1717bfa891a82e91), C64e(0x999971e858e82958), + C64e(0x3a3a536927697427), C64e(0x2727f7d0b9d04eb9), + C64e(0xd9d991483848a938), C64e(0xebebde351335cd13), + C64e(0x2b2be5ceb3ce56b3), C64e(0x2222775533554433), + C64e(0xd2d204d6bbd6bfbb), C64e(0xa9a9399070904970), + C64e(0x0707878089800e89), C64e(0x3333c1f2a7f266a7), + C64e(0x2d2decc1b6c15ab6), C64e(0x3c3c5a6622667822), + C64e(0x1515b8ad92ad2a92), C64e(0xc9c9a96020608920), + C64e(0x87875cdb49db1549), C64e(0xaaaab01aff1a4fff), + C64e(0x5050d8887888a078), C64e(0xa5a52b8e7a8e517a), + C64e(0x0303898a8f8a068f), C64e(0x59594a13f813b2f8), + C64e(0x0909929b809b1280), C64e(0x1a1a233917393417), + C64e(0x65651075da75cada), C64e(0xd7d784533153b531), + C64e(0x8484d551c65113c6), C64e(0xd0d003d3b8d3bbb8), + C64e(0x8282dc5ec35e1fc3), C64e(0x2929e2cbb0cb52b0), + C64e(0x5a5ac3997799b477), C64e(0x1e1e2d3311333c11), + C64e(0x7b7b3d46cb46f6cb), C64e(0xa8a8b71ffc1f4bfc), + C64e(0x6d6d0c61d661dad6), C64e(0x2c2c624e3a4e583a) +}; +/* +__constant static const ulong T2_G[] = { + C64e(0xa5c6c632f4a5f497), C64e(0x84f8f86f978497eb), + C64e(0x99eeee5eb099b0c7), C64e(0x8df6f67a8c8d8cf7), + C64e(0x0dffffe8170d17e5), C64e(0xbdd6d60adcbddcb7), + C64e(0xb1dede16c8b1c8a7), C64e(0x5491916dfc54fc39), + C64e(0x50606090f050f0c0), C64e(0x0302020705030504), + C64e(0xa9cece2ee0a9e087), C64e(0x7d5656d1877d87ac), + C64e(0x19e7e7cc2b192bd5), C64e(0x62b5b513a662a671), + C64e(0xe64d4d7c31e6319a), C64e(0x9aecec59b59ab5c3), + C64e(0x458f8f40cf45cf05), C64e(0x9d1f1fa3bc9dbc3e), + C64e(0x40898949c040c009), C64e(0x87fafa68928792ef), + C64e(0x15efefd03f153fc5), C64e(0xebb2b29426eb267f), + C64e(0xc98e8ece40c94007), C64e(0x0bfbfbe61d0b1ded), + C64e(0xec41416e2fec2f82), C64e(0x67b3b31aa967a97d), + C64e(0xfd5f5f431cfd1cbe), C64e(0xea45456025ea258a), + C64e(0xbf2323f9dabfda46), C64e(0xf753535102f702a6), + C64e(0x96e4e445a196a1d3), C64e(0x5b9b9b76ed5bed2d), + C64e(0xc27575285dc25dea), C64e(0x1ce1e1c5241c24d9), + C64e(0xae3d3dd4e9aee97a), C64e(0x6a4c4cf2be6abe98), + C64e(0x5a6c6c82ee5aeed8), C64e(0x417e7ebdc341c3fc), + C64e(0x02f5f5f3060206f1), C64e(0x4f838352d14fd11d), + C64e(0x5c68688ce45ce4d0), C64e(0xf451515607f407a2), + C64e(0x34d1d18d5c345cb9), C64e(0x08f9f9e1180818e9), + C64e(0x93e2e24cae93aedf), C64e(0x73abab3e9573954d), + C64e(0x53626297f553f5c4), C64e(0x3f2a2a6b413f4154), + C64e(0x0c08081c140c1410), C64e(0x52959563f652f631), + C64e(0x654646e9af65af8c), C64e(0x5e9d9d7fe25ee221), + C64e(0x2830304878287860), C64e(0xa13737cff8a1f86e), + C64e(0x0f0a0a1b110f1114), C64e(0xb52f2febc4b5c45e), + C64e(0x090e0e151b091b1c), C64e(0x3624247e5a365a48), + C64e(0x9b1b1badb69bb636), C64e(0x3ddfdf98473d47a5), + C64e(0x26cdcda76a266a81), C64e(0x694e4ef5bb69bb9c), + C64e(0xcd7f7f334ccd4cfe), C64e(0x9feaea50ba9fbacf), + C64e(0x1b12123f2d1b2d24), C64e(0x9e1d1da4b99eb93a), + C64e(0x745858c49c749cb0), C64e(0x2e343446722e7268), + C64e(0x2d363641772d776c), C64e(0xb2dcdc11cdb2cda3), + C64e(0xeeb4b49d29ee2973), C64e(0xfb5b5b4d16fb16b6), + C64e(0xf6a4a4a501f60153), C64e(0x4d7676a1d74dd7ec), + C64e(0x61b7b714a361a375), C64e(0xce7d7d3449ce49fa), + C64e(0x7b5252df8d7b8da4), C64e(0x3edddd9f423e42a1), + C64e(0x715e5ecd937193bc), C64e(0x971313b1a297a226), + C64e(0xf5a6a6a204f50457), C64e(0x68b9b901b868b869), + C64e(0x0000000000000000), C64e(0x2cc1c1b5742c7499), + C64e(0x604040e0a060a080), C64e(0x1fe3e3c2211f21dd), + C64e(0xc879793a43c843f2), C64e(0xedb6b69a2ced2c77), + C64e(0xbed4d40dd9bed9b3), C64e(0x468d8d47ca46ca01), + C64e(0xd967671770d970ce), C64e(0x4b7272afdd4bdde4), + C64e(0xde9494ed79de7933), C64e(0xd49898ff67d4672b), + C64e(0xe8b0b09323e8237b), C64e(0x4a85855bde4ade11), + C64e(0x6bbbbb06bd6bbd6d), C64e(0x2ac5c5bb7e2a7e91), + C64e(0xe54f4f7b34e5349e), C64e(0x16ededd73a163ac1), + C64e(0xc58686d254c55417), C64e(0xd79a9af862d7622f), + C64e(0x55666699ff55ffcc), C64e(0x941111b6a794a722), + C64e(0xcf8a8ac04acf4a0f), C64e(0x10e9e9d9301030c9), + C64e(0x0604040e0a060a08), C64e(0x81fefe66988198e7), + C64e(0xf0a0a0ab0bf00b5b), C64e(0x447878b4cc44ccf0), + C64e(0xba2525f0d5bad54a), C64e(0xe34b4b753ee33e96), + C64e(0xf3a2a2ac0ef30e5f), C64e(0xfe5d5d4419fe19ba), + C64e(0xc08080db5bc05b1b), C64e(0x8a050580858a850a), + C64e(0xad3f3fd3ecadec7e), C64e(0xbc2121fedfbcdf42), + C64e(0x487070a8d848d8e0), C64e(0x04f1f1fd0c040cf9), + C64e(0xdf6363197adf7ac6), C64e(0xc177772f58c158ee), + C64e(0x75afaf309f759f45), C64e(0x634242e7a563a584), + C64e(0x3020207050305040), C64e(0x1ae5e5cb2e1a2ed1), + C64e(0x0efdfdef120e12e1), C64e(0x6dbfbf08b76db765), + C64e(0x4c818155d44cd419), C64e(0x141818243c143c30), + C64e(0x352626795f355f4c), C64e(0x2fc3c3b2712f719d), + C64e(0xe1bebe8638e13867), C64e(0xa23535c8fda2fd6a), + C64e(0xcc8888c74fcc4f0b), C64e(0x392e2e654b394b5c), + C64e(0x5793936af957f93d), C64e(0xf25555580df20daa), + C64e(0x82fcfc619d829de3), C64e(0x477a7ab3c947c9f4), + C64e(0xacc8c827efacef8b), C64e(0xe7baba8832e7326f), + C64e(0x2b32324f7d2b7d64), C64e(0x95e6e642a495a4d7), + C64e(0xa0c0c03bfba0fb9b), C64e(0x981919aab398b332), + C64e(0xd19e9ef668d16827), C64e(0x7fa3a322817f815d), + C64e(0x664444eeaa66aa88), C64e(0x7e5454d6827e82a8), + C64e(0xab3b3bdde6abe676), C64e(0x830b0b959e839e16), + C64e(0xca8c8cc945ca4503), C64e(0x29c7c7bc7b297b95), + C64e(0xd36b6b056ed36ed6), C64e(0x3c28286c443c4450), + C64e(0x79a7a72c8b798b55), C64e(0xe2bcbc813de23d63), + C64e(0x1d161631271d272c), C64e(0x76adad379a769a41), + C64e(0x3bdbdb964d3b4dad), C64e(0x5664649efa56fac8), + C64e(0x4e7474a6d24ed2e8), C64e(0x1e141436221e2228), + C64e(0xdb9292e476db763f), C64e(0x0a0c0c121e0a1e18), + C64e(0x6c4848fcb46cb490), C64e(0xe4b8b88f37e4376b), + C64e(0x5d9f9f78e75de725), C64e(0x6ebdbd0fb26eb261), + C64e(0xef4343692aef2a86), C64e(0xa6c4c435f1a6f193), + C64e(0xa83939dae3a8e372), C64e(0xa43131c6f7a4f762), + C64e(0x37d3d38a593759bd), C64e(0x8bf2f274868b86ff), + C64e(0x32d5d583563256b1), C64e(0x438b8b4ec543c50d), + C64e(0x596e6e85eb59ebdc), C64e(0xb7dada18c2b7c2af), + C64e(0x8c01018e8f8c8f02), C64e(0x64b1b11dac64ac79), + C64e(0xd29c9cf16dd26d23), C64e(0xe04949723be03b92), + C64e(0xb4d8d81fc7b4c7ab), C64e(0xfaacacb915fa1543), + C64e(0x07f3f3fa090709fd), C64e(0x25cfcfa06f256f85), + C64e(0xafcaca20eaafea8f), C64e(0x8ef4f47d898e89f3), + C64e(0xe947476720e9208e), C64e(0x1810103828182820), + C64e(0xd56f6f0b64d564de), C64e(0x88f0f073838883fb), + C64e(0x6f4a4afbb16fb194), C64e(0x725c5cca967296b8), + C64e(0x243838546c246c70), C64e(0xf157575f08f108ae), + C64e(0xc773732152c752e6), C64e(0x51979764f351f335), + C64e(0x23cbcbae6523658d), C64e(0x7ca1a125847c8459), + C64e(0x9ce8e857bf9cbfcb), C64e(0x213e3e5d6321637c), + C64e(0xdd9696ea7cdd7c37), C64e(0xdc61611e7fdc7fc2), + C64e(0x860d0d9c9186911a), C64e(0x850f0f9b9485941e), + C64e(0x90e0e04bab90abdb), C64e(0x427c7cbac642c6f8), + C64e(0xc471712657c457e2), C64e(0xaacccc29e5aae583), + C64e(0xd89090e373d8733b), C64e(0x050606090f050f0c), + C64e(0x01f7f7f4030103f5), C64e(0x121c1c2a36123638), + C64e(0xa3c2c23cfea3fe9f), C64e(0x5f6a6a8be15fe1d4), + C64e(0xf9aeaebe10f91047), C64e(0xd06969026bd06bd2), + C64e(0x911717bfa891a82e), C64e(0x58999971e858e829), + C64e(0x273a3a5369276974), C64e(0xb92727f7d0b9d04e), + C64e(0x38d9d991483848a9), C64e(0x13ebebde351335cd), + C64e(0xb32b2be5ceb3ce56), C64e(0x3322227755335544), + C64e(0xbbd2d204d6bbd6bf), C64e(0x70a9a93990709049), + C64e(0x890707878089800e), C64e(0xa73333c1f2a7f266), + C64e(0xb62d2decc1b6c15a), C64e(0x223c3c5a66226678), + C64e(0x921515b8ad92ad2a), C64e(0x20c9c9a960206089), + C64e(0x4987875cdb49db15), C64e(0xffaaaab01aff1a4f), + C64e(0x785050d8887888a0), C64e(0x7aa5a52b8e7a8e51), + C64e(0x8f0303898a8f8a06), C64e(0xf859594a13f813b2), + C64e(0x800909929b809b12), C64e(0x171a1a2339173934), + C64e(0xda65651075da75ca), C64e(0x31d7d784533153b5), + C64e(0xc68484d551c65113), C64e(0xb8d0d003d3b8d3bb), + C64e(0xc38282dc5ec35e1f), C64e(0xb02929e2cbb0cb52), + C64e(0x775a5ac3997799b4), C64e(0x111e1e2d3311333c), + C64e(0xcb7b7b3d46cb46f6), C64e(0xfca8a8b71ffc1f4b), + C64e(0xd66d6d0c61d661da), C64e(0x3a2c2c624e3a4e58) +}; + +__constant static const ulong T3_G[] = { + C64e(0x97a5c6c632f4a5f4), C64e(0xeb84f8f86f978497), + C64e(0xc799eeee5eb099b0), C64e(0xf78df6f67a8c8d8c), + C64e(0xe50dffffe8170d17), C64e(0xb7bdd6d60adcbddc), + C64e(0xa7b1dede16c8b1c8), C64e(0x395491916dfc54fc), + C64e(0xc050606090f050f0), C64e(0x0403020207050305), + C64e(0x87a9cece2ee0a9e0), C64e(0xac7d5656d1877d87), + C64e(0xd519e7e7cc2b192b), C64e(0x7162b5b513a662a6), + C64e(0x9ae64d4d7c31e631), C64e(0xc39aecec59b59ab5), + C64e(0x05458f8f40cf45cf), C64e(0x3e9d1f1fa3bc9dbc), + C64e(0x0940898949c040c0), C64e(0xef87fafa68928792), + C64e(0xc515efefd03f153f), C64e(0x7febb2b29426eb26), + C64e(0x07c98e8ece40c940), C64e(0xed0bfbfbe61d0b1d), + C64e(0x82ec41416e2fec2f), C64e(0x7d67b3b31aa967a9), + C64e(0xbefd5f5f431cfd1c), C64e(0x8aea45456025ea25), + C64e(0x46bf2323f9dabfda), C64e(0xa6f753535102f702), + C64e(0xd396e4e445a196a1), C64e(0x2d5b9b9b76ed5bed), + C64e(0xeac27575285dc25d), C64e(0xd91ce1e1c5241c24), + C64e(0x7aae3d3dd4e9aee9), C64e(0x986a4c4cf2be6abe), + C64e(0xd85a6c6c82ee5aee), C64e(0xfc417e7ebdc341c3), + C64e(0xf102f5f5f3060206), C64e(0x1d4f838352d14fd1), + C64e(0xd05c68688ce45ce4), C64e(0xa2f451515607f407), + C64e(0xb934d1d18d5c345c), C64e(0xe908f9f9e1180818), + C64e(0xdf93e2e24cae93ae), C64e(0x4d73abab3e957395), + C64e(0xc453626297f553f5), C64e(0x543f2a2a6b413f41), + C64e(0x100c08081c140c14), C64e(0x3152959563f652f6), + C64e(0x8c654646e9af65af), C64e(0x215e9d9d7fe25ee2), + C64e(0x6028303048782878), C64e(0x6ea13737cff8a1f8), + C64e(0x140f0a0a1b110f11), C64e(0x5eb52f2febc4b5c4), + C64e(0x1c090e0e151b091b), C64e(0x483624247e5a365a), + C64e(0x369b1b1badb69bb6), C64e(0xa53ddfdf98473d47), + C64e(0x8126cdcda76a266a), C64e(0x9c694e4ef5bb69bb), + C64e(0xfecd7f7f334ccd4c), C64e(0xcf9feaea50ba9fba), + C64e(0x241b12123f2d1b2d), C64e(0x3a9e1d1da4b99eb9), + C64e(0xb0745858c49c749c), C64e(0x682e343446722e72), + C64e(0x6c2d363641772d77), C64e(0xa3b2dcdc11cdb2cd), + C64e(0x73eeb4b49d29ee29), C64e(0xb6fb5b5b4d16fb16), + C64e(0x53f6a4a4a501f601), C64e(0xec4d7676a1d74dd7), + C64e(0x7561b7b714a361a3), C64e(0xface7d7d3449ce49), + C64e(0xa47b5252df8d7b8d), C64e(0xa13edddd9f423e42), + C64e(0xbc715e5ecd937193), C64e(0x26971313b1a297a2), + C64e(0x57f5a6a6a204f504), C64e(0x6968b9b901b868b8), + C64e(0x0000000000000000), C64e(0x992cc1c1b5742c74), + C64e(0x80604040e0a060a0), C64e(0xdd1fe3e3c2211f21), + C64e(0xf2c879793a43c843), C64e(0x77edb6b69a2ced2c), + C64e(0xb3bed4d40dd9bed9), C64e(0x01468d8d47ca46ca), + C64e(0xced967671770d970), C64e(0xe44b7272afdd4bdd), + C64e(0x33de9494ed79de79), C64e(0x2bd49898ff67d467), + C64e(0x7be8b0b09323e823), C64e(0x114a85855bde4ade), + C64e(0x6d6bbbbb06bd6bbd), C64e(0x912ac5c5bb7e2a7e), + C64e(0x9ee54f4f7b34e534), C64e(0xc116ededd73a163a), + C64e(0x17c58686d254c554), C64e(0x2fd79a9af862d762), + C64e(0xcc55666699ff55ff), C64e(0x22941111b6a794a7), + C64e(0x0fcf8a8ac04acf4a), C64e(0xc910e9e9d9301030), + C64e(0x080604040e0a060a), C64e(0xe781fefe66988198), + C64e(0x5bf0a0a0ab0bf00b), C64e(0xf0447878b4cc44cc), + C64e(0x4aba2525f0d5bad5), C64e(0x96e34b4b753ee33e), + C64e(0x5ff3a2a2ac0ef30e), C64e(0xbafe5d5d4419fe19), + C64e(0x1bc08080db5bc05b), C64e(0x0a8a050580858a85), + C64e(0x7ead3f3fd3ecadec), C64e(0x42bc2121fedfbcdf), + C64e(0xe0487070a8d848d8), C64e(0xf904f1f1fd0c040c), + C64e(0xc6df6363197adf7a), C64e(0xeec177772f58c158), + C64e(0x4575afaf309f759f), C64e(0x84634242e7a563a5), + C64e(0x4030202070503050), C64e(0xd11ae5e5cb2e1a2e), + C64e(0xe10efdfdef120e12), C64e(0x656dbfbf08b76db7), + C64e(0x194c818155d44cd4), C64e(0x30141818243c143c), + C64e(0x4c352626795f355f), C64e(0x9d2fc3c3b2712f71), + C64e(0x67e1bebe8638e138), C64e(0x6aa23535c8fda2fd), + C64e(0x0bcc8888c74fcc4f), C64e(0x5c392e2e654b394b), + C64e(0x3d5793936af957f9), C64e(0xaaf25555580df20d), + C64e(0xe382fcfc619d829d), C64e(0xf4477a7ab3c947c9), + C64e(0x8bacc8c827efacef), C64e(0x6fe7baba8832e732), + C64e(0x642b32324f7d2b7d), C64e(0xd795e6e642a495a4), + C64e(0x9ba0c0c03bfba0fb), C64e(0x32981919aab398b3), + C64e(0x27d19e9ef668d168), C64e(0x5d7fa3a322817f81), + C64e(0x88664444eeaa66aa), C64e(0xa87e5454d6827e82), + C64e(0x76ab3b3bdde6abe6), C64e(0x16830b0b959e839e), + C64e(0x03ca8c8cc945ca45), C64e(0x9529c7c7bc7b297b), + C64e(0xd6d36b6b056ed36e), C64e(0x503c28286c443c44), + C64e(0x5579a7a72c8b798b), C64e(0x63e2bcbc813de23d), + C64e(0x2c1d161631271d27), C64e(0x4176adad379a769a), + C64e(0xad3bdbdb964d3b4d), C64e(0xc85664649efa56fa), + C64e(0xe84e7474a6d24ed2), C64e(0x281e141436221e22), + C64e(0x3fdb9292e476db76), C64e(0x180a0c0c121e0a1e), + C64e(0x906c4848fcb46cb4), C64e(0x6be4b8b88f37e437), + C64e(0x255d9f9f78e75de7), C64e(0x616ebdbd0fb26eb2), + C64e(0x86ef4343692aef2a), C64e(0x93a6c4c435f1a6f1), + C64e(0x72a83939dae3a8e3), C64e(0x62a43131c6f7a4f7), + C64e(0xbd37d3d38a593759), C64e(0xff8bf2f274868b86), + C64e(0xb132d5d583563256), C64e(0x0d438b8b4ec543c5), + C64e(0xdc596e6e85eb59eb), C64e(0xafb7dada18c2b7c2), + C64e(0x028c01018e8f8c8f), C64e(0x7964b1b11dac64ac), + C64e(0x23d29c9cf16dd26d), C64e(0x92e04949723be03b), + C64e(0xabb4d8d81fc7b4c7), C64e(0x43faacacb915fa15), + C64e(0xfd07f3f3fa090709), C64e(0x8525cfcfa06f256f), + C64e(0x8fafcaca20eaafea), C64e(0xf38ef4f47d898e89), + C64e(0x8ee947476720e920), C64e(0x2018101038281828), + C64e(0xded56f6f0b64d564), C64e(0xfb88f0f073838883), + C64e(0x946f4a4afbb16fb1), C64e(0xb8725c5cca967296), + C64e(0x70243838546c246c), C64e(0xaef157575f08f108), + C64e(0xe6c773732152c752), C64e(0x3551979764f351f3), + C64e(0x8d23cbcbae652365), C64e(0x597ca1a125847c84), + C64e(0xcb9ce8e857bf9cbf), C64e(0x7c213e3e5d632163), + C64e(0x37dd9696ea7cdd7c), C64e(0xc2dc61611e7fdc7f), + C64e(0x1a860d0d9c918691), C64e(0x1e850f0f9b948594), + C64e(0xdb90e0e04bab90ab), C64e(0xf8427c7cbac642c6), + C64e(0xe2c471712657c457), C64e(0x83aacccc29e5aae5), + C64e(0x3bd89090e373d873), C64e(0x0c050606090f050f), + C64e(0xf501f7f7f4030103), C64e(0x38121c1c2a361236), + C64e(0x9fa3c2c23cfea3fe), C64e(0xd45f6a6a8be15fe1), + C64e(0x47f9aeaebe10f910), C64e(0xd2d06969026bd06b), + C64e(0x2e911717bfa891a8), C64e(0x2958999971e858e8), + C64e(0x74273a3a53692769), C64e(0x4eb92727f7d0b9d0), + C64e(0xa938d9d991483848), C64e(0xcd13ebebde351335), + C64e(0x56b32b2be5ceb3ce), C64e(0x4433222277553355), + C64e(0xbfbbd2d204d6bbd6), C64e(0x4970a9a939907090), + C64e(0x0e89070787808980), C64e(0x66a73333c1f2a7f2), + C64e(0x5ab62d2decc1b6c1), C64e(0x78223c3c5a662266), + C64e(0x2a921515b8ad92ad), C64e(0x8920c9c9a9602060), + C64e(0x154987875cdb49db), C64e(0x4fffaaaab01aff1a), + C64e(0xa0785050d8887888), C64e(0x517aa5a52b8e7a8e), + C64e(0x068f0303898a8f8a), C64e(0xb2f859594a13f813), + C64e(0x12800909929b809b), C64e(0x34171a1a23391739), + C64e(0xcada65651075da75), C64e(0xb531d7d784533153), + C64e(0x13c68484d551c651), C64e(0xbbb8d0d003d3b8d3), + C64e(0x1fc38282dc5ec35e), C64e(0x52b02929e2cbb0cb), + C64e(0xb4775a5ac3997799), C64e(0x3c111e1e2d331133), + C64e(0xf6cb7b7b3d46cb46), C64e(0x4bfca8a8b71ffc1f), + C64e(0xdad66d6d0c61d661), C64e(0x583a2c2c624e3a4e) +}; + +__constant static const ulong T4_G[] = { + C64e(0xf497a5c6c632f4a5), C64e(0x97eb84f8f86f9784), + C64e(0xb0c799eeee5eb099), C64e(0x8cf78df6f67a8c8d), + C64e(0x17e50dffffe8170d), C64e(0xdcb7bdd6d60adcbd), + C64e(0xc8a7b1dede16c8b1), C64e(0xfc395491916dfc54), + C64e(0xf0c050606090f050), C64e(0x0504030202070503), + C64e(0xe087a9cece2ee0a9), C64e(0x87ac7d5656d1877d), + C64e(0x2bd519e7e7cc2b19), C64e(0xa67162b5b513a662), + C64e(0x319ae64d4d7c31e6), C64e(0xb5c39aecec59b59a), + C64e(0xcf05458f8f40cf45), C64e(0xbc3e9d1f1fa3bc9d), + C64e(0xc00940898949c040), C64e(0x92ef87fafa689287), + C64e(0x3fc515efefd03f15), C64e(0x267febb2b29426eb), + C64e(0x4007c98e8ece40c9), C64e(0x1ded0bfbfbe61d0b), + C64e(0x2f82ec41416e2fec), C64e(0xa97d67b3b31aa967), + C64e(0x1cbefd5f5f431cfd), C64e(0x258aea45456025ea), + C64e(0xda46bf2323f9dabf), C64e(0x02a6f753535102f7), + C64e(0xa1d396e4e445a196), C64e(0xed2d5b9b9b76ed5b), + C64e(0x5deac27575285dc2), C64e(0x24d91ce1e1c5241c), + C64e(0xe97aae3d3dd4e9ae), C64e(0xbe986a4c4cf2be6a), + C64e(0xeed85a6c6c82ee5a), C64e(0xc3fc417e7ebdc341), + C64e(0x06f102f5f5f30602), C64e(0xd11d4f838352d14f), + C64e(0xe4d05c68688ce45c), C64e(0x07a2f451515607f4), + C64e(0x5cb934d1d18d5c34), C64e(0x18e908f9f9e11808), + C64e(0xaedf93e2e24cae93), C64e(0x954d73abab3e9573), + C64e(0xf5c453626297f553), C64e(0x41543f2a2a6b413f), + C64e(0x14100c08081c140c), C64e(0xf63152959563f652), + C64e(0xaf8c654646e9af65), C64e(0xe2215e9d9d7fe25e), + C64e(0x7860283030487828), C64e(0xf86ea13737cff8a1), + C64e(0x11140f0a0a1b110f), C64e(0xc45eb52f2febc4b5), + C64e(0x1b1c090e0e151b09), C64e(0x5a483624247e5a36), + C64e(0xb6369b1b1badb69b), C64e(0x47a53ddfdf98473d), + C64e(0x6a8126cdcda76a26), C64e(0xbb9c694e4ef5bb69), + C64e(0x4cfecd7f7f334ccd), C64e(0xbacf9feaea50ba9f), + C64e(0x2d241b12123f2d1b), C64e(0xb93a9e1d1da4b99e), + C64e(0x9cb0745858c49c74), C64e(0x72682e343446722e), + C64e(0x776c2d363641772d), C64e(0xcda3b2dcdc11cdb2), + C64e(0x2973eeb4b49d29ee), C64e(0x16b6fb5b5b4d16fb), + C64e(0x0153f6a4a4a501f6), C64e(0xd7ec4d7676a1d74d), + C64e(0xa37561b7b714a361), C64e(0x49face7d7d3449ce), + C64e(0x8da47b5252df8d7b), C64e(0x42a13edddd9f423e), + C64e(0x93bc715e5ecd9371), C64e(0xa226971313b1a297), + C64e(0x0457f5a6a6a204f5), C64e(0xb86968b9b901b868), + C64e(0x0000000000000000), C64e(0x74992cc1c1b5742c), + C64e(0xa080604040e0a060), C64e(0x21dd1fe3e3c2211f), + C64e(0x43f2c879793a43c8), C64e(0x2c77edb6b69a2ced), + C64e(0xd9b3bed4d40dd9be), C64e(0xca01468d8d47ca46), + C64e(0x70ced967671770d9), C64e(0xdde44b7272afdd4b), + C64e(0x7933de9494ed79de), C64e(0x672bd49898ff67d4), + C64e(0x237be8b0b09323e8), C64e(0xde114a85855bde4a), + C64e(0xbd6d6bbbbb06bd6b), C64e(0x7e912ac5c5bb7e2a), + C64e(0x349ee54f4f7b34e5), C64e(0x3ac116ededd73a16), + C64e(0x5417c58686d254c5), C64e(0x622fd79a9af862d7), + C64e(0xffcc55666699ff55), C64e(0xa722941111b6a794), + C64e(0x4a0fcf8a8ac04acf), C64e(0x30c910e9e9d93010), + C64e(0x0a080604040e0a06), C64e(0x98e781fefe669881), + C64e(0x0b5bf0a0a0ab0bf0), C64e(0xccf0447878b4cc44), + C64e(0xd54aba2525f0d5ba), C64e(0x3e96e34b4b753ee3), + C64e(0x0e5ff3a2a2ac0ef3), C64e(0x19bafe5d5d4419fe), + C64e(0x5b1bc08080db5bc0), C64e(0x850a8a050580858a), + C64e(0xec7ead3f3fd3ecad), C64e(0xdf42bc2121fedfbc), + C64e(0xd8e0487070a8d848), C64e(0x0cf904f1f1fd0c04), + C64e(0x7ac6df6363197adf), C64e(0x58eec177772f58c1), + C64e(0x9f4575afaf309f75), C64e(0xa584634242e7a563), + C64e(0x5040302020705030), C64e(0x2ed11ae5e5cb2e1a), + C64e(0x12e10efdfdef120e), C64e(0xb7656dbfbf08b76d), + C64e(0xd4194c818155d44c), C64e(0x3c30141818243c14), + C64e(0x5f4c352626795f35), C64e(0x719d2fc3c3b2712f), + C64e(0x3867e1bebe8638e1), C64e(0xfd6aa23535c8fda2), + C64e(0x4f0bcc8888c74fcc), C64e(0x4b5c392e2e654b39), + C64e(0xf93d5793936af957), C64e(0x0daaf25555580df2), + C64e(0x9de382fcfc619d82), C64e(0xc9f4477a7ab3c947), + C64e(0xef8bacc8c827efac), C64e(0x326fe7baba8832e7), + C64e(0x7d642b32324f7d2b), C64e(0xa4d795e6e642a495), + C64e(0xfb9ba0c0c03bfba0), C64e(0xb332981919aab398), + C64e(0x6827d19e9ef668d1), C64e(0x815d7fa3a322817f), + C64e(0xaa88664444eeaa66), C64e(0x82a87e5454d6827e), + C64e(0xe676ab3b3bdde6ab), C64e(0x9e16830b0b959e83), + C64e(0x4503ca8c8cc945ca), C64e(0x7b9529c7c7bc7b29), + C64e(0x6ed6d36b6b056ed3), C64e(0x44503c28286c443c), + C64e(0x8b5579a7a72c8b79), C64e(0x3d63e2bcbc813de2), + C64e(0x272c1d161631271d), C64e(0x9a4176adad379a76), + C64e(0x4dad3bdbdb964d3b), C64e(0xfac85664649efa56), + C64e(0xd2e84e7474a6d24e), C64e(0x22281e141436221e), + C64e(0x763fdb9292e476db), C64e(0x1e180a0c0c121e0a), + C64e(0xb4906c4848fcb46c), C64e(0x376be4b8b88f37e4), + C64e(0xe7255d9f9f78e75d), C64e(0xb2616ebdbd0fb26e), + C64e(0x2a86ef4343692aef), C64e(0xf193a6c4c435f1a6), + C64e(0xe372a83939dae3a8), C64e(0xf762a43131c6f7a4), + C64e(0x59bd37d3d38a5937), C64e(0x86ff8bf2f274868b), + C64e(0x56b132d5d5835632), C64e(0xc50d438b8b4ec543), + C64e(0xebdc596e6e85eb59), C64e(0xc2afb7dada18c2b7), + C64e(0x8f028c01018e8f8c), C64e(0xac7964b1b11dac64), + C64e(0x6d23d29c9cf16dd2), C64e(0x3b92e04949723be0), + C64e(0xc7abb4d8d81fc7b4), C64e(0x1543faacacb915fa), + C64e(0x09fd07f3f3fa0907), C64e(0x6f8525cfcfa06f25), + C64e(0xea8fafcaca20eaaf), C64e(0x89f38ef4f47d898e), + C64e(0x208ee947476720e9), C64e(0x2820181010382818), + C64e(0x64ded56f6f0b64d5), C64e(0x83fb88f0f0738388), + C64e(0xb1946f4a4afbb16f), C64e(0x96b8725c5cca9672), + C64e(0x6c70243838546c24), C64e(0x08aef157575f08f1), + C64e(0x52e6c773732152c7), C64e(0xf33551979764f351), + C64e(0x658d23cbcbae6523), C64e(0x84597ca1a125847c), + C64e(0xbfcb9ce8e857bf9c), C64e(0x637c213e3e5d6321), + C64e(0x7c37dd9696ea7cdd), C64e(0x7fc2dc61611e7fdc), + C64e(0x911a860d0d9c9186), C64e(0x941e850f0f9b9485), + C64e(0xabdb90e0e04bab90), C64e(0xc6f8427c7cbac642), + C64e(0x57e2c471712657c4), C64e(0xe583aacccc29e5aa), + C64e(0x733bd89090e373d8), C64e(0x0f0c050606090f05), + C64e(0x03f501f7f7f40301), C64e(0x3638121c1c2a3612), + C64e(0xfe9fa3c2c23cfea3), C64e(0xe1d45f6a6a8be15f), + C64e(0x1047f9aeaebe10f9), C64e(0x6bd2d06969026bd0), + C64e(0xa82e911717bfa891), C64e(0xe82958999971e858), + C64e(0x6974273a3a536927), C64e(0xd04eb92727f7d0b9), + C64e(0x48a938d9d9914838), C64e(0x35cd13ebebde3513), + C64e(0xce56b32b2be5ceb3), C64e(0x5544332222775533), + C64e(0xd6bfbbd2d204d6bb), C64e(0x904970a9a9399070), + C64e(0x800e890707878089), C64e(0xf266a73333c1f2a7), + C64e(0xc15ab62d2decc1b6), C64e(0x6678223c3c5a6622), + C64e(0xad2a921515b8ad92), C64e(0x608920c9c9a96020), + C64e(0xdb154987875cdb49), C64e(0x1a4fffaaaab01aff), + C64e(0x88a0785050d88878), C64e(0x8e517aa5a52b8e7a), + C64e(0x8a068f0303898a8f), C64e(0x13b2f859594a13f8), + C64e(0x9b12800909929b80), C64e(0x3934171a1a233917), + C64e(0x75cada65651075da), C64e(0x53b531d7d7845331), + C64e(0x5113c68484d551c6), C64e(0xd3bbb8d0d003d3b8), + C64e(0x5e1fc38282dc5ec3), C64e(0xcb52b02929e2cbb0), + C64e(0x99b4775a5ac39977), C64e(0x333c111e1e2d3311), + C64e(0x46f6cb7b7b3d46cb), C64e(0x1f4bfca8a8b71ffc), + C64e(0x61dad66d6d0c61d6), C64e(0x4e583a2c2c624e3a) +}; + +__constant static const ulong T5_G[] = { + C64e(0xa5f497a5c6c632f4), C64e(0x8497eb84f8f86f97), + C64e(0x99b0c799eeee5eb0), C64e(0x8d8cf78df6f67a8c), + C64e(0x0d17e50dffffe817), C64e(0xbddcb7bdd6d60adc), + C64e(0xb1c8a7b1dede16c8), C64e(0x54fc395491916dfc), + C64e(0x50f0c050606090f0), C64e(0x0305040302020705), + C64e(0xa9e087a9cece2ee0), C64e(0x7d87ac7d5656d187), + C64e(0x192bd519e7e7cc2b), C64e(0x62a67162b5b513a6), + C64e(0xe6319ae64d4d7c31), C64e(0x9ab5c39aecec59b5), + C64e(0x45cf05458f8f40cf), C64e(0x9dbc3e9d1f1fa3bc), + C64e(0x40c00940898949c0), C64e(0x8792ef87fafa6892), + C64e(0x153fc515efefd03f), C64e(0xeb267febb2b29426), + C64e(0xc94007c98e8ece40), C64e(0x0b1ded0bfbfbe61d), + C64e(0xec2f82ec41416e2f), C64e(0x67a97d67b3b31aa9), + C64e(0xfd1cbefd5f5f431c), C64e(0xea258aea45456025), + C64e(0xbfda46bf2323f9da), C64e(0xf702a6f753535102), + C64e(0x96a1d396e4e445a1), C64e(0x5bed2d5b9b9b76ed), + C64e(0xc25deac27575285d), C64e(0x1c24d91ce1e1c524), + C64e(0xaee97aae3d3dd4e9), C64e(0x6abe986a4c4cf2be), + C64e(0x5aeed85a6c6c82ee), C64e(0x41c3fc417e7ebdc3), + C64e(0x0206f102f5f5f306), C64e(0x4fd11d4f838352d1), + C64e(0x5ce4d05c68688ce4), C64e(0xf407a2f451515607), + C64e(0x345cb934d1d18d5c), C64e(0x0818e908f9f9e118), + C64e(0x93aedf93e2e24cae), C64e(0x73954d73abab3e95), + C64e(0x53f5c453626297f5), C64e(0x3f41543f2a2a6b41), + C64e(0x0c14100c08081c14), C64e(0x52f63152959563f6), + C64e(0x65af8c654646e9af), C64e(0x5ee2215e9d9d7fe2), + C64e(0x2878602830304878), C64e(0xa1f86ea13737cff8), + C64e(0x0f11140f0a0a1b11), C64e(0xb5c45eb52f2febc4), + C64e(0x091b1c090e0e151b), C64e(0x365a483624247e5a), + C64e(0x9bb6369b1b1badb6), C64e(0x3d47a53ddfdf9847), + C64e(0x266a8126cdcda76a), C64e(0x69bb9c694e4ef5bb), + C64e(0xcd4cfecd7f7f334c), C64e(0x9fbacf9feaea50ba), + C64e(0x1b2d241b12123f2d), C64e(0x9eb93a9e1d1da4b9), + C64e(0x749cb0745858c49c), C64e(0x2e72682e34344672), + C64e(0x2d776c2d36364177), C64e(0xb2cda3b2dcdc11cd), + C64e(0xee2973eeb4b49d29), C64e(0xfb16b6fb5b5b4d16), + C64e(0xf60153f6a4a4a501), C64e(0x4dd7ec4d7676a1d7), + C64e(0x61a37561b7b714a3), C64e(0xce49face7d7d3449), + C64e(0x7b8da47b5252df8d), C64e(0x3e42a13edddd9f42), + C64e(0x7193bc715e5ecd93), C64e(0x97a226971313b1a2), + C64e(0xf50457f5a6a6a204), C64e(0x68b86968b9b901b8), + C64e(0x0000000000000000), C64e(0x2c74992cc1c1b574), + C64e(0x60a080604040e0a0), C64e(0x1f21dd1fe3e3c221), + C64e(0xc843f2c879793a43), C64e(0xed2c77edb6b69a2c), + C64e(0xbed9b3bed4d40dd9), C64e(0x46ca01468d8d47ca), + C64e(0xd970ced967671770), C64e(0x4bdde44b7272afdd), + C64e(0xde7933de9494ed79), C64e(0xd4672bd49898ff67), + C64e(0xe8237be8b0b09323), C64e(0x4ade114a85855bde), + C64e(0x6bbd6d6bbbbb06bd), C64e(0x2a7e912ac5c5bb7e), + C64e(0xe5349ee54f4f7b34), C64e(0x163ac116ededd73a), + C64e(0xc55417c58686d254), C64e(0xd7622fd79a9af862), + C64e(0x55ffcc55666699ff), C64e(0x94a722941111b6a7), + C64e(0xcf4a0fcf8a8ac04a), C64e(0x1030c910e9e9d930), + C64e(0x060a080604040e0a), C64e(0x8198e781fefe6698), + C64e(0xf00b5bf0a0a0ab0b), C64e(0x44ccf0447878b4cc), + C64e(0xbad54aba2525f0d5), C64e(0xe33e96e34b4b753e), + C64e(0xf30e5ff3a2a2ac0e), C64e(0xfe19bafe5d5d4419), + C64e(0xc05b1bc08080db5b), C64e(0x8a850a8a05058085), + C64e(0xadec7ead3f3fd3ec), C64e(0xbcdf42bc2121fedf), + C64e(0x48d8e0487070a8d8), C64e(0x040cf904f1f1fd0c), + C64e(0xdf7ac6df6363197a), C64e(0xc158eec177772f58), + C64e(0x759f4575afaf309f), C64e(0x63a584634242e7a5), + C64e(0x3050403020207050), C64e(0x1a2ed11ae5e5cb2e), + C64e(0x0e12e10efdfdef12), C64e(0x6db7656dbfbf08b7), + C64e(0x4cd4194c818155d4), C64e(0x143c30141818243c), + C64e(0x355f4c352626795f), C64e(0x2f719d2fc3c3b271), + C64e(0xe13867e1bebe8638), C64e(0xa2fd6aa23535c8fd), + C64e(0xcc4f0bcc8888c74f), C64e(0x394b5c392e2e654b), + C64e(0x57f93d5793936af9), C64e(0xf20daaf25555580d), + C64e(0x829de382fcfc619d), C64e(0x47c9f4477a7ab3c9), + C64e(0xacef8bacc8c827ef), C64e(0xe7326fe7baba8832), + C64e(0x2b7d642b32324f7d), C64e(0x95a4d795e6e642a4), + C64e(0xa0fb9ba0c0c03bfb), C64e(0x98b332981919aab3), + C64e(0xd16827d19e9ef668), C64e(0x7f815d7fa3a32281), + C64e(0x66aa88664444eeaa), C64e(0x7e82a87e5454d682), + C64e(0xabe676ab3b3bdde6), C64e(0x839e16830b0b959e), + C64e(0xca4503ca8c8cc945), C64e(0x297b9529c7c7bc7b), + C64e(0xd36ed6d36b6b056e), C64e(0x3c44503c28286c44), + C64e(0x798b5579a7a72c8b), C64e(0xe23d63e2bcbc813d), + C64e(0x1d272c1d16163127), C64e(0x769a4176adad379a), + C64e(0x3b4dad3bdbdb964d), C64e(0x56fac85664649efa), + C64e(0x4ed2e84e7474a6d2), C64e(0x1e22281e14143622), + C64e(0xdb763fdb9292e476), C64e(0x0a1e180a0c0c121e), + C64e(0x6cb4906c4848fcb4), C64e(0xe4376be4b8b88f37), + C64e(0x5de7255d9f9f78e7), C64e(0x6eb2616ebdbd0fb2), + C64e(0xef2a86ef4343692a), C64e(0xa6f193a6c4c435f1), + C64e(0xa8e372a83939dae3), C64e(0xa4f762a43131c6f7), + C64e(0x3759bd37d3d38a59), C64e(0x8b86ff8bf2f27486), + C64e(0x3256b132d5d58356), C64e(0x43c50d438b8b4ec5), + C64e(0x59ebdc596e6e85eb), C64e(0xb7c2afb7dada18c2), + C64e(0x8c8f028c01018e8f), C64e(0x64ac7964b1b11dac), + C64e(0xd26d23d29c9cf16d), C64e(0xe03b92e04949723b), + C64e(0xb4c7abb4d8d81fc7), C64e(0xfa1543faacacb915), + C64e(0x0709fd07f3f3fa09), C64e(0x256f8525cfcfa06f), + C64e(0xafea8fafcaca20ea), C64e(0x8e89f38ef4f47d89), + C64e(0xe9208ee947476720), C64e(0x1828201810103828), + C64e(0xd564ded56f6f0b64), C64e(0x8883fb88f0f07383), + C64e(0x6fb1946f4a4afbb1), C64e(0x7296b8725c5cca96), + C64e(0x246c70243838546c), C64e(0xf108aef157575f08), + C64e(0xc752e6c773732152), C64e(0x51f33551979764f3), + C64e(0x23658d23cbcbae65), C64e(0x7c84597ca1a12584), + C64e(0x9cbfcb9ce8e857bf), C64e(0x21637c213e3e5d63), + C64e(0xdd7c37dd9696ea7c), C64e(0xdc7fc2dc61611e7f), + C64e(0x86911a860d0d9c91), C64e(0x85941e850f0f9b94), + C64e(0x90abdb90e0e04bab), C64e(0x42c6f8427c7cbac6), + C64e(0xc457e2c471712657), C64e(0xaae583aacccc29e5), + C64e(0xd8733bd89090e373), C64e(0x050f0c050606090f), + C64e(0x0103f501f7f7f403), C64e(0x123638121c1c2a36), + C64e(0xa3fe9fa3c2c23cfe), C64e(0x5fe1d45f6a6a8be1), + C64e(0xf91047f9aeaebe10), C64e(0xd06bd2d06969026b), + C64e(0x91a82e911717bfa8), C64e(0x58e82958999971e8), + C64e(0x276974273a3a5369), C64e(0xb9d04eb92727f7d0), + C64e(0x3848a938d9d99148), C64e(0x1335cd13ebebde35), + C64e(0xb3ce56b32b2be5ce), C64e(0x3355443322227755), + C64e(0xbbd6bfbbd2d204d6), C64e(0x70904970a9a93990), + C64e(0x89800e8907078780), C64e(0xa7f266a73333c1f2), + C64e(0xb6c15ab62d2decc1), C64e(0x226678223c3c5a66), + C64e(0x92ad2a921515b8ad), C64e(0x20608920c9c9a960), + C64e(0x49db154987875cdb), C64e(0xff1a4fffaaaab01a), + C64e(0x7888a0785050d888), C64e(0x7a8e517aa5a52b8e), + C64e(0x8f8a068f0303898a), C64e(0xf813b2f859594a13), + C64e(0x809b12800909929b), C64e(0x173934171a1a2339), + C64e(0xda75cada65651075), C64e(0x3153b531d7d78453), + C64e(0xc65113c68484d551), C64e(0xb8d3bbb8d0d003d3), + C64e(0xc35e1fc38282dc5e), C64e(0xb0cb52b02929e2cb), + C64e(0x7799b4775a5ac399), C64e(0x11333c111e1e2d33), + C64e(0xcb46f6cb7b7b3d46), C64e(0xfc1f4bfca8a8b71f), + C64e(0xd661dad66d6d0c61), C64e(0x3a4e583a2c2c624e) +}; + +__constant static const ulong T6_G[] = { + C64e(0xf4a5f497a5c6c632), C64e(0x978497eb84f8f86f), + C64e(0xb099b0c799eeee5e), C64e(0x8c8d8cf78df6f67a), + C64e(0x170d17e50dffffe8), C64e(0xdcbddcb7bdd6d60a), + C64e(0xc8b1c8a7b1dede16), C64e(0xfc54fc395491916d), + C64e(0xf050f0c050606090), C64e(0x0503050403020207), + C64e(0xe0a9e087a9cece2e), C64e(0x877d87ac7d5656d1), + C64e(0x2b192bd519e7e7cc), C64e(0xa662a67162b5b513), + C64e(0x31e6319ae64d4d7c), C64e(0xb59ab5c39aecec59), + C64e(0xcf45cf05458f8f40), C64e(0xbc9dbc3e9d1f1fa3), + C64e(0xc040c00940898949), C64e(0x928792ef87fafa68), + C64e(0x3f153fc515efefd0), C64e(0x26eb267febb2b294), + C64e(0x40c94007c98e8ece), C64e(0x1d0b1ded0bfbfbe6), + C64e(0x2fec2f82ec41416e), C64e(0xa967a97d67b3b31a), + C64e(0x1cfd1cbefd5f5f43), C64e(0x25ea258aea454560), + C64e(0xdabfda46bf2323f9), C64e(0x02f702a6f7535351), + C64e(0xa196a1d396e4e445), C64e(0xed5bed2d5b9b9b76), + C64e(0x5dc25deac2757528), C64e(0x241c24d91ce1e1c5), + C64e(0xe9aee97aae3d3dd4), C64e(0xbe6abe986a4c4cf2), + C64e(0xee5aeed85a6c6c82), C64e(0xc341c3fc417e7ebd), + C64e(0x060206f102f5f5f3), C64e(0xd14fd11d4f838352), + C64e(0xe45ce4d05c68688c), C64e(0x07f407a2f4515156), + C64e(0x5c345cb934d1d18d), C64e(0x180818e908f9f9e1), + C64e(0xae93aedf93e2e24c), C64e(0x9573954d73abab3e), + C64e(0xf553f5c453626297), C64e(0x413f41543f2a2a6b), + C64e(0x140c14100c08081c), C64e(0xf652f63152959563), + C64e(0xaf65af8c654646e9), C64e(0xe25ee2215e9d9d7f), + C64e(0x7828786028303048), C64e(0xf8a1f86ea13737cf), + C64e(0x110f11140f0a0a1b), C64e(0xc4b5c45eb52f2feb), + C64e(0x1b091b1c090e0e15), C64e(0x5a365a483624247e), + C64e(0xb69bb6369b1b1bad), C64e(0x473d47a53ddfdf98), + C64e(0x6a266a8126cdcda7), C64e(0xbb69bb9c694e4ef5), + C64e(0x4ccd4cfecd7f7f33), C64e(0xba9fbacf9feaea50), + C64e(0x2d1b2d241b12123f), C64e(0xb99eb93a9e1d1da4), + C64e(0x9c749cb0745858c4), C64e(0x722e72682e343446), + C64e(0x772d776c2d363641), C64e(0xcdb2cda3b2dcdc11), + C64e(0x29ee2973eeb4b49d), C64e(0x16fb16b6fb5b5b4d), + C64e(0x01f60153f6a4a4a5), C64e(0xd74dd7ec4d7676a1), + C64e(0xa361a37561b7b714), C64e(0x49ce49face7d7d34), + C64e(0x8d7b8da47b5252df), C64e(0x423e42a13edddd9f), + C64e(0x937193bc715e5ecd), C64e(0xa297a226971313b1), + C64e(0x04f50457f5a6a6a2), C64e(0xb868b86968b9b901), + C64e(0x0000000000000000), C64e(0x742c74992cc1c1b5), + C64e(0xa060a080604040e0), C64e(0x211f21dd1fe3e3c2), + C64e(0x43c843f2c879793a), C64e(0x2ced2c77edb6b69a), + C64e(0xd9bed9b3bed4d40d), C64e(0xca46ca01468d8d47), + C64e(0x70d970ced9676717), C64e(0xdd4bdde44b7272af), + C64e(0x79de7933de9494ed), C64e(0x67d4672bd49898ff), + C64e(0x23e8237be8b0b093), C64e(0xde4ade114a85855b), + C64e(0xbd6bbd6d6bbbbb06), C64e(0x7e2a7e912ac5c5bb), + C64e(0x34e5349ee54f4f7b), C64e(0x3a163ac116ededd7), + C64e(0x54c55417c58686d2), C64e(0x62d7622fd79a9af8), + C64e(0xff55ffcc55666699), C64e(0xa794a722941111b6), + C64e(0x4acf4a0fcf8a8ac0), C64e(0x301030c910e9e9d9), + C64e(0x0a060a080604040e), C64e(0x988198e781fefe66), + C64e(0x0bf00b5bf0a0a0ab), C64e(0xcc44ccf0447878b4), + C64e(0xd5bad54aba2525f0), C64e(0x3ee33e96e34b4b75), + C64e(0x0ef30e5ff3a2a2ac), C64e(0x19fe19bafe5d5d44), + C64e(0x5bc05b1bc08080db), C64e(0x858a850a8a050580), + C64e(0xecadec7ead3f3fd3), C64e(0xdfbcdf42bc2121fe), + C64e(0xd848d8e0487070a8), C64e(0x0c040cf904f1f1fd), + C64e(0x7adf7ac6df636319), C64e(0x58c158eec177772f), + C64e(0x9f759f4575afaf30), C64e(0xa563a584634242e7), + C64e(0x5030504030202070), C64e(0x2e1a2ed11ae5e5cb), + C64e(0x120e12e10efdfdef), C64e(0xb76db7656dbfbf08), + C64e(0xd44cd4194c818155), C64e(0x3c143c3014181824), + C64e(0x5f355f4c35262679), C64e(0x712f719d2fc3c3b2), + C64e(0x38e13867e1bebe86), C64e(0xfda2fd6aa23535c8), + C64e(0x4fcc4f0bcc8888c7), C64e(0x4b394b5c392e2e65), + C64e(0xf957f93d5793936a), C64e(0x0df20daaf2555558), + C64e(0x9d829de382fcfc61), C64e(0xc947c9f4477a7ab3), + C64e(0xefacef8bacc8c827), C64e(0x32e7326fe7baba88), + C64e(0x7d2b7d642b32324f), C64e(0xa495a4d795e6e642), + C64e(0xfba0fb9ba0c0c03b), C64e(0xb398b332981919aa), + C64e(0x68d16827d19e9ef6), C64e(0x817f815d7fa3a322), + C64e(0xaa66aa88664444ee), C64e(0x827e82a87e5454d6), + C64e(0xe6abe676ab3b3bdd), C64e(0x9e839e16830b0b95), + C64e(0x45ca4503ca8c8cc9), C64e(0x7b297b9529c7c7bc), + C64e(0x6ed36ed6d36b6b05), C64e(0x443c44503c28286c), + C64e(0x8b798b5579a7a72c), C64e(0x3de23d63e2bcbc81), + C64e(0x271d272c1d161631), C64e(0x9a769a4176adad37), + C64e(0x4d3b4dad3bdbdb96), C64e(0xfa56fac85664649e), + C64e(0xd24ed2e84e7474a6), C64e(0x221e22281e141436), + C64e(0x76db763fdb9292e4), C64e(0x1e0a1e180a0c0c12), + C64e(0xb46cb4906c4848fc), C64e(0x37e4376be4b8b88f), + C64e(0xe75de7255d9f9f78), C64e(0xb26eb2616ebdbd0f), + C64e(0x2aef2a86ef434369), C64e(0xf1a6f193a6c4c435), + C64e(0xe3a8e372a83939da), C64e(0xf7a4f762a43131c6), + C64e(0x593759bd37d3d38a), C64e(0x868b86ff8bf2f274), + C64e(0x563256b132d5d583), C64e(0xc543c50d438b8b4e), + C64e(0xeb59ebdc596e6e85), C64e(0xc2b7c2afb7dada18), + C64e(0x8f8c8f028c01018e), C64e(0xac64ac7964b1b11d), + C64e(0x6dd26d23d29c9cf1), C64e(0x3be03b92e0494972), + C64e(0xc7b4c7abb4d8d81f), C64e(0x15fa1543faacacb9), + C64e(0x090709fd07f3f3fa), C64e(0x6f256f8525cfcfa0), + C64e(0xeaafea8fafcaca20), C64e(0x898e89f38ef4f47d), + C64e(0x20e9208ee9474767), C64e(0x2818282018101038), + C64e(0x64d564ded56f6f0b), C64e(0x838883fb88f0f073), + C64e(0xb16fb1946f4a4afb), C64e(0x967296b8725c5cca), + C64e(0x6c246c7024383854), C64e(0x08f108aef157575f), + C64e(0x52c752e6c7737321), C64e(0xf351f33551979764), + C64e(0x6523658d23cbcbae), C64e(0x847c84597ca1a125), + C64e(0xbf9cbfcb9ce8e857), C64e(0x6321637c213e3e5d), + C64e(0x7cdd7c37dd9696ea), C64e(0x7fdc7fc2dc61611e), + C64e(0x9186911a860d0d9c), C64e(0x9485941e850f0f9b), + C64e(0xab90abdb90e0e04b), C64e(0xc642c6f8427c7cba), + C64e(0x57c457e2c4717126), C64e(0xe5aae583aacccc29), + C64e(0x73d8733bd89090e3), C64e(0x0f050f0c05060609), + C64e(0x030103f501f7f7f4), C64e(0x36123638121c1c2a), + C64e(0xfea3fe9fa3c2c23c), C64e(0xe15fe1d45f6a6a8b), + C64e(0x10f91047f9aeaebe), C64e(0x6bd06bd2d0696902), + C64e(0xa891a82e911717bf), C64e(0xe858e82958999971), + C64e(0x69276974273a3a53), C64e(0xd0b9d04eb92727f7), + C64e(0x483848a938d9d991), C64e(0x351335cd13ebebde), + C64e(0xceb3ce56b32b2be5), C64e(0x5533554433222277), + C64e(0xd6bbd6bfbbd2d204), C64e(0x9070904970a9a939), + C64e(0x8089800e89070787), C64e(0xf2a7f266a73333c1), + C64e(0xc1b6c15ab62d2dec), C64e(0x66226678223c3c5a), + C64e(0xad92ad2a921515b8), C64e(0x6020608920c9c9a9), + C64e(0xdb49db154987875c), C64e(0x1aff1a4fffaaaab0), + C64e(0x887888a0785050d8), C64e(0x8e7a8e517aa5a52b), + C64e(0x8a8f8a068f030389), C64e(0x13f813b2f859594a), + C64e(0x9b809b1280090992), C64e(0x39173934171a1a23), + C64e(0x75da75cada656510), C64e(0x533153b531d7d784), + C64e(0x51c65113c68484d5), C64e(0xd3b8d3bbb8d0d003), + C64e(0x5ec35e1fc38282dc), C64e(0xcbb0cb52b02929e2), + C64e(0x997799b4775a5ac3), C64e(0x3311333c111e1e2d), + C64e(0x46cb46f6cb7b7b3d), C64e(0x1ffc1f4bfca8a8b7), + C64e(0x61d661dad66d6d0c), C64e(0x4e3a4e583a2c2c62) +}; + +__constant static const ulong T7_G[] = { + C64e(0x32f4a5f497a5c6c6), C64e(0x6f978497eb84f8f8), + C64e(0x5eb099b0c799eeee), C64e(0x7a8c8d8cf78df6f6), + C64e(0xe8170d17e50dffff), C64e(0x0adcbddcb7bdd6d6), + C64e(0x16c8b1c8a7b1dede), C64e(0x6dfc54fc39549191), + C64e(0x90f050f0c0506060), C64e(0x0705030504030202), + C64e(0x2ee0a9e087a9cece), C64e(0xd1877d87ac7d5656), + C64e(0xcc2b192bd519e7e7), C64e(0x13a662a67162b5b5), + C64e(0x7c31e6319ae64d4d), C64e(0x59b59ab5c39aecec), + C64e(0x40cf45cf05458f8f), C64e(0xa3bc9dbc3e9d1f1f), + C64e(0x49c040c009408989), C64e(0x68928792ef87fafa), + C64e(0xd03f153fc515efef), C64e(0x9426eb267febb2b2), + C64e(0xce40c94007c98e8e), C64e(0xe61d0b1ded0bfbfb), + C64e(0x6e2fec2f82ec4141), C64e(0x1aa967a97d67b3b3), + C64e(0x431cfd1cbefd5f5f), C64e(0x6025ea258aea4545), + C64e(0xf9dabfda46bf2323), C64e(0x5102f702a6f75353), + C64e(0x45a196a1d396e4e4), C64e(0x76ed5bed2d5b9b9b), + C64e(0x285dc25deac27575), C64e(0xc5241c24d91ce1e1), + C64e(0xd4e9aee97aae3d3d), C64e(0xf2be6abe986a4c4c), + C64e(0x82ee5aeed85a6c6c), C64e(0xbdc341c3fc417e7e), + C64e(0xf3060206f102f5f5), C64e(0x52d14fd11d4f8383), + C64e(0x8ce45ce4d05c6868), C64e(0x5607f407a2f45151), + C64e(0x8d5c345cb934d1d1), C64e(0xe1180818e908f9f9), + C64e(0x4cae93aedf93e2e2), C64e(0x3e9573954d73abab), + C64e(0x97f553f5c4536262), C64e(0x6b413f41543f2a2a), + C64e(0x1c140c14100c0808), C64e(0x63f652f631529595), + C64e(0xe9af65af8c654646), C64e(0x7fe25ee2215e9d9d), + C64e(0x4878287860283030), C64e(0xcff8a1f86ea13737), + C64e(0x1b110f11140f0a0a), C64e(0xebc4b5c45eb52f2f), + C64e(0x151b091b1c090e0e), C64e(0x7e5a365a48362424), + C64e(0xadb69bb6369b1b1b), C64e(0x98473d47a53ddfdf), + C64e(0xa76a266a8126cdcd), C64e(0xf5bb69bb9c694e4e), + C64e(0x334ccd4cfecd7f7f), C64e(0x50ba9fbacf9feaea), + C64e(0x3f2d1b2d241b1212), C64e(0xa4b99eb93a9e1d1d), + C64e(0xc49c749cb0745858), C64e(0x46722e72682e3434), + C64e(0x41772d776c2d3636), C64e(0x11cdb2cda3b2dcdc), + C64e(0x9d29ee2973eeb4b4), C64e(0x4d16fb16b6fb5b5b), + C64e(0xa501f60153f6a4a4), C64e(0xa1d74dd7ec4d7676), + C64e(0x14a361a37561b7b7), C64e(0x3449ce49face7d7d), + C64e(0xdf8d7b8da47b5252), C64e(0x9f423e42a13edddd), + C64e(0xcd937193bc715e5e), C64e(0xb1a297a226971313), + C64e(0xa204f50457f5a6a6), C64e(0x01b868b86968b9b9), + C64e(0x0000000000000000), C64e(0xb5742c74992cc1c1), + C64e(0xe0a060a080604040), C64e(0xc2211f21dd1fe3e3), + C64e(0x3a43c843f2c87979), C64e(0x9a2ced2c77edb6b6), + C64e(0x0dd9bed9b3bed4d4), C64e(0x47ca46ca01468d8d), + C64e(0x1770d970ced96767), C64e(0xafdd4bdde44b7272), + C64e(0xed79de7933de9494), C64e(0xff67d4672bd49898), + C64e(0x9323e8237be8b0b0), C64e(0x5bde4ade114a8585), + C64e(0x06bd6bbd6d6bbbbb), C64e(0xbb7e2a7e912ac5c5), + C64e(0x7b34e5349ee54f4f), C64e(0xd73a163ac116eded), + C64e(0xd254c55417c58686), C64e(0xf862d7622fd79a9a), + C64e(0x99ff55ffcc556666), C64e(0xb6a794a722941111), + C64e(0xc04acf4a0fcf8a8a), C64e(0xd9301030c910e9e9), + C64e(0x0e0a060a08060404), C64e(0x66988198e781fefe), + C64e(0xab0bf00b5bf0a0a0), C64e(0xb4cc44ccf0447878), + C64e(0xf0d5bad54aba2525), C64e(0x753ee33e96e34b4b), + C64e(0xac0ef30e5ff3a2a2), C64e(0x4419fe19bafe5d5d), + C64e(0xdb5bc05b1bc08080), C64e(0x80858a850a8a0505), + C64e(0xd3ecadec7ead3f3f), C64e(0xfedfbcdf42bc2121), + C64e(0xa8d848d8e0487070), C64e(0xfd0c040cf904f1f1), + C64e(0x197adf7ac6df6363), C64e(0x2f58c158eec17777), + C64e(0x309f759f4575afaf), C64e(0xe7a563a584634242), + C64e(0x7050305040302020), C64e(0xcb2e1a2ed11ae5e5), + C64e(0xef120e12e10efdfd), C64e(0x08b76db7656dbfbf), + C64e(0x55d44cd4194c8181), C64e(0x243c143c30141818), + C64e(0x795f355f4c352626), C64e(0xb2712f719d2fc3c3), + C64e(0x8638e13867e1bebe), C64e(0xc8fda2fd6aa23535), + C64e(0xc74fcc4f0bcc8888), C64e(0x654b394b5c392e2e), + C64e(0x6af957f93d579393), C64e(0x580df20daaf25555), + C64e(0x619d829de382fcfc), C64e(0xb3c947c9f4477a7a), + C64e(0x27efacef8bacc8c8), C64e(0x8832e7326fe7baba), + C64e(0x4f7d2b7d642b3232), C64e(0x42a495a4d795e6e6), + C64e(0x3bfba0fb9ba0c0c0), C64e(0xaab398b332981919), + C64e(0xf668d16827d19e9e), C64e(0x22817f815d7fa3a3), + C64e(0xeeaa66aa88664444), C64e(0xd6827e82a87e5454), + C64e(0xdde6abe676ab3b3b), C64e(0x959e839e16830b0b), + C64e(0xc945ca4503ca8c8c), C64e(0xbc7b297b9529c7c7), + C64e(0x056ed36ed6d36b6b), C64e(0x6c443c44503c2828), + C64e(0x2c8b798b5579a7a7), C64e(0x813de23d63e2bcbc), + C64e(0x31271d272c1d1616), C64e(0x379a769a4176adad), + C64e(0x964d3b4dad3bdbdb), C64e(0x9efa56fac8566464), + C64e(0xa6d24ed2e84e7474), C64e(0x36221e22281e1414), + C64e(0xe476db763fdb9292), C64e(0x121e0a1e180a0c0c), + C64e(0xfcb46cb4906c4848), C64e(0x8f37e4376be4b8b8), + C64e(0x78e75de7255d9f9f), C64e(0x0fb26eb2616ebdbd), + C64e(0x692aef2a86ef4343), C64e(0x35f1a6f193a6c4c4), + C64e(0xdae3a8e372a83939), C64e(0xc6f7a4f762a43131), + C64e(0x8a593759bd37d3d3), C64e(0x74868b86ff8bf2f2), + C64e(0x83563256b132d5d5), C64e(0x4ec543c50d438b8b), + C64e(0x85eb59ebdc596e6e), C64e(0x18c2b7c2afb7dada), + C64e(0x8e8f8c8f028c0101), C64e(0x1dac64ac7964b1b1), + C64e(0xf16dd26d23d29c9c), C64e(0x723be03b92e04949), + C64e(0x1fc7b4c7abb4d8d8), C64e(0xb915fa1543faacac), + C64e(0xfa090709fd07f3f3), C64e(0xa06f256f8525cfcf), + C64e(0x20eaafea8fafcaca), C64e(0x7d898e89f38ef4f4), + C64e(0x6720e9208ee94747), C64e(0x3828182820181010), + C64e(0x0b64d564ded56f6f), C64e(0x73838883fb88f0f0), + C64e(0xfbb16fb1946f4a4a), C64e(0xca967296b8725c5c), + C64e(0x546c246c70243838), C64e(0x5f08f108aef15757), + C64e(0x2152c752e6c77373), C64e(0x64f351f335519797), + C64e(0xae6523658d23cbcb), C64e(0x25847c84597ca1a1), + C64e(0x57bf9cbfcb9ce8e8), C64e(0x5d6321637c213e3e), + C64e(0xea7cdd7c37dd9696), C64e(0x1e7fdc7fc2dc6161), + C64e(0x9c9186911a860d0d), C64e(0x9b9485941e850f0f), + C64e(0x4bab90abdb90e0e0), C64e(0xbac642c6f8427c7c), + C64e(0x2657c457e2c47171), C64e(0x29e5aae583aacccc), + C64e(0xe373d8733bd89090), C64e(0x090f050f0c050606), + C64e(0xf4030103f501f7f7), C64e(0x2a36123638121c1c), + C64e(0x3cfea3fe9fa3c2c2), C64e(0x8be15fe1d45f6a6a), + C64e(0xbe10f91047f9aeae), C64e(0x026bd06bd2d06969), + C64e(0xbfa891a82e911717), C64e(0x71e858e829589999), + C64e(0x5369276974273a3a), C64e(0xf7d0b9d04eb92727), + C64e(0x91483848a938d9d9), C64e(0xde351335cd13ebeb), + C64e(0xe5ceb3ce56b32b2b), C64e(0x7755335544332222), + C64e(0x04d6bbd6bfbbd2d2), C64e(0x399070904970a9a9), + C64e(0x878089800e890707), C64e(0xc1f2a7f266a73333), + C64e(0xecc1b6c15ab62d2d), C64e(0x5a66226678223c3c), + C64e(0xb8ad92ad2a921515), C64e(0xa96020608920c9c9), + C64e(0x5cdb49db15498787), C64e(0xb01aff1a4fffaaaa), + C64e(0xd8887888a0785050), C64e(0x2b8e7a8e517aa5a5), + C64e(0x898a8f8a068f0303), C64e(0x4a13f813b2f85959), + C64e(0x929b809b12800909), C64e(0x2339173934171a1a), + C64e(0x1075da75cada6565), C64e(0x84533153b531d7d7), + C64e(0xd551c65113c68484), C64e(0x03d3b8d3bbb8d0d0), + C64e(0xdc5ec35e1fc38282), C64e(0xe2cbb0cb52b02929), + C64e(0xc3997799b4775a5a), C64e(0x2d3311333c111e1e), + C64e(0x3d46cb46f6cb7b7b), C64e(0xb71ffc1f4bfca8a8), + C64e(0x0c61d661dad66d6d), C64e(0x624e3a4e583a2c2c) +}; +*/ +#define RBTT(d, b0, b1, b2, b3, b4, b5, b6, b7) do { \ + d = T0[t0[b0]] \ + ^ T1[t1[b1]] \ + ^ T2[t2[b2]] \ + ^ T3[t3[b3]] \ + ^ T4[t4[b4]] \ + ^ T5[t5[b5]] \ + ^ T6[t6[b6]] \ + ^ T7[t7[b7]]; \ + } while (0) + +#define ROUND_BIG_P(a, r) do { \ + t0[0x0] = B64_0(a[0x0]) ^ PC64(0x00, r); \ + t1[0x0] = B64_1(a[0x0]); \ + t2[0x0] = B64_2(a[0x0]); \ + t3[0x0] = B64_3(a[0x0]); \ + t4[0x0] = B64_4(a[0x0]); \ + t5[0x0] = B64_5(a[0x0]); \ + t6[0x0] = B64_6(a[0x0]); \ + t7[0x0] = B64_7(a[0x0]); \ + t0[0x1] = B64_0(a[0x1]) ^ PC64(0x10, r); \ + t1[0x1] = B64_1(a[0x1]); \ + t2[0x1] = B64_2(a[0x1]); \ + t3[0x1] = B64_3(a[0x1]); \ + t4[0x1] = B64_4(a[0x1]); \ + t5[0x1] = B64_5(a[0x1]); \ + t6[0x1] = B64_6(a[0x1]); \ + t7[0x1] = B64_7(a[0x1]); \ + t0[0x2] = B64_0(a[0x2]) ^ PC64(0x20, r); \ + t1[0x2] = B64_1(a[0x2]); \ + t2[0x2] = B64_2(a[0x2]); \ + t3[0x2] = B64_3(a[0x2]); \ + t4[0x2] = B64_4(a[0x2]); \ + t5[0x2] = B64_5(a[0x2]); \ + t6[0x2] = B64_6(a[0x2]); \ + t7[0x2] = B64_7(a[0x2]); \ + t0[0x3] = B64_0(a[0x3]) ^ PC64(0x30, r); \ + t1[0x3] = B64_1(a[0x3]); \ + t2[0x3] = B64_2(a[0x3]); \ + t3[0x3] = B64_3(a[0x3]); \ + t4[0x3] = B64_4(a[0x3]); \ + t5[0x3] = B64_5(a[0x3]); \ + t6[0x3] = B64_6(a[0x3]); \ + t7[0x3] = B64_7(a[0x3]); \ + t0[0x4] = B64_0(a[0x4]) ^ PC64(0x40, r); \ + t1[0x4] = B64_1(a[0x4]); \ + t2[0x4] = B64_2(a[0x4]); \ + t3[0x4] = B64_3(a[0x4]); \ + t4[0x4] = B64_4(a[0x4]); \ + t5[0x4] = B64_5(a[0x4]); \ + t6[0x4] = B64_6(a[0x4]); \ + t7[0x4] = B64_7(a[0x4]); \ + t0[0x5] = B64_0(a[0x5]) ^ PC64(0x50, r); \ + t1[0x5] = B64_1(a[0x5]); \ + t2[0x5] = B64_2(a[0x5]); \ + t3[0x5] = B64_3(a[0x5]); \ + t4[0x5] = B64_4(a[0x5]); \ + t5[0x5] = B64_5(a[0x5]); \ + t6[0x5] = B64_6(a[0x5]); \ + t7[0x5] = B64_7(a[0x5]); \ + t0[0x6] = B64_0(a[0x6]) ^ PC64(0x60, r); \ + t1[0x6] = B64_1(a[0x6]); \ + t2[0x6] = B64_2(a[0x6]); \ + t3[0x6] = B64_3(a[0x6]); \ + t4[0x6] = B64_4(a[0x6]); \ + t5[0x6] = B64_5(a[0x6]); \ + t6[0x6] = B64_6(a[0x6]); \ + t7[0x6] = B64_7(a[0x6]); \ + t0[0x7] = B64_0(a[0x7]) ^ PC64(0x70, r); \ + t1[0x7] = B64_1(a[0x7]); \ + t2[0x7] = B64_2(a[0x7]); \ + t3[0x7] = B64_3(a[0x7]); \ + t4[0x7] = B64_4(a[0x7]); \ + t5[0x7] = B64_5(a[0x7]); \ + t6[0x7] = B64_6(a[0x7]); \ + t7[0x7] = B64_7(a[0x7]); \ + t0[0x8] = B64_0(a[0x8]) ^ PC64(0x80, r); \ + t1[0x8] = B64_1(a[0x8]); \ + t2[0x8] = B64_2(a[0x8]); \ + t3[0x8] = B64_3(a[0x8]); \ + t4[0x8] = B64_4(a[0x8]); \ + t5[0x8] = B64_5(a[0x8]); \ + t6[0x8] = B64_6(a[0x8]); \ + t7[0x8] = B64_7(a[0x8]); \ + t0[0x9] = B64_0(a[0x9]) ^ PC64(0x90, r); \ + t1[0x9] = B64_1(a[0x9]); \ + t2[0x9] = B64_2(a[0x9]); \ + t3[0x9] = B64_3(a[0x9]); \ + t4[0x9] = B64_4(a[0x9]); \ + t5[0x9] = B64_5(a[0x9]); \ + t6[0x9] = B64_6(a[0x9]); \ + t7[0x9] = B64_7(a[0x9]); \ + t0[0xA] = B64_0(a[0xA]) ^ PC64(0xA0, r); \ + t1[0xA] = B64_1(a[0xA]); \ + t2[0xA] = B64_2(a[0xA]); \ + t3[0xA] = B64_3(a[0xA]); \ + t4[0xA] = B64_4(a[0xA]); \ + t5[0xA] = B64_5(a[0xA]); \ + t6[0xA] = B64_6(a[0xA]); \ + t7[0xA] = B64_7(a[0xA]); \ + t0[0xB] = B64_0(a[0xB]) ^ PC64(0xB0, r); \ + t1[0xB] = B64_1(a[0xB]); \ + t2[0xB] = B64_2(a[0xB]); \ + t3[0xB] = B64_3(a[0xB]); \ + t4[0xB] = B64_4(a[0xB]); \ + t5[0xB] = B64_5(a[0xB]); \ + t6[0xB] = B64_6(a[0xB]); \ + t7[0xB] = B64_7(a[0xB]); \ + t0[0xC] = B64_0(a[0xC]) ^ PC64(0xC0, r); \ + t1[0xC] = B64_1(a[0xC]); \ + t2[0xC] = B64_2(a[0xC]); \ + t3[0xC] = B64_3(a[0xC]); \ + t4[0xC] = B64_4(a[0xC]); \ + t5[0xC] = B64_5(a[0xC]); \ + t6[0xC] = B64_6(a[0xC]); \ + t7[0xC] = B64_7(a[0xC]); \ + t0[0xD] = B64_0(a[0xD]) ^ PC64(0xD0, r); \ + t1[0xD] = B64_1(a[0xD]); \ + t2[0xD] = B64_2(a[0xD]); \ + t3[0xD] = B64_3(a[0xD]); \ + t4[0xD] = B64_4(a[0xD]); \ + t5[0xD] = B64_5(a[0xD]); \ + t6[0xD] = B64_6(a[0xD]); \ + t7[0xD] = B64_7(a[0xD]); \ + t0[0xE] = B64_0(a[0xE]) ^ PC64(0xE0, r); \ + t1[0xE] = B64_1(a[0xE]); \ + t2[0xE] = B64_2(a[0xE]); \ + t3[0xE] = B64_3(a[0xE]); \ + t4[0xE] = B64_4(a[0xE]); \ + t5[0xE] = B64_5(a[0xE]); \ + t6[0xE] = B64_6(a[0xE]); \ + t7[0xE] = B64_7(a[0xE]); \ + t0[0xF] = B64_0(a[0xF]) ^ PC64(0xF0, r); \ + t1[0xF] = B64_1(a[0xF]); \ + t2[0xF] = B64_2(a[0xF]); \ + t3[0xF] = B64_3(a[0xF]); \ + t4[0xF] = B64_4(a[0xF]); \ + t5[0xF] = B64_5(a[0xF]); \ + t6[0xF] = B64_6(a[0xF]); \ + t7[0xF] = B64_7(a[0xF]); \ + RBTT(a[0x0], 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0xB); \ + RBTT(a[0x1], 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0xC); \ + RBTT(a[0x2], 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0xD); \ + RBTT(a[0x3], 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xE); \ + RBTT(a[0x4], 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xF); \ + RBTT(a[0x5], 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0x0); \ + RBTT(a[0x6], 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0x1); \ + RBTT(a[0x7], 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0x2); \ + RBTT(a[0x8], 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0x3); \ + RBTT(a[0x9], 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x4); \ + RBTT(a[0xA], 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x0, 0x5); \ + RBTT(a[0xB], 0xB, 0xC, 0xD, 0xE, 0xF, 0x0, 0x1, 0x6); \ + RBTT(a[0xC], 0xC, 0xD, 0xE, 0xF, 0x0, 0x1, 0x2, 0x7); \ + RBTT(a[0xD], 0xD, 0xE, 0xF, 0x0, 0x1, 0x2, 0x3, 0x8); \ + RBTT(a[0xE], 0xE, 0xF, 0x0, 0x1, 0x2, 0x3, 0x4, 0x9); \ + RBTT(a[0xF], 0xF, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0xA); \ + } while (0) + +#define ROUND_BIG_Q(a, r) do { \ + a[0x0] ^= QC64(0x00, r); \ + a[0x1] ^= QC64(0x10, r); \ + a[0x2] ^= QC64(0x20, r); \ + a[0x3] ^= QC64(0x30, r); \ + a[0x4] ^= QC64(0x40, r); \ + a[0x5] ^= QC64(0x50, r); \ + a[0x6] ^= QC64(0x60, r); \ + a[0x7] ^= QC64(0x70, r); \ + a[0x8] ^= QC64(0x80, r); \ + a[0x9] ^= QC64(0x90, r); \ + a[0xA] ^= QC64(0xA0, r); \ + a[0xB] ^= QC64(0xB0, r); \ + a[0xC] ^= QC64(0xC0, r); \ + a[0xD] ^= QC64(0xD0, r); \ + a[0xE] ^= QC64(0xE0, r); \ + a[0xF] ^= QC64(0xF0, r); \ + t0[0x0] = B64_0(a[0x0]); \ + t1[0x0] = B64_1(a[0x0]); \ + t2[0x0] = B64_2(a[0x0]); \ + t3[0x0] = B64_3(a[0x0]); \ + t4[0x0] = B64_4(a[0x0]); \ + t5[0x0] = B64_5(a[0x0]); \ + t6[0x0] = B64_6(a[0x0]); \ + t7[0x0] = B64_7(a[0x0]); \ + t0[0x1] = B64_0(a[0x1]); \ + t1[0x1] = B64_1(a[0x1]); \ + t2[0x1] = B64_2(a[0x1]); \ + t3[0x1] = B64_3(a[0x1]); \ + t4[0x1] = B64_4(a[0x1]); \ + t5[0x1] = B64_5(a[0x1]); \ + t6[0x1] = B64_6(a[0x1]); \ + t7[0x1] = B64_7(a[0x1]); \ + t0[0x2] = B64_0(a[0x2]); \ + t1[0x2] = B64_1(a[0x2]); \ + t2[0x2] = B64_2(a[0x2]); \ + t3[0x2] = B64_3(a[0x2]); \ + t4[0x2] = B64_4(a[0x2]); \ + t5[0x2] = B64_5(a[0x2]); \ + t6[0x2] = B64_6(a[0x2]); \ + t7[0x2] = B64_7(a[0x2]); \ + t0[0x3] = B64_0(a[0x3]); \ + t1[0x3] = B64_1(a[0x3]); \ + t2[0x3] = B64_2(a[0x3]); \ + t3[0x3] = B64_3(a[0x3]); \ + t4[0x3] = B64_4(a[0x3]); \ + t5[0x3] = B64_5(a[0x3]); \ + t6[0x3] = B64_6(a[0x3]); \ + t7[0x3] = B64_7(a[0x3]); \ + t0[0x4] = B64_0(a[0x4]); \ + t1[0x4] = B64_1(a[0x4]); \ + t2[0x4] = B64_2(a[0x4]); \ + t3[0x4] = B64_3(a[0x4]); \ + t4[0x4] = B64_4(a[0x4]); \ + t5[0x4] = B64_5(a[0x4]); \ + t6[0x4] = B64_6(a[0x4]); \ + t7[0x4] = B64_7(a[0x4]); \ + t0[0x5] = B64_0(a[0x5]); \ + t1[0x5] = B64_1(a[0x5]); \ + t2[0x5] = B64_2(a[0x5]); \ + t3[0x5] = B64_3(a[0x5]); \ + t4[0x5] = B64_4(a[0x5]); \ + t5[0x5] = B64_5(a[0x5]); \ + t6[0x5] = B64_6(a[0x5]); \ + t7[0x5] = B64_7(a[0x5]); \ + t0[0x6] = B64_0(a[0x6]); \ + t1[0x6] = B64_1(a[0x6]); \ + t2[0x6] = B64_2(a[0x6]); \ + t3[0x6] = B64_3(a[0x6]); \ + t4[0x6] = B64_4(a[0x6]); \ + t5[0x6] = B64_5(a[0x6]); \ + t6[0x6] = B64_6(a[0x6]); \ + t7[0x6] = B64_7(a[0x6]); \ + t0[0x7] = B64_0(a[0x7]); \ + t1[0x7] = B64_1(a[0x7]); \ + t2[0x7] = B64_2(a[0x7]); \ + t3[0x7] = B64_3(a[0x7]); \ + t4[0x7] = B64_4(a[0x7]); \ + t5[0x7] = B64_5(a[0x7]); \ + t6[0x7] = B64_6(a[0x7]); \ + t7[0x7] = B64_7(a[0x7]); \ + t0[0x8] = B64_0(a[0x8]); \ + t1[0x8] = B64_1(a[0x8]); \ + t2[0x8] = B64_2(a[0x8]); \ + t3[0x8] = B64_3(a[0x8]); \ + t4[0x8] = B64_4(a[0x8]); \ + t5[0x8] = B64_5(a[0x8]); \ + t6[0x8] = B64_6(a[0x8]); \ + t7[0x8] = B64_7(a[0x8]); \ + t0[0x9] = B64_0(a[0x9]); \ + t1[0x9] = B64_1(a[0x9]); \ + t2[0x9] = B64_2(a[0x9]); \ + t3[0x9] = B64_3(a[0x9]); \ + t4[0x9] = B64_4(a[0x9]); \ + t5[0x9] = B64_5(a[0x9]); \ + t6[0x9] = B64_6(a[0x9]); \ + t7[0x9] = B64_7(a[0x9]); \ + t0[0xA] = B64_0(a[0xA]); \ + t1[0xA] = B64_1(a[0xA]); \ + t2[0xA] = B64_2(a[0xA]); \ + t3[0xA] = B64_3(a[0xA]); \ + t4[0xA] = B64_4(a[0xA]); \ + t5[0xA] = B64_5(a[0xA]); \ + t6[0xA] = B64_6(a[0xA]); \ + t7[0xA] = B64_7(a[0xA]); \ + t0[0xB] = B64_0(a[0xB]); \ + t1[0xB] = B64_1(a[0xB]); \ + t2[0xB] = B64_2(a[0xB]); \ + t3[0xB] = B64_3(a[0xB]); \ + t4[0xB] = B64_4(a[0xB]); \ + t5[0xB] = B64_5(a[0xB]); \ + t6[0xB] = B64_6(a[0xB]); \ + t7[0xB] = B64_7(a[0xB]); \ + t0[0xC] = B64_0(a[0xC]); \ + t1[0xC] = B64_1(a[0xC]); \ + t2[0xC] = B64_2(a[0xC]); \ + t3[0xC] = B64_3(a[0xC]); \ + t4[0xC] = B64_4(a[0xC]); \ + t5[0xC] = B64_5(a[0xC]); \ + t6[0xC] = B64_6(a[0xC]); \ + t7[0xC] = B64_7(a[0xC]); \ + t0[0xD] = B64_0(a[0xD]); \ + t1[0xD] = B64_1(a[0xD]); \ + t2[0xD] = B64_2(a[0xD]); \ + t3[0xD] = B64_3(a[0xD]); \ + t4[0xD] = B64_4(a[0xD]); \ + t5[0xD] = B64_5(a[0xD]); \ + t6[0xD] = B64_6(a[0xD]); \ + t7[0xD] = B64_7(a[0xD]); \ + t0[0xE] = B64_0(a[0xE]); \ + t1[0xE] = B64_1(a[0xE]); \ + t2[0xE] = B64_2(a[0xE]); \ + t3[0xE] = B64_3(a[0xE]); \ + t4[0xE] = B64_4(a[0xE]); \ + t5[0xE] = B64_5(a[0xE]); \ + t6[0xE] = B64_6(a[0xE]); \ + t7[0xE] = B64_7(a[0xE]); \ + t0[0xF] = B64_0(a[0xF]); \ + t1[0xF] = B64_1(a[0xF]); \ + t2[0xF] = B64_2(a[0xF]); \ + t3[0xF] = B64_3(a[0xF]); \ + t4[0xF] = B64_4(a[0xF]); \ + t5[0xF] = B64_5(a[0xF]); \ + t6[0xF] = B64_6(a[0xF]); \ + t7[0xF] = B64_7(a[0xF]); \ + RBTT(a[0x0], 0x1, 0x3, 0x5, 0xB, 0x0, 0x2, 0x4, 0x6); \ + RBTT(a[0x1], 0x2, 0x4, 0x6, 0xC, 0x1, 0x3, 0x5, 0x7); \ + RBTT(a[0x2], 0x3, 0x5, 0x7, 0xD, 0x2, 0x4, 0x6, 0x8); \ + RBTT(a[0x3], 0x4, 0x6, 0x8, 0xE, 0x3, 0x5, 0x7, 0x9); \ + RBTT(a[0x4], 0x5, 0x7, 0x9, 0xF, 0x4, 0x6, 0x8, 0xA); \ + RBTT(a[0x5], 0x6, 0x8, 0xA, 0x0, 0x5, 0x7, 0x9, 0xB); \ + RBTT(a[0x6], 0x7, 0x9, 0xB, 0x1, 0x6, 0x8, 0xA, 0xC); \ + RBTT(a[0x7], 0x8, 0xA, 0xC, 0x2, 0x7, 0x9, 0xB, 0xD); \ + RBTT(a[0x8], 0x9, 0xB, 0xD, 0x3, 0x8, 0xA, 0xC, 0xE); \ + RBTT(a[0x9], 0xA, 0xC, 0xE, 0x4, 0x9, 0xB, 0xD, 0xF); \ + RBTT(a[0xA], 0xB, 0xD, 0xF, 0x5, 0xA, 0xC, 0xE, 0x0); \ + RBTT(a[0xB], 0xC, 0xE, 0x0, 0x6, 0xB, 0xD, 0xF, 0x1); \ + RBTT(a[0xC], 0xD, 0xF, 0x1, 0x7, 0xC, 0xE, 0x0, 0x2); \ + RBTT(a[0xD], 0xE, 0x0, 0x2, 0x8, 0xD, 0xF, 0x1, 0x3); \ + RBTT(a[0xE], 0xF, 0x1, 0x3, 0x9, 0xE, 0x0, 0x2, 0x4); \ + RBTT(a[0xF], 0x0, 0x2, 0x4, 0xA, 0xF, 0x1, 0x3, 0x5); \ + } while (0) + +#define PERM_BIG_P(a, start, end) do { \ + for (u = start; u < end; u++) { \ + ROUND_BIG_P(a, u); \ + } \ + } while (0) + +#define PERM_BIG_Q(a) do { \ + /* for (ulong u = 0; u < (14UL << 56); u += (1UL << 56)) { */ \ + for (u = 0; u < 14; u++) { \ + ROUND_BIG_Q(a, u); \ + } \ + } while (0) + + +__attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) +__kernel void search(__global unsigned char* block, volatile __global uint* output, const ulong target) { + __local ulong T2[256], T3[256], T4[256], T5[256], T6[256], T7[256]; + uint u; + + // for (u = get_local_id(0); u < 256; u += get_local_size(0)) { + u = get_local_id(0); + /* + T1[u] = T1_G[u]; + T2[u] = T2_G[u]; + T3[u] = T3_G[u]; + T4[u] = T4_G[u]; + T5[u] = T5_G[u]; + T6[u] = T6_G[u]; + T7[u] = T7_G[u]; + */ + // create other tables based on T0: avoids keeping them in the kernel. +// T1[u] = ROTL64(T0[u], 8UL); + T2[u] = ROTL64(T0[u], 16UL); + T3[u] = ROTL64(T0[u], 24UL); + T4[u] = ROTL64(T0[u], 32UL); + T5[u] = ROTL64(T0[u], 40UL); + T6[u] = ROTL64(T0[u], 48UL); + T7[u] = ROTL64(T0[u], 56UL); + barrier(CLK_LOCAL_MEM_FENCE); + + ulong g[16], m[16], t0[16], t1[16], t2[16], t3[16], t4[16], t5[16], t6[16], t7[16]; + uint flag = 0, gid = get_global_id(0), r = 13; + + m[0] = DEC64E(block + 0 * 8); + m[1] = DEC64E(block + 1 * 8); + m[2] = DEC64E(block + 2 * 8); + m[3] = DEC64E(block + 3 * 8); + m[4] = DEC64E(block + 4 * 8); + m[5] = DEC64E(block + 5 * 8); + m[6] = DEC64E(block + 6 * 8); + m[7] = DEC64E(block + 7 * 8); + m[8] = DEC64E(block + 8 * 8); + m[9] = DEC64E(block + 9 * 8); + m[9] &= 0x00000000FFFFFFFF; + m[9] |= ((ulong) gid << 32); + m[10] = 0x80; + +perm: + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = M15; + +#pragma unroll + for (u = 0; u < 15; u++) g[u] = m[u]; + g[15] = M15 ^ H15; + + + g[0x0] ^= PC64(0x00, 0); + g[0x1] ^= PC64(0x10, 0); + g[0x2] ^= PC64(0x20, 0); + g[0x3] ^= PC64(0x30, 0); + g[0x4] ^= PC64(0x40, 0); + g[0x5] ^= PC64(0x50, 0); + g[0x6] ^= PC64(0x60, 0); + g[0x7] ^= PC64(0x70, 0); + g[0x8] ^= PC64(0x80, 0); + g[0x9] ^= PC64(0x90, 0); + g[0xA] ^= PC64(0xA0, 0); + g[0xB] = PC64(0xB0, 0); + g[0xC] = PC64(0xC0, 0); + g[0xD] = PC64(0xD0, 0); + g[0xE] = PC64(0xE0, 0); + g[0xF] ^= PC64(0xF0, 0); + t0[0x0] = B64_0(g[0x0]); + t1[0x0] = B64_1(g[0x0]); + t2[0x0] = B64_2(g[0x0]); + t3[0x0] = B64_3(g[0x0]); + t4[0x0] = B64_4(g[0x0]); + t5[0x0] = B64_5(g[0x0]); + t6[0x0] = B64_6(g[0x0]); + t7[0x0] = B64_7(g[0x0]); + t0[0x1] = B64_0(g[0x1]); + t1[0x1] = B64_1(g[0x1]); + t2[0x1] = B64_2(g[0x1]); + t3[0x1] = B64_3(g[0x1]); + t4[0x1] = B64_4(g[0x1]); + t5[0x1] = B64_5(g[0x1]); + t6[0x1] = B64_6(g[0x1]); + t7[0x1] = B64_7(g[0x1]); + t0[0x2] = B64_0(g[0x2]); + t1[0x2] = B64_1(g[0x2]); + t2[0x2] = B64_2(g[0x2]); + t3[0x2] = B64_3(g[0x2]); + t4[0x2] = B64_4(g[0x2]); + t5[0x2] = B64_5(g[0x2]); + t6[0x2] = B64_6(g[0x2]); + t7[0x2] = B64_7(g[0x2]); + t0[0x3] = B64_0(g[0x3]); + t1[0x3] = B64_1(g[0x3]); + t2[0x3] = B64_2(g[0x3]); + t3[0x3] = B64_3(g[0x3]); + t4[0x3] = B64_4(g[0x3]); + t5[0x3] = B64_5(g[0x3]); + t6[0x3] = B64_6(g[0x3]); + t7[0x3] = B64_7(g[0x3]); + t0[0x4] = B64_0(g[0x4]); + t1[0x4] = B64_1(g[0x4]); + t2[0x4] = B64_2(g[0x4]); + t3[0x4] = B64_3(g[0x4]); + t4[0x4] = B64_4(g[0x4]); + t5[0x4] = B64_5(g[0x4]); + t6[0x4] = B64_6(g[0x4]); + t7[0x4] = B64_7(g[0x4]); + t0[0x5] = B64_0(g[0x5]); + t1[0x5] = B64_1(g[0x5]); + t2[0x5] = B64_2(g[0x5]); + t3[0x5] = B64_3(g[0x5]); + t4[0x5] = B64_4(g[0x5]); + t5[0x5] = B64_5(g[0x5]); + t6[0x5] = B64_6(g[0x5]); + t7[0x5] = B64_7(g[0x5]); + t0[0x6] = B64_0(g[0x6]); + t1[0x6] = B64_1(g[0x6]); + t2[0x6] = B64_2(g[0x6]); + t3[0x6] = B64_3(g[0x6]); + t4[0x6] = B64_4(g[0x6]); + t5[0x6] = B64_5(g[0x6]); + t6[0x6] = B64_6(g[0x6]); + t7[0x6] = B64_7(g[0x6]); + t0[0x7] = B64_0(g[0x7]); + t1[0x7] = B64_1(g[0x7]); + t2[0x7] = B64_2(g[0x7]); + t3[0x7] = B64_3(g[0x7]); + t4[0x7] = B64_4(g[0x7]); + t5[0x7] = B64_5(g[0x7]); + t6[0x7] = B64_6(g[0x7]); + t7[0x7] = B64_7(g[0x7]); + t0[0x8] = B64_0(g[0x8]); + t1[0x8] = B64_1(g[0x8]); + t2[0x8] = B64_2(g[0x8]); + t3[0x8] = B64_3(g[0x8]); + t4[0x8] = B64_4(g[0x8]); + t5[0x8] = B64_5(g[0x8]); + t6[0x8] = B64_6(g[0x8]); + t7[0x8] = B64_7(g[0x8]); + t0[0x9] = B64_0(g[0x9]); + t1[0x9] = B64_1(g[0x9]); + t2[0x9] = B64_2(g[0x9]); + t3[0x9] = B64_3(g[0x9]); + t4[0x9] = B64_4(g[0x9]); + t5[0x9] = B64_5(g[0x9]); + t6[0x9] = B64_6(g[0x9]); + t7[0x9] = B64_7(g[0x9]); + t0[0xA] = B64_0(g[0xA]); + t1[0xA] = B64_1(g[0xA]); + t2[0xA] = B64_2(g[0xA]); + t3[0xA] = B64_3(g[0xA]); + t4[0xA] = B64_4(g[0xA]); + t5[0xA] = B64_5(g[0xA]); + t6[0xA] = B64_6(g[0xA]); + t7[0xA] = B64_7(g[0xA]); + t0[0xB] = B64_0(g[0xB]); + t1[0xB] = B64_1(g[0xB]); + t2[0xB] = B64_2(g[0xB]); + t3[0xB] = B64_3(g[0xB]); + t4[0xB] = B64_4(g[0xB]); + t5[0xB] = B64_5(g[0xB]); + t6[0xB] = B64_6(g[0xB]); + t7[0xB] = B64_7(g[0xB]); + t0[0xC] = B64_0(g[0xC]); + t1[0xC] = B64_1(g[0xC]); + t2[0xC] = B64_2(g[0xC]); + t3[0xC] = B64_3(g[0xC]); + t4[0xC] = B64_4(g[0xC]); + t5[0xC] = B64_5(g[0xC]); + t6[0xC] = B64_6(g[0xC]); + t7[0xC] = B64_7(g[0xC]); + t0[0xD] = B64_0(g[0xD]); + t1[0xD] = B64_1(g[0xD]); + t2[0xD] = B64_2(g[0xD]); + t3[0xD] = B64_3(g[0xD]); + t4[0xD] = B64_4(g[0xD]); + t5[0xD] = B64_5(g[0xD]); + t6[0xD] = B64_6(g[0xD]); + t7[0xD] = B64_7(g[0xD]); + t0[0xE] = B64_0(g[0xE]); + t1[0xE] = B64_1(g[0xE]); + t2[0xE] = B64_2(g[0xE]); + t3[0xE] = B64_3(g[0xE]); + t4[0xE] = B64_4(g[0xE]); + t5[0xE] = B64_5(g[0xE]); + t6[0xE] = B64_6(g[0xE]); + t7[0xE] = B64_7(g[0xE]); + t0[0xF] = B64_0(g[0xF]); + t1[0xF] = B64_1(g[0xF]); + t2[0xF] = B64_2(g[0xF]); + t3[0xF] = B64_3(g[0xF]); + t4[0xF] = B64_4(g[0xF]); + t5[0xF] = B64_5(g[0xF]); + t6[0xF] = B64_6(g[0xF]); + t7[0xF] = B64_7(g[0xF]); + g[0x0] = T0[t0[0x0]] ^ T1[t1[0x1]] ^ T2[t2[0x2]] ^ T3[t3[0x3]] ^ T4[t4[0x4]] ^ T5[t5[0x5]] ^ T6[t6[0x6]] ^ C64e(0x32f4a5f497a5c6c6); + g[0x1] = T0[t0[0x1]] ^ T1[t1[0x2]] ^ T2[t2[0x3]] ^ T3[t3[0x4]] ^ T4[t4[0x5]] ^ T5[t5[0x6]] ^ T6[t6[0x7]] ^ C64e(0x32f4a5f497a5c6c6); + g[0x2] = T0[t0[0x2]] ^ T1[t1[0x3]] ^ T2[t2[0x4]] ^ T3[t3[0x5]] ^ T4[t4[0x6]] ^ T5[t5[0x7]] ^ T6[t6[0x8]] ^ C64e(0x32f4a5f497a5c6c6); + g[0x3] = T0[t0[0x3]] ^ T1[t1[0x4]] ^ T2[t2[0x5]] ^ T3[t3[0x6]] ^ T4[t4[0x7]] ^ T5[t5[0x8]] ^ T6[t6[0x9]] ^ C64e(0x32f4a5f497a5c6c6); + g[0x4] = T0[t0[0x4]] ^ T1[t1[0x5]] ^ T2[t2[0x6]] ^ T3[t3[0x7]] ^ T4[t4[0x8]] ^ T5[t5[0x9]] ^ C64e(0xf4a5f497a5c6c632) ^ T7[t7[0xF]]; + g[0x5] = T0[t0[0x5]] ^ T1[t1[0x6]] ^ T2[t2[0x7]] ^ T3[t3[0x8]] ^ T4[t4[0x9]] ^ C64e(0xa5f497a5c6c632f4) ^ C64e(0xf4a5f497a5c6c632) ^ T7[t7[0x0]]; + g[0x6] = T0[t0[0x6]] ^ T1[t1[0x7]] ^ T2[t2[0x8]] ^ T3[t3[0x9]] ^ C64e(0xf497a5c6c632f4a5) ^ C64e(0xa5f497a5c6c632f4) ^ C64e(0xf4a5f497a5c6c632) ^ T7[t7[0x1]]; + g[0x7] = T0[t0[0x7]] ^ T1[t1[0x8]] ^ T2[t2[0x9]] ^ C64e(0x97a5c6c632f4a5f4) ^ C64e(0xf497a5c6c632f4a5) ^ C64e(0xa5f497a5c6c632f4) ^ C64e(0xf4a5f497a5c6c632) ^ T7[t7[0x2]]; + g[0x8] = T0[t0[0x8]] ^ T1[t1[0x9]] ^ C64e(0xa5c6c632f4a5f497) ^ C64e(0x97a5c6c632f4a5f4) ^ C64e(0xf497a5c6c632f4a5) ^ C64e(0xa5f497a5c6c632f4) ^ C64e(0xf4a5f497a5c6c632) ^ T7[t7[0x3]]; + g[0x9] = T0[t0[0x9]] ^ C64e(0xc6c632f4a5f497a5) ^ C64e(0xa5c6c632f4a5f497) ^ C64e(0x97a5c6c632f4a5f4) ^ C64e(0xf497a5c6c632f4a5) ^ C64e(0xa5f497a5c6c632f4) ^ T6[t6[0xF]] ^ T7[t7[0x4]]; + g[0xA] = T0[t0[0xA]] ^ C64e(0xc6c632f4a5f497a5) ^ C64e(0xa5c6c632f4a5f497) ^ C64e(0x97a5c6c632f4a5f4) ^ C64e(0xf497a5c6c632f4a5) ^ T5[t5[0xF]] ^ T6[t6[0x0]] ^ T7[t7[0x5]]; + g[0xB] = T0[t0[0xB]] ^ C64e(0xc6c632f4a5f497a5) ^ C64e(0xa5c6c632f4a5f497) ^ C64e(0x97a5c6c632f4a5f4) ^ T4[t4[0xF]] ^ T5[t5[0x0]] ^ T6[t6[0x1]] ^ T7[t7[0x6]]; + g[0xC] = T0[t0[0xC]] ^ C64e(0xc6c632f4a5f497a5) ^ C64e(0xa5c6c632f4a5f497) ^ T3[t3[0xF]] ^ T4[t4[0x0]] ^ T5[t5[0x1]] ^ T6[t6[0x2]] ^ T7[t7[0x7]]; + g[0xD] = T0[t0[0xD]] ^ C64e(0xc6c632f4a5f497a5) ^ T2[t2[0xF]] ^ T3[t3[0x0]] ^ T4[t4[0x1]] ^ T5[t5[0x2]] ^ T6[t6[0x3]] ^ T7[t7[0x8]]; + g[0xE] = T0[t0[0xE]] ^ T1[t1[0xF]] ^ T2[t2[0x0]] ^ T3[t3[0x1]] ^ T4[t4[0x2]] ^ T5[t5[0x3]] ^ T6[t6[0x4]] ^ T7[t7[0x9]]; + g[0xF] = T0[t0[0xF]] ^ T1[t1[0x0]] ^ T2[t2[0x1]] ^ T3[t3[0x2]] ^ T4[t4[0x3]] ^ T5[t5[0x4]] ^ T6[t6[0x5]] ^ T7[t7[0xA]]; + + + PERM_BIG_P(g, 1, 14); + PERM_BIG_Q(m); + +#pragma unroll + for (u = 0; u < 16; u++) g[u] ^= m[u]; +#pragma unroll + for (u = 0; u < 8; u++) m[u] = g[u + 8]; + g[15] ^= H15; + PERM_BIG_P(g, 0, r); + +round: +// move the ^= to the relevant first byte down here? tried that, was slower?!?!? + g[0x0] ^= PC64(0x00, r); + g[0x1] ^= PC64(0x10, r); + g[0x6] ^= PC64(0x60, r); + g[0xB] ^= PC64(0xB0, r); + g[0xC] ^= PC64(0xC0, r); + g[0xD] ^= PC64(0xD0, r); + g[0xE] ^= PC64(0xE0, r); + g[0xF] ^= PC64(0xF0, r); + t0[0x0] = B64_0(g[0x0]); + t1[0x0] = B64_1(g[0x0]); + t2[0x0] = B64_2(g[0x0]); + t3[0x0] = B64_3(g[0x0]); + t4[0x0] = B64_4(g[0x0]); + t5[0x0] = B64_5(g[0x0]); + t6[0x0] = B64_6(g[0x0]); + t7[0x0] = B64_7(g[0x0]); + t0[0x1] = B64_0(g[0x1]); + t1[0x1] = B64_1(g[0x1]); + t2[0x1] = B64_2(g[0x1]); + t3[0x1] = B64_3(g[0x1]); + t4[0x1] = B64_4(g[0x1]); + t5[0x1] = B64_5(g[0x1]); + t6[0x1] = B64_6(g[0x1]); + t7[0x1] = B64_7(g[0x1]); + t0[0x6] = B64_0(g[0x6]); + t1[0x6] = B64_1(g[0x6]); + t2[0x6] = B64_2(g[0x6]); + t3[0x6] = B64_3(g[0x6]); + t4[0x6] = B64_4(g[0x6]); + t5[0x6] = B64_5(g[0x6]); + t6[0x6] = B64_6(g[0x6]); + t7[0x6] = B64_7(g[0x6]); + t0[0xB] = B64_0(g[0xB]); + t1[0xB] = B64_1(g[0xB]); + t2[0xB] = B64_2(g[0xB]); + t3[0xB] = B64_3(g[0xB]); + t4[0xB] = B64_4(g[0xB]); + t5[0xB] = B64_5(g[0xB]); + t6[0xB] = B64_6(g[0xB]); + t7[0xB] = B64_7(g[0xB]); + t0[0xC] = B64_0(g[0xC]); + t1[0xC] = B64_1(g[0xC]); + t2[0xC] = B64_2(g[0xC]); + t3[0xC] = B64_3(g[0xC]); + t4[0xC] = B64_4(g[0xC]); + t5[0xC] = B64_5(g[0xC]); + t6[0xC] = B64_6(g[0xC]); + t7[0xC] = B64_7(g[0xC]); + t0[0xD] = B64_0(g[0xD]); + t1[0xD] = B64_1(g[0xD]); + t2[0xD] = B64_2(g[0xD]); + t3[0xD] = B64_3(g[0xD]); + t4[0xD] = B64_4(g[0xD]); + t5[0xD] = B64_5(g[0xD]); + t6[0xD] = B64_6(g[0xD]); + t7[0xD] = B64_7(g[0xD]); + t0[0xE] = B64_0(g[0xE]); + t1[0xE] = B64_1(g[0xE]); + t2[0xE] = B64_2(g[0xE]); + t3[0xE] = B64_3(g[0xE]); + t4[0xE] = B64_4(g[0xE]); + t5[0xE] = B64_5(g[0xE]); + t6[0xE] = B64_6(g[0xE]); + t7[0xE] = B64_7(g[0xE]); + t0[0xF] = B64_0(g[0xF]); + t1[0xF] = B64_1(g[0xF]); + t2[0xF] = B64_2(g[0xF]); + t3[0xF] = B64_3(g[0xF]); + t4[0xF] = B64_4(g[0xF]); + t5[0xF] = B64_5(g[0xF]); + t6[0xF] = B64_6(g[0xF]); + t7[0xF] = B64_7(g[0xF]); + + if (flag < 2) { + g[0x2] ^= PC64(0x20, r); + g[0x3] ^= PC64(0x30, r); + g[0x4] ^= PC64(0x40, r); + g[0x5] ^= PC64(0x50, r); + g[0x7] ^= PC64(0x70, r); + g[0x8] ^= PC64(0x80, r); + g[0x9] ^= PC64(0x90, r); + g[0xA] ^= PC64(0xA0, r); + t0[0x2] = B64_0(g[0x2]); + t1[0x2] = B64_1(g[0x2]); + t2[0x2] = B64_2(g[0x2]); + t3[0x2] = B64_3(g[0x2]); + t4[0x2] = B64_4(g[0x2]); + t5[0x2] = B64_5(g[0x2]); + t6[0x2] = B64_6(g[0x2]); + t7[0x2] = B64_7(g[0x2]); + t0[0x3] = B64_0(g[0x3]); + t1[0x3] = B64_1(g[0x3]); + t2[0x3] = B64_2(g[0x3]); + t3[0x3] = B64_3(g[0x3]); + t4[0x3] = B64_4(g[0x3]); + t5[0x3] = B64_5(g[0x3]); + t6[0x3] = B64_6(g[0x3]); + t7[0x3] = B64_7(g[0x3]); + t0[0x4] = B64_0(g[0x4]); + t1[0x4] = B64_1(g[0x4]); + t2[0x4] = B64_2(g[0x4]); + t3[0x4] = B64_3(g[0x4]); + t4[0x4] = B64_4(g[0x4]); + t5[0x4] = B64_5(g[0x4]); + t6[0x4] = B64_6(g[0x4]); + t7[0x4] = B64_7(g[0x4]); + t0[0x5] = B64_0(g[0x5]); + t1[0x5] = B64_1(g[0x5]); + t2[0x5] = B64_2(g[0x5]); + t3[0x5] = B64_3(g[0x5]); + t4[0x5] = B64_4(g[0x5]); + t5[0x5] = B64_5(g[0x5]); + t6[0x5] = B64_6(g[0x5]); + t7[0x5] = B64_7(g[0x5]); + t0[0x7] = B64_0(g[0x7]); + t1[0x7] = B64_1(g[0x7]); + t2[0x7] = B64_2(g[0x7]); + t3[0x7] = B64_3(g[0x7]); + t4[0x7] = B64_4(g[0x7]); + t5[0x7] = B64_5(g[0x7]); + t6[0x7] = B64_6(g[0x7]); + t7[0x7] = B64_7(g[0x7]); + t0[0x8] = B64_0(g[0x8]); + t1[0x8] = B64_1(g[0x8]); + t2[0x8] = B64_2(g[0x8]); + t3[0x8] = B64_3(g[0x8]); + t4[0x8] = B64_4(g[0x8]); + t5[0x8] = B64_5(g[0x8]); + t6[0x8] = B64_6(g[0x8]); + t7[0x8] = B64_7(g[0x8]); + t0[0x9] = B64_0(g[0x9]); + t1[0x9] = B64_1(g[0x9]); + t2[0x9] = B64_2(g[0x9]); + t3[0x9] = B64_3(g[0x9]); + t4[0x9] = B64_4(g[0x9]); + t5[0x9] = B64_5(g[0x9]); + t6[0x9] = B64_6(g[0x9]); + t7[0x9] = B64_7(g[0x9]); + t0[0xA] = B64_0(g[0xA]); + t1[0xA] = B64_1(g[0xA]); + t2[0xA] = B64_2(g[0xA]); + t3[0xA] = B64_3(g[0xA]); + t4[0xA] = B64_4(g[0xA]); + t5[0xA] = B64_5(g[0xA]); + t6[0xA] = B64_6(g[0xA]); + t7[0xA] = B64_7(g[0xA]); + if (flag == 0) { + RBTT(g[0x8], 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0x3); + RBTT(g[0x9], 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x4); + RBTT(g[0xA], 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x0, 0x5); + } else { + RBTT(g[0x0], 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0xB); + RBTT(g[0x1], 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0xC); + RBTT(g[0x6], 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0x1); + } + RBTT(g[0xC], 0xC, 0xD, 0xE, 0xF, 0x0, 0x1, 0x2, 0x7); + RBTT(g[0xD], 0xD, 0xE, 0xF, 0x0, 0x1, 0x2, 0x3, 0x8); + RBTT(g[0xE], 0xE, 0xF, 0x0, 0x1, 0x2, 0x3, 0x4, 0x9); + RBTT(g[0xF], 0xF, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0xA); + } + RBTT(g[0xB], 0xB, 0xC, 0xD, 0xE, 0xF, 0x0, 0x1, 0x6); + + if (flag == 2) goto end; + if (flag++ == 1) { + r = 13; + goto round; + } + + r = 12; +#pragma unroll + for (u = 0; u < 8; u++) m[u] ^= g[u + 8]; + m[7] ^= H15; + m[8] = 0x80; + m[9] = 0; + m[10] = 0; + goto perm; + +end: + if ((g[3 + 8] ^ m[3]) <= target) output[output[0xFF]++] = as_uint(as_uchar4(gid).wzyx); +} + +#endif + diff --git a/kernel/skein256.cl b/kernel/skein256.cl index 8a5e8481f..afbe75719 100644 --- a/kernel/skein256.cl +++ b/kernel/skein256.cl @@ -68,9 +68,7 @@ __constant static const sph_u64 t12[6] = 0xff00000000000000UL, 0xff00000000000008UL }; -static inline ulong ROTL64(const ulong v, const ulong n){ - return rotate(v,n); -} + #define Round512(p0,p1,p2,p3,p4,p5,p6,p7,ROT) { \ p0 += p1; p1 = SPH_ROTL64(p1, ROT256[ROT][0]); p1 ^= p0; \ From 94a1e1b6a947b5fbe081bc1d2ca441589c5a4cbc Mon Sep 17 00:00:00 2001 From: djm34 Date: Tue, 23 Dec 2014 17:28:01 +0100 Subject: [PATCH 08/27] change the difficulty adjustment to 128 instead of 256 --- algorithm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/algorithm.c b/algorithm.c index 2e2241529..e2d44be4a 100644 --- a/algorithm.c +++ b/algorithm.c @@ -753,7 +753,7 @@ static algorithm_settings_t algos[] = { { "fresh", ALGO_FRESH, "", 1, 256, 256, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 4, 4 * 16 * 4194304, 0, fresh_regenhash, queue_fresh_kernel, gen_hash, NULL}, - { "Lyra2RE", ALGO_LYRA2RE, "", 1, 256, 256, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 4,2 * 8 * 4194304 , 0, lyra2re_regenhash, queue_lyra2RE_kernel, gen_hash, NULL}, + { "Lyra2RE", ALGO_LYRA2RE, "", 1, 128, 128, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 4,2 * 8 * 4194304 , 0, lyra2re_regenhash, queue_lyra2RE_kernel, gen_hash, NULL}, // kernels starting from this will have difficulty calculated by using fuguecoin algorithm #define A_FUGUE(a, b, c) \ From cdae391248915793467dffd619bb7bc7a5dae36f Mon Sep 17 00:00:00 2001 From: djm34 Date: Sun, 22 Feb 2015 16:55:14 +0100 Subject: [PATCH 09/27] pluck algo --- Makefile.am | 1 + algorithm.c | 35 +++- algorithm.h | 3 +- algorithm/pluck.c | 482 ++++++++++++++++++++++++++++++++++++++++++++++ algorithm/pluck.h | 10 + kernel/pluck.cl | 463 ++++++++++++++++++++++++++++++++++++++++++++ ocl.c | 102 +++++++++- sgminer.c | 2 +- 8 files changed, 1092 insertions(+), 6 deletions(-) create mode 100644 algorithm/pluck.c create mode 100644 algorithm/pluck.h create mode 100644 kernel/pluck.cl diff --git a/Makefile.am b/Makefile.am index f70986b5b..35eb9ca38 100644 --- a/Makefile.am +++ b/Makefile.am @@ -68,6 +68,7 @@ sgminer_SOURCES += algorithm/x14.c algorithm/x14.h sgminer_SOURCES += algorithm/fresh.c algorithm/fresh.h sgminer_SOURCES += algorithm/whirlcoin.c algorithm/whirlcoin.h sgminer_SOURCES += algorithm/neoscrypt.c algorithm/neoscrypt.h +sgminer_SOURCES += algorithm/pluck.c algorithm/pluck.h sgminer_SOURCES += algorithm/Lyra2RE.c algorithm/Lyra2RE.h algorithm/Lyra2.c algorithm/Lyra2.h algorithm/Sponge.c algorithm/Sponge.h bin_SCRIPTS = $(top_srcdir)/kernel/*.cl diff --git a/algorithm.c b/algorithm.c index e2d44be4a..ca2419139 100644 --- a/algorithm.c +++ b/algorithm.c @@ -32,6 +32,7 @@ #include "algorithm/whirlcoin.h" #include "algorithm/neoscrypt.h" #include "algorithm/Lyra2RE.h" +#include "algorithm/pluck.h" #include "compat.h" @@ -54,7 +55,8 @@ const char *algorithm_type_str[] = { "Fresh", "Whirlcoin", "Neoscrypt", - "Lyra2RE" + "Lyra2RE", + "pluck" }; void sha256(const unsigned char *message, unsigned int len, unsigned char *digest) @@ -180,6 +182,29 @@ static cl_int queue_neoscrypt_kernel(_clState *clState, dev_blk_ctx *blk, __mayb return status; } +static cl_int queue_pluck_kernel(_clState *clState, dev_blk_ctx *blk, __maybe_unused cl_uint threads) +{ + cl_kernel *kernel = &clState->kernel; + unsigned int num = 0; + cl_uint le_target; + cl_int status = 0; + + +// le_target = (*(cl_uint *)(blk->work->device_target + 28)); + le_target = (cl_uint)le32toh(((uint32_t *)blk->work->/*device_*/target)[7]); +// memcpy(clState->cldata, blk->work->data, 80); + flip80(clState->cldata, blk->work->data); + status = clEnqueueWriteBuffer(clState->commandQueue, clState->CLbuffer0, true, 0, 80, clState->cldata, 0, NULL, NULL); + + CL_SET_ARG(clState->CLbuffer0); + CL_SET_ARG(clState->outputBuffer); + CL_SET_ARG(clState->padbuffer8); + CL_SET_ARG(le_target); + + return status; +} + + static cl_int queue_maxcoin_kernel(struct __clState *clState, struct _dev_blk_ctx *blk, __maybe_unused cl_uint threads) { cl_kernel *kernel = &clState->kernel; @@ -717,6 +742,12 @@ static algorithm_settings_t algos[] = { A_NEOSCRYPT("neoscrypt"), #undef A_NEOSCRYPT +#define A_PLUCK(a) \ + { a, ALGO_PLUCK, "", 1, 65536, 65536, 0, 0, 0xFF, 0xFFFF000000000000ULL, 0x0000ffffUL, 0, -1, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, pluck_regenhash, queue_pluck_kernel, gen_hash, append_neoscrypt_compiler_options} + A_PLUCK("pluck"), +#undef A_PLUCK + + // kernels starting from this will have difficulty calculated by using quarkcoin algorithm #define A_QUARK(a, b) \ { a, ALGO_QUARK, "", 256, 256, 256, 0, 0, 0xFF, 0xFFFFFFULL, 0x0000ffffUL, 0, 0, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, b, queue_sph_kernel, gen_hash, append_x11_compiler_options} @@ -753,7 +784,7 @@ static algorithm_settings_t algos[] = { { "fresh", ALGO_FRESH, "", 1, 256, 256, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 4, 4 * 16 * 4194304, 0, fresh_regenhash, queue_fresh_kernel, gen_hash, NULL}, - { "Lyra2RE", ALGO_LYRA2RE, "", 1, 128, 128, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 4,2 * 8 * 4194304 , 0, lyra2re_regenhash, queue_lyra2RE_kernel, gen_hash, NULL}, + { "Lyra2RE", ALGO_LYRA2RE, "", 1, 256, 256, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 4,2 * 8 * 4194304 , 0, lyra2re_regenhash, queue_lyra2RE_kernel, gen_hash, NULL}, // kernels starting from this will have difficulty calculated by using fuguecoin algorithm #define A_FUGUE(a, b, c) \ diff --git a/algorithm.h b/algorithm.h index a121be198..99f1a5827 100644 --- a/algorithm.h +++ b/algorithm.h @@ -26,7 +26,8 @@ typedef enum { ALGO_FRESH, ALGO_WHIRL, ALGO_NEOSCRYPT, - ALGO_LYRA2RE + ALGO_LYRA2RE, + ALGO_PLUCK } algorithm_type_t; extern const char *algorithm_type_str[]; diff --git a/algorithm/pluck.c b/algorithm/pluck.c new file mode 100644 index 000000000..093dd68ee --- /dev/null +++ b/algorithm/pluck.c @@ -0,0 +1,482 @@ +/*- + * Copyright 2014 James Lovejoy + * Copyright 2014 phm + * 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 "config.h" +#include "miner.h" + +#include +#include +#include + + + +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]) + + +/* +* 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]; +} + +/* + * Encode a length len/4 vector of (uint32_t) into a length len vector of + * (unsigned char) in big-endian form. Assumes len is a multiple of 4. + */ +static inline void +be32enc_vect(uint32_t *dst, const uint32_t *src, uint32_t len) +{ + uint32_t i; + + for (i = 0; i < len; i++) + dst[i] = htobe32(src[i]); +} +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 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)); +} +#define ROTL(a, b) (((a) << (b)) | ((a) >> (32 - (b)))) +//note, this is 64 bytes +static inline void xor_salsa8(uint32_t B[16], const uint32_t Bx[16]) +{ +#define ROTL(a, b) (((a) << (b)) | ((a) >> (32 - (b)))) + uint32_t x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10, x11, x12, x13, x14, x15; + int i; + + x00 = (B[0] ^= Bx[0]); + x01 = (B[1] ^= Bx[1]); + x02 = (B[2] ^= Bx[2]); + x03 = (B[3] ^= Bx[3]); + x04 = (B[4] ^= Bx[4]); + x05 = (B[5] ^= Bx[5]); + x06 = (B[6] ^= Bx[6]); + x07 = (B[7] ^= Bx[7]); + x08 = (B[8] ^= Bx[8]); + x09 = (B[9] ^= Bx[9]); + x10 = (B[10] ^= Bx[10]); + x11 = (B[11] ^= Bx[11]); + x12 = (B[12] ^= Bx[12]); + x13 = (B[13] ^= Bx[13]); + x14 = (B[14] ^= Bx[14]); + x15 = (B[15] ^= Bx[15]); + for (i = 0; i < 8; i += 2) { + /* Operate on columns. */ + x04 ^= ROTL(x00 + x12, 7); x09 ^= ROTL(x05 + x01, 7); + x14 ^= ROTL(x10 + x06, 7); x03 ^= ROTL(x15 + x11, 7); + + x08 ^= ROTL(x04 + x00, 9); x13 ^= ROTL(x09 + x05, 9); + x02 ^= ROTL(x14 + x10, 9); x07 ^= ROTL(x03 + x15, 9); + + x12 ^= ROTL(x08 + x04, 13); x01 ^= ROTL(x13 + x09, 13); + x06 ^= ROTL(x02 + x14, 13); x11 ^= ROTL(x07 + x03, 13); + + x00 ^= ROTL(x12 + x08, 18); x05 ^= ROTL(x01 + x13, 18); + x10 ^= ROTL(x06 + x02, 18); x15 ^= ROTL(x11 + x07, 18); + + /* Operate on rows. */ + x01 ^= ROTL(x00 + x03, 7); x06 ^= ROTL(x05 + x04, 7); + x11 ^= ROTL(x10 + x09, 7); x12 ^= ROTL(x15 + x14, 7); + + x02 ^= ROTL(x01 + x00, 9); x07 ^= ROTL(x06 + x05, 9); + x08 ^= ROTL(x11 + x10, 9); x13 ^= ROTL(x12 + x15, 9); + + x03 ^= ROTL(x02 + x01, 13); x04 ^= ROTL(x07 + x06, 13); + x09 ^= ROTL(x08 + x11, 13); x14 ^= ROTL(x13 + x12, 13); + + x00 ^= ROTL(x03 + x02, 18); x05 ^= ROTL(x04 + x07, 18); + x10 ^= ROTL(x09 + x08, 18); x15 ^= ROTL(x14 + x13, 18); + } + B[0] += x00; + B[1] += x01; + B[2] += x02; + B[3] += x03; + B[4] += x04; + B[5] += x05; + B[6] += x06; + B[7] += x07; + B[8] += x08; + B[9] += x09; + B[10] += x10; + B[11] += x11; + B[12] += x12; + B[13] += x13; + B[14] += x14; + B[15] += x15; +#undef ROTL +} + +void sha256_hash(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); + } + for (i = 0; i < 8; i++) + be32enc((uint32_t *)hash + i, S[i]); +} + +void sha256_hash512(unsigned char *hash, const unsigned char *data) +{ + uint32_t S[16], T[16]; + int i; + + sha256_init(S); + + memcpy(T, data, 64); + + for (i = 0; i < 16; i++) + T[i] = be32dec(T + i); + sha256_transform(S, T, 0); + + memset(T, 0, 64); + //memcpy(T, data + 64, 0); + ((unsigned char *)T)[0] = 0x80; + for (i = 0; i < 16; i++) + T[i] = be32dec(T + i); + T[15] = 8 * 64; + sha256_transform(S, T, 0); + + for (i = 0; i < 8; i++) + be32enc((uint32_t *)hash + i, S[i]); +} + +inline void pluckrehash(void *state, const void *input) +{ + + int i,j; + uint32_t data[20]; + + const int HASH_MEMORY = 128 * 1024; + uint8_t * scratchbuf = (uint8_t*)malloc(HASH_MEMORY); + memcpy(data,input,80); + + uint8_t hashbuffer[128*1024]; //don't allocate this on stack, since it's huge.. + int size = HASH_MEMORY; + memset(hashbuffer, 0, 64); + sha256_hash(&hashbuffer[0], (uint8_t*)data, 80); + for (i = 64; i < size - 32; i += 32) + { + int randmax = i - 4; //we could use size here, but then it's probable to use 0 as the value in most cases + uint32_t joint[16]; + uint32_t randbuffer[16]; + + uint32_t randseed[16]; + memcpy(randseed, &hashbuffer[i - 64], 64); + if (i>128) + { + memcpy(randbuffer, &hashbuffer[i - 128], 64); + } + else + { + memset(&randbuffer, 0, 64); + } + + xor_salsa8(randbuffer, randseed); + + memcpy(joint, &hashbuffer[i - 32], 32); + //use the last hash value as the seed + for (j = 32; j < 64; j += 4) + { + uint32_t rand = randbuffer[(j - 32) / 4] % (randmax - 32); + joint[j / 4] = *((uint32_t*)&hashbuffer[rand]); + + } + sha256_hash512(&hashbuffer[i], (uint8_t*)joint); + + memcpy(randseed, &hashbuffer[i - 32], 64); + if (i>128) + { + memcpy(randbuffer, &hashbuffer[i - 128], 64); + } + else + { + memset(randbuffer, 0, 64); + } + xor_salsa8(randbuffer, randseed); + for (j = 0; j < 32; j += 2) + { + uint32_t rand = randbuffer[j / 2] % randmax; + *((uint32_t*)&hashbuffer[rand]) = *((uint32_t*)&hashbuffer[j + i - 4]); + } + } + + + //printf("cpu hashbuffer %08x nonce %08x\n", ((uint32_t*)hashbuffer)[7],data[19]); + + memcpy(state, hashbuffer, 32); +} + +static const uint32_t diff1targ = 0x0000ffff; + + +/* Used externally as confirmation of correct OCL code */ +int pluck_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t nonce) +{ + uint32_t tmp_hash7, Htarg = le32toh(((const uint32_t *)ptarget)[7]); + uint32_t data[20], ohash[8]; + + be32enc_vect(data, (const uint32_t *)pdata, 19); + data[19] = htobe32(nonce); + pluckrehash(ohash, data); + + tmp_hash7 = be32toh(ohash[7]); + + applog(LOG_DEBUG, "htarget %08lx diff1 %08lx hash %08lx", + (long unsigned int)Htarg, + (long unsigned int)diff1targ, + (long unsigned int)tmp_hash7); + + if (tmp_hash7 > diff1targ) + return -1; + + if (tmp_hash7 > Htarg) + return 0; + + return 1; +} + +void pluck_regenhash(struct work *work) +{ + uint32_t data[20]; + uint32_t *nonce = (uint32_t *)(work->data + 76); + uint32_t *ohash = (uint32_t *)(work->hash); + + be32enc_vect(data, (const uint32_t *)work->data, 19); + data[19] = htobe32(*nonce); + + pluckrehash(ohash, data); +} + + +bool scanhash_pluck(struct thr_info *thr, const unsigned char __maybe_unused *pmidstate, + unsigned char *pdata, unsigned char __maybe_unused *phash1, + unsigned char __maybe_unused *phash, const unsigned char *ptarget, + uint32_t max_nonce, uint32_t *last_nonce, uint32_t n) +{ + uint32_t *nonce = (uint32_t *)(pdata + 76); + uint32_t data[20]; + uint32_t tmp_hash7; + uint32_t Htarg = le32toh(((const uint32_t *)ptarget)[7]); + bool ret = false; + + be32enc_vect(data, (const uint32_t *)pdata, 19); + + while (1) + { + uint32_t ostate[8]; + + *nonce = ++n; + data[19] = (n); + pluckrehash(ostate, data); + tmp_hash7 = (ostate[7]); + + applog(LOG_INFO, "data7 %08lx", (long unsigned int)data[7]); + + if (unlikely(tmp_hash7 <= Htarg)) + { + ((uint32_t *)pdata)[19] = htobe32(n); + *last_nonce = n; + ret = true; + break; + } + + if (unlikely((n >= max_nonce) || thr->work_restart)) + { + *last_nonce = n; + break; + } + } + + return ret; +} \ No newline at end of file diff --git a/algorithm/pluck.h b/algorithm/pluck.h new file mode 100644 index 000000000..7582554e3 --- /dev/null +++ b/algorithm/pluck.h @@ -0,0 +1,10 @@ +#ifndef PLUCK_H +#define PLUCK_H + +#include "miner.h" +#define PLUCK_SCRATCHBUF_SIZE (128 * 1024) +extern int pluck_test(unsigned char *pdata, const unsigned char *ptarget, + uint32_t nonce); +extern void pluck_regenhash(struct work *work); + +#endif /* PLUCK_H */ diff --git a/kernel/pluck.cl b/kernel/pluck.cl new file mode 100644 index 000000000..4fa501c76 --- /dev/null +++ b/kernel/pluck.cl @@ -0,0 +1,463 @@ +/* +* "pluck" kernel implementation. +* +* ==========================(LICENSE BEGIN)============================ +* +* Copyright (c) 2015 djm34 +* +* 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 djm34 +*/ +#if !defined(cl_khr_byte_addressable_store) +#error "Device does not support unaligned stores" +#endif +#define ROL32(x, n) rotate(x, (uint) n) +//#define ROL32(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) +#define HASH_MEMORY 4096 + + +#define SALSA(a,b,c,d) do { \ + t =a+d; b^=rotate(t, 7U); \ + t =b+a; c^=rotate(t, 9U); \ + t =c+b; d^=rotate(t, 13U); \ + t =d+c; a^=rotate(t, 18U); \ +} while(0) + + +#define SALSA_CORE(state) do { \ +\ +SALSA(state.s0,state.s4,state.s8,state.sc); \ +SALSA(state.s5,state.s9,state.sd,state.s1); \ +SALSA(state.sa,state.se,state.s2,state.s6); \ +SALSA(state.sf,state.s3,state.s7,state.sb); \ +SALSA(state.s0,state.s1,state.s2,state.s3); \ +SALSA(state.s5,state.s6,state.s7,state.s4); \ +SALSA(state.sa,state.sb,state.s8,state.s9); \ +SALSA(state.sf,state.sc,state.sd,state.se); \ + } while(0) + +/* +#define SALSA_CORE(state) do { \ + state.s4 ^= rotate(state.s0 + state.sc, 7U); state.s8 ^= rotate(state.s4 + state.s0, 9U); state.sc ^= rotate(state.s8 + state.s4, 13U); state.s0 ^= rotate(state.sc + state.s8, 18U); \ + state.s9 ^= rotate(state.s5 + state.s1, 7U); state.sd ^= rotate(state.s9 + state.s5, 9U); state.s1 ^= rotate(state.sd + state.s9, 13U); state.s5 ^= rotate(state.s1 + state.sd, 18U); \ + state.se ^= rotate(state.sa + state.s6, 7U); state.s2 ^= rotate(state.se + state.sa, 9U); state.s6 ^= rotate(state.s2 + state.se, 13U); state.sa ^= rotate(state.s6 + state.s2, 18U); \ + state.s3 ^= rotate(state.sf + state.sb, 7U); state.s7 ^= rotate(state.s3 + state.sf, 9U); state.sb ^= rotate(state.s7 + state.s3, 13U); state.sf ^= rotate(state.sb + state.s7, 18U); \ + state.s1 ^= rotate(state.s0 + state.s3, 7U); state.s2 ^= rotate(state.s1 + state.s0, 9U); state.s3 ^= rotate(state.s2 + state.s1, 13U); state.s0 ^= rotate(state.s3 + state.s2, 18U); \ + state.s6 ^= rotate(state.s5 + state.s4, 7U); state.s7 ^= rotate(state.s6 + state.s5, 9U); state.s4 ^= rotate(state.s7 + state.s6, 13U); state.s5 ^= rotate(state.s4 + state.s7, 18U); \ + state.sb ^= rotate(state.sa + state.s9, 7U); state.s8 ^= rotate(state.sb + state.sa, 9U); state.s9 ^= rotate(state.s8 + state.sb, 13U); state.sa ^= rotate(state.s9 + state.s8, 18U); \ + state.sc ^= rotate(state.sf + state.se, 7U); state.sd ^= rotate(state.sc + state.sf, 9U); state.se ^= rotate(state.sd + state.sc, 13U); state.sf ^= rotate(state.se + state.sd, 18U); \ +} while(0) +*/ +uint16 xor_salsa8(uint16 Bx) +{ +uint t; + uint16 st = Bx; + SALSA_CORE(st); + SALSA_CORE(st); + SALSA_CORE(st); + SALSA_CORE(st); + return(st + Bx); +} + + + +#define SHR(x, n) ((x) >> n) +#define SWAP32(a) (as_uint(as_uchar4(a).wzyx)) + +#define S0(x) (ROL32(x, 25) ^ ROL32(x, 14) ^ SHR(x, 3)) +#define S1(x) (ROL32(x, 15) ^ ROL32(x, 13) ^ SHR(x, 10)) + +#define S2(x) (ROL32(x, 30) ^ ROL32(x, 19) ^ ROL32(x, 10)) +#define S3(x) (ROL32(x, 26) ^ ROL32(x, 21) ^ ROL32(x, 7)) + +#define P(a,b,c,d,e,f,g,h,x,K) \ +{ \ + temp1 = h + S3(e) + F1(e,f,g) + (K + x); \ + d += temp1; h = temp1 + S2(a) + F0(a,b,c); \ +} + +#define PLAST(a,b,c,d,e,f,g,h,x,K) \ +{ \ + d += h + S3(e) + F1(e,f,g) + (x + K); \ +} + +#define F0(y, x, z) bitselect(z, y, z ^ x) +#define F1(x, y, z) bitselect(z, y, x) + +#define R0 (W0 = S1(W14) + W9 + S0(W1) + W0) +#define R1 (W1 = S1(W15) + W10 + S0(W2) + W1) +#define R2 (W2 = S1(W0) + W11 + S0(W3) + W2) +#define R3 (W3 = S1(W1) + W12 + S0(W4) + W3) +#define R4 (W4 = S1(W2) + W13 + S0(W5) + W4) +#define R5 (W5 = S1(W3) + W14 + S0(W6) + W5) +#define R6 (W6 = S1(W4) + W15 + S0(W7) + W6) +#define R7 (W7 = S1(W5) + W0 + S0(W8) + W7) +#define R8 (W8 = S1(W6) + W1 + S0(W9) + W8) +#define R9 (W9 = S1(W7) + W2 + S0(W10) + W9) +#define R10 (W10 = S1(W8) + W3 + S0(W11) + W10) +#define R11 (W11 = S1(W9) + W4 + S0(W12) + W11) +#define R12 (W12 = S1(W10) + W5 + S0(W13) + W12) +#define R13 (W13 = S1(W11) + W6 + S0(W14) + W13) +#define R14 (W14 = S1(W12) + W7 + S0(W15) + W14) +#define R15 (W15 = S1(W13) + W8 + S0(W0) + W15) + +#define RD14 (S1(W12) + W7 + S0(W15) + W14) +#define RD15 (S1(W13) + W8 + S0(W0) + W15) + +inline uint8 sha256_round1(uint16 data) +{ + uint temp1; + uint8 res; + uint W0 = SWAP32(data.s0); + uint W1 = SWAP32(data.s1); + uint W2 = SWAP32(data.s2); + uint W3 = SWAP32(data.s3); + uint W4 = SWAP32(data.s4); + uint W5 = SWAP32(data.s5); + uint W6 = SWAP32(data.s6); + uint W7 = SWAP32(data.s7); + uint W8 = SWAP32(data.s8); + uint W9 = SWAP32(data.s9); + uint W10 = SWAP32(data.sA); + uint W11 = SWAP32(data.sB); + uint W12 = SWAP32(data.sC); + uint W13 = SWAP32(data.sD); + uint W14 = SWAP32(data.sE); + uint W15 = SWAP32(data.sF); + + uint v0 = 0x6A09E667; + uint v1 = 0xBB67AE85; + uint v2 = 0x3C6EF372; + uint v3 = 0xA54FF53A; + uint v4 = 0x510E527F; + uint v5 = 0x9B05688C; + uint v6 = 0x1F83D9AB; + uint v7 = 0x5BE0CD19; + + P(v0, v1, v2, v3, v4, v5, v6, v7, W0, 0x428A2F98); + P(v7, v0, v1, v2, v3, v4, v5, v6, W1, 0x71374491); + P(v6, v7, v0, v1, v2, v3, v4, v5, W2, 0xB5C0FBCF); + P(v5, v6, v7, v0, v1, v2, v3, v4, W3, 0xE9B5DBA5); + P(v4, v5, v6, v7, v0, v1, v2, v3, W4, 0x3956C25B); + P(v3, v4, v5, v6, v7, v0, v1, v2, W5, 0x59F111F1); + P(v2, v3, v4, v5, v6, v7, v0, v1, W6, 0x923F82A4); + P(v1, v2, v3, v4, v5, v6, v7, v0, W7, 0xAB1C5ED5); + P(v0, v1, v2, v3, v4, v5, v6, v7, W8, 0xD807AA98); + P(v7, v0, v1, v2, v3, v4, v5, v6, W9, 0x12835B01); + P(v6, v7, v0, v1, v2, v3, v4, v5, W10, 0x243185BE); + P(v5, v6, v7, v0, v1, v2, v3, v4, W11, 0x550C7DC3); + P(v4, v5, v6, v7, v0, v1, v2, v3, W12, 0x72BE5D74); + P(v3, v4, v5, v6, v7, v0, v1, v2, W13, 0x80DEB1FE); + P(v2, v3, v4, v5, v6, v7, v0, v1, W14, 0x9BDC06A7); + P(v1, v2, v3, v4, v5, v6, v7, v0, W15, 0xC19BF174); + + P(v0, v1, v2, v3, v4, v5, v6, v7, R0, 0xE49B69C1); + P(v7, v0, v1, v2, v3, v4, v5, v6, R1, 0xEFBE4786); + P(v6, v7, v0, v1, v2, v3, v4, v5, R2, 0x0FC19DC6); + P(v5, v6, v7, v0, v1, v2, v3, v4, R3, 0x240CA1CC); + P(v4, v5, v6, v7, v0, v1, v2, v3, R4, 0x2DE92C6F); + P(v3, v4, v5, v6, v7, v0, v1, v2, R5, 0x4A7484AA); + P(v2, v3, v4, v5, v6, v7, v0, v1, R6, 0x5CB0A9DC); + P(v1, v2, v3, v4, v5, v6, v7, v0, R7, 0x76F988DA); + P(v0, v1, v2, v3, v4, v5, v6, v7, R8, 0x983E5152); + P(v7, v0, v1, v2, v3, v4, v5, v6, R9, 0xA831C66D); + P(v6, v7, v0, v1, v2, v3, v4, v5, R10, 0xB00327C8); + P(v5, v6, v7, v0, v1, v2, v3, v4, R11, 0xBF597FC7); + P(v4, v5, v6, v7, v0, v1, v2, v3, R12, 0xC6E00BF3); + P(v3, v4, v5, v6, v7, v0, v1, v2, R13, 0xD5A79147); + P(v2, v3, v4, v5, v6, v7, v0, v1, R14, 0x06CA6351); + P(v1, v2, v3, v4, v5, v6, v7, v0, R15, 0x14292967); + + P(v0, v1, v2, v3, v4, v5, v6, v7, R0, 0x27B70A85); + P(v7, v0, v1, v2, v3, v4, v5, v6, R1, 0x2E1B2138); + P(v6, v7, v0, v1, v2, v3, v4, v5, R2, 0x4D2C6DFC); + P(v5, v6, v7, v0, v1, v2, v3, v4, R3, 0x53380D13); + P(v4, v5, v6, v7, v0, v1, v2, v3, R4, 0x650A7354); + P(v3, v4, v5, v6, v7, v0, v1, v2, R5, 0x766A0ABB); + P(v2, v3, v4, v5, v6, v7, v0, v1, R6, 0x81C2C92E); + P(v1, v2, v3, v4, v5, v6, v7, v0, R7, 0x92722C85); + P(v0, v1, v2, v3, v4, v5, v6, v7, R8, 0xA2BFE8A1); + P(v7, v0, v1, v2, v3, v4, v5, v6, R9, 0xA81A664B); + P(v6, v7, v0, v1, v2, v3, v4, v5, R10, 0xC24B8B70); + P(v5, v6, v7, v0, v1, v2, v3, v4, R11, 0xC76C51A3); + P(v4, v5, v6, v7, v0, v1, v2, v3, R12, 0xD192E819); + P(v3, v4, v5, v6, v7, v0, v1, v2, R13, 0xD6990624); + P(v2, v3, v4, v5, v6, v7, v0, v1, R14, 0xF40E3585); + P(v1, v2, v3, v4, v5, v6, v7, v0, R15, 0x106AA070); + + P(v0, v1, v2, v3, v4, v5, v6, v7, R0, 0x19A4C116); + P(v7, v0, v1, v2, v3, v4, v5, v6, R1, 0x1E376C08); + P(v6, v7, v0, v1, v2, v3, v4, v5, R2, 0x2748774C); + P(v5, v6, v7, v0, v1, v2, v3, v4, R3, 0x34B0BCB5); + P(v4, v5, v6, v7, v0, v1, v2, v3, R4, 0x391C0CB3); + P(v3, v4, v5, v6, v7, v0, v1, v2, R5, 0x4ED8AA4A); + P(v2, v3, v4, v5, v6, v7, v0, v1, R6, 0x5B9CCA4F); + P(v1, v2, v3, v4, v5, v6, v7, v0, R7, 0x682E6FF3); + P(v0, v1, v2, v3, v4, v5, v6, v7, R8, 0x748F82EE); + P(v7, v0, v1, v2, v3, v4, v5, v6, R9, 0x78A5636F); + P(v6, v7, v0, v1, v2, v3, v4, v5, R10, 0x84C87814); + P(v5, v6, v7, v0, v1, v2, v3, v4, R11, 0x8CC70208); + P(v4, v5, v6, v7, v0, v1, v2, v3, R12, 0x90BEFFFA); + P(v3, v4, v5, v6, v7, v0, v1, v2, R13, 0xA4506CEB); + P(v2, v3, v4, v5, v6, v7, v0, v1, RD14, 0xBEF9A3F7); + P(v1, v2, v3, v4, v5, v6, v7, v0, RD15, 0xC67178F2); + + res.s0 = v0 + 0x6A09E667; + res.s1 = v1 + 0xBB67AE85; + res.s2 = v2 + 0x3C6EF372; + res.s3 = v3 + 0xA54FF53A; + res.s4 = v4 + 0x510E527F; + res.s5 = v5 + 0x9B05688C; + res.s6 = v6 + 0x1F83D9AB; + res.s7 = v7 + 0x5BE0CD19; + return (res); +} + + +inline uint8 sha256_round2(uint16 data,uint8 buf) +{ + uint temp1; + uint8 res; + uint W0 = data.s0; + uint W1 = data.s1; + uint W2 = data.s2; + uint W3 = data.s3; + uint W4 = data.s4; + uint W5 = data.s5; + uint W6 = data.s6; + uint W7 = data.s7; + uint W8 = data.s8; + uint W9 = data.s9; + uint W10 = data.sA; + uint W11 = data.sB; + uint W12 = data.sC; + uint W13 = data.sD; + uint W14 = data.sE; + uint W15 = data.sF; + + uint v0 = buf.s0; + uint v1 = buf.s1; + uint v2 = buf.s2; + uint v3 = buf.s3; + uint v4 = buf.s4; + uint v5 = buf.s5; + uint v6 = buf.s6; + uint v7 = buf.s7; + + P(v0, v1, v2, v3, v4, v5, v6, v7, W0, 0x428A2F98); + P(v7, v0, v1, v2, v3, v4, v5, v6, W1, 0x71374491); + P(v6, v7, v0, v1, v2, v3, v4, v5, W2, 0xB5C0FBCF); + P(v5, v6, v7, v0, v1, v2, v3, v4, W3, 0xE9B5DBA5); + P(v4, v5, v6, v7, v0, v1, v2, v3, W4, 0x3956C25B); + P(v3, v4, v5, v6, v7, v0, v1, v2, W5, 0x59F111F1); + P(v2, v3, v4, v5, v6, v7, v0, v1, W6, 0x923F82A4); + P(v1, v2, v3, v4, v5, v6, v7, v0, W7, 0xAB1C5ED5); + P(v0, v1, v2, v3, v4, v5, v6, v7, W8, 0xD807AA98); + P(v7, v0, v1, v2, v3, v4, v5, v6, W9, 0x12835B01); + P(v6, v7, v0, v1, v2, v3, v4, v5, W10, 0x243185BE); + P(v5, v6, v7, v0, v1, v2, v3, v4, W11, 0x550C7DC3); + P(v4, v5, v6, v7, v0, v1, v2, v3, W12, 0x72BE5D74); + P(v3, v4, v5, v6, v7, v0, v1, v2, W13, 0x80DEB1FE); + P(v2, v3, v4, v5, v6, v7, v0, v1, W14, 0x9BDC06A7); + P(v1, v2, v3, v4, v5, v6, v7, v0, W15, 0xC19BF174); + + P(v0, v1, v2, v3, v4, v5, v6, v7, R0, 0xE49B69C1); + P(v7, v0, v1, v2, v3, v4, v5, v6, R1, 0xEFBE4786); + P(v6, v7, v0, v1, v2, v3, v4, v5, R2, 0x0FC19DC6); + P(v5, v6, v7, v0, v1, v2, v3, v4, R3, 0x240CA1CC); + P(v4, v5, v6, v7, v0, v1, v2, v3, R4, 0x2DE92C6F); + P(v3, v4, v5, v6, v7, v0, v1, v2, R5, 0x4A7484AA); + P(v2, v3, v4, v5, v6, v7, v0, v1, R6, 0x5CB0A9DC); + P(v1, v2, v3, v4, v5, v6, v7, v0, R7, 0x76F988DA); + P(v0, v1, v2, v3, v4, v5, v6, v7, R8, 0x983E5152); + P(v7, v0, v1, v2, v3, v4, v5, v6, R9, 0xA831C66D); + P(v6, v7, v0, v1, v2, v3, v4, v5, R10, 0xB00327C8); + P(v5, v6, v7, v0, v1, v2, v3, v4, R11, 0xBF597FC7); + P(v4, v5, v6, v7, v0, v1, v2, v3, R12, 0xC6E00BF3); + P(v3, v4, v5, v6, v7, v0, v1, v2, R13, 0xD5A79147); + P(v2, v3, v4, v5, v6, v7, v0, v1, R14, 0x06CA6351); + P(v1, v2, v3, v4, v5, v6, v7, v0, R15, 0x14292967); + + P(v0, v1, v2, v3, v4, v5, v6, v7, R0, 0x27B70A85); + P(v7, v0, v1, v2, v3, v4, v5, v6, R1, 0x2E1B2138); + P(v6, v7, v0, v1, v2, v3, v4, v5, R2, 0x4D2C6DFC); + P(v5, v6, v7, v0, v1, v2, v3, v4, R3, 0x53380D13); + P(v4, v5, v6, v7, v0, v1, v2, v3, R4, 0x650A7354); + P(v3, v4, v5, v6, v7, v0, v1, v2, R5, 0x766A0ABB); + P(v2, v3, v4, v5, v6, v7, v0, v1, R6, 0x81C2C92E); + P(v1, v2, v3, v4, v5, v6, v7, v0, R7, 0x92722C85); + P(v0, v1, v2, v3, v4, v5, v6, v7, R8, 0xA2BFE8A1); + P(v7, v0, v1, v2, v3, v4, v5, v6, R9, 0xA81A664B); + P(v6, v7, v0, v1, v2, v3, v4, v5, R10, 0xC24B8B70); + P(v5, v6, v7, v0, v1, v2, v3, v4, R11, 0xC76C51A3); + P(v4, v5, v6, v7, v0, v1, v2, v3, R12, 0xD192E819); + P(v3, v4, v5, v6, v7, v0, v1, v2, R13, 0xD6990624); + P(v2, v3, v4, v5, v6, v7, v0, v1, R14, 0xF40E3585); + P(v1, v2, v3, v4, v5, v6, v7, v0, R15, 0x106AA070); + + P(v0, v1, v2, v3, v4, v5, v6, v7, R0, 0x19A4C116); + P(v7, v0, v1, v2, v3, v4, v5, v6, R1, 0x1E376C08); + P(v6, v7, v0, v1, v2, v3, v4, v5, R2, 0x2748774C); + P(v5, v6, v7, v0, v1, v2, v3, v4, R3, 0x34B0BCB5); + P(v4, v5, v6, v7, v0, v1, v2, v3, R4, 0x391C0CB3); + P(v3, v4, v5, v6, v7, v0, v1, v2, R5, 0x4ED8AA4A); + P(v2, v3, v4, v5, v6, v7, v0, v1, R6, 0x5B9CCA4F); + P(v1, v2, v3, v4, v5, v6, v7, v0, R7, 0x682E6FF3); + P(v0, v1, v2, v3, v4, v5, v6, v7, R8, 0x748F82EE); + P(v7, v0, v1, v2, v3, v4, v5, v6, R9, 0x78A5636F); + P(v6, v7, v0, v1, v2, v3, v4, v5, R10, 0x84C87814); + P(v5, v6, v7, v0, v1, v2, v3, v4, R11, 0x8CC70208); + P(v4, v5, v6, v7, v0, v1, v2, v3, R12, 0x90BEFFFA); + P(v3, v4, v5, v6, v7, v0, v1, v2, R13, 0xA4506CEB); + P(v2, v3, v4, v5, v6, v7, v0, v1, RD14, 0xBEF9A3F7); + P(v1, v2, v3, v4, v5, v6, v7, v0, RD15, 0xC67178F2); + + res.s0 = SWAP32(v0 + buf.s0); + res.s1 = SWAP32(v1 + buf.s1); + res.s2 = SWAP32(v2 + buf.s2); + res.s3 = SWAP32(v3 + buf.s3); + res.s4 = SWAP32(v4 + buf.s4); + res.s5 = SWAP32(v5 + buf.s5); + res.s6 = SWAP32(v6 + buf.s6); + res.s7 = SWAP32(v7 + buf.s7); + return (res); +} + +inline uint8 sha256_80(uint* data,uint nonce) +{ + +uint8 buf = sha256_round1( ((uint16*)data)[0]); +uint in[16]; +for (int i = 0; i<3; i++) { in[i] = SWAP32(data[i + 16]); } +in[3] = SWAP32(nonce); +in[4] = 0x80000000; +in[15] = 0x280; +for (int i = 5; i<15; i++) { in[i] = 0; } + +return(sha256_round2(((uint16*)in)[0], buf)); +} + +inline uint8 sha256_64(uint* data) +{ + +uint8 buf=sha256_round1(((uint16*)data)[0]); +uint in[16]; +for (int i = 1; i<15; i++) { in[i] = 0; } +in[0] = 0x80000000; +in[15] = 0x200; + + return(sha256_round2(((uint16*)in)[0],buf)); +} + + +__attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) +__kernel void search(__global const uchar* restrict input, __global uint* restrict output, __global uchar *padcache, const uint target) +{ + + __global uchar *hashbuffer = (__global uchar *)(padcache + (1024*128 * (get_global_id(0) % MAX_GLOBAL_THREADS))); + + uint data[20]; + + ((uint16 *)data)[0] = ((__global const uint16 *)input)[0]; + ((uint4 *)data)[4] = ((__global const uint4 *)input)[4]; + + ((__global uint8*)hashbuffer)[0] = sha256_80(data,get_global_id(0)); + ((__global uint8*)hashbuffer)[1] = 0; + + for (int i = 2; i < 4096 - 1; i++) + { + uint randmax = i * 32 - 4; + uint randseed[16]; + uint randbuffer[16]; + uint joint[16]; + + ((uint8*)randseed)[0] = ((__global uint8*)hashbuffer)[i - 2]; + ((uint8*)randseed)[1] = ((__global uint8*)hashbuffer)[i - 1]; + + if (i>4) + { + + ((uint8*)randseed)[0] ^= ((__global uint8*)hashbuffer)[i - 4]; + ((uint8*)randseed)[1] ^= ((__global uint8*)hashbuffer)[i - 3]; + } + + ((uint16*)randbuffer)[0] = xor_salsa8(((uint16*)randseed)[0]); + + + + ((uint8*)joint)[0] = ((__global uint8*)hashbuffer)[i - 1]; + for (int j = 0; j < 8; j++) + { + uint rand = randbuffer[j] % (randmax - 32); + + ((uchar4*)joint)[(j + 8)].x =((__global uchar*)(hashbuffer))[0+rand]; + ((uchar4*)joint)[(j + 8)].y =((__global uchar*)(hashbuffer))[1+rand]; + ((uchar4*)joint)[(j + 8)].z =((__global uchar*)(hashbuffer))[2+rand]; + ((uchar4*)joint)[(j + 8)].w =((__global uchar*)(hashbuffer))[3+rand]; +} + ((__global uint8*)(hashbuffer))[i] = sha256_64(joint); + + + + (( uint8*)randseed)[0] = ((__global uint8*)(hashbuffer))[i - 1]; + (( uint8*)randseed)[1] = ((__global uint8*)(hashbuffer))[i]; + + + if (i>4) + { + + ((uint8*)randseed)[0] ^= ((__global uint8*)(hashbuffer))[i - 4]; + ((uint8*)randseed)[1] ^= ((__global uint8*)(hashbuffer))[i - 3]; + + } + + ((uint16*)randbuffer)[0] = xor_salsa8(((uint16*)randseed)[0]); + + for (int j = 0; j < 32; j += 2) + { + uint rand = randbuffer[j / 2] % randmax; + uchar4 Tohere; + + Tohere.x = ((__global uchar*)(hashbuffer))[randmax + j]; + Tohere.y = ((__global uchar*)(hashbuffer))[randmax + j + 1]; + Tohere.z = ((__global uchar*)(hashbuffer))[randmax + j + 2]; + Tohere.w = ((__global uchar*)(hashbuffer))[randmax + j + 3]; + ((__global uchar*)(hashbuffer))[rand] = Tohere.x; + ((__global uchar*)(hashbuffer))[rand+1] = Tohere.y; + ((__global uchar*)(hashbuffer))[rand+2] = Tohere.z; + ((__global uchar*)(hashbuffer))[rand+3] = Tohere.w; + + } + + } // main loop + + + if( ((__global uint *)hashbuffer)[7] <= (target)) {output[atomic_inc(output + 0xFF)] = SWAP32(get_global_id(0)); +//printf("gpu hashbuffer %08x nonce %08x\n",((__global uint *)hashbuffer)[7] ,SWAP32(get_global_id(0))); +} + + + +///////////////////////////////////////////////////////////////// + +} \ No newline at end of file diff --git a/ocl.c b/ocl.c index 1d624e317..441a8a39c 100644 --- a/ocl.c +++ b/ocl.c @@ -35,6 +35,7 @@ #include "ocl/build_kernel.h" #include "ocl/binary_kernel.h" #include "algorithm/neoscrypt.h" +#include "algorithm/pluck.h" /* FIXME: only here for global config vars, replace with configuration.h * or similar as soon as config is in a struct instead of littered all @@ -429,7 +430,92 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize, algorithm_t *alg applog(LOG_DEBUG, "GPU %d: computing max. global thread count to %u", gpu, (unsigned)(cgpu->thread_concurrency)); - } else if (!cgpu->opt_tc) { + } +/////////////////////////////////// pluck + // neoscrypt TC + else if (!safe_cmp(cgpu->algorithm.name, "pluck") && !cgpu->opt_tc) { + size_t glob_thread_count; + long max_int; + unsigned char type = 0; + + // determine which intensity type to use + if (cgpu->rawintensity > 0) { + glob_thread_count = cgpu->rawintensity; + max_int = glob_thread_count; + type = 2; + } + else if (cgpu->xintensity > 0) { + glob_thread_count = clState->compute_shaders * ((cgpu->algorithm.xintensity_shift) ? (1UL << (cgpu->algorithm.xintensity_shift + cgpu->xintensity)) : cgpu->xintensity); + max_int = cgpu->xintensity; + type = 1; + } + else { + glob_thread_count = 1UL << (cgpu->algorithm.intensity_shift + cgpu->intensity); + max_int = ((cgpu->dynamic) ? MAX_INTENSITY : cgpu->intensity); + } + + glob_thread_count = ((glob_thread_count < cgpu->work_size) ? cgpu->work_size : glob_thread_count); + + // if TC * scratchbuf size is too big for memory... reduce to max + if ((glob_thread_count * PLUCK_SCRATCHBUF_SIZE) >= (uint64_t)cgpu->max_alloc) { + + /* Selected intensity will not run on this GPU. Not enough memory. + * Adapt the memory setting. */ + // depending on intensity type used, reduce the intensity until it fits into the GPU max_alloc + switch (type) { + //raw intensity + case 2: + while ((glob_thread_count * PLUCK_SCRATCHBUF_SIZE) > (uint64_t)cgpu->max_alloc) { + --glob_thread_count; + } + + max_int = glob_thread_count; + cgpu->rawintensity = glob_thread_count; + break; + + //x intensity + case 1: + glob_thread_count = cgpu->max_alloc / PLUCK_SCRATCHBUF_SIZE; + max_int = glob_thread_count / clState->compute_shaders; + + while (max_int && ((clState->compute_shaders * (1UL << max_int)) > glob_thread_count)) { + --max_int; + } + + /* Check if max_intensity is >0. */ + if (max_int < MIN_XINTENSITY) { + applog(LOG_ERR, "GPU %d: Max xintensity is below minimum.", gpu); + max_int = MIN_XINTENSITY; + } + + cgpu->xintensity = max_int; + glob_thread_count = clState->compute_shaders * (1UL << max_int); + break; + + default: + glob_thread_count = cgpu->max_alloc / PLUCK_SCRATCHBUF_SIZE; + while (max_int && ((1UL << max_int) & glob_thread_count) == 0) { + --max_int; + } + + /* Check if max_intensity is >0. */ + if (max_int < MIN_INTENSITY) { + applog(LOG_ERR, "GPU %d: Max intensity is below minimum.", gpu); + max_int = MIN_INTENSITY; + } + + cgpu->intensity = max_int; + glob_thread_count = 1UL << max_int; + break; + } + } + + // TC is glob thread count + cgpu->thread_concurrency = glob_thread_count; + + applog(LOG_DEBUG, "GPU %d: computing max. global thread count to %u", gpu, (unsigned)(cgpu->thread_concurrency)); + + } else if (!cgpu->opt_tc) { unsigned int sixtyfours; sixtyfours = cgpu->max_alloc / 131072 / 64 / (algorithm->n/1024) - 1; @@ -546,7 +632,19 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize, algorithm_t *alg applog(LOG_DEBUG, "Neoscrypt buffer sizes: %lu RW, %lu R", (unsigned long)bufsize, (unsigned long)readbufsize); // scrypt/n-scrypt - } else { + } + else if (!safe_cmp(algorithm->name, "pluck")) { + /* The scratch/pad-buffer needs 32kBytes memory per thread. */ + bufsize = PLUCK_SCRATCHBUF_SIZE * cgpu->thread_concurrency; + + /* This is the input buffer. For pluck this is guaranteed to be + * 80 bytes only. */ + readbufsize = 80; + + applog(LOG_DEBUG, "pluck buffer sizes: %lu RW, %lu R", (unsigned long)bufsize, (unsigned long)readbufsize); + // scrypt/n-scrypt + } + else { size_t ipt = (algorithm->n / cgpu->lookup_gap + (algorithm->n % cgpu->lookup_gap > 0)); bufsize = 128 * ipt * cgpu->thread_concurrency; applog(LOG_DEBUG, "Scrypt buffer sizes: %lu RW, %lu R", (unsigned long)bufsize, (unsigned long)readbufsize); diff --git a/sgminer.c b/sgminer.c index 97f4fae33..28b16d308 100644 --- a/sgminer.c +++ b/sgminer.c @@ -7081,7 +7081,7 @@ bool test_nonce(struct work *work, uint32_t nonce) rebuild_nonce(work, nonce); // for Neoscrypt, the diff1targ value is in work->target - if (!safe_cmp(work->pool->algorithm.name, "neoscrypt")) { + if (!safe_cmp(work->pool->algorithm.name, "neoscrypt") || !safe_cmp(work->pool->algorithm.name, "pluck")) { diff1targ = ((uint32_t *)work->target)[7]; } else { From 3eccf326a338ada4717c2d9c69b8aec303b5ba3d Mon Sep 17 00:00:00 2001 From: djm34 Date: Fri, 1 May 2015 04:32:54 +0200 Subject: [PATCH 10/27] first version supporting yescrypt algo this is a temporary kernel a somewhat faster should be implemented soon --- Makefile.am | 1 + algorithm.c | 79 +- algorithm.h | 3 +- algorithm/pluck.h | 2 + algorithm/sysendian.h | 140 ++++ algorithm/yescrypt-opt.c | 1364 ++++++++++++++++++++++++++++++++++ algorithm/yescrypt.c | 128 ++++ algorithm/yescrypt.h | 10 + algorithm/yescrypt_core.h | 376 ++++++++++ algorithm/yescryptcommon.c | 360 +++++++++ example.bat | 13 +- kernel/yescrypt.cl | 271 +++++++ kernel/yescrypt_essential.cl | 746 +++++++++++++++++++ miner.h | 4 +- ocl.c | 123 ++- ocl.h | 3 + sgminer.c | 6 +- sph/Makefile.am | 2 +- sph/sha256_Y.c | 418 +++++++++++ sph/sha256_Y.h | 63 ++ 20 files changed, 4099 insertions(+), 13 deletions(-) create mode 100644 algorithm/sysendian.h create mode 100644 algorithm/yescrypt-opt.c create mode 100644 algorithm/yescrypt.c create mode 100644 algorithm/yescrypt.h create mode 100644 algorithm/yescrypt_core.h create mode 100644 algorithm/yescryptcommon.c create mode 100644 kernel/yescrypt.cl create mode 100644 kernel/yescrypt_essential.cl create mode 100644 sph/sha256_Y.c create mode 100644 sph/sha256_Y.h diff --git a/Makefile.am b/Makefile.am index 35eb9ca38..716a68813 100644 --- a/Makefile.am +++ b/Makefile.am @@ -70,6 +70,7 @@ sgminer_SOURCES += algorithm/whirlcoin.c algorithm/whirlcoin.h sgminer_SOURCES += algorithm/neoscrypt.c algorithm/neoscrypt.h sgminer_SOURCES += algorithm/pluck.c algorithm/pluck.h sgminer_SOURCES += algorithm/Lyra2RE.c algorithm/Lyra2RE.h algorithm/Lyra2.c algorithm/Lyra2.h algorithm/Sponge.c algorithm/Sponge.h +sgminer_SOURCES += algorithm/yescrypt.h algorithm/yescrypt.c algorithm/yescrypt_core.h algorithm/yescrypt-opt.c algorithm/yescryptcommon.c algorithm/sysendian.h bin_SCRIPTS = $(top_srcdir)/kernel/*.cl diff --git a/algorithm.c b/algorithm.c index ca2419139..57df5634c 100644 --- a/algorithm.c +++ b/algorithm.c @@ -33,6 +33,7 @@ #include "algorithm/neoscrypt.h" #include "algorithm/Lyra2RE.h" #include "algorithm/pluck.h" +#include "algorithm/yescrypt.h" #include "compat.h" @@ -56,7 +57,8 @@ const char *algorithm_type_str[] = { "Whirlcoin", "Neoscrypt", "Lyra2RE", - "pluck" + "pluck", + "yescrypt" }; void sha256(const unsigned char *message, unsigned int len, unsigned char *digest) @@ -205,6 +207,71 @@ static cl_int queue_pluck_kernel(_clState *clState, dev_blk_ctx *blk, __maybe_un } +static cl_int queue_yescrypt_kernel(_clState *clState, dev_blk_ctx *blk, __maybe_unused cl_uint threads) +{ + cl_kernel *kernel = &clState->kernel; + unsigned int num = 0; + cl_uint le_target; + cl_int status = 0; + + + // le_target = (*(cl_uint *)(blk->work->device_target + 28)); + le_target = (cl_uint)le32toh(((uint32_t *)blk->work->/*device_*/target)[7]); + // memcpy(clState->cldata, blk->work->data, 80); + flip80(clState->cldata, blk->work->data); + status = clEnqueueWriteBuffer(clState->commandQueue, clState->CLbuffer0, true, 0, 80, clState->cldata, 0, NULL, NULL); + + CL_SET_ARG(clState->CLbuffer0); + CL_SET_ARG(clState->outputBuffer); + CL_SET_ARG(clState->padbuffer8); + CL_SET_ARG(clState->buffer1); + CL_SET_ARG(le_target); + + return status; +} + +static cl_int queue_yescrypt_multikernel(_clState *clState, dev_blk_ctx *blk, __maybe_unused cl_uint threads) +{ +// cl_kernel *kernel = &clState->kernel; + cl_kernel *kernel; + unsigned int num = 0; + cl_uint le_target; + cl_int status = 0; + + + // le_target = (*(cl_uint *)(blk->work->device_target + 28)); + le_target = (cl_uint)le32toh(((uint32_t *)blk->work->/*device_*/target)[7]); + // memcpy(clState->cldata, blk->work->data, 80); + flip80(clState->cldata, blk->work->data); + status = clEnqueueWriteBuffer(clState->commandQueue, clState->CLbuffer0, true, 0, 80, clState->cldata, 0, NULL, NULL); +//pbkdf and initial sha + kernel = &clState->kernel; + CL_SET_ARG_0(clState->CLbuffer0); + CL_SET_ARG(clState->buffer2); + CL_SET_ARG(clState->buffer3); +//mix1_1 (salsa) + num = 0; + kernel = clState->extra_kernels; + CL_SET_ARG_0(clState->buffer1); + CL_SET_ARG(clState->buffer2); +//mix1_2/2_2 (pwxform) + CL_NEXTKERNEL_SET_ARG_0(clState->padbuffer8); + CL_SET_ARG(clState->buffer1); + CL_SET_ARG(clState->buffer2); +//mix2_2 +// CL_NEXTKERNEL_SET_ARG_0(clState->padbuffer8); +// CL_SET_ARG(clState->buffer1); +// CL_SET_ARG(clState->buffer2); +//pbkdf and finalization + CL_NEXTKERNEL_SET_ARG_0(clState->CLbuffer0); + CL_SET_ARG(clState->outputBuffer); + CL_SET_ARG(clState->buffer2); + CL_SET_ARG(clState->buffer3); + CL_SET_ARG(le_target); + + return status; +} + static cl_int queue_maxcoin_kernel(struct __clState *clState, struct _dev_blk_ctx *blk, __maybe_unused cl_uint threads) { cl_kernel *kernel = &clState->kernel; @@ -747,6 +814,16 @@ static algorithm_settings_t algos[] = { A_PLUCK("pluck"), #undef A_PLUCK +#define A_YESCRYPT(a) \ + { a, ALGO_YESCRYPT, "", 1, 65536, 65536, 0, 0, 0xFF, 0xFFFF000000000000ULL, 0x0000ffffUL, 0, -1, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, yescrypt_regenhash, queue_yescrypt_kernel, gen_hash, append_neoscrypt_compiler_options} + A_YESCRYPT("yescrypt"), +#undef A_YESCRYPT + +//#define A_YESCRYPT(a) \ +// { a, ALGO_YESCRYPT, "", 1, 65536, 65536, 0, 0, 0xFF, 0xFFFF000000000000ULL, 0x0000ffffUL, 3, -1,CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE , yescrypt_regenhash, queue_yescrypt_multikernel, gen_hash, append_neoscrypt_compiler_options} +// A_YESCRYPT("yescrypt"), +//#undef A_YESCRYPT + // kernels starting from this will have difficulty calculated by using quarkcoin algorithm #define A_QUARK(a, b) \ diff --git a/algorithm.h b/algorithm.h index 99f1a5827..2e072f0dd 100644 --- a/algorithm.h +++ b/algorithm.h @@ -27,7 +27,8 @@ typedef enum { ALGO_WHIRL, ALGO_NEOSCRYPT, ALGO_LYRA2RE, - ALGO_PLUCK + ALGO_PLUCK, + ALGO_YESCRYPT } algorithm_type_t; extern const char *algorithm_type_str[]; diff --git a/algorithm/pluck.h b/algorithm/pluck.h index 7582554e3..619eb0137 100644 --- a/algorithm/pluck.h +++ b/algorithm/pluck.h @@ -3,6 +3,8 @@ #include "miner.h" #define PLUCK_SCRATCHBUF_SIZE (128 * 1024) +#define PLUCK_SECBUF_SIZE (64 * 1024) + extern int pluck_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t nonce); extern void pluck_regenhash(struct work *work); diff --git a/algorithm/sysendian.h b/algorithm/sysendian.h new file mode 100644 index 000000000..31ac985fb --- /dev/null +++ b/algorithm/sysendian.h @@ -0,0 +1,140 @@ +/*- + * Copyright 2007-2009 Colin Percival + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file was originally written by Colin Percival as part of the Tarsnap + * online backup system. + */ +#ifndef _SYSENDIAN_H_ +#define _SYSENDIAN_H_ + +/* If we don't have be64enc, the we have isn't usable. */ +#if !HAVE_DECL_BE64ENC +#undef HAVE_SYS_ENDIAN_H +#endif + +#ifdef HAVE_SYS_ENDIAN_H + +#include + +#else + +#include + +#if !HAVE_DECL_LE32DEC +static 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)); +} +#endif + +#if !HAVE_DECL_BE32ENC +static 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 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 + +#if !HAVE_DECL_LE32ENC +static 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 + +static uint64_t +be64dec(const void *pp) +{ + const uint8_t *p = (uint8_t const *)pp; + + return ((uint64_t)(p[7]) + ((uint64_t)(p[6]) << 8) + + ((uint64_t)(p[5]) << 16) + ((uint64_t)(p[4]) << 24) + + ((uint64_t)(p[3]) << 32) + ((uint64_t)(p[2]) << 40) + + ((uint64_t)(p[1]) << 48) + ((uint64_t)(p[0]) << 56)); +} + +static 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 uint64_t +le64dec(const void *pp) +{ + const uint8_t *p = (uint8_t const *)pp; + + return ((uint64_t)(p[0]) + ((uint64_t)(p[1]) << 8) + + ((uint64_t)(p[2]) << 16) + ((uint64_t)(p[3]) << 24) + + ((uint64_t)(p[4]) << 32) + ((uint64_t)(p[5]) << 40) + + ((uint64_t)(p[6]) << 48) + ((uint64_t)(p[7]) << 56)); +} + +static void +le64enc(void *pp, uint64_t x) +{ + uint8_t * p = (uint8_t *)pp; + + p[0] = x & 0xff; + p[1] = (x >> 8) & 0xff; + p[2] = (x >> 16) & 0xff; + p[3] = (x >> 24) & 0xff; + p[4] = (x >> 32) & 0xff; + p[5] = (x >> 40) & 0xff; + p[6] = (x >> 48) & 0xff; + p[7] = (x >> 56) & 0xff; +} +#endif /* !HAVE_SYS_ENDIAN_H */ + +#endif /* !_SYSENDIAN_H_ */ diff --git a/algorithm/yescrypt-opt.c b/algorithm/yescrypt-opt.c new file mode 100644 index 000000000..b54be469d --- /dev/null +++ b/algorithm/yescrypt-opt.c @@ -0,0 +1,1364 @@ +/*- + * 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. + */ + +#ifdef __i386__ +#warning "This implementation does not use SIMD, and thus it runs a lot slower than the SIMD-enabled implementation. Enable at least SSE2 in the C compiler and use yescrypt-best.c instead unless you're building this SIMD-less implementation on purpose (portability to older CPUs or testing)." +#elif defined(__x86_64__) +#warning "This implementation does not use SIMD, and thus it runs a lot slower than the SIMD-enabled implementation. Use yescrypt-best.c instead unless you're building this SIMD-less implementation on purpose (for testing only)." +#endif + +#include +#include +#include +#include "algorithm/yescrypt_core.h" +#include "sph/sha256_Y.h" +#include "algorithm/sysendian.h" + +// #include "sph/yescrypt-platform.c" +#define HUGEPAGE_THRESHOLD (12 * 1024 * 1024) + +#ifdef __x86_64__ +#define HUGEPAGE_SIZE (2 * 1024 * 1024) +#else +#undef HUGEPAGE_SIZE +#endif + + +static void * +alloc_region(yescrypt_region_t * region, size_t size) +{ + size_t base_size = size; + uint8_t * base, *aligned; +#ifdef MAP_ANON + int flags = +#ifdef MAP_NOCORE + MAP_NOCORE | +#endif + MAP_ANON | MAP_PRIVATE; +#if defined(MAP_HUGETLB) && defined(HUGEPAGE_SIZE) + size_t new_size = size; + const size_t hugepage_mask = (size_t)HUGEPAGE_SIZE - 1; + if (size >= HUGEPAGE_THRESHOLD && size + hugepage_mask >= size) { + flags |= MAP_HUGETLB; + /* + * Linux's munmap() fails on MAP_HUGETLB mappings if size is not a multiple of + * huge page size, so let's round up to huge page size here. + */ + new_size = size + hugepage_mask; + new_size &= ~hugepage_mask; + } + 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) { + flags &= ~MAP_HUGETLB; + base = mmap(NULL, size, PROT_READ | PROT_WRITE, flags, -1, 0); + } + +#else + base = mmap(NULL, size, PROT_READ | PROT_WRITE, flags, -1, 0); +#endif + if (base == MAP_FAILED) + base = NULL; + aligned = base; +#elif defined(HAVE_POSIX_MEMALIGN) + if ((errno = posix_memalign((void **)&base, 64, size)) != 0) + base = NULL; + aligned = base; +#else + base = aligned = NULL; + if (size + 63 < size) { + errno = ENOMEM; + } + else if ((base = malloc(size + 63)) != NULL) { + aligned = base + 63; + aligned -= (uintptr_t)aligned & 63; + } +#endif + region->base = base; + region->aligned = aligned; + region->base_size = base ? base_size : 0; + region->aligned_size = base ? size : 0; + return aligned; +} + +static void init_region(yescrypt_region_t * region) +{ + region->base = region->aligned = NULL; + region->base_size = region->aligned_size = 0; +} + +static int +free_region(yescrypt_region_t * region) +{ + if (region->base) { +#ifdef MAP_ANON + if (munmap(region->base, region->base_size)) + return -1; +#else + free(region->base); +#endif + } + 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; + // yescrypt_shared_t * 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_size = half1.shared1.aligned_size; + half2.shared1.aligned = (char*)half2.shared1.aligned + 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); +} + + +static 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 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 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 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; + + for (j = 0; j < S_P; j++) { + + uint64_t *Xj = X[j]; + uint64_t x0 = Xj[0]; + uint64_t x1 = Xj[1]; + + 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]; + + x1 = (uint64_t)(x1 >> 32) * (uint32_t)x1; + x1 += p0[1]; + x1 ^= p1[1]; + } + Xj[0] = x0; + Xj[1] = x1; + } + + + +} + + +/** + * 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; + // S_P_SIZE = 8; + /* 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++; +/// not used yescrypt + + 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 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 */ + + + for (i = 0; i < p; i++) { + uint64_t Vchunk = i * Nchunk; + uint64_t * Bp = &B[i * s]; + uint64_t * Vp = &V[Vchunk * s]; + uint64_t * XYp = XY; + + 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) { + + for (i = 0; i < p; i++) { + uint64_t * Bp = &B[i * s]; + + uint64_t * XYp = XY; + + 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); + + } + } + + + + +} + +static void +smix_old(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 */ + + + for (i = 0; i < p; i++) { + uint64_t Vchunk = i * Nchunk; + uint64_t * Bp = &B[i * s]; + uint64_t * Vp = &V[Vchunk * s]; + uint64_t * XYp = XY; + + 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) { + + for (i = 0; i < p; i++) { + uint64_t * Bp = &B[i * s]; + + uint64_t * XYp = XY; + + 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); + } + } +} + +/** + * 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; + } + + if ((flags & YESCRYPT_PWXFORM) && + 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; + + 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; + + need += XY_size; + if (need < XY_size) { + errno = ENOMEM; + return -1; + } + if (flags & YESCRYPT_PWXFORM) { + size_t S_size = S_SIZE_ALL * sizeof(*S); + + if (flags & YESCRYPT_PARALLEL_SMIX) + S_size *= p; + + 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 */ + for (i = 0; i < p; i++) { + /* 3: B_i <-- MF(B_i, N) */ + smix(&B[(size_t)16 * r * i], r, N, 1, t, flags, V, NROM, shared, XY, S); + } + } + + /* 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); + 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; +} + +int +yescrypt_kdf_old(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; + } + + if ((flags & YESCRYPT_PWXFORM) && + 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; + + 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; + + need += XY_size; + if (need < XY_size) { + errno = ENOMEM; + return -1; + } + if (flags & YESCRYPT_PWXFORM) { + size_t S_size = S_SIZE_ALL * sizeof(*S); + + if (flags & YESCRYPT_PARALLEL_SMIX) + S_size *= p; + + 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])); + } + smix(B, r, N, p, t, flags, V, NROM, shared, XY, S); + + + /* 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); + 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/algorithm/yescrypt.c b/algorithm/yescrypt.c new file mode 100644 index 000000000..305f3b71d --- /dev/null +++ b/algorithm/yescrypt.c @@ -0,0 +1,128 @@ +/*- + * Copyright 2015 djm34 + * 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 "config.h" +#include "miner.h" + +#include +#include +#include + +#include "algorithm/yescrypt_core.h" + +static const uint32_t diff1targ = 0x0000ffff; + +static inline void +be32enc_vect(uint32_t *dst, const uint32_t *src, uint32_t len) +{ + uint32_t i; + + for (i = 0; i < len; i++) + dst[i] = htobe32(src[i]); +} + +/* Used externally as confirmation of correct OCL code */ +int yescrypt_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t nonce) +{ + uint32_t tmp_hash7, Htarg = le32toh(((const uint32_t *)ptarget)[7]); + uint32_t data[20], ohash[8]; + + be32enc_vect(data, (const uint32_t *)pdata, 19); + data[19] = htobe32(nonce); + yescrypt_hash((unsigned char*)data,(unsigned char*)ohash); + + tmp_hash7 = be32toh(ohash[7]); + + applog(LOG_DEBUG, "htarget %08lx diff1 %08lx hash %08lx", + (long unsigned int)Htarg, + (long unsigned int)diff1targ, + (long unsigned int)tmp_hash7); + + if (tmp_hash7 > diff1targ) + return -1; + + if (tmp_hash7 > Htarg) + return 0; + + return 1; +} + +void yescrypt_regenhash(struct work *work) +{ + uint32_t data[20]; + uint32_t *nonce = (uint32_t *)(work->data + 76); + uint32_t *ohash = (uint32_t *)(work->hash); + + be32enc_vect(data, (const uint32_t *)work->data, 19); + data[19] = htobe32(*nonce); + + yescrypt_hash((unsigned char*)data, (unsigned char*)ohash); + +} + + +bool scanhash_yescrypt(struct thr_info *thr, const unsigned char __maybe_unused *pmidstate, + unsigned char *pdata, unsigned char __maybe_unused *phash1, + unsigned char __maybe_unused *phash, const unsigned char *ptarget, + uint32_t max_nonce, uint32_t *last_nonce, uint32_t n) +{ + uint32_t *nonce = (uint32_t *)(pdata + 76); + uint32_t data[20]; + uint32_t tmp_hash7; + uint32_t Htarg = le32toh(((const uint32_t *)ptarget)[7]); + bool ret = false; + + be32enc_vect(data, (const uint32_t *)pdata, 19); + + while (1) + { + uint32_t ostate[8]; + + *nonce = ++n; + data[19] = (n); + pluckrehash(ostate, data); + yescrypt_hash((unsigned char*)data, (unsigned char*)ostate); + tmp_hash7 = (ostate[7]); + + applog(LOG_INFO, "data7 %08lx", (long unsigned int)data[7]); + + if (unlikely(tmp_hash7 <= Htarg)) + { + ((uint32_t *)pdata)[19] = htobe32(n); + *last_nonce = n; + ret = true; + break; + } + + if (unlikely((n >= max_nonce) || thr->work_restart)) + { + *last_nonce = n; + break; + } + } + + return ret; +} \ No newline at end of file diff --git a/algorithm/yescrypt.h b/algorithm/yescrypt.h new file mode 100644 index 000000000..b51cb4959 --- /dev/null +++ b/algorithm/yescrypt.h @@ -0,0 +1,10 @@ +#ifndef YESCRYPT_H +#define YESCRYPT_H + +#include "miner.h" +#define YESCRYPT_SCRATCHBUF_SIZE (128 * 2048 * 8 ) //uchar +#define YESCRYP_SECBUF_SIZE (128*64*8) +extern int yescrypt_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t nonce); +extern void yescrypt_regenhash(struct work *work); + +#endif /* YESCRYPT_H */ diff --git a/algorithm/yescrypt_core.h b/algorithm/yescrypt_core.h new file mode 100644 index 000000000..64b9a11f6 --- /dev/null +++ b/algorithm/yescrypt_core.h @@ -0,0 +1,376 @@ +/*- + * 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_ + +#include +#include /* for size_t */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +//extern void yescrypt_hash_sp(const unsigned char *input, unsigned char *output); +extern void yescrypt_hash(const unsigned char *input, unsigned char *output); + + + +/** + * 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 /* !_YESCRYPT_H_ */ diff --git a/algorithm/yescryptcommon.c b/algorithm/yescryptcommon.c new file mode 100644 index 000000000..cf7067d02 --- /dev/null +++ b/algorithm/yescryptcommon.c @@ -0,0 +1,360 @@ +/*- + * 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 "algorithm/yescrypt_core.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; + fflush(stdout); + if (setting[0] != '$' || setting[1] != '7') + { + fflush(stdout); + return NULL; + } + fflush(stdout); + src = setting + 2; + fflush(stdout); + switch ((version = *src)) { + case '$': + fflush(stdout); + break; + case 'X': + src++; + flags = YESCRYPT_RW; + fflush(stdout); + break; + default: + { + fflush(stdout); + return NULL; + } + } + + fflush(stdout); + if (*src != '$') { + uint32_t decoded_flags; + if (decode64_one(&decoded_flags, *src)) + + { + fflush(stdout); + return NULL; + } + flags = decoded_flags; + if (*++src != '$') + { + fflush(stdout); + return NULL; + } + } + src++; + + { + uint32_t N_log2; + if (decode64_one(&N_log2, *src)) + { + return NULL; + } + src++; + N = (uint64_t)1 << N_log2; + } + + src = decode64_uint32(&r, 30, src); + if (!src) + { + return NULL; + } + + src = decode64_uint32(&p, 30, src); + if (!src) + { + 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) + + { + fflush(stdout); + return NULL; + } + +fflush(stdout); + if (yescrypt_kdf(shared, local, passwd, passwdlen, salt, saltlen, + N, r, p, 0, flags, hash, sizeof(hash))) + { + 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 */ + { + return NULL; + } + + *dst = 0; /* NUL termination */ + 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) +{ + static __thread int initialized = 0; + static __thread yescrypt_shared_t shared; + static __thread yescrypt_local_t local; + +// static __declspec(thread) int initialized = 0; +// static __declspec(thread) yescrypt_shared_t shared; +// static __declspec(thread) yescrypt_local_t local; + + int retval; + if (!initialized) { +/* "shared" could in fact be shared, but it's simpler to keep it private + * along with "local". It's dummy and tiny anyway. */ + 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; + } + initialized = 1; + } + retval = yescrypt_kdf(&shared, &local, + passwd, passwdlen, salt, saltlen, N, r, p, 0, YESCRYPT_FLAGS, + buf, buflen); + + return retval; +} + +void yescrypt_hash(const unsigned char *input, unsigned char *output) +{ + + yescrypt_bsty((const uint8_t *)input, 80, (const uint8_t *) input, 80, 2048, 8, 1, (uint8_t *)output, 32); +} diff --git a/example.bat b/example.bat index 605501dad..2206270df 100644 --- a/example.bat +++ b/example.bat @@ -1,9 +1,12 @@ -setx GPU_FORCE_64BIT_PTR 0 -setx GPU_MAX_HEAP_SIZE 100 -setx GPU_USE_SYNC_OBJECTS 1 -setx GPU_MAX_ALLOC_PERCENT 100 +rem setx GPU_MAX_HEAP_SIZE 100 +rem setx GPU_USE_SYNC_OBJECTS 1 +rem setx GPU_MAX_ALLOC_PERCENT 100 del *.bin -sgminer.exe --no-submit-stale --kernel Lyra2RE -o stratum+tcp://92.27.201.170:9174 -u m -p 1 --gpu-platform 2 -I 19 --shaders 2816 -w 64 -g 2 +@rem sgminer.exe --no-submit-stale --kernel Lyra2RE -o stratum+tcp://pool.verters.com:4444 -u djm34t.user -p password --gpu-platform 2 +@rem sgminer.exe --no-submit-stale --kernel pluck -o stratum+tcp://sup.suprnova.cc:7777 -u djm34.2 -p password --gpu-platform 2 --thread-concurrency 8192 -w 4 -I 12 +@rem sgminer.exe --no-submit-stale --kernel yescrypt -o stratum+tcp://mine2.bsty.nonce-pool.com:4095 -u djm34.1 -p password --gpu-platform 1 -w 32 --thread-concurrency 512 --text-only --debug +@rem sgminer.exe --no-submit-stale --kernel yescrypt -o stratum+tcp://mine2.bsty.nonce-pool.com:4095 -u djm34.1 -p password --gpu-platform 1 -w 32 --thread-concurrency 512 --text-only -D +sgminer.exe --no-submit-stale --kernel yescrypt -o stratum+tcp://mine2.bsty.nonce-pool.com:4095 -u djm34.1 -p password --gpu-platform 0 -w 16 -g 2 pause \ No newline at end of file diff --git a/kernel/yescrypt.cl b/kernel/yescrypt.cl new file mode 100644 index 000000000..b152602b7 --- /dev/null +++ b/kernel/yescrypt.cl @@ -0,0 +1,271 @@ +/* +* "yescrypt" kernel implementation. +* +* ==========================(LICENSE BEGIN)============================ +* +* Copyright (c) 2015 djm34 +* +* 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 djm34 +*/ +#if !defined(cl_khr_byte_addressable_store) +#error "Device does not support unaligned stores" +#endif + +#include "yescrypt_essential.cl" + + + + +__attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) +__kernel void search(__global const uchar* restrict input, __global uint* restrict output, __global uchar *padcache, __global uchar* buff2, const uint target) +{ + + __global ulong16 *hashbuffer = (__global ulong16 *)(padcache + (2048*128 *sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))); + __global ulong16 *prevstate = (__global ulong16 *)(buff2 + (64 * 128 * sizeof(ulong)*(get_global_id(0) % MAX_GLOBAL_THREADS))); + + + + uint nonce = (get_global_id(0)); + uint data[20]; + uint16 in; + uint8 state1, state2; + uint8 sha256tokeep; + + ulong16 Bdev[8]; // will require an additional buffer + ((uint16 *)data)[0] = ((__global const uint16 *)input)[0]; + ((uint4 *)data)[4] = ((__global const uint4 *)input)[4]; + for (int i = 0; i<20; i++) { data[i] = SWAP32(data[i]); } +// if (nonce == 10) { printf("data %08x %08x\n", data[0], data[1]); } + uint8 passwd = sha256_80(data, nonce); +//pbkdf + in.lo = pad1.lo ^ passwd; + in.hi = pad1.hi; + state1 = sha256_Transform(in, H256); + + in.lo = pad2.lo ^ passwd; + in.hi = pad2.hi; + state2 = sha256_Transform(in, H256); + + in = ((uint16*)data)[0]; + state1 = sha256_Transform(in, state1); + + for (int i = 0; i<8; i++) + { + uint16 result; + in = pad3; + in.s0 = data[16]; + in.s1 = data[17]; + in.s2 = data[18]; + in.s3 = nonce; + in.s4 = 4*i+1; + in.lo = sha256_Transform(in, state1); + in.hi = pad4; + result.lo = swapvec(sha256_Transform(in, state2)); + if (i == 0) sha256tokeep = result.lo; + in = pad3; + in.s0 = data[16]; + in.s1 = data[17]; + in.s2 = data[18]; + in.s3 = nonce; + in.s4 = 4 * i + 2; + in.lo = sha256_Transform(in, state1); + in.hi = pad4; + result.hi = swapvec(sha256_Transform(in, state2)); + Bdev[i].lo = as_ulong8(shuffle(result)); + in = pad3; + in.s0 = data[16]; + in.s1 = data[17]; + in.s2 = data[18]; + in.s3 = nonce; + in.s4 = 4 * i + 3; + in.lo = sha256_Transform(in, state1); + in.hi = pad4; + result.lo = swapvec(sha256_Transform(in, state2)); + in = pad3; + in.s0 = data[16]; + in.s1 = data[17]; + in.s2 = data[18]; + in.s3 = nonce; + in.s4 = 4 * i + 4; + in.lo = sha256_Transform(in, state1); + in.hi = pad4; + result.hi = swapvec(sha256_Transform(in, state2)); + + + Bdev[i].hi = as_ulong8(shuffle(result)); + } + +//mixing1 + + prevstate[0] = Bdev[0]; + Bdev[0]=blockmix_salsa8_small2(Bdev[0]); + prevstate[1] = Bdev[0]; + Bdev[0] = blockmix_salsa8_small2(Bdev[0]); + + + + uint n = 1; +#pragma unroll 1 + for (uint i = 2; i < 64; i++) + { + + prevstate[i] = Bdev[0]; + + if ((i&(i - 1)) == 0) n = n << 1; + + uint j = as_uint2(Bdev[0].hi.s0).x & (n - 1); + + j += i - n; + Bdev[0] ^= prevstate[j]; + + Bdev[0] = blockmix_salsa8_small2(Bdev[0]); + } +//mixing1_2 + + for (int i = 0; i<8; i++) + hashbuffer[i] = Bdev[i]; + + blockmix_pwxform((ulong8*)Bdev,prevstate); + + + for (int i = 0; i<8; i++) + hashbuffer[i + 8] = Bdev[i]; + + blockmix_pwxform((ulong8*)Bdev,prevstate); + n = 1; +#pragma unroll 1 + for (int i = 2; i < 2048; i++) + { + + + for (int k = 0; k<8; k++) + (hashbuffer + 8 * i)[k] = Bdev[k]; + + + if ((i&(i - 1)) == 0) n = n << 1; + + uint j = as_uint2(Bdev[7].hi.s0).x & (n - 1); + j += i - n; + + for (int k = 0; k < 8; k++) + Bdev[k] ^= (hashbuffer + 8 * j)[k]; + + + blockmix_pwxform( (ulong8*)Bdev,prevstate); + + } +///////////////////////// + +////mix2_2 + + + //#pragma unroll +#pragma unroll 1 + for (int z = 0; z < 684; z++) + { + + uint j = as_uint2(Bdev[7].hi.s0).x & 2047; + + + for (int k = 0; k < 8; k++) + Bdev[k] ^= (hashbuffer + 8 * j)[k]; + + if (z<682) + for (int k = 0; k<8; k++) + (hashbuffer+8 * j)[k] = Bdev[k]; + + blockmix_pwxform((ulong8*)Bdev,prevstate); + + } + + + for (int i = 0; i<8; i++) { + Bdev[i].lo = as_ulong8(unshuffle(Bdev[i].lo)); + Bdev[i].hi = as_ulong8(unshuffle(Bdev[i].hi)); + } +///////////////////////////////////// +///////// pbkdf final + + + uint8 swpass = swapvec(sha256tokeep); + in.lo = pad1.lo ^ swpass; + in.hi = pad1.hi; + + state1 = sha256_Transform(in, H256); + + in.lo = pad2.lo ^ swpass; + in.hi = pad2.hi; + state2 = sha256_Transform(in, H256); + + for (int i = 0; i<8; i++) { + in = as_uint16(Bdev[i].lo); + in = swapvec16(in); + state1 = sha256_Transform(in, state1); + in = as_uint16(Bdev[i].hi); + in = swapvec16(in); + state1 = sha256_Transform(in, state1); + } + in = pad5; + state1 = sha256_Transform(in, state1); + in.lo = state1; + in.hi = pad4; + uint8 res = sha256_Transform(in, state2); + + //hmac and final sha + + in.lo = pad1.lo ^ res; + in.hi = pad1.hi; + state1 = sha256_Transform(in, H256); + in.lo = pad2.lo ^ res; + in.hi = pad2.hi; + state2 = sha256_Transform(in, H256); + in = ((uint16*)data)[0]; + state1 = sha256_Transform(in, state1); + in = padsha80; + in.s0 = data[16]; + in.s1 = data[17]; + in.s2 = data[18]; + in.s3 = nonce; + in.sf = 0x480; + state1 = sha256_Transform(in, state1); + in.lo = state1; + in.hi = pad4; + state1 = sha256_Transform(in, state2); + // state2 = H256; + in.lo = state1; + in.hi = pad4; + in.sf = 0x100; + res = sha256_Transform(in, H256); + // return(swapvec(res)); + + +// if (nonce == 10) { } + + if ( SWAP32(res.s7) <= (target)) { + output[atomic_inc(output + 0xFF)] = (nonce); + //printf("gpu hashbuffer %08x nonce %08x\n",((__global uint *)hashbuffer)[7] ,SWAP32(get_global_id(0))); +} + + +} \ No newline at end of file diff --git a/kernel/yescrypt_essential.cl b/kernel/yescrypt_essential.cl new file mode 100644 index 000000000..8743d7b94 --- /dev/null +++ b/kernel/yescrypt_essential.cl @@ -0,0 +1,746 @@ +/* +* "yescrypt" kernel implementation. +* +* ==========================(LICENSE BEGIN)============================ +* +* Copyright (c) 2015 djm34 +* +* 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 djm34 +*/ + +#define ROL32(x, n) rotate(x, (uint) n) +#define SWAP32(a) (as_uint(as_uchar4(a).wzyx)) +//#define ROL32(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) +#define HASH_MEMORY 4096 + + +#define SALSA(a,b,c,d) do { \ + t =a+d; b^=ROL32(t, 7U); \ + t =b+a; c^=ROL32(t, 9U); \ + t =c+b; d^=ROL32(t, 13U); \ + t =d+c; a^=ROL32(t, 18U); \ +} while(0) + + +#define SALSA_CORE(state) do { \ +\ +SALSA(state.s0,state.s4,state.s8,state.sc); \ +SALSA(state.s5,state.s9,state.sd,state.s1); \ +SALSA(state.sa,state.se,state.s2,state.s6); \ +SALSA(state.sf,state.s3,state.s7,state.sb); \ +SALSA(state.s0,state.s1,state.s2,state.s3); \ +SALSA(state.s5,state.s6,state.s7,state.s4); \ +SALSA(state.sa,state.sb,state.s8,state.s9); \ +SALSA(state.sf,state.sc,state.sd,state.se); \ + } while(0) + +#define uSALSA_CORE(state) do { \ +\ +SALSA(state.s0,state.s4,state.s8,state.sc); \ +SALSA(state.s1,state.s5,state.s9,state.sd); \ +SALSA(state.s2,state.s6,state.sa,state.se); \ +SALSA(state.s3,state.s7,state.sb,state.sf); \ +SALSA(state.s0,state.sd,state.sa,state.s7); \ +SALSA(state.s1,state.se,state.sb,state.s4); \ +SALSA(state.s2,state.sf,state.s8,state.s5); \ +SALSA(state.s3,state.sc,state.s9,state.s6); \ +} while(0) + + +#define unshuffle(state) (as_uint16(state).s0da741eb852fc963) + +#define shuffle(state) (as_uint16(state).s05af49e38d27c16b) + +static __constant uint16 pad1 = +{ + 0x36363636, 0x36363636, 0x36363636, 0x36363636, + 0x36363636, 0x36363636, 0x36363636, 0x36363636, + 0x36363636, 0x36363636, 0x36363636, 0x36363636, + 0x36363636, 0x36363636, 0x36363636, 0x36363636 +}; + +static __constant uint16 pad2 = +{ + 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, + 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, + 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, + 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c, 0x5c5c5c5c +}; + +static __constant uint16 pad5 = +{ + 0x00000001, 0x80000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00002220 +}; + +static __constant uint16 pad3 = +{ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x80000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x000004a0 +}; + +static __constant uint16 padsha80 = +{ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x80000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000280 +}; + +static __constant uint8 pad4 = +{ + 0x80000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000300 +}; + + + +static __constant uint8 H256 = { + 0x6A09E667, 0xBB67AE85, 0x3C6EF372, + 0xA54FF53A, 0x510E527F, 0x9B05688C, + 0x1F83D9AB, 0x5BE0CD19 +}; + +inline uint8 swapvec(uint8 buf) +{ + uint8 vec; + vec.s0 = SWAP32(buf.s0); + vec.s1 = SWAP32(buf.s1); + vec.s2 = SWAP32(buf.s2); + vec.s3 = SWAP32(buf.s3); + vec.s4 = SWAP32(buf.s4); + vec.s5 = SWAP32(buf.s5); + vec.s6 = SWAP32(buf.s6); + vec.s7 = SWAP32(buf.s7); + return vec; +} + +inline uint16 swapvec16(uint16 buf) +{ + uint16 vec; + vec.s0 = SWAP32(buf.s0); + vec.s1 = SWAP32(buf.s1); + vec.s2 = SWAP32(buf.s2); + vec.s3 = SWAP32(buf.s3); + vec.s4 = SWAP32(buf.s4); + vec.s5 = SWAP32(buf.s5); + vec.s6 = SWAP32(buf.s6); + vec.s7 = SWAP32(buf.s7); + vec.s8 = SWAP32(buf.s8); + vec.s9 = SWAP32(buf.s9); + vec.sa = SWAP32(buf.sa); + vec.sb = SWAP32(buf.sb); + vec.sc = SWAP32(buf.sc); + vec.sd = SWAP32(buf.sd); + vec.se = SWAP32(buf.se); + vec.sf = SWAP32(buf.sf); + return vec; +} + + ulong8 salsa20_8(uint16 Bx) +{ +uint t; + uint16 st = Bx; + uSALSA_CORE(st); + uSALSA_CORE(st); + uSALSA_CORE(st); + uSALSA_CORE(st); + return(as_ulong8(st + Bx)); +} + + ulong16 blockmix_salsa8_small2(ulong16 Bin) +{ + ulong8 X = Bin.hi; + X ^= Bin.lo; + X = salsa20_8(as_uint16(X)); + Bin.lo = X; + X ^= Bin.hi; + X = salsa20_8(as_uint16(X)); + Bin.hi = X; + return(Bin); +} +/* + uint16 salsa20_8_2(uint16 Bx) + { + uint t; + uint16 st = Bx; + uSALSA_CORE(st); + uSALSA_CORE(st); + uSALSA_CORE(st); + uSALSA_CORE(st); + return(st + Bx); + } + + ulong16 blockmix_salsa8_small2(ulong16 Bin) + { + uint16 X = as_uint16(Bin.hi); + X ^= as_uint16(Bin.lo); + X = salsa20_8_2(as_uint16(X)); + Bin.lo = as_ulong8(X); + X ^= as_uint16(Bin.hi); + X = salsa20_8_2(as_uint16(X)); + Bin.hi = as_ulong8(X); + return(Bin); + } +*/ + + +inline ulong2 madd4long2(uint4 a, uint4 b) +{ + uint4 result; + result.x = a.x*a.y + b.x; + result.y = b.y + mad_hi(a.x, a.y, b.x); + result.z = a.z*a.w + b.z; + result.w = b.w + mad_hi(a.z, a.w, b.z); + return as_ulong2(result); +} + +inline ulong2 madd4long3(uint4 a, ulong2 b) +{ + ulong2 result; + result.x = (ulong)a.x*(ulong)a.y + b.x; + result.y = (ulong)a.z*(ulong)a.w + b.y; + return result; +} + + +inline ulong8 block_pwxform_long_old(ulong8 Bout, __global ulong16 *prevstate) +{ + + ulong2 vec = Bout.lo.lo; + + for (int i = 0; i < 6; i++) + { + ulong2 p0, p1; + uint2 x = as_uint2((vec.x >> 4) & 0x000000FF000000FF); + p0 = ((__global ulong2*)(prevstate ))[x.x]; + vec = madd4long3(as_uint4(vec), p0); + p1 = ((__global ulong2*)(prevstate + 32))[x.y]; + + vec ^= p1; + } + Bout.lo.lo = vec; + vec = Bout.lo.hi; + for (int i = 0; i < 6; i++) + { + + ulong2 p0, p1; + uint2 x = as_uint2((vec.x >> 4) & 0x000000FF000000FF); + p0 = ((__global ulong2*)(prevstate))[x.x]; + vec = madd4long3(as_uint4(vec), p0); + p1 = ((__global ulong2*)(prevstate + 32))[x.y]; + + vec ^= p1; + } + Bout.lo.hi = vec; + + vec = Bout.hi.lo; + for (int i = 0; i < 6; i++) + { + ulong2 p0, p1; + uint2 x = as_uint2((vec.x >> 4) & 0x000000FF000000FF); + p0 = ((__global ulong2*)(prevstate))[x.x]; + vec = madd4long3(as_uint4(vec), p0); + p1 = ((__global ulong2*)(prevstate + 32))[x.y]; + vec ^= p1; + } + Bout.hi.lo = vec; + vec = Bout.hi.hi; + for (int i = 0; i < 6; i++) + { + ulong2 p0, p1; + uint2 x = as_uint2((vec.x >> 4) & 0x000000FF000000FF); + p0 = ((__global ulong2*)(prevstate))[x.x]; + vec = madd4long3(as_uint4(vec), p0); + p1 = ((__global ulong2*)(prevstate + 32))[x.y]; + + vec ^= p1; + } + Bout.hi.hi = vec; + + return(Bout); +} + +inline ulong8 block_pwxform_long(ulong8 Bout, __global ulong2 *prevstate) +{ + + ulong2 vec = Bout.lo.lo; + + for (int i = 0; i < 6; i++) + { + ulong2 p0, p1; + uint2 x = as_uint2((vec.x >> 4) & 0x000000FF000000FF); + p0 = prevstate[x.x]; + vec = madd4long3(as_uint4(vec), p0); + p1 = (prevstate + 32*8)[x.y]; + + vec ^= p1; + } + Bout.lo.lo = vec; + vec = Bout.lo.hi; + for (int i = 0; i < 6; i++) + { + + ulong2 p0, p1; + uint2 x = as_uint2((vec.x >> 4) & 0x000000FF000000FF); + p0 = prevstate[x.x]; + vec = madd4long3(as_uint4(vec), p0); + p1 = (prevstate + 32 * 8)[x.y]; + + vec ^= p1; + } + Bout.lo.hi = vec; + + vec = Bout.hi.lo; + for (int i = 0; i < 6; i++) + { + ulong2 p0, p1; + uint2 x = as_uint2((vec.x >> 4) & 0x000000FF000000FF); + p0 = prevstate[x.x]; + vec = madd4long3(as_uint4(vec), p0); + p1 = (prevstate + 32 * 8)[x.y]; + vec ^= p1; + } + Bout.hi.lo = vec; + vec = Bout.hi.hi; + for (int i = 0; i < 6; i++) + { + ulong2 p0, p1; + uint2 x = as_uint2((vec.x >> 4) & 0x000000FF000000FF); + p0 = prevstate[x.x]; + vec = madd4long3(as_uint4(vec), p0); + p1 = (prevstate + 32 * 8)[x.y]; + + vec ^= p1; + } + Bout.hi.hi = vec; + + return(Bout); +} + + + + +inline void blockmix_pwxform( ulong8 *Bin, __global ulong16 *prevstate) +{ + Bin[0] ^= Bin[15]; + Bin[0] = block_pwxform_long_old(Bin[0], prevstate); +#pragma unroll 1 + for (int i = 1; i < 16; i++) + { + Bin[i] ^= Bin[i - 1]; + Bin[i] = block_pwxform_long_old(Bin[i], prevstate); + } + Bin[15] = salsa20_8(as_uint16(Bin[15])); +} + +#define SHR(x, n) ((x) >> n) + + +#define S0(x) (ROL32(x, 25) ^ ROL32(x, 14) ^ SHR(x, 3)) +#define S1(x) (ROL32(x, 15) ^ ROL32(x, 13) ^ SHR(x, 10)) + +#define S2(x) (ROL32(x, 30) ^ ROL32(x, 19) ^ ROL32(x, 10)) +#define S3(x) (ROL32(x, 26) ^ ROL32(x, 21) ^ ROL32(x, 7)) + +#define P(a,b,c,d,e,f,g,h,x,K) \ +{ \ + temp1 = h + S3(e) + F1(e,f,g) + (K + x); \ + d += temp1; h = temp1 + S2(a) + F0(a,b,c); \ +} + +#define PLAST(a,b,c,d,e,f,g,h,x,K) \ +{ \ + d += h + S3(e) + F1(e,f,g) + (x + K); \ +} + +#define F0(y, x, z) bitselect(z, y, z ^ x) +#define F1(x, y, z) bitselect(z, y, x) + +#define R0 (W0 = S1(W14) + W9 + S0(W1) + W0) +#define R1 (W1 = S1(W15) + W10 + S0(W2) + W1) +#define R2 (W2 = S1(W0) + W11 + S0(W3) + W2) +#define R3 (W3 = S1(W1) + W12 + S0(W4) + W3) +#define R4 (W4 = S1(W2) + W13 + S0(W5) + W4) +#define R5 (W5 = S1(W3) + W14 + S0(W6) + W5) +#define R6 (W6 = S1(W4) + W15 + S0(W7) + W6) +#define R7 (W7 = S1(W5) + W0 + S0(W8) + W7) +#define R8 (W8 = S1(W6) + W1 + S0(W9) + W8) +#define R9 (W9 = S1(W7) + W2 + S0(W10) + W9) +#define R10 (W10 = S1(W8) + W3 + S0(W11) + W10) +#define R11 (W11 = S1(W9) + W4 + S0(W12) + W11) +#define R12 (W12 = S1(W10) + W5 + S0(W13) + W12) +#define R13 (W13 = S1(W11) + W6 + S0(W14) + W13) +#define R14 (W14 = S1(W12) + W7 + S0(W15) + W14) +#define R15 (W15 = S1(W13) + W8 + S0(W0) + W15) + +#define RD14 (S1(W12) + W7 + S0(W15) + W14) +#define RD15 (S1(W13) + W8 + S0(W0) + W15) + +/// generic sha transform +inline uint8 sha256_Transform(uint16 data, uint8 state) +{ +uint temp1; + uint8 res = state; + uint W0 = data.s0; + uint W1 = data.s1; + uint W2 = data.s2; + uint W3 = data.s3; + uint W4 = data.s4; + uint W5 = data.s5; + uint W6 = data.s6; + uint W7 = data.s7; + uint W8 = data.s8; + uint W9 = data.s9; + uint W10 = data.sA; + uint W11 = data.sB; + uint W12 = data.sC; + uint W13 = data.sD; + uint W14 = data.sE; + uint W15 = data.sF; + +#define v0 res.s0 +#define v1 res.s1 +#define v2 res.s2 +#define v3 res.s3 +#define v4 res.s4 +#define v5 res.s5 +#define v6 res.s6 +#define v7 res.s7 + + P(v0, v1, v2, v3, v4, v5, v6, v7, W0, 0x428A2F98); + P(v7, v0, v1, v2, v3, v4, v5, v6, W1, 0x71374491); + P(v6, v7, v0, v1, v2, v3, v4, v5, W2, 0xB5C0FBCF); + P(v5, v6, v7, v0, v1, v2, v3, v4, W3, 0xE9B5DBA5); + P(v4, v5, v6, v7, v0, v1, v2, v3, W4, 0x3956C25B); + P(v3, v4, v5, v6, v7, v0, v1, v2, W5, 0x59F111F1); + P(v2, v3, v4, v5, v6, v7, v0, v1, W6, 0x923F82A4); + P(v1, v2, v3, v4, v5, v6, v7, v0, W7, 0xAB1C5ED5); + P(v0, v1, v2, v3, v4, v5, v6, v7, W8, 0xD807AA98); + P(v7, v0, v1, v2, v3, v4, v5, v6, W9, 0x12835B01); + P(v6, v7, v0, v1, v2, v3, v4, v5, W10, 0x243185BE); + P(v5, v6, v7, v0, v1, v2, v3, v4, W11, 0x550C7DC3); + P(v4, v5, v6, v7, v0, v1, v2, v3, W12, 0x72BE5D74); + P(v3, v4, v5, v6, v7, v0, v1, v2, W13, 0x80DEB1FE); + P(v2, v3, v4, v5, v6, v7, v0, v1, W14, 0x9BDC06A7); + P(v1, v2, v3, v4, v5, v6, v7, v0, W15, 0xC19BF174); + + P(v0, v1, v2, v3, v4, v5, v6, v7, R0, 0xE49B69C1); + P(v7, v0, v1, v2, v3, v4, v5, v6, R1, 0xEFBE4786); + P(v6, v7, v0, v1, v2, v3, v4, v5, R2, 0x0FC19DC6); + P(v5, v6, v7, v0, v1, v2, v3, v4, R3, 0x240CA1CC); + P(v4, v5, v6, v7, v0, v1, v2, v3, R4, 0x2DE92C6F); + P(v3, v4, v5, v6, v7, v0, v1, v2, R5, 0x4A7484AA); + P(v2, v3, v4, v5, v6, v7, v0, v1, R6, 0x5CB0A9DC); + P(v1, v2, v3, v4, v5, v6, v7, v0, R7, 0x76F988DA); + P(v0, v1, v2, v3, v4, v5, v6, v7, R8, 0x983E5152); + P(v7, v0, v1, v2, v3, v4, v5, v6, R9, 0xA831C66D); + P(v6, v7, v0, v1, v2, v3, v4, v5, R10, 0xB00327C8); + P(v5, v6, v7, v0, v1, v2, v3, v4, R11, 0xBF597FC7); + P(v4, v5, v6, v7, v0, v1, v2, v3, R12, 0xC6E00BF3); + P(v3, v4, v5, v6, v7, v0, v1, v2, R13, 0xD5A79147); + P(v2, v3, v4, v5, v6, v7, v0, v1, R14, 0x06CA6351); + P(v1, v2, v3, v4, v5, v6, v7, v0, R15, 0x14292967); + + P(v0, v1, v2, v3, v4, v5, v6, v7, R0, 0x27B70A85); + P(v7, v0, v1, v2, v3, v4, v5, v6, R1, 0x2E1B2138); + P(v6, v7, v0, v1, v2, v3, v4, v5, R2, 0x4D2C6DFC); + P(v5, v6, v7, v0, v1, v2, v3, v4, R3, 0x53380D13); + P(v4, v5, v6, v7, v0, v1, v2, v3, R4, 0x650A7354); + P(v3, v4, v5, v6, v7, v0, v1, v2, R5, 0x766A0ABB); + P(v2, v3, v4, v5, v6, v7, v0, v1, R6, 0x81C2C92E); + P(v1, v2, v3, v4, v5, v6, v7, v0, R7, 0x92722C85); + P(v0, v1, v2, v3, v4, v5, v6, v7, R8, 0xA2BFE8A1); + P(v7, v0, v1, v2, v3, v4, v5, v6, R9, 0xA81A664B); + P(v6, v7, v0, v1, v2, v3, v4, v5, R10, 0xC24B8B70); + P(v5, v6, v7, v0, v1, v2, v3, v4, R11, 0xC76C51A3); + P(v4, v5, v6, v7, v0, v1, v2, v3, R12, 0xD192E819); + P(v3, v4, v5, v6, v7, v0, v1, v2, R13, 0xD6990624); + P(v2, v3, v4, v5, v6, v7, v0, v1, R14, 0xF40E3585); + P(v1, v2, v3, v4, v5, v6, v7, v0, R15, 0x106AA070); + + P(v0, v1, v2, v3, v4, v5, v6, v7, R0, 0x19A4C116); + P(v7, v0, v1, v2, v3, v4, v5, v6, R1, 0x1E376C08); + P(v6, v7, v0, v1, v2, v3, v4, v5, R2, 0x2748774C); + P(v5, v6, v7, v0, v1, v2, v3, v4, R3, 0x34B0BCB5); + P(v4, v5, v6, v7, v0, v1, v2, v3, R4, 0x391C0CB3); + P(v3, v4, v5, v6, v7, v0, v1, v2, R5, 0x4ED8AA4A); + P(v2, v3, v4, v5, v6, v7, v0, v1, R6, 0x5B9CCA4F); + P(v1, v2, v3, v4, v5, v6, v7, v0, R7, 0x682E6FF3); + P(v0, v1, v2, v3, v4, v5, v6, v7, R8, 0x748F82EE); + P(v7, v0, v1, v2, v3, v4, v5, v6, R9, 0x78A5636F); + P(v6, v7, v0, v1, v2, v3, v4, v5, R10, 0x84C87814); + P(v5, v6, v7, v0, v1, v2, v3, v4, R11, 0x8CC70208); + P(v4, v5, v6, v7, v0, v1, v2, v3, R12, 0x90BEFFFA); + P(v3, v4, v5, v6, v7, v0, v1, v2, R13, 0xA4506CEB); + P(v2, v3, v4, v5, v6, v7, v0, v1, RD14, 0xBEF9A3F7); + P(v1, v2, v3, v4, v5, v6, v7, v0, RD15, 0xC67178F2); +#undef v0 +#undef v1 +#undef v2 +#undef v3 +#undef v4 +#undef v5 +#undef v6 +#undef v7 + return (res+state); +} + + +static inline uint8 sha256_round1(uint16 data) +{ + uint temp1; + uint8 res; + uint W0 = data.s0; + uint W1 = data.s1; + uint W2 = data.s2; + uint W3 = data.s3; + uint W4 = data.s4; + uint W5 = data.s5; + uint W6 = data.s6; + uint W7 = data.s7; + uint W8 = data.s8; + uint W9 = data.s9; + uint W10 = data.sA; + uint W11 = data.sB; + uint W12 = data.sC; + uint W13 = data.sD; + uint W14 = data.sE; + uint W15 = data.sF; + + uint v0 = 0x6A09E667; + uint v1 = 0xBB67AE85; + uint v2 = 0x3C6EF372; + uint v3 = 0xA54FF53A; + uint v4 = 0x510E527F; + uint v5 = 0x9B05688C; + uint v6 = 0x1F83D9AB; + uint v7 = 0x5BE0CD19; + + P(v0, v1, v2, v3, v4, v5, v6, v7, W0, 0x428A2F98); + P(v7, v0, v1, v2, v3, v4, v5, v6, W1, 0x71374491); + P(v6, v7, v0, v1, v2, v3, v4, v5, W2, 0xB5C0FBCF); + P(v5, v6, v7, v0, v1, v2, v3, v4, W3, 0xE9B5DBA5); + P(v4, v5, v6, v7, v0, v1, v2, v3, W4, 0x3956C25B); + P(v3, v4, v5, v6, v7, v0, v1, v2, W5, 0x59F111F1); + P(v2, v3, v4, v5, v6, v7, v0, v1, W6, 0x923F82A4); + P(v1, v2, v3, v4, v5, v6, v7, v0, W7, 0xAB1C5ED5); + P(v0, v1, v2, v3, v4, v5, v6, v7, W8, 0xD807AA98); + P(v7, v0, v1, v2, v3, v4, v5, v6, W9, 0x12835B01); + P(v6, v7, v0, v1, v2, v3, v4, v5, W10, 0x243185BE); + P(v5, v6, v7, v0, v1, v2, v3, v4, W11, 0x550C7DC3); + P(v4, v5, v6, v7, v0, v1, v2, v3, W12, 0x72BE5D74); + P(v3, v4, v5, v6, v7, v0, v1, v2, W13, 0x80DEB1FE); + P(v2, v3, v4, v5, v6, v7, v0, v1, W14, 0x9BDC06A7); + P(v1, v2, v3, v4, v5, v6, v7, v0, W15, 0xC19BF174); + + P(v0, v1, v2, v3, v4, v5, v6, v7, R0, 0xE49B69C1); + P(v7, v0, v1, v2, v3, v4, v5, v6, R1, 0xEFBE4786); + P(v6, v7, v0, v1, v2, v3, v4, v5, R2, 0x0FC19DC6); + P(v5, v6, v7, v0, v1, v2, v3, v4, R3, 0x240CA1CC); + P(v4, v5, v6, v7, v0, v1, v2, v3, R4, 0x2DE92C6F); + P(v3, v4, v5, v6, v7, v0, v1, v2, R5, 0x4A7484AA); + P(v2, v3, v4, v5, v6, v7, v0, v1, R6, 0x5CB0A9DC); + P(v1, v2, v3, v4, v5, v6, v7, v0, R7, 0x76F988DA); + P(v0, v1, v2, v3, v4, v5, v6, v7, R8, 0x983E5152); + P(v7, v0, v1, v2, v3, v4, v5, v6, R9, 0xA831C66D); + P(v6, v7, v0, v1, v2, v3, v4, v5, R10, 0xB00327C8); + P(v5, v6, v7, v0, v1, v2, v3, v4, R11, 0xBF597FC7); + P(v4, v5, v6, v7, v0, v1, v2, v3, R12, 0xC6E00BF3); + P(v3, v4, v5, v6, v7, v0, v1, v2, R13, 0xD5A79147); + P(v2, v3, v4, v5, v6, v7, v0, v1, R14, 0x06CA6351); + P(v1, v2, v3, v4, v5, v6, v7, v0, R15, 0x14292967); + + P(v0, v1, v2, v3, v4, v5, v6, v7, R0, 0x27B70A85); + P(v7, v0, v1, v2, v3, v4, v5, v6, R1, 0x2E1B2138); + P(v6, v7, v0, v1, v2, v3, v4, v5, R2, 0x4D2C6DFC); + P(v5, v6, v7, v0, v1, v2, v3, v4, R3, 0x53380D13); + P(v4, v5, v6, v7, v0, v1, v2, v3, R4, 0x650A7354); + P(v3, v4, v5, v6, v7, v0, v1, v2, R5, 0x766A0ABB); + P(v2, v3, v4, v5, v6, v7, v0, v1, R6, 0x81C2C92E); + P(v1, v2, v3, v4, v5, v6, v7, v0, R7, 0x92722C85); + P(v0, v1, v2, v3, v4, v5, v6, v7, R8, 0xA2BFE8A1); + P(v7, v0, v1, v2, v3, v4, v5, v6, R9, 0xA81A664B); + P(v6, v7, v0, v1, v2, v3, v4, v5, R10, 0xC24B8B70); + P(v5, v6, v7, v0, v1, v2, v3, v4, R11, 0xC76C51A3); + P(v4, v5, v6, v7, v0, v1, v2, v3, R12, 0xD192E819); + P(v3, v4, v5, v6, v7, v0, v1, v2, R13, 0xD6990624); + P(v2, v3, v4, v5, v6, v7, v0, v1, R14, 0xF40E3585); + P(v1, v2, v3, v4, v5, v6, v7, v0, R15, 0x106AA070); + + P(v0, v1, v2, v3, v4, v5, v6, v7, R0, 0x19A4C116); + P(v7, v0, v1, v2, v3, v4, v5, v6, R1, 0x1E376C08); + P(v6, v7, v0, v1, v2, v3, v4, v5, R2, 0x2748774C); + P(v5, v6, v7, v0, v1, v2, v3, v4, R3, 0x34B0BCB5); + P(v4, v5, v6, v7, v0, v1, v2, v3, R4, 0x391C0CB3); + P(v3, v4, v5, v6, v7, v0, v1, v2, R5, 0x4ED8AA4A); + P(v2, v3, v4, v5, v6, v7, v0, v1, R6, 0x5B9CCA4F); + P(v1, v2, v3, v4, v5, v6, v7, v0, R7, 0x682E6FF3); + P(v0, v1, v2, v3, v4, v5, v6, v7, R8, 0x748F82EE); + P(v7, v0, v1, v2, v3, v4, v5, v6, R9, 0x78A5636F); + P(v6, v7, v0, v1, v2, v3, v4, v5, R10, 0x84C87814); + P(v5, v6, v7, v0, v1, v2, v3, v4, R11, 0x8CC70208); + P(v4, v5, v6, v7, v0, v1, v2, v3, R12, 0x90BEFFFA); + P(v3, v4, v5, v6, v7, v0, v1, v2, R13, 0xA4506CEB); + P(v2, v3, v4, v5, v6, v7, v0, v1, RD14, 0xBEF9A3F7); + P(v1, v2, v3, v4, v5, v6, v7, v0, RD15, 0xC67178F2); + + res.s0 = v0 + 0x6A09E667; + res.s1 = v1 + 0xBB67AE85; + res.s2 = v2 + 0x3C6EF372; + res.s3 = v3 + 0xA54FF53A; + res.s4 = v4 + 0x510E527F; + res.s5 = v5 + 0x9B05688C; + res.s6 = v6 + 0x1F83D9AB; + res.s7 = v7 + 0x5BE0CD19; + return (res); +} + + +static inline uint8 sha256_round2(uint16 data,uint8 buf) +{ + uint temp1; + uint8 res; + uint W0 = data.s0; + uint W1 = data.s1; + uint W2 = data.s2; + uint W3 = data.s3; + uint W4 = data.s4; + uint W5 = data.s5; + uint W6 = data.s6; + uint W7 = data.s7; + uint W8 = data.s8; + uint W9 = data.s9; + uint W10 = data.sA; + uint W11 = data.sB; + uint W12 = data.sC; + uint W13 = data.sD; + uint W14 = data.sE; + uint W15 = data.sF; + + uint v0 = buf.s0; + uint v1 = buf.s1; + uint v2 = buf.s2; + uint v3 = buf.s3; + uint v4 = buf.s4; + uint v5 = buf.s5; + uint v6 = buf.s6; + uint v7 = buf.s7; + + P(v0, v1, v2, v3, v4, v5, v6, v7, W0, 0x428A2F98); + P(v7, v0, v1, v2, v3, v4, v5, v6, W1, 0x71374491); + P(v6, v7, v0, v1, v2, v3, v4, v5, W2, 0xB5C0FBCF); + P(v5, v6, v7, v0, v1, v2, v3, v4, W3, 0xE9B5DBA5); + P(v4, v5, v6, v7, v0, v1, v2, v3, W4, 0x3956C25B); + P(v3, v4, v5, v6, v7, v0, v1, v2, W5, 0x59F111F1); + P(v2, v3, v4, v5, v6, v7, v0, v1, W6, 0x923F82A4); + P(v1, v2, v3, v4, v5, v6, v7, v0, W7, 0xAB1C5ED5); + P(v0, v1, v2, v3, v4, v5, v6, v7, W8, 0xD807AA98); + P(v7, v0, v1, v2, v3, v4, v5, v6, W9, 0x12835B01); + P(v6, v7, v0, v1, v2, v3, v4, v5, W10, 0x243185BE); + P(v5, v6, v7, v0, v1, v2, v3, v4, W11, 0x550C7DC3); + P(v4, v5, v6, v7, v0, v1, v2, v3, W12, 0x72BE5D74); + P(v3, v4, v5, v6, v7, v0, v1, v2, W13, 0x80DEB1FE); + P(v2, v3, v4, v5, v6, v7, v0, v1, W14, 0x9BDC06A7); + P(v1, v2, v3, v4, v5, v6, v7, v0, W15, 0xC19BF174); + + P(v0, v1, v2, v3, v4, v5, v6, v7, R0, 0xE49B69C1); + P(v7, v0, v1, v2, v3, v4, v5, v6, R1, 0xEFBE4786); + P(v6, v7, v0, v1, v2, v3, v4, v5, R2, 0x0FC19DC6); + P(v5, v6, v7, v0, v1, v2, v3, v4, R3, 0x240CA1CC); + P(v4, v5, v6, v7, v0, v1, v2, v3, R4, 0x2DE92C6F); + P(v3, v4, v5, v6, v7, v0, v1, v2, R5, 0x4A7484AA); + P(v2, v3, v4, v5, v6, v7, v0, v1, R6, 0x5CB0A9DC); + P(v1, v2, v3, v4, v5, v6, v7, v0, R7, 0x76F988DA); + P(v0, v1, v2, v3, v4, v5, v6, v7, R8, 0x983E5152); + P(v7, v0, v1, v2, v3, v4, v5, v6, R9, 0xA831C66D); + P(v6, v7, v0, v1, v2, v3, v4, v5, R10, 0xB00327C8); + P(v5, v6, v7, v0, v1, v2, v3, v4, R11, 0xBF597FC7); + P(v4, v5, v6, v7, v0, v1, v2, v3, R12, 0xC6E00BF3); + P(v3, v4, v5, v6, v7, v0, v1, v2, R13, 0xD5A79147); + P(v2, v3, v4, v5, v6, v7, v0, v1, R14, 0x06CA6351); + P(v1, v2, v3, v4, v5, v6, v7, v0, R15, 0x14292967); + + P(v0, v1, v2, v3, v4, v5, v6, v7, R0, 0x27B70A85); + P(v7, v0, v1, v2, v3, v4, v5, v6, R1, 0x2E1B2138); + P(v6, v7, v0, v1, v2, v3, v4, v5, R2, 0x4D2C6DFC); + P(v5, v6, v7, v0, v1, v2, v3, v4, R3, 0x53380D13); + P(v4, v5, v6, v7, v0, v1, v2, v3, R4, 0x650A7354); + P(v3, v4, v5, v6, v7, v0, v1, v2, R5, 0x766A0ABB); + P(v2, v3, v4, v5, v6, v7, v0, v1, R6, 0x81C2C92E); + P(v1, v2, v3, v4, v5, v6, v7, v0, R7, 0x92722C85); + P(v0, v1, v2, v3, v4, v5, v6, v7, R8, 0xA2BFE8A1); + P(v7, v0, v1, v2, v3, v4, v5, v6, R9, 0xA81A664B); + P(v6, v7, v0, v1, v2, v3, v4, v5, R10, 0xC24B8B70); + P(v5, v6, v7, v0, v1, v2, v3, v4, R11, 0xC76C51A3); + P(v4, v5, v6, v7, v0, v1, v2, v3, R12, 0xD192E819); + P(v3, v4, v5, v6, v7, v0, v1, v2, R13, 0xD6990624); + P(v2, v3, v4, v5, v6, v7, v0, v1, R14, 0xF40E3585); + P(v1, v2, v3, v4, v5, v6, v7, v0, R15, 0x106AA070); + + P(v0, v1, v2, v3, v4, v5, v6, v7, R0, 0x19A4C116); + P(v7, v0, v1, v2, v3, v4, v5, v6, R1, 0x1E376C08); + P(v6, v7, v0, v1, v2, v3, v4, v5, R2, 0x2748774C); + P(v5, v6, v7, v0, v1, v2, v3, v4, R3, 0x34B0BCB5); + P(v4, v5, v6, v7, v0, v1, v2, v3, R4, 0x391C0CB3); + P(v3, v4, v5, v6, v7, v0, v1, v2, R5, 0x4ED8AA4A); + P(v2, v3, v4, v5, v6, v7, v0, v1, R6, 0x5B9CCA4F); + P(v1, v2, v3, v4, v5, v6, v7, v0, R7, 0x682E6FF3); + P(v0, v1, v2, v3, v4, v5, v6, v7, R8, 0x748F82EE); + P(v7, v0, v1, v2, v3, v4, v5, v6, R9, 0x78A5636F); + P(v6, v7, v0, v1, v2, v3, v4, v5, R10, 0x84C87814); + P(v5, v6, v7, v0, v1, v2, v3, v4, R11, 0x8CC70208); + P(v4, v5, v6, v7, v0, v1, v2, v3, R12, 0x90BEFFFA); + P(v3, v4, v5, v6, v7, v0, v1, v2, R13, 0xA4506CEB); + P(v2, v3, v4, v5, v6, v7, v0, v1, RD14, 0xBEF9A3F7); + P(v1, v2, v3, v4, v5, v6, v7, v0, RD15, 0xC67178F2); + + res.s0 = (v0 + buf.s0); + res.s1 = (v1 + buf.s1); + res.s2 = (v2 + buf.s2); + res.s3 = (v3 + buf.s3); + res.s4 = (v4 + buf.s4); + res.s5 = (v5 + buf.s5); + res.s6 = (v6 + buf.s6); + res.s7 = (v7 + buf.s7); + return (res); +} + +static inline uint8 sha256_80(uint* data,uint nonce) +{ + +uint8 buf = sha256_round1( ((uint16*)data)[0]); +uint16 in = padsha80; +in.s0 = data[16]; +in.s1 = data[17]; +in.s2 = data[18]; +in.s3 = nonce; + +return(sha256_round2(in,buf)); +} + diff --git a/miner.h b/miner.h index 9917fdeb3..0d98a8e50 100644 --- a/miner.h +++ b/miner.h @@ -1136,8 +1136,8 @@ extern bool add_pool_details(struct pool *pool, bool live, char *url, char *user #define MAX_GPUDEVICES 16 #define MAX_DEVICES 4096 -#define MIN_INTENSITY 8 -#define MIN_INTENSITY_STR "8" +#define MIN_INTENSITY 4 +#define MIN_INTENSITY_STR "4" #define MAX_INTENSITY 31 #define MAX_INTENSITY_STR "31" #define MIN_XINTENSITY 1 diff --git a/ocl.c b/ocl.c index 441a8a39c..73a79939d 100644 --- a/ocl.c +++ b/ocl.c @@ -36,6 +36,7 @@ #include "ocl/binary_kernel.h" #include "algorithm/neoscrypt.h" #include "algorithm/pluck.h" +#include "algorithm/yescrypt.h" /* FIXME: only here for global config vars, replace with configuration.h * or similar as soon as config is in a struct instead of littered all @@ -514,7 +515,90 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize, algorithm_t *alg cgpu->thread_concurrency = glob_thread_count; applog(LOG_DEBUG, "GPU %d: computing max. global thread count to %u", gpu, (unsigned)(cgpu->thread_concurrency)); + } + else if (!safe_cmp(cgpu->algorithm.name, "yescrypt") && !cgpu->opt_tc) { + size_t glob_thread_count; + long max_int; + unsigned char type = 0; + + // determine which intensity type to use + if (cgpu->rawintensity > 0) { + glob_thread_count = cgpu->rawintensity; + max_int = glob_thread_count; + type = 2; + } + else if (cgpu->xintensity > 0) { + glob_thread_count = clState->compute_shaders * ((cgpu->algorithm.xintensity_shift) ? (1UL << (cgpu->algorithm.xintensity_shift + cgpu->xintensity)) : cgpu->xintensity); + max_int = cgpu->xintensity; + type = 1; + } + else { + glob_thread_count = 1UL << (cgpu->algorithm.intensity_shift + cgpu->intensity); + max_int = ((cgpu->dynamic) ? MAX_INTENSITY : cgpu->intensity); + } + + glob_thread_count = ((glob_thread_count < cgpu->work_size) ? cgpu->work_size : glob_thread_count); + + // if TC * scratchbuf size is too big for memory... reduce to max + if ((glob_thread_count * YESCRYPT_SCRATCHBUF_SIZE) >= (uint64_t)cgpu->max_alloc) { + + /* Selected intensity will not run on this GPU. Not enough memory. + * Adapt the memory setting. */ + // depending on intensity type used, reduce the intensity until it fits into the GPU max_alloc + switch (type) { + //raw intensity + case 2: + while ((glob_thread_count * YESCRYPT_SCRATCHBUF_SIZE) > (uint64_t)cgpu->max_alloc) { + --glob_thread_count; + } + + max_int = glob_thread_count; + cgpu->rawintensity = glob_thread_count; + break; + + //x intensity + case 1: + glob_thread_count = cgpu->max_alloc / YESCRYPT_SCRATCHBUF_SIZE; + max_int = glob_thread_count / clState->compute_shaders; + + while (max_int && ((clState->compute_shaders * (1UL << max_int)) > glob_thread_count)) { + --max_int; + } + + /* Check if max_intensity is >0. */ + if (max_int < MIN_XINTENSITY) { + applog(LOG_ERR, "GPU %d: Max xintensity is below minimum.", gpu); + max_int = MIN_XINTENSITY; + } + + cgpu->xintensity = max_int; + glob_thread_count = clState->compute_shaders * (1UL << max_int); + break; + + default: + glob_thread_count = cgpu->max_alloc / YESCRYPT_SCRATCHBUF_SIZE; + while (max_int && ((1UL << max_int) & glob_thread_count) == 0) { + --max_int; + } + + /* Check if max_intensity is >0. */ + if (max_int < MIN_INTENSITY) { + applog(LOG_ERR, "GPU %d: Max intensity is below minimum.", gpu); + max_int = MIN_INTENSITY; + } + + cgpu->intensity = max_int; + glob_thread_count = 1UL << max_int; + break; + } + } + // TC is glob thread count + cgpu->thread_concurrency = glob_thread_count; + + applog(LOG_DEBUG, "GPU %d: computing max. global thread count to %u", gpu, (unsigned)(cgpu->thread_concurrency)); + + } else if (!cgpu->opt_tc) { unsigned int sixtyfours; @@ -611,7 +695,7 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize, algorithm_t *alg snprintf(kernel_name, 9, "%s%d", "search", i + 1); clState->extra_kernels[i] = clCreateKernel(clState->program, kernel_name, &status); if (status != CL_SUCCESS) { - applog(LOG_ERR, "Error %d: Creating ExtraKernel #%d from program. (clCreateKernel)", status, i); + applog(LOG_DEBUG, "Error %d: Creating ExtraKernel #%d from program. (clCreateKernel)", status, i); return NULL; } } @@ -633,6 +717,20 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize, algorithm_t *alg applog(LOG_DEBUG, "Neoscrypt buffer sizes: %lu RW, %lu R", (unsigned long)bufsize, (unsigned long)readbufsize); // scrypt/n-scrypt } + else if (!safe_cmp(algorithm->name, "yescrypt")) { + /* The scratch/pad-buffer needs 32kBytes memory per thread. */ + bufsize = YESCRYPT_SCRATCHBUF_SIZE * cgpu->thread_concurrency; + + /* This is the input buffer. For yescrypt this is guaranteed to be + * 80 bytes only. */ + readbufsize = 80; + + applog(LOG_DEBUG, "yescrypt buffer sizes: %lu RW, %lu R", (unsigned long)bufsize, (unsigned long)readbufsize); + // scrypt/n-scrypt + + + + } else if (!safe_cmp(algorithm->name, "pluck")) { /* The scratch/pad-buffer needs 32kBytes memory per thread. */ bufsize = PLUCK_SCRATCHBUF_SIZE * cgpu->thread_concurrency; @@ -666,6 +764,29 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize, algorithm_t *alg applog(LOG_WARNING, "Your settings come to %lu", (unsigned long)bufsize); } + + if (!safe_cmp(algorithm->name, "yescrypt")) { +// need additionnal buffers + clState->buffer1 = clCreateBuffer(clState->context, CL_MEM_READ_WRITE, PLUCK_SECBUF_SIZE * cgpu->thread_concurrency, NULL, &status); + if (status != CL_SUCCESS && !clState->buffer1) { + applog(LOG_DEBUG, "Error %d: clCreateBuffer (buffer1), decrease TC or increase LG", status); + return NULL;} + + clState->buffer2 = clCreateBuffer(clState->context, CL_MEM_READ_WRITE, 128 * 8 * 8 * cgpu->thread_concurrency, NULL, &status); + if (status != CL_SUCCESS && !clState->buffer2) { + applog(LOG_DEBUG, "Error %d: clCreateBuffer (buffer2), decrease TC or increase LG", status); + return NULL; + } + + clState->buffer3 = clCreateBuffer(clState->context, CL_MEM_READ_WRITE, 8 * 8 * 4 * cgpu->thread_concurrency, NULL, &status); + if (status != CL_SUCCESS && !clState->buffer3) { + applog(LOG_DEBUG, "Error %d: clCreateBuffer (buffer3), decrease TC or increase LG", status); + return NULL; + } + + +} + /* This buffer is weird and might work to some degree even if * the create buffer call has apparently failed, so check if we * get anything back before we call it a failure. */ diff --git a/ocl.h b/ocl.h index 272246da1..9fa348d38 100644 --- a/ocl.h +++ b/ocl.h @@ -22,6 +22,9 @@ typedef struct __clState { cl_mem outputBuffer; cl_mem CLbuffer0; cl_mem padbuffer8; + cl_mem buffer1; + cl_mem buffer2; + cl_mem buffer3; unsigned char cldata[80]; bool hasBitAlign; bool goffset; diff --git a/sgminer.c b/sgminer.c index 28b16d308..fcbc94d75 100644 --- a/sgminer.c +++ b/sgminer.c @@ -7081,7 +7081,8 @@ bool test_nonce(struct work *work, uint32_t nonce) rebuild_nonce(work, nonce); // for Neoscrypt, the diff1targ value is in work->target - if (!safe_cmp(work->pool->algorithm.name, "neoscrypt") || !safe_cmp(work->pool->algorithm.name, "pluck")) { + if (!safe_cmp(work->pool->algorithm.name, "neoscrypt") || !safe_cmp(work->pool->algorithm.name, "pluck") + || !safe_cmp(work->pool->algorithm.name, "yescrypt") ) { diff1targ = ((uint32_t *)work->target)[7]; } else { @@ -8725,7 +8726,8 @@ int main(int argc, char *argv[]) #endif /* Default algorithm specified in algorithm.c ATM */ - set_algorithm(&default_profile.algorithm, "scrypt"); + /* changed to x11 which won't cause crash*/ + set_algorithm(&default_profile.algorithm, "x11"); devcursor = 8; logstart = devcursor + 1; diff --git a/sph/Makefile.am b/sph/Makefile.am index d80e438ad..bc2f4b238 100644 --- a/sph/Makefile.am +++ b/sph/Makefile.am @@ -1,3 +1,3 @@ noinst_LIBRARIES = libsph.a -libsph_a_SOURCES = bmw.c echo.c jh.c luffa.c simd.c blake.c cubehash.c groestl.c keccak.c shavite.c skein.c sha2.c sha2big.c fugue.c hamsi.c panama.c shabal.c whirlpool.c +libsph_a_SOURCES = bmw.c echo.c jh.c luffa.c simd.c blake.c cubehash.c groestl.c keccak.c shavite.c skein.c sha2.c sha2big.c fugue.c hamsi.c panama.c shabal.c whirlpool.c sha256_Y.c diff --git a/sph/sha256_Y.c b/sph/sha256_Y.c new file mode 100644 index 000000000..a5d786d3f --- /dev/null +++ b/sph/sha256_Y.c @@ -0,0 +1,418 @@ +/*- + * Copyright 2005,2007,2009 Colin Percival + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include +#include + +#include "algorithm/sysendian.h" + +#include "sph/sha256_Y.h" + +/* + * Encode a length len/4 vector of (uint32_t) into a length len vector of + * (unsigned char) in big-endian form. Assumes len is a multiple of 4. + */ +static void +be32enc_vect(unsigned char *dst, const uint32_t *src, size_t len) +{ + size_t i; + + for (i = 0; i < len / 4; i++) + be32enc(dst + i * 4, src[i]); +} + +/* + * Decode a big-endian length len vector of (unsigned char) into a length + * len/4 vector of (uint32_t). Assumes len is a multiple of 4. + */ +static void +be32dec_vect(uint32_t *dst, const unsigned char *src, size_t len) +{ + size_t i; + + for (i = 0; i < len / 4; i++) + dst[i] = be32dec(src + i * 4); +} + +/* Elementary functions used by SHA256 */ +#define Ch(x, y, z) ((x & (y ^ z)) ^ z) +#define Maj(x, y, z) ((x & (y | z)) | (y & z)) +#define SHR(x, n) (x >> n) +#define ROTR(x, n) ((x >> n) | (x << (32 - n))) +#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) +#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) +#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3)) +#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10)) + +/* SHA256 round function */ +#define RND(a, b, c, d, e, f, g, h, k) \ + t0 = h + S1(e) + Ch(e, f, g) + k; \ + t1 = S0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + +/* Adjusted round function for rotating state */ +#define RNDr(S, W, i, k) \ + RND(S[(64 - i) % 8], S[(65 - i) % 8], \ + S[(66 - i) % 8], S[(67 - i) % 8], \ + S[(68 - i) % 8], S[(69 - i) % 8], \ + S[(70 - i) % 8], S[(71 - i) % 8], \ + W[i] + k) + +/* + * SHA256 block compression function. The 256-bit state is transformed via + * the 512-bit input block to produce a new state. + */ +static void +SHA256_Transform(uint32_t * state, const unsigned char block[64]) +{ + uint32_t W[64]; + uint32_t S[8]; + uint32_t t0, t1; + int i; + /* 1. Prepare message schedule W. */ + be32dec_vect(W, block, 64); + + for (i = 16; i < 64; i++) + W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; + + /* 2. Initialize working variables. */ + memcpy(S, state, 32); + + /* 3. Mix. */ + RNDr(S, W, 0, 0x428a2f98); + RNDr(S, W, 1, 0x71374491); + RNDr(S, W, 2, 0xb5c0fbcf); + RNDr(S, W, 3, 0xe9b5dba5); + RNDr(S, W, 4, 0x3956c25b); + RNDr(S, W, 5, 0x59f111f1); + RNDr(S, W, 6, 0x923f82a4); + RNDr(S, W, 7, 0xab1c5ed5); + RNDr(S, W, 8, 0xd807aa98); + RNDr(S, W, 9, 0x12835b01); + RNDr(S, W, 10, 0x243185be); + RNDr(S, W, 11, 0x550c7dc3); + RNDr(S, W, 12, 0x72be5d74); + RNDr(S, W, 13, 0x80deb1fe); + RNDr(S, W, 14, 0x9bdc06a7); + RNDr(S, W, 15, 0xc19bf174); + RNDr(S, W, 16, 0xe49b69c1); + RNDr(S, W, 17, 0xefbe4786); + RNDr(S, W, 18, 0x0fc19dc6); + RNDr(S, W, 19, 0x240ca1cc); + RNDr(S, W, 20, 0x2de92c6f); + RNDr(S, W, 21, 0x4a7484aa); + RNDr(S, W, 22, 0x5cb0a9dc); + RNDr(S, W, 23, 0x76f988da); + RNDr(S, W, 24, 0x983e5152); + RNDr(S, W, 25, 0xa831c66d); + RNDr(S, W, 26, 0xb00327c8); + RNDr(S, W, 27, 0xbf597fc7); + RNDr(S, W, 28, 0xc6e00bf3); + RNDr(S, W, 29, 0xd5a79147); + RNDr(S, W, 30, 0x06ca6351); + RNDr(S, W, 31, 0x14292967); + RNDr(S, W, 32, 0x27b70a85); + RNDr(S, W, 33, 0x2e1b2138); + RNDr(S, W, 34, 0x4d2c6dfc); + RNDr(S, W, 35, 0x53380d13); + RNDr(S, W, 36, 0x650a7354); + RNDr(S, W, 37, 0x766a0abb); + RNDr(S, W, 38, 0x81c2c92e); + RNDr(S, W, 39, 0x92722c85); + RNDr(S, W, 40, 0xa2bfe8a1); + RNDr(S, W, 41, 0xa81a664b); + RNDr(S, W, 42, 0xc24b8b70); + RNDr(S, W, 43, 0xc76c51a3); + RNDr(S, W, 44, 0xd192e819); + RNDr(S, W, 45, 0xd6990624); + RNDr(S, W, 46, 0xf40e3585); + RNDr(S, W, 47, 0x106aa070); + RNDr(S, W, 48, 0x19a4c116); + RNDr(S, W, 49, 0x1e376c08); + RNDr(S, W, 50, 0x2748774c); + RNDr(S, W, 51, 0x34b0bcb5); + RNDr(S, W, 52, 0x391c0cb3); + RNDr(S, W, 53, 0x4ed8aa4a); + RNDr(S, W, 54, 0x5b9cca4f); + RNDr(S, W, 55, 0x682e6ff3); + RNDr(S, W, 56, 0x748f82ee); + RNDr(S, W, 57, 0x78a5636f); + RNDr(S, W, 58, 0x84c87814); + RNDr(S, W, 59, 0x8cc70208); + RNDr(S, W, 60, 0x90befffa); + RNDr(S, W, 61, 0xa4506ceb); + RNDr(S, W, 62, 0xbef9a3f7); + RNDr(S, W, 63, 0xc67178f2); + + /* 4. Mix local working variables into global state */ + for (i = 0; i < 8; i++) { + state[i] += S[i]; + +} + + /* Clean the stack. */ + memset(W, 0, 256); + memset(S, 0, 32); + t0 = t1 = 0; +} + +static unsigned char PAD[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* Add padding and terminating bit-count. */ +static void +SHA256_Pad(SHA256_CTX_Y * ctx) +{ + unsigned char len[8]; + uint32_t r, plen; + + /* + * Convert length to a vector of bytes -- we do this now rather + * than later because the length will change after we pad. + */ + be32enc_vect(len, ctx->count, 8); + + /* Add 1--64 bytes so that the resulting length is 56 mod 64 */ + r = (ctx->count[1] >> 3) & 0x3f; + plen = (r < 56) ? (56 - r) : (120 - r); + SHA256_Update_Y(ctx, PAD, (size_t)plen); + + /* Add the terminating bit-count */ + SHA256_Update_Y(ctx, len, 8); +} + +/* SHA-256 initialization. Begins a SHA-256 operation. */ +void +SHA256_Init_Y(SHA256_CTX_Y * ctx) +{ + + /* Zero bits processed so far */ + ctx->count[0] = ctx->count[1] = 0; + + /* Magic initialization constants */ + ctx->state[0] = 0x6A09E667; + ctx->state[1] = 0xBB67AE85; + ctx->state[2] = 0x3C6EF372; + ctx->state[3] = 0xA54FF53A; + ctx->state[4] = 0x510E527F; + ctx->state[5] = 0x9B05688C; + ctx->state[6] = 0x1F83D9AB; + ctx->state[7] = 0x5BE0CD19; +} + +/* Add bytes into the hash */ +void +SHA256_Update_Y(SHA256_CTX_Y * ctx, const void *in, size_t len) +{ + uint32_t bitlen[2]; + uint32_t r; + const unsigned char *src = in; + + /* Number of bytes left in the buffer from previous updates */ + r = (ctx->count[1] >> 3) & 0x3f; + + /* Convert the length into a number of bits */ + bitlen[1] = ((uint32_t)len) << 3; + bitlen[0] = (uint32_t)(len >> 29); + + /* Update number of bits */ + if ((ctx->count[1] += bitlen[1]) < bitlen[1]) + ctx->count[0]++; + ctx->count[0] += bitlen[0]; + + /* Handle the case where we don't need to perform any transforms */ + if (len < 64 - r) { + + memcpy(&ctx->buf[r], src, len); + return; + } + + /* Finish the current block */ + memcpy(&ctx->buf[r], src, 64 - r); + + SHA256_Transform(ctx->state, ctx->buf); + src += 64 - r; + len -= 64 - r; + + /* Perform complete blocks */ + + while (len >= 64) { + SHA256_Transform(ctx->state, src); + src += 64; + len -= 64; + } + + /* Copy left over data into buffer */ + memcpy(ctx->buf, src, len); +} + +/* + * SHA-256 finalization. Pads the input data, exports the hash value, + * and clears the context state. + */ +void +SHA256_Final_Y(unsigned char digest[32], SHA256_CTX_Y * ctx) +{ + /* Add padding */ + SHA256_Pad(ctx); + + /* Write the hash */ + be32enc_vect(digest, ctx->state, 32); + + /* Clear the context state */ + memset((void *)ctx, 0, sizeof(*ctx)); +} + +/* Initialize an HMAC-SHA256 operation with the given key. */ +void +HMAC_SHA256_Init_Y(HMAC_SHA256_CTX_Y * ctx, const void * _K, size_t Klen) +{ + unsigned char pad[64]; + unsigned char khash[32]; + const unsigned char * K = _K; + size_t i; + + /* If Klen > 64, the key is really SHA256(K). */ + if (Klen > 64) { + SHA256_Init_Y(&ctx->ictx); + SHA256_Update_Y(&ctx->ictx, K, Klen); + SHA256_Final_Y(khash, &ctx->ictx); + K = khash; + Klen = 32; + } + + /* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */ + SHA256_Init_Y(&ctx->ictx); + memset(pad, 0x36, 64); + for (i = 0; i < Klen; i++) { + pad[i] ^= K[i]; + } + SHA256_Update_Y(&ctx->ictx, pad, 64); + + /* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */ + SHA256_Init_Y(&ctx->octx); + memset(pad, 0x5c, 64); + for (i = 0; i < Klen; i++) + { + pad[i] ^= K[i]; + } + SHA256_Update_Y(&ctx->octx, pad, 64); + + /* Clean the stack. */ + memset(khash, 0, 32); +} + +/* Add bytes to the HMAC-SHA256 operation. */ +void +HMAC_SHA256_Update_Y(HMAC_SHA256_CTX_Y * ctx, const void *in, size_t len) +{ + /* Feed data to the inner SHA256 operation. */ + SHA256_Update_Y(&ctx->ictx, in, len); +} + +/* Finish an HMAC-SHA256 operation. */ +void +HMAC_SHA256_Final_Y(unsigned char digest[32], HMAC_SHA256_CTX_Y * ctx) +{ + unsigned char ihash[32]; + + /* Finish the inner SHA256 operation. */ + SHA256_Final_Y(ihash, &ctx->ictx); + + /* Feed the inner hash to the outer SHA256 operation. */ + SHA256_Update_Y(&ctx->octx, ihash, 32); + + /* Finish the outer SHA256 operation. */ + SHA256_Final_Y(digest, &ctx->octx); + + /* Clean the stack. */ + memset(ihash, 0, 32); +} + +/** + * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): + * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and + * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). + */ + +void +PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt, +size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen) +{ + HMAC_SHA256_CTX_Y PShctx, hctx; + size_t i; + uint8_t ivec[4]; + uint8_t U[32]; + uint8_t T[32]; + uint64_t j; + int k; + size_t clen; + + /* Compute HMAC state after processing P and S. */ + HMAC_SHA256_Init_Y(&PShctx, passwd, passwdlen); + HMAC_SHA256_Update_Y(&PShctx, salt, saltlen); + + /* Iterate through the blocks. */ + for (i = 0; i * 32 < dkLen; i++) { + /* Generate INT(i + 1). */ + be32enc(ivec, (uint32_t)(i + 1)); + + /* Compute U_1 = PRF(P, S || INT(i)). */ + memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX_Y)); + HMAC_SHA256_Update_Y(&hctx, ivec, 4); + HMAC_SHA256_Final_Y(U, &hctx); + + /* T_i = U_1 ... */ + memcpy(T, U, 32); + + for (j = 2; j <= c; j++) { + /* Compute U_j. */ + HMAC_SHA256_Init_Y(&hctx, passwd, passwdlen); + HMAC_SHA256_Update_Y(&hctx, U, 32); + HMAC_SHA256_Final_Y(U, &hctx); + + /* ... xor U_j ... */ + for (k = 0; k < 32; k++) + T[k] ^= U[k]; + } + + /* Copy as many bytes as necessary into buf. */ + clen = dkLen - i * 32; + if (clen > 32) + clen = 32; + memcpy(&buf[i * 32], T, clen); + } + + /* Clean PShctx, since we never called _Final on it. */ + memset(&PShctx, 0, sizeof(HMAC_SHA256_CTX_Y)); +} diff --git a/sph/sha256_Y.h b/sph/sha256_Y.h new file mode 100644 index 000000000..e97b81ba2 --- /dev/null +++ b/sph/sha256_Y.h @@ -0,0 +1,63 @@ +/*- + * Copyright 2005,2007,2009 Colin Percival + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libmd/sha256_Y.h,v 1.2 2006/01/17 15:35:56 phk Exp $ + */ + +#ifndef _SHA256_H_ +#define _SHA256_H_ + +#include + +#include + +typedef struct SHA256Context { + uint32_t state[8]; + uint32_t count[2]; + unsigned char buf[64]; +} SHA256_CTX_Y; + +typedef struct HMAC_SHA256Context { + SHA256_CTX_Y ictx; + SHA256_CTX_Y octx; +} HMAC_SHA256_CTX_Y; + +void SHA256_Init_Y(SHA256_CTX_Y *); +void SHA256_Update_Y(SHA256_CTX_Y *, const void *, size_t); +void SHA256_Final_Y(unsigned char [32], SHA256_CTX_Y *); +void HMAC_SHA256_Init_Y(HMAC_SHA256_CTX_Y *, const void *, size_t); +void HMAC_SHA256_Update_Y(HMAC_SHA256_CTX_Y *, const void *, size_t); +void HMAC_SHA256_Final_Y(unsigned char [32], HMAC_SHA256_CTX_Y *); + +/** + * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): + * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and + * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). + */ +void PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t, + uint64_t, uint8_t *, size_t); + + +#endif /* !_SHA256_H_ */ From f5f828cbc4854054fab7a2cecb2a645f219c4d11 Mon Sep 17 00:00:00 2001 From: djm34 Date: Sat, 2 May 2015 15:39:31 +0200 Subject: [PATCH 11/27] faster kernels choice between --kernel yescrypt and --kernel yescrypt-multi --kernel yescrypt for amd --kernel yescrypt-multi for nvidia (> 5.0) --- algorithm.c | 74 +++++--- algorithm.h | 3 +- driver-opencl.c | 8 +- example.bat | 4 +- kernel/yescrypt-multi.cl | 314 ++++++++++++++++++++++++++++++++ kernel/yescrypt.cl | 338 +++++++++++++++++------------------ kernel/yescrypt_essential.cl | 16 +- ocl.c | 27 ++- sgminer.c | 4 +- sgminer.exe | Bin 0 -> 1675783 bytes 10 files changed, 576 insertions(+), 212 deletions(-) create mode 100644 kernel/yescrypt-multi.cl create mode 100644 sgminer.exe diff --git a/algorithm.c b/algorithm.c index 57df5634c..212ef648f 100644 --- a/algorithm.c +++ b/algorithm.c @@ -58,7 +58,8 @@ const char *algorithm_type_str[] = { "Neoscrypt", "Lyra2RE", "pluck", - "yescrypt" + "yescrypt", + "yescrypt-multi" }; void sha256(const unsigned char *message, unsigned int len, unsigned char *digest) @@ -196,6 +197,8 @@ static cl_int queue_pluck_kernel(_clState *clState, dev_blk_ctx *blk, __maybe_un le_target = (cl_uint)le32toh(((uint32_t *)blk->work->/*device_*/target)[7]); // memcpy(clState->cldata, blk->work->data, 80); flip80(clState->cldata, blk->work->data); +//int i; +//for (i = 0; i<20; i++) ((uint32_t*)clState->cldata)[i] = ((uint32_t*)blk->work->data)[i]; // don't flip status = clEnqueueWriteBuffer(clState->commandQueue, clState->CLbuffer0, true, 0, 80, clState->cldata, 0, NULL, NULL); CL_SET_ARG(clState->CLbuffer0); @@ -215,9 +218,12 @@ static cl_int queue_yescrypt_kernel(_clState *clState, dev_blk_ctx *blk, __maybe cl_int status = 0; - // le_target = (*(cl_uint *)(blk->work->device_target + 28)); +// le_target = (*(cl_uint *)(blk->work->device_target + 28)); le_target = (cl_uint)le32toh(((uint32_t *)blk->work->/*device_*/target)[7]); - // memcpy(clState->cldata, blk->work->data, 80); +// le_target = (cl_uint)((uint32_t *)blk->work->target)[7]; + + +// memcpy(clState->cldata, blk->work->data, 80); flip80(clState->cldata, blk->work->data); status = clEnqueueWriteBuffer(clState->commandQueue, clState->CLbuffer0, true, 0, 80, clState->cldata, 0, NULL, NULL); @@ -225,6 +231,7 @@ static cl_int queue_yescrypt_kernel(_clState *clState, dev_blk_ctx *blk, __maybe CL_SET_ARG(clState->outputBuffer); CL_SET_ARG(clState->padbuffer8); CL_SET_ARG(clState->buffer1); + CL_SET_ARG(clState->buffer2); CL_SET_ARG(le_target); return status; @@ -241,29 +248,54 @@ static cl_int queue_yescrypt_multikernel(_clState *clState, dev_blk_ctx *blk, __ // le_target = (*(cl_uint *)(blk->work->device_target + 28)); le_target = (cl_uint)le32toh(((uint32_t *)blk->work->/*device_*/target)[7]); - // memcpy(clState->cldata, blk->work->data, 80); - flip80(clState->cldata, blk->work->data); + memcpy(clState->cldata, blk->work->data, 80); +// flip80(clState->cldata, blk->work->data); status = clEnqueueWriteBuffer(clState->commandQueue, clState->CLbuffer0, true, 0, 80, clState->cldata, 0, NULL, NULL); //pbkdf and initial sha kernel = &clState->kernel; - CL_SET_ARG_0(clState->CLbuffer0); + + CL_SET_ARG(clState->CLbuffer0); + CL_SET_ARG(clState->outputBuffer); + CL_SET_ARG(clState->padbuffer8); + CL_SET_ARG(clState->buffer1); CL_SET_ARG(clState->buffer2); CL_SET_ARG(clState->buffer3); -//mix1_1 (salsa) + CL_SET_ARG(le_target); + +//inactive kernel num = 0; kernel = clState->extra_kernels; - CL_SET_ARG_0(clState->buffer1); - CL_SET_ARG(clState->buffer2); -//mix1_2/2_2 (pwxform) - CL_NEXTKERNEL_SET_ARG_0(clState->padbuffer8); - CL_SET_ARG(clState->buffer1); - CL_SET_ARG(clState->buffer2); + CL_SET_ARG_N(0,clState->buffer1); + CL_SET_ARG_N(1,clState->buffer2); +// CL_SET_ARG_N(3, clState->buffer3); + //mix2_2 -// CL_NEXTKERNEL_SET_ARG_0(clState->padbuffer8); -// CL_SET_ARG(clState->buffer1); -// CL_SET_ARG(clState->buffer2); + num = 0; + CL_NEXTKERNEL_SET_ARG_N(0, clState->padbuffer8); + CL_SET_ARG_N(1,clState->buffer1); + CL_SET_ARG_N(2,clState->buffer2); + //mix2_2 +//inactive kernel +// num = 0; +// CL_NEXTKERNEL_SET_ARG_N(0, clState->buffer1); +// CL_SET_ARG_N(1, clState->buffer2); + //mix2_2 + + num = 0; + CL_NEXTKERNEL_SET_ARG_N(0, clState->padbuffer8); + CL_SET_ARG_N(1, clState->buffer1); + CL_SET_ARG_N(2, clState->buffer2); + + //inactive kernel +// num = 0; +// CL_NEXTKERNEL_SET_ARG_N(0, clState->buffer1); +// CL_SET_ARG_N(1, clState->buffer2); + //mix2_2 + + //pbkdf and finalization - CL_NEXTKERNEL_SET_ARG_0(clState->CLbuffer0); + num=0; + CL_NEXTKERNEL_SET_ARG(clState->CLbuffer0); CL_SET_ARG(clState->outputBuffer); CL_SET_ARG(clState->buffer2); CL_SET_ARG(clState->buffer3); @@ -819,10 +851,10 @@ static algorithm_settings_t algos[] = { A_YESCRYPT("yescrypt"), #undef A_YESCRYPT -//#define A_YESCRYPT(a) \ -// { a, ALGO_YESCRYPT, "", 1, 65536, 65536, 0, 0, 0xFF, 0xFFFF000000000000ULL, 0x0000ffffUL, 3, -1,CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE , yescrypt_regenhash, queue_yescrypt_multikernel, gen_hash, append_neoscrypt_compiler_options} -// A_YESCRYPT("yescrypt"), -//#undef A_YESCRYPT +#define A_YESCRYPT_MULTI(a) \ + { a, ALGO_YESCRYPT_MULTI, "", 1, 65536, 65536, 0, 0, 0xFF, 0xFFFF000000000000ULL, 0x0000ffffUL, 4,-1,CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE , yescrypt_regenhash, queue_yescrypt_multikernel, gen_hash, append_neoscrypt_compiler_options} + A_YESCRYPT_MULTI("yescrypt-multi"), +#undef A_YESCRYPT_MULTI // kernels starting from this will have difficulty calculated by using quarkcoin algorithm diff --git a/algorithm.h b/algorithm.h index 2e072f0dd..16ead85fe 100644 --- a/algorithm.h +++ b/algorithm.h @@ -28,7 +28,8 @@ typedef enum { ALGO_NEOSCRYPT, ALGO_LYRA2RE, ALGO_PLUCK, - ALGO_YESCRYPT + ALGO_YESCRYPT, + ALGO_YESCRYPT_MULTI, } algorithm_type_t; extern const char *algorithm_type_str[]; diff --git a/driver-opencl.c b/driver-opencl.c index aa56d1d36..a912732b2 100644 --- a/driver-opencl.c +++ b/driver-opencl.c @@ -1431,7 +1431,7 @@ static int64_t opencl_scanhash(struct thr_info *thr, struct work *work, status = clEnqueueNDRangeKernel(clState->commandQueue, clState->extra_kernels[i], 1, p_global_work_offset, globalThreads, localThreads, 0, NULL, NULL); if (unlikely(status != CL_SUCCESS)) { - applog(LOG_ERR, "Error %d: Enqueueing kernel onto command queue. (clEnqueueNDRangeKernel)", status); + applog(LOG_ERR, "Error %d: Enqueueing kernel onto command queue. (clEnqueueNDRangeKernel) %d", status,i); return -1; } } @@ -1483,6 +1483,12 @@ static void opencl_thread_shutdown(struct thr_info *thr) clFinish(clState->commandQueue); clReleaseMemObject(clState->outputBuffer); clReleaseMemObject(clState->CLbuffer0); + if (clState->buffer1) + clReleaseMemObject(clState->buffer1); + if (clState->buffer2) + clReleaseMemObject(clState->buffer2); + if (clState->buffer3) + clReleaseMemObject(clState->buffer3); if (clState->padbuffer8) clReleaseMemObject(clState->padbuffer8); clReleaseKernel(clState->kernel); diff --git a/example.bat b/example.bat index 2206270df..db97f5631 100644 --- a/example.bat +++ b/example.bat @@ -6,7 +6,7 @@ del *.bin @rem sgminer.exe --no-submit-stale --kernel Lyra2RE -o stratum+tcp://pool.verters.com:4444 -u djm34t.user -p password --gpu-platform 2 @rem sgminer.exe --no-submit-stale --kernel pluck -o stratum+tcp://sup.suprnova.cc:7777 -u djm34.2 -p password --gpu-platform 2 --thread-concurrency 8192 -w 4 -I 12 @rem sgminer.exe --no-submit-stale --kernel yescrypt -o stratum+tcp://mine2.bsty.nonce-pool.com:4095 -u djm34.1 -p password --gpu-platform 1 -w 32 --thread-concurrency 512 --text-only --debug -@rem sgminer.exe --no-submit-stale --kernel yescrypt -o stratum+tcp://mine2.bsty.nonce-pool.com:4095 -u djm34.1 -p password --gpu-platform 1 -w 32 --thread-concurrency 512 --text-only -D +sgminer.exe --no-submit-stale --kernel yescrypt -o stratum+tcp://mine2.bsty.nonce-pool.com:4095 -u djm34.1 -p password --gpu-platform 1 -w 8 --thread-concurrency 1024 -I 9 -sgminer.exe --no-submit-stale --kernel yescrypt -o stratum+tcp://mine2.bsty.nonce-pool.com:4095 -u djm34.1 -p password --gpu-platform 0 -w 16 -g 2 +@rem sgminer.exe --no-submit-stale --kernel yescrypt-multi -o stratum+tcp://mine2.bsty.nonce-pool.com:4095 -u djm34.1 -p password --gpu-platform 0 -w 4 -g 2 pause \ No newline at end of file diff --git a/kernel/yescrypt-multi.cl b/kernel/yescrypt-multi.cl new file mode 100644 index 000000000..3af7b28ac --- /dev/null +++ b/kernel/yescrypt-multi.cl @@ -0,0 +1,314 @@ +/* +* "yescrypt" kernel implementation. +* +* ==========================(LICENSE BEGIN)============================ +* +* Copyright (c) 2015 djm34 +* +* 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 djm34 +*/ +#if !defined(cl_khr_byte_addressable_store) +#error "Device does not support unaligned stores" +#endif + +#include "yescrypt_essential.cl" + +__attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) +__kernel void search(__global const uchar* restrict input, __global uint* restrict output, __global uchar *padcache, __global uchar* buff1, __global uchar* buff2, __global uchar* buff3, const uint target) +{ + + __global ulong16 *hashbuffer = (__global ulong16 *)(padcache + (2048 * 128 * sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))); + __global ulong16 *prevstate = (__global ulong16 *)(buff1 + (64 * 128 * sizeof(ulong)*(get_global_id(0) % MAX_GLOBAL_THREADS))); + __global uint8 *sha256tokeep = (__global uint8 *)(buff3 + (8 * sizeof(uint)*(get_global_id(0) % MAX_GLOBAL_THREADS))); + __global ulong16 *Bdev = (__global ulong16 *)(buff2 + (8 * 128 * sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))); + + + + uint nonce = (get_global_id(0)); + uint data[20]; + uint16 in; + uint8 state1, state2; +// uint8 sha256tokeep; + +// ulong16 Bdev[8]; // will require an additional buffer + ((uint16 *)data)[0] = ((__global const uint16 *)input)[0]; + ((uint4 *)data)[4] = ((__global const uint4 *)input)[4]; +// for (int i = 0; i<20; i++) { data[i] = SWAP32(data[i]); } + // if (nonce == 10) { printf("data %08x %08x\n", data[0], data[1]); } + uint8 passwd = sha256_80(data, nonce); + //pbkdf + in.lo = pad1.lo ^ passwd; + in.hi = pad1.hi; + state1 = sha256_Transform(in, H256); + + in.lo = pad2.lo ^ passwd; + in.hi = pad2.hi; + state2 = sha256_Transform(in, H256); + + in = ((uint16*)data)[0]; + state1 = sha256_Transform(in, state1); +#pragma unroll 1 + for (int i = 0; i<8; i++) + { + uint16 result; + in = pad3; + in.s0 = data[16]; + in.s1 = data[17]; + in.s2 = data[18]; + in.s3 = nonce; + in.s4 = 4 * i + 1; + in.lo = sha256_Transform(in, state1); + in.hi = pad4; + result.lo = swapvec(sha256_Transform(in, state2)); + if (i == 0) sha256tokeep[0] = result.lo; + in = pad3; + in.s0 = data[16]; + in.s1 = data[17]; + in.s2 = data[18]; + in.s3 = nonce; + in.s4 = 4 * i + 2; + in.lo = sha256_Transform(in, state1); + in.hi = pad4; + result.hi = swapvec(sha256_Transform(in, state2)); + Bdev[i].lo = as_ulong8(shuffle(result)); +// Bdev[i].lo = as_ulong8(result); + in = pad3; + in.s0 = data[16]; + in.s1 = data[17]; + in.s2 = data[18]; + in.s3 = nonce; + in.s4 = 4 * i + 3; + in.lo = sha256_Transform(in, state1); + in.hi = pad4; + result.lo = swapvec(sha256_Transform(in, state2)); + in = pad3; + in.s0 = data[16]; + in.s1 = data[17]; + in.s2 = data[18]; + in.s3 = nonce; + in.s4 = 4 * i + 4; + in.lo = sha256_Transform(in, state1); + in.hi = pad4; + result.hi = swapvec(sha256_Transform(in, state2)); + + + Bdev[i].hi = as_ulong8(shuffle(result)); +// Bdev[i].hi = as_ulong8(result); + } + + //mixing1 + + prevstate[0] = Bdev[0]; + Bdev[0] = blockmix_salsa8_small2(Bdev[0]); + prevstate[1] = Bdev[0]; + Bdev[0] = blockmix_salsa8_small2(Bdev[0]); + + uint n = 1; +#pragma unroll 1 + for (uint i = 2; i < 64; i++) + { + + prevstate[i] = Bdev[0]; + + if ((i&(i - 1)) == 0) n = n << 1; + + uint j = as_uint2(Bdev[0].hi.s0).x & (n - 1); + + j += i - n; + Bdev[0] ^= prevstate[j]; + + Bdev[0] = blockmix_salsa8_small2(Bdev[0]); + } + + +} + + + +__attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) +__kernel void search1(__global uchar *buffer1, __global uchar *buffer2) +{ +} + + + + +__attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) +__kernel void search2(__global uchar *padcache, __global uchar *buff1, __global uchar *buff2) +{ + + __global ulong16 *hashbuffer = (__global ulong16 *)(padcache + (2048 * 128 * sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))); + __global ulong16* prevstate = (__global ulong16 *)(buff1 + (64 * 128 * sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))); + __global ulong16 *Bdev = (__global ulong16 *)(buff2 + (8 * 128 * sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))); + + + for (int i = 0; i<8; i++) + hashbuffer[i] = Bdev[i]; + + blockmix_pwxform((__global ulong8*)Bdev, prevstate); + + + for (int i = 0; i<8; i++) + hashbuffer[i + 8] = Bdev[i]; + + blockmix_pwxform((__global ulong8*)Bdev, prevstate); + int n = 1; +#pragma unroll 1 + for (int i = 2; i < 2048; i ++) + { + + for (int k = 0; k<8; k++) + (hashbuffer + 8 * i)[k] = Bdev[k]; + + + if ((i&(i - 1)) == 0) n = n << 1; + + uint j = as_uint2(Bdev[7].hi.s0).x & (n - 1); + j += i - n; + + for (int k = 0; k < 8; k++) + Bdev[k] ^= (hashbuffer + 8 * j)[k]; + + + blockmix_pwxform((__global ulong8*)Bdev, prevstate); + } +} + +/* +__attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) +__kernel void search3(__global uchar *buffer1, __global uchar *buffer2) +{ +} +*/ + + +__attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) +__kernel void search3(__global uchar *padcache, __global uchar *buff1, __global uchar *buff2) +{ + + __global ulong16 *hashbuffer = (__global ulong16 *)(padcache + (2048 * 128 * sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))); + __global ulong16* prevstate = (__global ulong16 *)(buff1 + (64 * 128 * sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))); + __global ulong16 *Bdev = (__global ulong16 *)(buff2 + (8 * 128 * sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))); + + +#pragma unroll 1 + for (int z = 0; z < 684; z++) + { + + uint j = as_uint2(Bdev[7].hi.s0).x & 2047; + + + for (int k = 0; k < 8; k++) + Bdev[k] ^= (hashbuffer + 8 * j)[k]; + + if (z<682) + for (int k = 0; k<8; k++) + (hashbuffer + 8 * j)[k] = Bdev[k]; + + blockmix_pwxform((__global ulong8*)Bdev, prevstate); +//// + } + +} + +/* +__attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) +__kernel void search5(__global uchar *buffer1, __global uchar *buffer2) +{ +} +*/ + +__attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) +__kernel void search4(__global const uchar* restrict input, __global uint* restrict output, __global uchar *buff2,__global uchar* buff3, const uint target) +{ + + __global ulong16 *Bdev = (__global ulong16 *)(buff2 + (8 * 128 * sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))); + __global uint8 *sha256tokeep = (__global uint8 *)(buff3 + (8 * sizeof(uint)*(get_global_id(0) % MAX_GLOBAL_THREADS))); + + uint nonce = (get_global_id(0)); + + + uint data[20]; + ((uint16 *)data)[0] = ((__global const uint16 *)input)[0]; + ((uint4 *)data)[4] = ((__global const uint4 *)input)[4]; +// for (int i = 0; i<20; i++) { data[i] = SWAP32(data[i]); } + uint8 swpass = swapvec(sha256tokeep[0]); + uint16 in; + uint8 state1,state2; + in.lo = pad1.lo ^ swpass; + in.hi = pad1.hi; + + + state1 = sha256_Transform(in, H256); + + in.lo = pad2.lo ^ swpass; + in.hi = pad2.hi; + state2 = sha256_Transform(in, H256); + +#pragma unroll 1 + for (int i = 0; i<8; i++) { + in = unshuffle(Bdev[i].lo); + in = swapvec16(in); + state1 = sha256_Transform(in, state1); + in = unshuffle(Bdev[i].hi); + in = swapvec16(in); + state1 = sha256_Transform(in, state1); + } + in = pad5; + state1 = sha256_Transform(in, state1); + in.lo = state1; + in.hi = pad4; + uint8 res = sha256_Transform(in, state2); + + //hmac and final sha + + in.lo = pad1.lo ^ res; + in.hi = pad1.hi; + state1 = sha256_Transform(in, H256); + in.lo = pad2.lo ^ res; + in.hi = pad2.hi; + state2 = sha256_Transform(in, H256); + in = ((uint16*)data)[0]; + state1 = sha256_Transform(in, state1); + in = padsha80; + in.s0 = data[16]; + in.s1 = data[17]; + in.s2 = data[18]; + in.s3 = get_global_id(0); + in.sf = 0x480; + state1 = sha256_Transform(in, state1); + in.lo = state1; + in.hi = pad4; + state1 = sha256_Transform(in, state2); + // state2 = H256; + in.lo = state1; + in.hi = pad4; + in.sf = 0x100; + res = sha256_Transform(in, H256); + + + if (SWAP32(res.s7) <= (target)) + output[atomic_inc(output + 0xFF)] = (nonce); + +} diff --git a/kernel/yescrypt.cl b/kernel/yescrypt.cl index b152602b7..0a94ebcab 100644 --- a/kernel/yescrypt.cl +++ b/kernel/yescrypt.cl @@ -35,237 +35,219 @@ #include "yescrypt_essential.cl" - - __attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) -__kernel void search(__global const uchar* restrict input, __global uint* restrict output, __global uchar *padcache, __global uchar* buff2, const uint target) +__kernel void search(__global const uchar* restrict input, __global uint* restrict output, __global uchar *padcache, __global uchar* buff1, __global uchar* buff2, const uint target) { - __global ulong16 *hashbuffer = (__global ulong16 *)(padcache + (2048*128 *sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))); - __global ulong16 *prevstate = (__global ulong16 *)(buff2 + (64 * 128 * sizeof(ulong)*(get_global_id(0) % MAX_GLOBAL_THREADS))); + __global ulong16 *hashbuffer = (__global ulong16 *)(padcache + (2048 * 128 * sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))); + __global ulong16 *prevstate = (__global ulong16 *)(buff1 + (64 * 128 * sizeof(ulong)*(get_global_id(0) % MAX_GLOBAL_THREADS))); + __global ulong16 *Bdev = (__global ulong16 *)(buff2 + (8 * 128 * sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))); - uint nonce = (get_global_id(0)); - uint data[20]; - uint16 in; - uint8 state1, state2; + uint nonce = (get_global_id(0)); + uint data[20]; + uint16 in; + uint8 state1, state2; uint8 sha256tokeep; - - ulong16 Bdev[8]; // will require an additional buffer + ((uint16 *)data)[0] = ((__global const uint16 *)input)[0]; ((uint4 *)data)[4] = ((__global const uint4 *)input)[4]; for (int i = 0; i<20; i++) { data[i] = SWAP32(data[i]); } -// if (nonce == 10) { printf("data %08x %08x\n", data[0], data[1]); } + // if (nonce == 10) { printf("data %08x %08x\n", data[0], data[1]); } uint8 passwd = sha256_80(data, nonce); -//pbkdf - in.lo = pad1.lo ^ passwd; - in.hi = pad1.hi; - state1 = sha256_Transform(in, H256); - - in.lo = pad2.lo ^ passwd; - in.hi = pad2.hi; - state2 = sha256_Transform(in, H256); - - in = ((uint16*)data)[0]; - state1 = sha256_Transform(in, state1); - - for (int i = 0; i<8; i++) - { - uint16 result; - in = pad3; - in.s0 = data[16]; - in.s1 = data[17]; - in.s2 = data[18]; - in.s3 = nonce; - in.s4 = 4*i+1; - in.lo = sha256_Transform(in, state1); - in.hi = pad4; - result.lo = swapvec(sha256_Transform(in, state2)); - if (i == 0) sha256tokeep = result.lo; - in = pad3; - in.s0 = data[16]; - in.s1 = data[17]; - in.s2 = data[18]; - in.s3 = nonce; - in.s4 = 4 * i + 2; - in.lo = sha256_Transform(in, state1); - in.hi = pad4; - result.hi = swapvec(sha256_Transform(in, state2)); - Bdev[i].lo = as_ulong8(shuffle(result)); - in = pad3; - in.s0 = data[16]; - in.s1 = data[17]; - in.s2 = data[18]; - in.s3 = nonce; - in.s4 = 4 * i + 3; - in.lo = sha256_Transform(in, state1); - in.hi = pad4; - result.lo = swapvec(sha256_Transform(in, state2)); - in = pad3; - in.s0 = data[16]; - in.s1 = data[17]; - in.s2 = data[18]; - in.s3 = nonce; - in.s4 = 4 * i + 4; - in.lo = sha256_Transform(in, state1); - in.hi = pad4; - result.hi = swapvec(sha256_Transform(in, state2)); - - - Bdev[i].hi = as_ulong8(shuffle(result)); - } - -//mixing1 - - prevstate[0] = Bdev[0]; - Bdev[0]=blockmix_salsa8_small2(Bdev[0]); - prevstate[1] = Bdev[0]; - Bdev[0] = blockmix_salsa8_small2(Bdev[0]); - + //pbkdf + in.lo = pad1.lo ^ passwd; + in.hi = pad1.hi; + state1 = sha256_Transform(in, H256); + in.lo = pad2.lo ^ passwd; + in.hi = pad2.hi; + state2 = sha256_Transform(in, H256); - uint n = 1; + in = ((uint16*)data)[0]; + state1 = sha256_Transform(in, state1); #pragma unroll 1 - for (uint i = 2; i < 64; i++) - { + for (int i = 0; i<8; i++) + { + uint16 result; + in = pad3; + in.s0 = data[16]; + in.s1 = data[17]; + in.s2 = data[18]; + in.s3 = nonce; + in.s4 = 4 * i + 1; + in.lo = sha256_Transform(in, state1); + in.hi = pad4; + result.lo = swapvec(sha256_Transform(in, state2)); + if (i == 0) sha256tokeep = result.lo; + in = pad3; + in.s0 = data[16]; + in.s1 = data[17]; + in.s2 = data[18]; + in.s3 = nonce; + in.s4 = 4 * i + 2; + in.lo = sha256_Transform(in, state1); + in.hi = pad4; + result.hi = swapvec(sha256_Transform(in, state2)); + Bdev[i].lo = as_ulong8(shuffle(result)); + in = pad3; + in.s0 = data[16]; + in.s1 = data[17]; + in.s2 = data[18]; + in.s3 = nonce; + in.s4 = 4 * i + 3; + in.lo = sha256_Transform(in, state1); + in.hi = pad4; + result.lo = swapvec(sha256_Transform(in, state2)); + in = pad3; + in.s0 = data[16]; + in.s1 = data[17]; + in.s2 = data[18]; + in.s3 = nonce; + in.s4 = 4 * i + 4; + in.lo = sha256_Transform(in, state1); + in.hi = pad4; + result.hi = swapvec(sha256_Transform(in, state2)); - prevstate[i] = Bdev[0]; - if ((i&(i - 1)) == 0) n = n << 1; + Bdev[i].hi = as_ulong8(shuffle(result)); + } - uint j = as_uint2(Bdev[0].hi.s0).x & (n - 1); + //mixing1 - j += i - n; - Bdev[0] ^= prevstate[j]; + prevstate[0] = Bdev[0]; + Bdev[0] = blockmix_salsa8_small2(Bdev[0]); + prevstate[1] = Bdev[0]; + Bdev[0] = blockmix_salsa8_small2(Bdev[0]); - Bdev[0] = blockmix_salsa8_small2(Bdev[0]); - } -//mixing1_2 + uint n = 1; +#pragma unroll 1 + for (uint i = 2; i < 64; i++) + { - for (int i = 0; i<8; i++) - hashbuffer[i] = Bdev[i]; + prevstate[i] = Bdev[0]; - blockmix_pwxform((ulong8*)Bdev,prevstate); + if ((i&(i - 1)) == 0) n = n << 1; + uint j = as_uint2(Bdev[0].hi.s0).x & (n - 1); - for (int i = 0; i<8; i++) - hashbuffer[i + 8] = Bdev[i]; + j += i - n; + Bdev[0] ^= prevstate[j]; - blockmix_pwxform((ulong8*)Bdev,prevstate); - n = 1; -#pragma unroll 1 - for (int i = 2; i < 2048; i++) - { + Bdev[0] = blockmix_salsa8_small2(Bdev[0]); + } - for (int k = 0; k<8; k++) - (hashbuffer + 8 * i)[k] = Bdev[k]; + for (int i = 0; i<8; i++) + hashbuffer[i] = Bdev[i]; + blockmix_pwxform((__global ulong8*)Bdev, prevstate); - if ((i&(i - 1)) == 0) n = n << 1; - uint j = as_uint2(Bdev[7].hi.s0).x & (n - 1); - j += i - n; + for (int i = 0; i<8; i++) + hashbuffer[i + 8] = Bdev[i]; - for (int k = 0; k < 8; k++) - Bdev[k] ^= (hashbuffer + 8 * j)[k]; + blockmix_pwxform((__global ulong8*)Bdev, prevstate); + n = 1; +#pragma unroll 1 + for (int i = 2; i < 2048; i++) + { + for (int k = 0; k<8; k++) + (hashbuffer + 8 * i)[k] = Bdev[k]; - blockmix_pwxform( (ulong8*)Bdev,prevstate); - } -///////////////////////// + if ((i&(i - 1)) == 0) n = n << 1; -////mix2_2 + uint j = as_uint2(Bdev[7].hi.s0).x & (n - 1); + j += i - n; + for (int k = 0; k < 8; k++) + Bdev[k] ^= (hashbuffer + 8 * j)[k]; - //#pragma unroll -#pragma unroll 1 - for (int z = 0; z < 684; z++) - { - uint j = as_uint2(Bdev[7].hi.s0).x & 2047; + blockmix_pwxform((__global ulong8*)Bdev, prevstate); + } - for (int k = 0; k < 8; k++) - Bdev[k] ^= (hashbuffer + 8 * j)[k]; +#pragma unroll 1 + for (int z = 0; z < 684; z++) + { - if (z<682) - for (int k = 0; k<8; k++) - (hashbuffer+8 * j)[k] = Bdev[k]; + uint j = as_uint2(Bdev[7].hi.s0).x & 2047; - blockmix_pwxform((ulong8*)Bdev,prevstate); - } + for (int k = 0; k < 8; k++) + Bdev[k] ^= (hashbuffer + 8 * j)[k]; + if (z<682) + for (int k = 0; k<8; k++) + (hashbuffer + 8 * j)[k] = Bdev[k]; - for (int i = 0; i<8; i++) { - Bdev[i].lo = as_ulong8(unshuffle(Bdev[i].lo)); - Bdev[i].hi = as_ulong8(unshuffle(Bdev[i].hi)); - } -///////////////////////////////////// -///////// pbkdf final + blockmix_pwxform((__global ulong8*)Bdev, prevstate); + //// + } - uint8 swpass = swapvec(sha256tokeep); - in.lo = pad1.lo ^ swpass; - in.hi = pad1.hi; - state1 = sha256_Transform(in, H256); + uint8 swpass = swapvec(sha256tokeep); +// uint16 in; +// uint8 state1, state2; + in.lo = pad1.lo ^ swpass; + in.hi = pad1.hi; - in.lo = pad2.lo ^ swpass; - in.hi = pad2.hi; - state2 = sha256_Transform(in, H256); - for (int i = 0; i<8; i++) { - in = as_uint16(Bdev[i].lo); - in = swapvec16(in); - state1 = sha256_Transform(in, state1); - in = as_uint16(Bdev[i].hi); - in = swapvec16(in); - state1 = sha256_Transform(in, state1); - } - in = pad5; - state1 = sha256_Transform(in, state1); - in.lo = state1; - in.hi = pad4; - uint8 res = sha256_Transform(in, state2); + state1 = sha256_Transform(in, H256); - //hmac and final sha + in.lo = pad2.lo ^ swpass; + in.hi = pad2.hi; + state2 = sha256_Transform(in, H256); - in.lo = pad1.lo ^ res; - in.hi = pad1.hi; - state1 = sha256_Transform(in, H256); - in.lo = pad2.lo ^ res; - in.hi = pad2.hi; - state2 = sha256_Transform(in, H256); - in = ((uint16*)data)[0]; +#pragma unroll 1 + for (int i = 0; i<8; i++) { + in = unshuffle(Bdev[i].lo); + in = swapvec16(in); state1 = sha256_Transform(in, state1); - in = padsha80; - in.s0 = data[16]; - in.s1 = data[17]; - in.s2 = data[18]; - in.s3 = nonce; - in.sf = 0x480; + in = unshuffle(Bdev[i].hi); + in = swapvec16(in); state1 = sha256_Transform(in, state1); - in.lo = state1; - in.hi = pad4; - state1 = sha256_Transform(in, state2); - // state2 = H256; - in.lo = state1; - in.hi = pad4; - in.sf = 0x100; - res = sha256_Transform(in, H256); - // return(swapvec(res)); + } + in = pad5; + state1 = sha256_Transform(in, state1); + in.lo = state1; + in.hi = pad4; + uint8 res = sha256_Transform(in, state2); + + //hmac and final sha + + in.lo = pad1.lo ^ res; + in.hi = pad1.hi; + state1 = sha256_Transform(in, H256); + in.lo = pad2.lo ^ res; + in.hi = pad2.hi; + state2 = sha256_Transform(in, H256); + in = ((uint16*)data)[0]; + state1 = sha256_Transform(in, state1); + in = padsha80; + in.s0 = data[16]; + in.s1 = data[17]; + in.s2 = data[18]; + in.s3 = get_global_id(0); + in.sf = 0x480; + state1 = sha256_Transform(in, state1); + in.lo = state1; + in.hi = pad4; + state1 = sha256_Transform(in, state2); + // state2 = H256; + in.lo = state1; + in.hi = pad4; + in.sf = 0x100; + res = sha256_Transform(in, H256); + + + if (SWAP32(res.s7) <= (target)) + output[atomic_inc(output + 0xFF)] = (nonce); - -// if (nonce == 10) { } - - if ( SWAP32(res.s7) <= (target)) { - output[atomic_inc(output + 0xFF)] = (nonce); - //printf("gpu hashbuffer %08x nonce %08x\n",((__global uint *)hashbuffer)[7] ,SWAP32(get_global_id(0))); } - -} \ No newline at end of file diff --git a/kernel/yescrypt_essential.cl b/kernel/yescrypt_essential.cl index 8743d7b94..ba1816a8e 100644 --- a/kernel/yescrypt_essential.cl +++ b/kernel/yescrypt_essential.cl @@ -140,6 +140,8 @@ inline uint8 swapvec(uint8 buf) return vec; } + + inline uint16 swapvec16(uint16 buf) { uint16 vec; @@ -173,6 +175,18 @@ uint t; return(as_ulong8(st + Bx)); } + ulong8 salsa20_8n(uint16 Bx) + { + uint t; + uint16 st = Bx; + SALSA_CORE(st); + SALSA_CORE(st); + SALSA_CORE(st); + SALSA_CORE(st); + return(as_ulong8(st + Bx)); + } + + ulong16 blockmix_salsa8_small2(ulong16 Bin) { ulong8 X = Bin.hi; @@ -346,7 +360,7 @@ inline ulong8 block_pwxform_long(ulong8 Bout, __global ulong2 *prevstate) -inline void blockmix_pwxform( ulong8 *Bin, __global ulong16 *prevstate) +inline void blockmix_pwxform(__global ulong8 *Bin, __global ulong16 *prevstate) { Bin[0] ^= Bin[15]; Bin[0] = block_pwxform_long_old(Bin[0], prevstate); diff --git a/ocl.c b/ocl.c index 73a79939d..0757a5c43 100644 --- a/ocl.c +++ b/ocl.c @@ -516,7 +516,8 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize, algorithm_t *alg applog(LOG_DEBUG, "GPU %d: computing max. global thread count to %u", gpu, (unsigned)(cgpu->thread_concurrency)); } - else if (!safe_cmp(cgpu->algorithm.name, "yescrypt") && !cgpu->opt_tc) { + else if ((!safe_cmp(cgpu->algorithm.name, "yescrypt") || + !safe_cmp(algorithm->name, "yescrypt-multi")) && !cgpu->opt_tc) { size_t glob_thread_count; long max_int; unsigned char type = 0; @@ -702,6 +703,12 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize, algorithm_t *alg } size_t bufsize; + size_t buf1size; + size_t buf3size; + size_t buf2size; + + + size_t readbufsize = 128; if (algorithm->rw_buffer_size < 0) { @@ -717,10 +724,12 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize, algorithm_t *alg applog(LOG_DEBUG, "Neoscrypt buffer sizes: %lu RW, %lu R", (unsigned long)bufsize, (unsigned long)readbufsize); // scrypt/n-scrypt } - else if (!safe_cmp(algorithm->name, "yescrypt")) { + else if (!safe_cmp(algorithm->name, "yescrypt") || !safe_cmp(algorithm->name, "yescrypt-multi")) { /* The scratch/pad-buffer needs 32kBytes memory per thread. */ bufsize = YESCRYPT_SCRATCHBUF_SIZE * cgpu->thread_concurrency; - + buf1size = PLUCK_SECBUF_SIZE * cgpu->thread_concurrency; + buf2size = 128 * 8 * 8 * cgpu->thread_concurrency; + buf3size= 8 * 8 * 4 * cgpu->thread_concurrency; /* This is the input buffer. For yescrypt this is guaranteed to be * 80 bytes only. */ readbufsize = 80; @@ -753,6 +762,10 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize, algorithm_t *alg } clState->padbuffer8 = NULL; + clState->buffer1 = NULL; + clState->buffer2 = NULL; + clState->buffer3 = NULL; + if (bufsize > 0) { applog(LOG_DEBUG, "Creating read/write buffer sized %lu", (unsigned long)bufsize); @@ -765,20 +778,20 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize, algorithm_t *alg } - if (!safe_cmp(algorithm->name, "yescrypt")) { + if (!safe_cmp(algorithm->name, "yescrypt") || !safe_cmp(algorithm->name, "yescrypt-multi")) { // need additionnal buffers - clState->buffer1 = clCreateBuffer(clState->context, CL_MEM_READ_WRITE, PLUCK_SECBUF_SIZE * cgpu->thread_concurrency, NULL, &status); + clState->buffer1 = clCreateBuffer(clState->context, CL_MEM_READ_WRITE, buf1size, NULL, &status); if (status != CL_SUCCESS && !clState->buffer1) { applog(LOG_DEBUG, "Error %d: clCreateBuffer (buffer1), decrease TC or increase LG", status); return NULL;} - clState->buffer2 = clCreateBuffer(clState->context, CL_MEM_READ_WRITE, 128 * 8 * 8 * cgpu->thread_concurrency, NULL, &status); + clState->buffer2 = clCreateBuffer(clState->context, CL_MEM_READ_WRITE, buf2size, NULL, &status); if (status != CL_SUCCESS && !clState->buffer2) { applog(LOG_DEBUG, "Error %d: clCreateBuffer (buffer2), decrease TC or increase LG", status); return NULL; } - clState->buffer3 = clCreateBuffer(clState->context, CL_MEM_READ_WRITE, 8 * 8 * 4 * cgpu->thread_concurrency, NULL, &status); + clState->buffer3 = clCreateBuffer(clState->context, CL_MEM_READ_WRITE, buf3size, NULL, &status); if (status != CL_SUCCESS && !clState->buffer3) { applog(LOG_DEBUG, "Error %d: clCreateBuffer (buffer3), decrease TC or increase LG", status); return NULL; diff --git a/sgminer.c b/sgminer.c index fcbc94d75..028ec7e13 100644 --- a/sgminer.c +++ b/sgminer.c @@ -7082,7 +7082,9 @@ bool test_nonce(struct work *work, uint32_t nonce) // for Neoscrypt, the diff1targ value is in work->target if (!safe_cmp(work->pool->algorithm.name, "neoscrypt") || !safe_cmp(work->pool->algorithm.name, "pluck") - || !safe_cmp(work->pool->algorithm.name, "yescrypt") ) { + || !safe_cmp(work->pool->algorithm.name, "yescrypt") + || !safe_cmp(work->pool->algorithm.name, "yescrypt-multi") +) { diff1targ = ((uint32_t *)work->target)[7]; } else { diff --git a/sgminer.exe b/sgminer.exe new file mode 100644 index 0000000000000000000000000000000000000000..17491d63ba663c192d558ee1c9827f8544989c7c GIT binary patch literal 1675783 zcmeFaeS8!})<4=qCNP179yM8`8`iixu8F*u*##wm&LFN4 zCd>@bHiJ>nb=6h#2i;)0j};v|72peUeXkXK)~hX4jpz?Wt2_gmFHnFMwpe)ryg z?&ov!f$4fVbah!s;<7~#u_C_Q4~A=$6|_7hbR9$;`cxQ_>tZByj6Xb6)Bs} zud|hII=_6&%4%SI?lsqIW<+2-PLO7_``a;~E6ReIU_*n0dzsq3pKhtma9lg~r}C;o3n8o6V* zhveIaAo&-6{!B&bsVM6oJy+CAQL-g03$P6S%!iCbGL*f)l)?X7za1G0D4z7Ub6tj# z9%t&LY-N!5j_F<`*S(GUkRjF;d?)@@DtVQICfw@16^ZtN_+i}#;kg#igg=i`85wlH z1bps05>*xDD4zRIg7aKFSQf1Oo=?d3C>~#&B@@kGkCNvZblU?DFzQ*!-wgho^yeqt zJ0)EqL&#Fe0$3aHCj0?kWKhv{}aL(Zu|1Mv^c~bCj0o-v^Iuz@_5p0R4nNj{a6ma>n9#uf4lmU){ zJeQHqKgfCb#cucSm~toOI~8!0&+od!p&stv2?j%7Am0zTukgI&RB*o+f-XxYKH0aF za{-_5N4X?K|Nr3sha@mg`+96(|KM8xfw4*`;>~I)b~(sCo_4BGi`~U&Y;$0LD#Fe) zJc==4ZeOL$xa?4xVq_dnQ(8uJ5F|XJLo0SUYa>68RuD)HkN6G`2NBtoaT3uu#W)h` ztJFHL9S3T@tBeDP=^5)-#Azr;(v-kg9fs$7VBWzTB68HSI0E)sg#o+ExMF@^MQbu5 z0MW8s#?Co?m6rq#0O|dXuOFxAMNR^~Y!PE|y(o`qPjpQyW7-U)MemKpVl`48>G}wV z4)TSMD@x?S%L~JJ++Vty6AkOb>OvS4lyNnR29Dd*-~q%!5jFG-p6*CsUHVNM8tqEq zLKO90Q}`4gnS~4R@O|F?R!t%LQ^Z?X*pCUD6OaXABk+TS6=I>9)A90HO zj)eRRPLV(1CiG1cfAT5vk0+G>deO=Bi_w5q`SpqU7{oHQCf!r4H8dDbt+C+?NA(v9 z3|e*Nx|Bw(wPCMAUAZX*PiIPFc)0C!z_hW&vE52f~L8wRJqc<8X_C58j*GH+_CAz%7lfuyWqI<{zLxoqnfVc!-zf9hsoI~v;d*eA4Nmd^ znYD~`FtpMb3M0U>5sQGO%&soKn==SplqSu zX^CTJ0_w+zy0K=QsK@{`wLcXUw8rYjRuEEyE%^1n2vR1hQ=0Mr!-?u`4HMOEm>c&@b~!^a zb?#ph;CKHJST_LjxVcHm$FOA9Q*SYeG3qH9dm-qY8({D9C`xPo|0gqWr%O7)M+SME(yXVE-SXKVOH zxlM)TinbxGsE8mi0y9nM zs2XAi3`QX8DQd8iZBy(@2Y4!p-4CH@RdS^H_&W-JDhGm^!dUF~SJXL^Ah5v-8)Y-EE z#d`b|&r{UnYSbh8dvF3h3y+L#Ke&Cvj_9uK>YPu(i+gLh)HOweTBBro?q*cZITGWb zsNIZ&+8w1OD{BWl>g+*MTOEpX@y8T5D`ts%IBcX-vrRTR@tlIqGO{@jRux&;Ugf%e zqF(H}ensj;#LKr&c9rj`a+TnDJ(5e1COCX3fy44n4r_L$vtJAVnLK03pZhA*)D?VU z-Vz#`4J-rD;Ca!XL9zz2jH!!1R%cH{OlZ-@XD(;8P^);g?mqaRs`Wh}Pf@LMR_iU8 ze$a`T&5P98#}SS;f{ZyX&0?Mz{+hgyya&zSo&5d-|DOExU!8*VD3ZPm=qH-^+dm_2 z14`2!cg=soU2qEA*AVyapF43!;cJV9wod=G1?-MQ*CJomtbL7H!|`CpOxgxLl5@Df zP?!UzN2a`d)zXp`ai)~2AP($Sb4?6R2l-SobSS;Bj%S;9A3FR|+x4wTmW zrQ$cg!cmo{2A7~wnv(@~*o@{h4Y~rlRY1RQLhtpCj8Eh>dOv|Gji~e?0x&}WZmAmJ z{jEOTu6rE$4Ks^I;$fzX5mt7WKJE`+}PMBadt|Asc7*^!<1K zi5btM%rk1}euygnC-wPA^e%=P)yFFFY_FSGgRZ;X zvK+YHMOxrnf7t7)sCOX!$l~gCBq^rwiPl_#1f{kD#xC1n!d@(rF_DPGVhD+eV-gcT zzFQ_6}D6+I8hT2nlliKwNwc#>1OhMw0$l8Wtt zEk~T>41TcYZBgm zQ4fZhW!&lOtHkZ3@h*>kcc$*M>q)>VhTliQ7|YY!8?JIWwE~y12}22=i(Newt<5-b z47Ja4#jYP5jCdyzcp(ef)>O>)A87S65(>dgr&p7_gmEat7%e}sDo(L zorpu00&#)(t>|t~2}#n9TJmc!LJkr@;x@PTDOqYtVCjcJJrr29!A-p|tL{*P|AVK# zpak;3hqnJR*yF!OK%XO$BWiE}d>>d}sKMVL0O{CiqWAHF$>X+jjvm`q{S7#G z5Zy+WTfk)((XC-QqFauDK1U=2-M_%RKu6cNg>KCQu#OH_Z$uJS|LTatM0X3&h3B+V zET9?=h!B)*&Y7@&01P_zU_>oGtS_iAY35io&l5C7GH4#MXc`GLOH7(jFuS0szfn#! z2jGn%{3EbGg7+dsULIrB0wN#ysu4pSR&imb7B@o7Sx^(Z7<9nk!TY&>@uopVvr;+) zq7fa$(m<{PUQ&s8leuWito?Z@7iem5F4tRUAyzg9npa2AOIV6rWllnf3 z>U2r9uLgtArr1rg{&y)h)MOKCLVe&O%akfuEfR&)&>P6r-VHEtkU-R#K=fWgbW#_h9VXGS-H8gY1fl{E zL^l%f6gBOeKr}mn=s^qwdSG%FqTiWBw<51gO$As2Q2_{|kN+E@f4#R;yq*N2R|=w2 zyAVBY5*^r$=nDdD2fE(nitilwo(YF0I)gMXw|dlPVpWUI@moo<4_nlad=)_fN7|O;l6!rc@+qHJDN#`#TtlpyYlSwB- z0AQpZPDULkGCXcGV?*6106QRE*c9|`#voB5)m$UjN~$d?t}9F6?I^5mED)&r&Z zSq5OCu z1DSrYfS2K=V%;Fa0~5kaL|Lmc(Jep=TUWx}C23H6(PxiSb~1f;LijwGS`%v|Pn8Mj zeo@wav{M0P*%t)76xU}0Muvw9o@DrK!IKPMk`P`l>b6>lx+4MpJ{jhu5RD3)s|3%R zVFy{f%@Mpwoa+Tlyv`o5ggQ(AjaaI2UWd7~@T%e1o67DX4CPKAEIK8oei*R_(Z^w! zp+~N`8|$O#w<^A0>17i_TYYEw>uR99iucS%{T&DdI&5*DIsNKm^^&RBGO*tS+tFWF zOpLxGdRiX5#Gwr{2J8JQ>ETW?vH05bvZ=tj#l5xttQy_Ez)Fto{62b7YT)?UGoAWaN8rcH zXTsi@ZVzpJD79{f1vIgyISD%h?VIAV2$^G6pE?il3rsbX%*S{2RSG%5PfM%Iv~nP0 zt>1VU(m?U?#2UJiU3x!J=N&VCr4JEx?wda>)mwmyI`q`17|t7>|C#TIRgFIZnQ1j6 zDa&{l7O$QmN+PP;XSMgxS_A7`H~q0m;D_VvgGb9paDK#9tVO$6E33v%JcWbaFDc*p+Dv0Vj_l(B5i6 zJlP3hoQ+&mdkJJf-<)px^0SgebpQBuZcfy~NF%&YSOKDGZ zSKFUcu~oLh0tShVqTY0~XwBM3+mqjiZ*5QX!Sm^k$=@y3AYv;XT;^$qL>;3k`!R08 zi69mjPlG3}k0>7R=Uie@46?ljYt6vy(VwROI_}ld{|^3lJ>^H*t_6Ac)n_w55Xpm2 zXcg>OI%%B7?U}+gItlmp*;n%+P^?uI=}UllNPq7ch_2{7A*gMH_Q?HhJC?pgYx zfLmn3JxjRl7Pj3D+Yj!Es?Rhovtb#4Mc`e#e~8|MVGes2_-(iEYJ=<+uqj%E#3;|` z3^@+&YHKmgaW1G+k0Wd<)2PUf69)9q(=pbO&)wbOLwF6yz zV7nWlbhlVOw~G?OKcbA4{yxL9-!{SZBsSk4+G!K(1F{&lKO46D@vmX87bdNYfGER*^?0LU;3X6Cnf3)B}HgIj$YbDR2mU0KsF zG4fDTxo;Y_uZ)vXpNyz0Beu5om#PmES5f{tZUcagi z3h7^s@c{?COk+rE1I7Wy@4tp|fdC>|a3N>HF&=l6N2tbVN)M@GQU1y|I?T_c^hFB|Kc*=Y*%ri73VreL>r40}s|0e0O+m zG;=1JIUUXHM6-zT`qOUB9NE#?%z^!-Q1=RP0;T|+pa5!STzEUSkDNf2t(V!UIC`0b zi1o5mJks?t=Wslox+gt(G8{1$oqeDKWaXS9@f0Us$_1^`CTm}BpqR}MsPkWheB_Mo zj?|;K!w%EaXY1Du4Q=%%!{a(?qbJ|+?GOAA^Uid~+LK4+f9q9s`&zwXC=P%80a4$f z+RV>KlX{jrrf01M$t?AaB9D9Pu|rysM=u&GLj{1X+M}fj;8JPqIP79t z-1V!uQfp%=*izrO&#UK<(!O3kp0I2h7tI6^%hn*OnvgIL;6Rl7=lWTfm%DPR((yZB zRRO4|V;ZfzI>y^S5x(2xJoH?4SMVG_=Kwyr{7tJHhw_1S1!9~+j=c_X8b22U z7nf_-K{QNXWu~8Prk`o1)AlEP>=p^nwXkKAZ9*B#5gIsGI4O;b+u%Kgb`j?;;zYyu zH*tQCvKXodpnX`qFj^mdL)b>##L}x=In^7TU_r+;Cj^6Eo@0NUB>1_(Tb=Nhlvi`Icl-nRiO3)r`uj%w+&{0e0583_^w!yJx_6O|i1f(<6 zn?jJ#+vqf=g8=JirYuHE&9P?SL}Upf$C|T6cr~ycYxaonZ_w3`HTy+)p$OAN^yb8! zniBix#4a71-c*78L!_W>k2SNmddF&Q$(%FP;Kk&5HN%Mf8WA>;I0pj$U%pu=R;V}9 z&IR9DZSoJ@ZY$<=?WwVGRv4C{Q znesmbu4}aKtG`w}5`J=GHJTBrmA*6+eg)yHzft^P304x@KzO$-3UgROI>O90@F9iv zNWY=jM}j|O{%er>TJL>WDDG&_seyTui2?h+LNVVpp##40)J&Wly1S^lnUcL+6no?$ zbiZ^gski7O4Gypz0Ddmxg?q_W46bilhvANjMDwBdEx z&#+Q_62q5?a{2roN*BUabF9gQnmrdAIi{`#%c149JK;4#*;MJHM@Wp2#}oSFzcN5) zbva}Jo|64n&;eM;V%!kvKr)g{qwhGTeNn!Da_1=a4$5=yCj%>=s2w!Phc_3I3(0`x z^m~q&;KrA}u*Rqt1|}hI`yC*w(X|<=bt6J|2qR0dDHBaHBkjPeRqcNT+C+n;;q%qiE=rJB4WO zODO-}C{NKmF$63|;Yg~b6Hhh=U3?bJU_zNGf+lkqnn4DRayY(%zT>r*g-+^Y#X8o9zr8Ql#J*So^Mbp`}4L%+u4EJE$N zIp@N8zJ0mp+EuBZ{0`rKJt=?vjPo15?qT|A(l63_)C!MHYL0%EmRci`X}@nSy2}<5 zJ}@!$-vCERI*4WKVmVJ){;dL*t60o4_Lzv3vF3O-N8GOb6|h&ta25=b%JHC(-;Jx?Z(bSJ3r@o zxNYOkBre5wAKLXxap(%=rB4e8^ySAf_J@x8GIk{^n@6MAj_7Awc5M%c6>1GkicHG= zxlJ~ux{09RL^NJstWdiG!!Fbl_LO;MEWSDZYJ|3amN@SPAQwiv9DiY@ST>FgRJpQk z>Qhbr!ttD#y;lWyc>e_JCGHda1ey>>bu&=KBNd5}v4~IyU;@)z;Ca-4i{)&<26y;Y zn(&sq{i|Vhz$)mii!-noQwQn+2iwXV5x-05M(s{?TdQHNLO+0ybakdEzfqoUMET5^ z-w%v39xL%!0i3n<@Bm2{>^l;$hZC{y$GAlvTat4qGyJtA4~T~@LHo&8!oiC0~c;h*(LP!K+CLF3?}?*nf1OI^5nPrz7mpz&ai#47OTzSz-De? zp4}|==B%{VwZ(9RH-*ydhg#)ZqF4B9vW|0ly5^}?aHamT)0pQ$TTdCvf+{=Jv`v%L)BOO`0qq~wjy5QTp zLE!TMU-5s&_Zb9{h)=k^qT3^FX~%)l;;%;H8wz{{{|Vpp8J)P=(s=$9yrFNG$?|mR z4)zz`)fa8+I~$!YPaL*^oGOnj4y-G~IMXEjtJ&a++3b^Z-?Axi;$YIYrrV;Pozv~; zzH-rUW_e$w{mtzg+T^L%2QiqSE#vWDc8jlu8mpmu@Vjffg*Ho~1!?JKJd)M}U7uo) z76UM0owPmqXH;!xsjGY~cEABdpXju{Shq|Yqm1?)*|ohrsb<&qwn97NqW-ODkM-K- z`fPxw7`~LiiJofkA81QC9%=)YYvs%BrfAe4bwwYWbsAm?$OStDnWqPtu8&PWJ;+Rb ztn>6Bv-Gj4rw5shos83ibm?R5rw7Ry>$JR212{%d`j#Klz1&hO4AkSTaj!B#wT|?W zs`d7@?Cf$?2Ax_K;|vxpgG$8bFOKzEQK=mCFqy?_hO!04v2x2ttp;aI%y2y`p zkp1g2PW|3Tx)$*Mp$qU_u%@NEj5-Ni)(v=o3GBPtDs?VN{KYIaOO`rUmeT#%;4eQw zkE8mOoJ8~hUFBWVh+)2o!6PxWb*1Zjy!{{Iyp=m*><*&Nrl;n2fR;Yk>izKe$Q~@l z%GPZV{CY8RVq{o#G!}zHyl?e7LRr4hu&{ju3>>BZxIbBW_hqnA5BHa%;e@$&^SetK z=bBZ-Be3S+d{GS2)tVv9+!ke$*E_YvW54X;i-p0(jRot-$yo$jP6Mkwgi1Qz1~yif z%TAmVbkZQ{g-**nNJ^LkmN#Ivz4LTfk{nlPXQXp)OW+_p*vS}-qie9}dP;LmJEVP9 z$3tDliLsQ;smr+jO_@B5Z$i$dfMXeX60&#gcmyyR#rD?kI|p-M)6_AFq;s1n1J;Iu z^>Wx8v5WzLwG5K0o0ILFN1Ky{fnuEfDJ^pI%;NKJ<3!&f{GjOfsHE`-BzB#~ZGdyF zw!0rm;x#Pad2s?JR~N=IBwItpdoEx)s|4?1SS6`TDB0dxKQ09=*dpld<21utX{7?yh zQhO~Ba>U$Ty+0fJL7f=r=%O#;T@PrPfAK^lrq-R8>Oruqp-XPHGw& zj7A3-jV{MX4xMAU%5LTC|E63W%T;uiE9zG6{iajX^RwK)VC0(g{@ShF!hch)gyr6r z^yI!*pruE22NG~zdWDNaCnOS$BBB0+H1w!L@g6l5vsZmX*R)2Y#pfiG->`!N!DuTUUu07xs+Eou5OtBs(E_{+UBO?ACr3WSZcB@&M8-1@P)d9GrC{G|R8Y~}K@{uhcF8LTL9|htOSjcG(e=ULO@laJfwNEM_7&Zd(VKX|1oa-6kh{X zZ||CR?bR6f#2THa5x7y7UESn|0EyR>g74Sr%KvKaDU(cV<~L@?Iv!Z(i0PGQLcP((8p)!H`r@MNt~)2%#sfMzI2ospx@`jBL}q`kc($N z_QTZRL_qMQ{b&h!WxD>LL-Y1_=r=fE5~QLqlk7;cBYds>s^8p@6;8jd;fo%6ifv2m zN~9*8k$;&Qv=PA#sVLM_ALG=na_ToYWh52eMO}%Nq=HGTn6r2K{ivR(38wE1IAbub zpjqku{ZnyYC02}0gac~mH^^XrLUo~yQb1DZYUq7bTnavP)H{mP__#N*BBLX~+}X@d z5sm+T85@e=(?kG!^x%9oVlBxOHUFZ&Vm(mv-qG*H+zSb68O+r-N8dz>?XY$&gkq0| z5kbAI=8T?)g7t4=s91GpTtk~mI2dMQHumzfG5O)u z%;48-leLqOhDiv>u%bDmh8lGoLG6V8F0=BV=K(P2%~KQbq%K^9V&U19h_TkS#HPQ> zsD4d4UWLrmuW|OrBmWS#2?5F?V@YW#(dlyq?sC707=ZGs`<$P)QyAL+ffJ?bw{N` zeGr8FI)!E_6Ax}lWrD7yL!o{xU*X|473wRtamu7Rar7~c{=@@^@|Xg2MO2##+lq#j z(h@94EqQVnZa)zs6p2)vSx9P0W*YyZ<&rObwy0AN0UUKA5x8elelHPJYmBZCdXeiZrWvr7mrt-pq*W(t{(ROATGqhC{y~3)mFGhmO~c<-ro1B;mVz>_|ce zqVDq&>i*-8nCk7Woe6V;?~+(DXKf&fd0g>Kb9@|VN){A6cDRc3bWb^5@K};Q{!8$= zH_qqMQQ&i7*R<6mEI#EqOuMTMDsSn#?*ePwcY>_UG0C21F6=T%Xk|YTdJgYS$+hnY z5~}N(b{zb2Zwli5*>`hzft@{T_6q!JPw_WAe;LC%)3pFCOU+r`l*%VY!D9faZeGIJ zV4(S~1&Tv_rc};1rNWsCaw+T!4yVQCGLVV_-Aqio3|vn%=S6V%^r>e=o0ud`A}7s= zw?a`@ofU8AW{A3;%A1h(5yn!fj~wfzKSGXaKKG;jDxv?_5J{OUmleV$moQenq>`EW z^*2(=pT?))aU|HynQ$8j%J%jb3Qvcxmsqk)tTE^xhTEyb_{A#;FJacdoQ4(jWC&Ex z;2V|UKg9AsQXj)DKT7!86Iwx>=;jlljmr?sFUTpLi z-b|C$*E1=35u%=#SUb;4;+@cL`1?vR!>kf-Xm>~37ii_Xor5tdVOtaam#n6Eeco7{ zuxs@iBHh_fbXRq2uH{fm=m&T<+OR~na2pRK;+*k+hVvGQlj|x>rrE|!iP+Kuj8$Uv z>#~XW<)V|>?vo((?jrfgBltG=2j(_)4jk5uJq1&Wp1~0wv)CE>EHQg}QemHm8qr6B zcmt*wAmPcd+=eJH#jZ|IHA}x2<^c?ed!7C9$ls*~FCiMh zjU<}Y!jO1Eh~hdNpghB&FNhlwtGgN!RWMAY$w5P6!T)MVkP&@B+>p>MLt;VPkkGpu z66TJm_o28P6GgWTsqCW0-TAoCCJS=zY-HIl@!AoH%D$sv2(u1xQQ9{2aQlh`TlKHF z0R$L7N0RYmZjusx0DVah(2c_bS`T4xiU}D2=}oW|y^M7>66(D8Fm63b7Ro2pEs)epac<7-z^y{S18usoLB1aD!1Zz36D6tsK(7{@D9&;WajNd@S z7TBt20mgCDntc-c)8sKf^IU#% zS&HM6Fn;w=IvC{CBN^ss@uUaUg|pp*WVubNwZL@FIkH#}WdS-AnNb1PT)C?f3>2^} zLJE@MkApL}z`R7Ela3f>J)kL2Lbq;Sio--zFcpE*gf7be8!^v(EBs_DxdUGOPeqjm z>$4n`4Q5K}m9w{4_t^ntT!S-N{&xtEL5=M|0B)?ISOJ7&%pD?62d+b&wcX4Gavo~( zjt4jzzU`r{aV-G?E}MoR1v1I2!F-X|@MRBuVZR84v+We;@(<(Y3GI-&^7|Boa5A5q zYW8!n7|FxRJI}WU&6*efgF|~xpwHj_fGcbdlT~fwvCqOQ7Wxr{5C-e%J+<^+!vYa| z{(BD|MhzUSn;uFfWz;7u5uhE7e7vTqFBJGrW9L(FG`zSIqr=2VR0p5>KSx#4GMs)X zf6MSHKQ%Fw4TSoWF8&G~_OP8EFBW;n8D?8Afn7z}%*qkzADihT;^`$KT~rtF1LNrh zOgH-+^qgA$E|TOp8{cAB3{{Qm0QI)J4g`NMb-;x@G7?uOY+dWK$g=(fS*EO^a=0ff z`9;){yeDI$Lf#iAYVcYrz?x^d@M~+CH39heC$EW{H6E$*nz-g!*$4wLg2&j}k1-2q zvnmj7nU#(*bewggEMG~{S`F7m48J(Q5m*IA5`~qnhv-z$pZpoW z5EWlfaI)3)Y7cnTMXR4egx~DMbw72$EY5cLiGs?2zPV%pH{sb@*+{iUi&U4ffEmrC z(S-xi`wJ3!|Cs%N!&&!}p(+!gaseeFs87I(^Ah?jj<)&}9Bq-}L|xMLYU-z;TJ4Y_ zK{1$sYgaocqVv?cv4afn!(Z`?(yVL=icU#W-o0TpA5j%<*7`-9b^a^9MEvumn2Gjv zO?#hd-Qa?lXzQ1Dg?s#xlhcl}Y&W23<7#XE70OM=vkw_>L3Fg+qeQ^kLc~PqO zE62PWhcmYp&hNBru;)`h4#HXWW_`fl040lKJ538k(FEN6WXH2Xa zg`{I@X^TkGjPN8|e#awM>4k)l=Owf1^dgTwwjf+$)2_xl1dqIr%U(iFVr6-a$)&dr z2P10Np;kB(C(25W+g}9FF20X#1duCUR_-HSR#t=D6N8VNM>=Qj;XEX^mn)tV&QGC` zZzd>YX%q?xi!<)4g7kF%BH(}=vucS2bM<(AAjJcM?b`Ypyy@+$271t3R@Jz_VBcZcwjyLjp&rvl9z?f;}5cvGtJ9md1_ zrbpgv-xl{PHR(gB5PG2lzwP7TLwItt(}?+=mK07*O@`og$ui;U5*hPe9Lt}sa^D& zp;*@r5qF}(#eOH+Qh!uT2(2^?jd5QhOzJEQn8Iffpfo%-on#1{)jZ zq0L%4^CB|Oc$4YPO!qSdt^NX2c+hcx*unuJ5Od+qY9wXrBTSzy52wO@p}C55@q#Hj z=1_#4coyI(cEHp6mw(MXI<5(Ku(ZxD?mF}wQ&*;rS5(^>l~$f&ux zuKtRa4x2z&I(RoL=(++iERdn@Xd@QLO(;-?0_~gXall?#H9OwOSE51d_jXOY{$l#A zOdk!T{E4v1@&mNVaPS2*^yOIyUp^%J^U;brdPo)?`f9dtaI5$B?a2-t<=pugZL%&G zeM0QH&4Cm4I;^TttOIh$LDL)8y#SK~;r;;@$?s6Zq+v}8Jv9SLdQa!uUZ|V@UD;t5 z`rqw95e2@Qcg0wNcdig+)vILHDG_7bmo{+5&zM6Xp3ddz>&Swf_%^uZ!B#`Fm^eqQ9zd}3eS>>)pj-e(0g1(&Cx%IlA|Cor z=;R=$FD7vMTUiNSu37I@p)N1ReFNu0HR>Pins(VBq;-QkYv9Rg(*b9W9fAD=I-Nq6 z=kI5TL+>X%f3RLYXKeW-NFVHFqLNB`N{x0zU&$o*R#*==Vc^8Urr;-(z=8=#rr+%X zl#`CNTB6eHDv_a&;l@=Kwj=v<|7^P&oB}X{Uq>?1zZT!9tHMUz|6~7J{za&R;B2zs z3_EhC<6GkhGwVaB58DT~$@ZouneNIAx;s1NW;xT^KqawJy;)diWTL)u{hyk!{zpf* zj34-pC`qmoH=&`Wu*8;}+^0Km!AbtC&ybYh&!Uo}J-hm#(vXNXR~KK?Tfh&$6wD&+ z2B&PPs9&U6O&jI)4E2>x=-N&3p=s#==+K>A(^g}Q1Wnpb#;ETwvoxLJUc~U&+n^p5 z-{5@5W6%+C5(pFa{g7kVQ-IP}fILBz{_oK}*EKJZ}<#3JJXtKXf3~^p{ zxovJ+^*REG8AWT(V*&&BTzSXXJ4=soYi0 zj@yckYrdb4wR!2`rN_2l3rgEl|LxiXC*G-l=+fs`@h2P<$OAw1QD^T3ZQP-|m5A%iWTD zNb6u;D;R3THvyulAlsb#0WZ>Ux({mzg7D@BBiY>n=mxF1;b4;cgWN{J{ zw_H%E!8e!$EX{s_rAyDmJ{R`l!trin*GE=pu%l*WOV8cQ7+a&S;V0&LXD=9q;`XNE zqP-DJ!BxLz(1F{3&0sGAP{n&Pn}K9zGGG_KNd(x4Xb%D~U?Ttmimfra5aX~q_Xg&1$Br)vhP~3kCHw??!?X>$vIl9UTs>$;G$E9nSr5XW| zgD&?3-U$93UNIj8u5dXDDp-E34Q*7Wdy^;h_u3}F!!k{9;JqEm<+kqWQ*_n^&kZ;gMaryP7K(W{XIyzT?h zYyoqi{cYesj)fa=A2KN~ssX2|9LJ)(au4v>)9ckToPI(DZ-!Rdrk$~6f@?g;SFowX z>2g#|D|51XxR<*B)O2kKTUehm0Su1UN0v~0L0|~aDAunp)^AMLuX5&Y&;LLTZs;Y2 z`zD_H=u+llleN_8(62Amj(~KUKDxw|TWJrwKDHQBTFGxlR)+1KaB7H5={;<%G2AGQ zCU@lLtHHS-q>n5^oqFommy@rNyUerEnzvh48 zoBaof*|&5LJ>QeG5(gt?&i-ZT+O?EuprIJ8T&|U{-C`aJ#;ixn$V$%RmNbq@X+R?a zKVW7%gpEXvTR#=?$$l*-dkl+}+7WG=7JY{q=xb%1?}yuM4fsvQM@~ebC*H0RfnE)J zGey8*TMvK~0x-~<01WgY00KR1O^Df;&p;36Gmymmwp=5(Rcmi(Pjk0v@8!1VHenk5 z+~MAiU5ECx-1WJe-0iuoxoz4m&i3my1al3{-k&?&4gAPTGK#$CZiAt)UTbP-Pja`z zP*|V4is3_8kqEjjZjq&N8=RvjInD;87;uYE^xFgFtEuu+6WY`R@KsSNx zE75Vv`aD?0J{xm|oP9Yju%?iJ34u670MT^D9YSWEaUn5EM#zu>Ayo$KLSjN9&4>ya zF(9OdKo47U?m^fUsBxOR8MXZ$hR0rq+rX!a_NC<>%589OgyFFbJ9V%@4#Du)CZP8^ z-5oSKl3^q@y0_&vz+yQ}lW3!cVD1)P0M^^xO4CI}k!JTHYNmEorP)!>Z|&AkaiR}; zrs#HuRJQV#k!6;qDz;Xg$8`I0DAMi{8p$+v9V%&(1A}C^*q^**Z~id5I!hcAhHmTk z6$fUx@C~#=j^rcl;Ve(Xmr1llHf5qmt!IzA6#Wgauzss;N0+=ll~Bb>EVNl()25Gh z4Et!GZL>C#Z}&{nN20G~3ARQTo>0FwDK#wrRauJTAyi7(GVjU+}VV zas=OoGCw}@=pZ<9)KCt7amSyzI>4qi`X;ftF(WRYN^N03d@CHgnWaGk}md zl!@go58?g- zFHm{8GbU~(!^u%`Y!uDp_zTzIuxheVKcWUg51jmXRJP&xtxHG|M^rLwDyPTuty6~gu zwYVqO)}{@|Y+Dk&2oZE78e75-GCjc$G6F@T+hMX&0b7R2x%WzI?u9hu;35egbdt9vM`ihvU+Civ@1S)=$(cXGQ|kX@0$@dtRJF`AC*foYmd_rb}C zel9!DBk9nek;PP{`w?tO=2Xu=oYL6>K$|31%(SCS+Z~5{>m1Yu%2z_9 zU{Ybf8Sk3T!I57eWF9*{CU5F5t88#}k1&&s_p$SaFeba0;W!KU|A+Yh6~{k^G?V%A zN+-=%Koj@3;+={-LzydRptFn4$No~!4q<%wBnBBAKiSof1C6Q7YVdh%vXCdU)7bx* zAdFPpc@ljD0BDpy9)?W*(Uq4h4EEjAehFT>^IQwKxPRUJjvE@jcBbelxN*q=A)!MH z74l%Jh5%RrLx0~U`=Tbi@o;lpa1c!#;My_fDeiO*T29qlG3i)0nDmXGZ3|^0SsdE) zPj_Hk-Nm6$`0Oa9u=s|b7VrWo-c!OaY1azREatIaqpV(2iDdmcr*@;mI&SFfe{H%Z z{ID|DJl=ShQ$}OMQ)NI~z_RK}eY|)qxCIaRO~UieNE>#hO(Qn-)7Kk);<8KU5w z=C%YT1D=1T6z~#|?#6;EO`DQx9*+m}TCRKvMHg?8BsulrmJu-=M#Npvb3H(kf$6j% zZe-kJ4-fV`=|_VM()ce5q3 zy4e!xv?bmUV*B6Ci8%sJSQLw4QDnoSaHZm2%Is;hC}wFt$szGB6+@z6m*#{B(4vr4 zrZ?GXhU2ychhfXM5MW(Riy=aV;X^VY;qde10(H*eFoUO%fqN^R0!xsD6fU8-z8`?A zH@R}p!7BQE%yBt9^PsO~`J_=?;zzx`hhe_Q{wwY>$3T{a1sTAxxJk#bjl11^Uh$q$ zHt-TZpL!AC^)^0#U2Y?$RB&HQ)p#FBqLA^P9RRX@$9Z0#zpn9~V~FY4l5 zBav?{`sICcVX#|>ldkzv?c};YTde!D^m*dURR4KNP9Vm`?Owr;_f}Ld+qOQ+B|Peg zv&mSWmxE%K^bTB^z$;t;=`gyoz*83Ivun5@fgGc^A%OM2{GKr6m<<+c_>^>};!0Ip;X}b{5vzB0%L8E&#T7 z;@M>J0!Zf|Y5Lscq#LGY6pgI}v00&NM3GGA+E;85Y?#PkX%mH(Xvt^_`n?**-CHly8 zHZBl|C3+PR^sE(|TXMe!3l=q40h!A6`lrMt^TjCLGF+_Lqdrs!@|XJn9JYALI%H{| zh6zT)3A1VM*%jI!UwnY)dgjb!4(93cW=<<}urtNH$ILtr@)&=Xag@$8VV@(c*vx;? zg#3k>GfQF-mzKV6=KYB86tVQ-4+Vv6Vq9+K?Kbna$vn2deYKg_Xy&bwc{$8$GV@+W z9=i~~p_G_DAL)Ui$?C#l*CkBfWWrA~aeaaB`k#{$n1->5O)`jKXg_%n-+wB0!PTq=e<9Oz815~@c?_ROMw?8Qll~FVwI=h1>9_~yVR%Brad;rez9@`eP+RzN~3c~;&X33*Fo9?q`9i^_4=tnrit zn7M!nKUIQh5DqP#TDErA)X<+H%$B@5K8*8DV-0R8q{eVI zA?}|M*91f;0xfZ3C`bDO!f_EG^rr+b@L_`=QGOoG0DUbnsw;2EMco{d-$0}sVz7rt zT|`KnyfkhD<{MuI?J5wL_} z1+ysv9&}mb@^GAiG?wCEkREi=(*Xh6qCA^U6>A=sG@IvUP13!=O7z?%8&oNXE>$244;wLFv;RH1A z@5k54;r-(mDYvEI=|pt)ixNBs;5nxOz6jutmb)&Qdp#G*^3?!2*x19fUqvRh_543^ z2wB1yULFoVwM>Sx^w}Z}5Z~I-nMDk$j1VD22Di9~!3m&%6eGi}7y>J086~W|6q{cn}kmWO+xB;IZk$2Pq zQ~QegPcZnex+QMsm1D|aZWVK%s{eb}+|3y5yQdvQiSAf_!uV<0V0d>^!`V9Wd@*Qi z*v9<6fuaZpim~3NX!57q#JvS+;56`Gz0@G(p#3csRrIeerb>D*&#D_eNg$ z$p~`lnT<8nr$=6^UeBe82GwytD9`V8sm~>#4L$&_7~a+FCsu{gFF?+^FmQz;cE!cH zz333R1~ID&5f7Sz+p{Cy{+%gVNTF&I$5cs!bvB%!5xo%Q#XZpNJ8^maGf;1<&Ou&d z(TQanu00W776Wo;XY#v9)*3mv6aCnPD!jRhRfzKS!Z^yyx}Xf48s+3JC?8Ki`A3P8 z2aMx({}R|ir#LdDuW&_ZA@Q_Nhcu-Q0>|7)DCX1pkb?;AQ%6*gvvukSi2C^L}7xV(I5dec4bnc;JLX zox`14k~ei`FyM{XV?2^;HF+9iBL-+UyRh0TwY0??3qkA~C_h%wZH}xIG+n`5A;}t+)l`19_;CzF;sF zIp|u*tc9+p@zBM$i>PNPBGSQC7zPSKxE4d{Fx=Pm^u3`!96RzFY98Skl0y3SK&&A4 zDcK$Yx!1nWJ&6%Ho|hOf0c$zmfWqL|X2PYgeZ)fgqh#Fk3brx+$7l`uJoRtKm@e`G+QKST%n7 z^rWp~F^!o#Q=+LFXEHVT0)S0Qfk-9j*i9uN`+eRP<6-Dm;LRfZ($Cbiy#6Bwm@m=! z?08A!0!qLvDY}iQS^Akm|3uC9VDfJn0Yyd+f~-fRw~WXHZAIQj1WvxDZaC>gz01MN zgoFcioE^JJ@R>U4FLi2ocYNhFIqJ%B{S#fJ<1WJCEc!>s<>IwU%Q?DQI7i>($t{Qb zGaNcQn6_FtN8ii+$h}(}^*Ykfp6Y%NN4-Ad?sD8Yx;ys+_u*WCu~1SR_RHSx_W%dy zCYCkP&TfF=&^f~&W!l%IA(LB|*7oG47p=Un4a9hU8L->I!kes3L>6%y(7szk8@DB4%o ze~|$jXiVI;T!*;~kdRc&xBwg=oYD{rd2*@*PkDw4jHr2Deo!RK6LaRpr*C1Y zWb{1-v2v19qKgr)|F~-l+>SB6eoNQ1L9h!FrZW2kD7zOg@|u&FA{8DO@%>BOK}6LW zoRGE`X;hEm=W(u4#}j2F+Q~*xD*}YY}(IJLmGG+dF%^ zUzTSB8pqzSDY0bUIvJb8Q8qdmT z5}Q+Y^DSI?i-hkU`Tn@rqLlBCqnLb8SL&Yc(l{Q|zu)yTDq{`Xx(3$Js+6hLWmLCg zEbg9m8)Z7bE1W^NZfQM%FTSQLz?Mmwk&f2WnsmQ#cV)StGFgW4ETr-e$Vc0QYq%Ff zTeCD#3q6!0x|p{w`^L?aA&vl3^bk851S8T%h;*jtp#qVv2G4=~(RIu5c_BB;o-bgS ztB2@WvdX52bf$D(w^E~zEj|rX7ahCY)_59#T2V2_NcJ$vAjgU@?pEYPv1}Z=C+;LT z4Lqk$5Uxk+5-F0#ymIt6@qv}-3G|Q}-3!5BukR2d|L@mTto?9jlwbiIh;i))D1Nh_ zm(JM2HLp_K=0%B9u`p+Yn`c~_{o<92*jy)I0=Sb~?#a+crZvqicin>b3|Cq!t4bY=+JwC!)2a6m_Pi<4n&f>Sc<| zs@|_r7gmq5-Hi&6D&07&2-?cHXqnu5Iv30_uNr8XekRiKMA4zfwl@g_-`Y@hK5qQM z*bd*GN5K!ioC59DJ^-}}ZI{;6-V5*8=l|p#!!;(QyId6Ywqq6P`-XT2Ef?N3hl*w( zJx$URbS~=PJdKVuR1N(RbV$GkbiOy)N3?dGCkIPi1+Z!Z$75b+i8c%?9G`{1nOZb8DtyF*oj^vds6gGOp6%X9~E_F1=+XG#^_EN?@y@c z;a5@7C4i>yDc%ZyWhFQHC`cJD#o;IS z0klH_4zruBK3ujs`285#q!)SFBe#OQK6WbiGXthBe+rzam1xc1ikh)K)!?I){8+F5 z;ky+z^bE>17u{{cU?Ln!CCfcRJCKaeMlA%NXe8^)1m1foHH9q%xtcEA$!x`?cL;;U z0r)N_#BTd<^lH<%e(gC^zl_QoJH?kH+gsGU{1se$ROPw_syhRi+y~Ytxvs&`6rGLKWnTf}&(vqi#z9OxO4>O=Ug2wo+ihTwvt%tiA} zzH(Tc+3Kb|0;Bl^Sbu=wo#%(Rb_BKkxG4$u5zfX4CN68JTMSLZ9!7kCCeYj1Sc47= zpGk>qC|1OH9oG}#h~&uwJ~gE)ka_ihJ$ z_6DlC_Yd{AfFK9Li^Zqy)Zz~T#rKPy#K$3r%KQTw67Xfn;});+^=)ZN^mDS0%sOC* zo`KxZn&4%z;qGS4qUr@syv;$8ge{iT#TUU(I=IyOLX+5kdBDWOW{tW9?; znEyYVwZlOd%|;Xy+d0M5U|~1#i|NJ)zG=H2p9A4&#BsmGjyf9o7` zE_s?`jUG2}WTN9-S)eH!HuUGo`pP9NyywUwe(yT-su>@Jxw#4p?I^4@o9|CJ zy9IFf0o*enGelSOfIe%O3Obsx62=>34FtP9uzowCj*Cm-B$ zYFW>Eu2a?eL zT?8QUPaFRQ5vmjSa_|*V#8`p#U(wX^Jrci%E>nAk`UsF#2&IcgvminV5LJMHDPwq0>FAd*0_wTnuxiVFmS1D&KKLuTrCpEd ztp3KXaMK8PW!JPZ(Ua3woC5ALq{a6apW`OlLf0}rctSwTg-@9s--&96;W$Mm`~KFO zFf!u#8s4ZiXEoE?UyIc$tSn+N<~@j>A@&Fx5H+uAQbY5hw5CC0L9Shiy;Hd_jxQgP z1M$@|7$PP3FT{IX3QyP?S70~~uW(H!H@u2qca#UuYjAjguY3rLlPz);+sbsRW^`a_ zfJ8arVn_(X-^lV9M3J0Hym+SLLCXopQI|2qogz9&vF(cj!V3z-CQ{?m3N#{?jo~#e zFL4#1J&}YG1+==)LK<*(SzW$gE6-Ahla5gOHHdS5nTiUClZ_)M=}QD>hKBD+z!fFe z3LVC*J#y)M6vL%Ci;tYHEoTqW#Lc%LTMS0+<`N9Z--Gjp7H&B3BB78{kCg76qRsfr zbX<%xV?qx#xCwIbuPsIkVIctTB34(~C~9lQtf(lZ=neP21E1{dWqjA&dzN+6Pj68= z^ehVKh5T+&QlSes3mMaDW3k+pP;5pCN@{rDL0j)%?E)snH%PwvfYA%1HBIsVi?eru zkFvP_|2MF~h>06DXw;}tw>2qINd*m(XdvODqDDo0@xWm6g!V69u~7?sQ3n&Hs@T&s z>F@Uk1H+aYHLX81sfC-_IvwlqE)EMdA5Xq^`FkIg%TwwDmKp<6D`}p00T#}aR&*v7 zBK~L7due)UmyYCn^C6Jg; zs+12XH)#NpH*cAyx5n4>R^N$GlWj`VZA}nlI_yBF(G1w_`l_)cvpm4}2;Bgo?kD6H zsbDV6v~(x?&Z)^$pOBi@AE9yJcZ}89jT-HNN1~!H@zb4QDeYcBR3bQZs83Rp-1C6la#?s<#Xh9@j5LKoVOl||}|y~U-<*VfB64qIq7xQY>+ z4CS7yZ;JHDn{a1S4xi;rv}@|;S=iHjcwOAT>&LrOt2(y5u+`35MpLEt`gG$#5|Pow z53&85HEH&mO!R8b1gxlkKej5dQ`0*p;a)xLf1bh8=fJ43=aF59GZ55dE6CNt5V{RQ ziE{wh{U=4XQs5xqR*;_>#lk2$y+0^z({$(E-%@?(59wUn8Zu#{-m~i{{<-JJOneh3 zAobn^`n?N*UPP~ifbJx0+EzfzO3xl(SWZ@V`DU7^Rz*g5JtIq=_1DEC+7ZJHfxj{C z)iJMOuzyjXx2eZs;~#%}X5s0wB^4rJCT3FUV(l%NA0h57SX@>Yeeum;cEE>|pZ9L?ei+#7}L@wM86aG%6y zeM1Jg>WzVtkFN-A3nccZ$;!sORsK=8({{Ap3K^7AoR9uRy>oe{ANJK2)w`WHZd1+c z9`)(57v*dH?adrWH1C3~|73k$?saDeHe~1Xx2vYaJb%661r9V$cz-G_a_J6_QI)oJDJ~rG4%8N-1%*NblMcFiaJ}lnPT#IWaShLT501 z!#RkZdg+Pnv~0lPjCgJT9yDzFb-FOp6d}A}&qXNo-GK%5g15OKhTr^OP_O*v>RDQT zbH;hOn-;Y&+z1oWqHpW=+^8OnryJF7x=&9BIL|2^cnd4HRZU_6mq-GEQ%XLA+RMDL zY&lxj{L%E>VaIBG6q8LQD4NSAoV$=+m7U;TfDtnUl*mbui7-r`qte^`Ge5 z9DE|PseDxTyykFQNw9g7YAh5DP#NcLtPIoBZ48Dlb*|N^pBxvcq(EuagHM-i!H`~v zhI`!^=y&MXEBOC~$)TUNPY%5m4L5?kPTH@#K5jPQt4&->QHk7DS_r1+M|rm;WlV1 z!_A`xbzM5hqmdqhT}%pgK1^+_x)<7*$U~{nB$nB+mj_0iUQHFP@!wdwFZy6U2Obt> zO$=RFs*mhBe1zuIAaavmwqB3yI?Vi4{y3cVt-nJLQ^N?&znFAJAM9g=Nhia#kPuHi z8uWwYlg7uWI`1Yezd=3f0*{~t++$jFv#1o)7&}E9v|#u#s=!@(Ay?|{dQMNJ6pQ_- zZ|3>YTkN%YMGwYl??gA8LFsPLO~=p1k_d-m2UdFyQdY8)`n0 zwt`hrgwz#|OnKhFAhSFR-(W617V7ZUwchGRqSAhoMioShnc^-yJuDMe~2 z7k8nMo2yLSppYcVr`p_0W{{0S&Hz0JN^!-6`|C6F0?V}NW9Ns9@6aaB0So!NNVyEm z)?=d10BOO%0Z;QcG)FFZ+lV);NH@-lx(4W}&o1-i==vAv1Cq+@_BqXV67h$_RIBu; zZgZ8VLDjaq*fQpO-9;?nK8jf43&VGlNE(33Ci{}u2GduxfY4>06Wu&Sx!WGAwFw>Z zRNw4><`fvr3~~nONi>RF<_yt;qE3|_6U7#X>C<`1XAZGWl^z`hRs^h=c3(*UQs4|Q zHeZ&&v->NOmRGz5!%|Ln7Ivr8Gzb_av=E^FJ)V`=&X|t6JR@6TPCUj}%lhmU4LIEs zs7K3&=e@71*wqH!n5LBm@ph_w!}i2_L9IHGzp+IA#`4uXZ(*)&BfFTE{VlbpOWjM` zKs*6H*tc&3dm|I?r^4Gi6K^T7uJv8(+qPxmE)?#^nXtb?Gr2y1Je)kEI(br^MMiV7 zr8!lIqA{|zr}eqV@40nnB3`s#``7z$^k&x)6sn|jRXlicyr5B6=>$vlC&mp#&&KA= znG&w|{#CcMq=F`Ek5*zxJN&fz)0+cvD<&EA@%JTH4u_EoIoS zVq=wFv!&`wHe_okgXU=zqwnW8S2a@6Xdj9p<;pqKSRdFAxPNu%ClPeOvrMJFxHxf< zszK1@yv;QFH1tGoc;;#xB0|+ZcbZt)M6^=~F>-28dUaA-<+&Ig#b) zmAhe)X|Nvur~A_FMLN}HQf?D{aoudPCT>tNZk{jhRpJ)u#nEKBSNI|yQ>5N7PDXz2 zi@aTtg}%t}Vd-K_SEP2IB~y;^MP95(-D8uCobHP}g~+5j&1WMhJ5bGv-ZMdj+2Xxh zuq5TyFiLWgPtM=XL4Y-3CN$y5u0F93Lu21obtJP|=*#MLgIdtHCUuDSAHLWpY-}=N zhcD_b6O~G}$rp8#i5jCL3%(lO;lsGZVAMJ1=>%y?RSFJI3vZY(&MV-lN*0`glw?pm zw=td@YyVdtuA;&zxrzVJp>G?XtkDyFslS~q0n{e>9_x#G*F?=oMoscXbt)I4n2cTHi*<K+RxrC_ zOLpgog77=l+ML}vqHyy8)qz;M88YDTn*3?njp5mNW0DSpCO7?x=uJ;7sz#d-RR6?m zcr;@K@$lOt(n9^uEO01jiSlV`v}eOm&XLu6>9Lv;E9v^sIyk@{SsMy`2KCCu5q1D{yD#}sB#-b~V{)#(8H=basB;xVKRpA+;)USj zP13plX6uDJcpMrT4QoM7{|GKj2HDchYm)Bd>MZ8}3@9`UmR!yUAi`n}TCcI+)Ey#y zN$!P?ZX#2+;~ps6e3NW2mQ_Y9ed9}ikCd%=aI`h(8_1CF-Cn+3r(x$bRSZ#Y;|ppOHM+`yuBR10y9 zH=PLPm4uv{YGw^a7HbEdjS1&IV!)Bz*N1LVPoQ@-jzC%_Pp=Q$EOxwUOy3C7tEq;1 z3N&L4BW<%jn=J7y`$DpXB(_$Plk;m4q33KjNApadU|bTGYQ~8u>j%Kk+Hdu=EB*mKIT4)hLkD?}i9wP+=4SVEHGUb!( zfEL(lKttIJ+l09(vU4+OT=NX(luf&JYCkl88e!^)a7uf;bC(Yvovz8Dkcf1a;jDCD zsI*N{q-Cq`sW(l;1=~I3pHxjb6nPJqdv4UAuIC=%MQiMMCU?VgAI+c zLjl{AKE!XbC?}aD*O%lqUy}Pt(vhv!m*wQi&%*^H^JioAox=uW>B?8&!-#Z@7@Q?1 z#^;G&+5Vujro^a2O_})_U15JJEf6d7Ju!UaQ|KR)rzeJ0!>kyPxe>!3uQg&gPGUIV z$v%5%dv79%#;RO~! z9q;%Ty^VYPbC~deDlV~>Z`z!BFm%!r)Y=JlUYB}t zc;~U25~n_Q=yO$M*V&=@eofGNnHSk7j(N4}?D(jjp({i2 zdnmDeP}rb(&jZsaNN8F_>XqM5M4lOj!BbmFJ%juzF$0I_UEvh+1R-~(KF{ZK=&FVw zS4a;K4Y@8;ku5~JHMhx@+8&`XkRm;gIDom{Br4|}^=#xFKnvpXEzTx*_Z=1t>RzU4w+_X-VV z^}&^CbenRQ6e1VhH8$SJ$a9nw7W=B*WAKvygF&_W6oX^^3|^=Y^VFPoZN1Jh%T6A6 zJPRk!#cvpt+MKa3qnPDusUdGWM(Y~Fq1qk7e)>4D<=dITrpfxWS7*i^m|ZgTe@jyh zKE>=`e&mzp-}s;+3%xlyH)xq5V!n5)V{W7U&bfCFxt{!g?~3ubbjn|S`kcnn$}S65^&lU~+px*}aoXKH-R9&GDScuhn}=#7XU z9i%aQ?-}PM3=UGG-UH!5z1vTJ3qyPJF_dSh5tvT)UI0JKSCDPu8@5#KdHf%=V{wf) z-20h#G*+#UmV}z~0NKfa-Dkm6b^Z-II8w2Rdb4Y7JR?4;P})>Kykpd0dx?v+j=rhV zIhxE+=HDM~M>tVj;Cu(QoE_=N*TnqXUm8D`W*j%&mpG72q`5ioF*Dfpej z``mYJ?zcR_!#D}eE%!X-s`klmvKUySS>dSf7HbrrxDeLc-lyctRP0uj*^NBQVDo$y z_m{nQRT4H~Ik0h=cVM z)9{Tx&HcIBhxQt2(@#Zd?7z6cJbHZAXs zA;Ya|5P@YVwA>_*goT>(VX0}gXq$IaC8$PU)^mJh>n&MMQdD{-tAD9Eh4ic#c-V(| zx-gO3BbWB{bT1OkG9S&LuQFa5b+t}I&$o*h0Djy7Q#ni7Mm`g7%< zZc^sKcV)juqk8B0Ef49AA1AVzzgVd`IxYx)1?xc-oAcI#v*n@J z48|KC#`zf-TScXP%R_5~^UzDe;c3+$_;5CuWm}Cl-&wikp%ub=YPIm#;_`*K*^tcd z9Y!vj5}~_RF3Dm6I=W)h^IaR>*$uaaU>MCU{DIM2qm@IhGE&mz1BluBXgap*Qx*FGrqZGmk1|dZ&=?u&P z3{Y7+RjPb@sZ$qe?Zan1Z?b*$Bszk>dgQwPsK)MP!ZO@uZiC)D$5aNHZAo;k4@Gd5 zh^kS=ap6H)(koE%h(R-p_R>GC!qRnYZqzud>kj?(=vJ3(wz%U#>z9_}xA{4P2HjLQ z*6yo=8K=%HRB`{geL%xh)TplC7J_{2>~-BCHA<|8`>p{-<%+_~ zaVF7|RlZ)Z@onrEFmHL&vWsciVFx8rb*WM=oGA0(aDWWs z$J2ChGh$xu#vUX)D~HEYk^|r>x)s+n4pjL*`rcVisP_iLry8mT;*zmPYl_U91rzUcw z(%=3gPYem``mHGvNi)?gDVWRSk{;>$BI++$Pa^QNC16VQfr$|GexPFVb03o(zo64J z&#o>r^Z)hk8|BP%3`DrH$x_B;q>XhfHswXHw1t-&#fFt{YKd3M))>NL^y>|DVoDG^ z#TlX`PQfWUKGTi%c+a$6zs4(9Z?!xIoW`m@Nd-d9kI|Ct+W&yNfjB{}u7;CqUeSxt z?(&advqT(p|A4uOozK;Ej;CyJ+?Cwv zQfyg=X^5Y5s4-J`SBfb^E?zf7> zQ6nQP8U=@5Umu!v2!kS9^W^Ik<;MoXYMA3*HO0<=iR#IMH!J&fTz(;arX|`-GtGkl zPG5L2d_*lDDuMgh&pF6(SE_z88}}+i=x^MhdF{@$7j10w+KW+quQ^^J!5ghdd6tn$ z`A4=MDjziB3q>V!GmoOc&fq&VFipznL7$8cgtw&Ix$eknqjq9iMsno@u4tu9&FaIh$av;CQt_G&cEgb78`>!z;IF2GJ?m# zR8X}D{>3AWq88-Zi?GJt=01y00HqNgwg^1~zQHM{mi}l)bkvJBDR0h*nq#Bruv5eO zGcyn>=yu54=6ZNW)EIx%$8efvXsj1yhTONALM%~E5&L(k=$I=)sG}ZxJCDwNbw*Zz ztACv}72r@$BN;o^kLNdM+=xlOJ{0Kq0AKh;`9{4{w&fV+#9Pc9Sy>+ zid2G%q3WasZWgh%#gh@yU%3KBclTXxX#fcs}G*R!_)Xv0evh`saK{q;Y6 zcA>saOV{@)&)%zVmK$yS1@>a0Hipe7yARl_?8y$jay6M{oRuGInE`)_$XzA)oD_U|23*@;EIyv! z6n>FAUU|uE`s?Y2bYAIl9S3Iba=q;<*LQfpn>tog#AMM1dt_9!)Ev|O4@!)RvT&c4 z&n_RGC!r$+{>kDzZaZEfzM59450J?ja%vyLyhy6ga_@jzw&@alvU=*d3|ZBy*%(<( z^OZfK*X^Gp?Ysg(HxVaDfo2Y9o18_Z0Y3pjchBR)fKy!?jfIAUp~hv zA6(Mj_3hM1;FPrRCHo>MWXnGIb?4O8DcO@%p}Ug}I5?SwW17MwUluQNKq<1yj913; z{)2cdym*z5$7M>~t1Zp;5tu6i9l@l+t@4PZ+mejPy*2@S2HcBCkhDg(W1^I0k=k8a zE~EC4=QdxS2bw(1?i*?3*}e13UDU!vv3jxo4$GG1pV{B-`Vy-zh-c?(Z#G8V^bzhF z7?D1>d(~Nva##87qslN$QYN>qyRpeDvDQCdP9oUn8m29JB!g9l4s56SioLS)t=K20 z)t|6)ZPv@pA2ozpFDjLNwht!Q{mzIQ;b?lH4O)}$!7nO(bAjQURvuG7R2r8)R$e-D9y+})mQ|qBi zpwl>vEya^N`yN}~QNuQ5NYG@`Sv|KGTdDHF(-_EiXnLtXKkv}=VdMva91&1H$-Z;# zdFdh0!Dmrs+CmA6H%Psl4i94i30?PRa`A42ol6*uqR8qJ+JN=7vx0?c zcQ;mz!A}ubZa+V1tXj=zKk$_O+&~eF8mp%43#iqC+Nq7g#;WIpwakLndI!Fe7>!lG zPy!!~T*n+xgjyLh>=G0wOcO4~aZvy{?Uc&N{gJP7z2YnxkS@-o%Wbij`0>V4)ZDN; zM|cwm(_kvWb7$knT=X;}b_r#9zr4VlXqb*9RdbSU7lh&#EUe(4%x%`q+6rcimle8w z<(vU3XsbpY(RIr-7_rZq8GYR1XT_8Hw*|1`vGpiin4^SAg;BQKmF+^qjo6JZH1`#q zZ-q>jEAElB*ji3z!$!4&_pRFgUS<2R9;bdj|CY^VSKi{l@AHc~4W`X(fx@ zX=E_i+8(1_suHzVnoR+S$cvb@8HD*4fF$;^EpoBLT<@>_{< zYZwkxg^s}&JnK=faoh(S3K?o#pmKU;UV{=OenvW5>CAvL_*$J|U1G8_M_7w`0nSJf*0Uu=AH zU!;eo>Rtl%Jxi-;p5CW7)|m%I75PLcDT)Nb{PVtOUHWq|qs-XKXP1NArlD7?~&Dkk-Oyjw}X0dA3mn88+YYT(n^M$)vthZa-gBD8tA9vNj)3c4zge0O1wO` zj`yk3&%evnu%fprZ6vL#dg%fy$5u-HeLfFKm5=&0dC4X!-3*hi;XG|neJCYle;CHa`7 z4=$XEhNqZNPV8~H6?jK|@5WPDlPf?-JZ8OjvXWAYeAZiT|{ij>BP^ko!%1cKg)}znsWb_22XS=95wB`OQ#vCVTT0 z)hYFUwloT+(;7AW>s-koXCFkUNHYSgHJ2*88}>FsggS{eem=Ye!$*PUzNt-=yr>z9 zvLQ!C<%fbkD=2%21ji#N_#nX_u<%O3M_c$%!EdqfYR@1V<0z~6p2ay!I9FPn+TJ*i zTbwI|Guq;e$;4^c%i%$%4#UQDp%n{lRWGEzAh;X|GnHNUzgr;^`%ek=Gj>y~=r z_iR46{GT(&j6#jvrB(yX=HP-bH8t3MV0Ug{E&-NxM>MTg1)9bVa)op-nJ8r&t_Pnx zWnjRIuJ(S-(K5C=88 zKX+M8y4mzOMSU86G$QSeYwcE~5_jLFrb<-6g~sWZ>V_d!g~ zm;yofQLv5+0YXvPU1v&3&_RM8Z=iz()uNI!rb5u+20BjA(+zaIpg2gN zJ3&x+N1ZX1f@+oCsT(UO+kb)933|POjuBKVbk3NGg2o7TRZrQl-RyF^tNk%H_pObt zYuLB5dWxjoSv@rn*l}uC^|U>qOtUEULSap#vpP3eQ0o6`vbC$+20Z2=Ov*m%)=joB!d##(!h*B-!TsJ=lbR%4S5|{3j1qS#jWSPu9%~ zJlI%UUJ1R~@nCfZRwwB<-|WH0n6jB_X#R}{n<%`*m3+zX>tL-=Pyg1VhJkj&MevT! z>Ov#^WW3#1)Nq8SzB=9C_D(VSyEJuy&S}3xf464BUcEIhpu85nMhoGV=cB#-9WxIo z-y}m(Pc0^IYWUc=mbpjJT-?ySY39egaeN4Svh3a`v4lDWYKEEk8`m~I)u{P@{T2}# z2%+xxeLgwbbXn}pv{SnU(@$xGP;kGj#l@VrX6soT)NRQ1O^xJ#5r#08myBc_^>~Mq`%R1Ne$yLS$#Mp0Gn$0IFNr#{H}j=`iFqu(U)D;jts@CMV?7QY>9O3xG`x6dpZaH=JiA|~$vt=gGe>1bciMbADR_lYb~taR z+29h@}C3#~Y3D)Z!< zr|b&!vT^csfiCq>(6d%#j#1fCC#~Ju8dMJKS|@u)5`o0i!9W%K^CO27uGp@*qDL-W+hcmix=v$94lwM^MO(EWgt zGJV4*)4Lc5c=RDwAa2Vc{AKnQhz7aT3=-~*r5|4%Np|6hTRjpWZhIACp$E1Vk`sy^q&7=-)yJg`#GBP@X_W*X z>=SA}ofHoS>q{i&#z|l^>d9uv-mveYZOmx+%Hzv!%3OM(seNx(o2h->_?SMsc_3e* zCx>VUqI0Z_qEjXFCdG|?8eLbvFT=C`jjh(Q?WMa9`~IX}O8YO$;gL1P%lFE`nA6OB zrf;h@#XvU6N-+}G>o5|BCV0khQt`=<9!5L*P72n5X@_3^7J|Z*iQG)#- z6ZVnl9g_+BYIgGe-^jKyHthfInv6zY6 zWYTatDc~aa36gWn1f4I+GRI1ih-1@;ZVO1Ur*vK>J}OKB+(UVgu4B}RI>FLeT@8m^ z@tQoU;%;w5R_313j)=BTX6a~2b&%PEJ%qL4`AvyUoMP|#qb7)Y7Smqs+;%}e^*=w= zUP@K3<1=9=&Pvu{)3&FT?Ze^M^mC?$6w{nD3;8K_P7Crg##~q&S-}fPdmsFKxELPeMyKB78gHzI!Q*jcG~PIv(62QDlQ^y} zB$MXL`1EmNI5W|YHY%gGsQ!)(4;p3`214^s3YzRIB!;gs?ZQoo;Tv&`#F3=Af#`nh zF-5NE7+G!d>}VQK-Dbt3;TFh>go{&~(o}Ssju)W8>uhRNkbj*`VnF|(Bbtz>b}FwA}>ZpbdwY5C{PbamEEl!e4y!>4RXT$iVmq1mqj z+wgn~fLvwOb~2l`b~_=c=<-- zZf^boaGO|7g<|B!);c$fKj(Kr{+fbusvx!|dn<$_m9y9Y8J}maU`CX+FjCyqz8O{H zYn=Uh-+qm?U)$_go#c?c#AY)gHMyydpBX0Qcqgw8V?tvI^HR1-a3 z(X)x}7>P|9nX*X@DVy|@8Q7#*_gWsOsFM2LtN|cZqR~UHXsX$z^sbtnP;c{KM1lux zeVGbRnezWcm1BQ0jqNycS9K`*1jMuI!zKI8VE8~i4l^xk#vwQ53^Oh4x_m)nCLFV^ zZE3g>da+Lja)pEfUYmb99M#vZfxK{|Ks0}`qCW-e>D`JUTF3`AYRj-YvBilBEKgb=?R2p#})YQ+t6$cugcenjJtzv zTCxErGsH?v1x_2425SZ3;q5pZ-zLHbyF;+QrePGhE{1wE3Vu!oe5~M81V7TkPxorT zTvzOgJuwf~p?_A)ilnJiLiZ$+&&kX!$Y2|1p}>l3X|o!rv3etq_8 zj`DV$GmW#hxjZWC>349UuQy+L0$sl4MiS1jrW?A9Jx%O_XK-ZS&FFfnO%GSxM`+U* zcMdmRoTk<4h>aiHpQ6jAKw$%Jol>Y-mWV)SwdwsjM^>1xk;%R>xPTq%G;B3+_b`%l zj2x0>8fTGd_&I;E2lCCq9kQAlqx!ObWD1jF^h;m18-8qP$e#>4oyi2KC36ca^TgK- z;fX7DhUZA!LbE|r>Q%l{&x4pSy;932sBAHK_~HjmPFvHyyML>+>du|JBP(PkCWZd7rZu36(7K(U&`73) zX0Io+&_Bk8r?e;fQ!7&v=Ms%xLT5_oAGP60pw^p(i7APbG&=&`zE$IpDFo|zYcPE0 z&KX>{(ykcMRa8P(#xV}oQw7m|#o)-Ge?XHF9^BaepS|MI@PjHho!5YmtU;C>nmSIU z0IiXC4z1a_oy)9u?XP!vb_ng=>Aov9oBzr>wfpsTOf^*aK;llm5vGo{^dx55_MN`- z0UnFep1=JD83m!;1l(^1Q6KoC%2&7>vNRA!bL7WbWc*7k(^yx~9Wd9tDbzfUU+35g z5SqE1_LpbSBqcI|mbLea@ol2~nK<*+9)oS&Mr$gXKh*JS>Y4K@x6I+TsL+#4`baz$hjY>a?5T>}OvGefIIt0*Gi00&wH}CS6d|CIv0cpePIYd` zWnH|&9uXmmHHw)>JIBhYTfU;ZFVW7p=74j0?$F&g28YK^&#fMYmNk6PSz|^U+>!&) zU})Cs6vO%&q!mRivBQ+x+?uKPER@eJ$xzZeJH&D+{{6QW@OpCk)`F^9CY03D5~MZs zolsO`@#F(rc3p@|R_$6*>g+AUbM{^iVJ`>?Ki~s>A@h6Xv-7;4??ML9g90UeMJC>y zhuTJL>_cxd*YmE)uP5Am2bJmMX=gU;9P}P-f%fhV}FQSN#g_#&3}n#&wox6ewN5UHJ3Kc|5|((HS;&%6dkOj z(7$q$UK+oTB%_DE-SD<)d_}h=v^2J}=5qD3YV{(5)n zHT>3lH?QGp&LCTvMPG$pN4EJ8%{m{=36`elxV6x9`YzV_X2h^R2CpMq$Dgwj^C7_9 zPv`v<_<<+Tp0uRe;&>;MidquyGD>ODhU@5YERoD&>~Mfp9O60@C*PwvW!bh-w-FpR zEqR9P9ZYcB5&0Rg@2&^d3oj~Ibtc|Ddr12a?04IUOuRn=L!Q=lKTJ`v-PN(T=&Q!C zb7cj9xeLOYLCqN#9_>7&(T@|+xX1nbF=p~usXZr=Q?j`V3uxn0WBJQ9!xp+%DEec* zQNPSfUiQ%>mtMW6x|q9OP@bNVgkMNC$+21&f*+?*1!cepw4w<1x(*yM< zMXI#LCu`<$_}byGM?uhVA|Ma@$<wN`g1 zK)?->i~F;c#&%nm`_D0by}Jc@MF_pO}dxZI^kS03HNQko;rHWa}@; z17A>(V^Ng0f=v2XE6+nSVKd1yxtDXS+W9J64UJHZ%?n5Qnai$B!0c&V%$HZ=*8O82 zO66MmdsSEbqudV?q<5(1>$ATRCD)q%5w(@zqpLsrn`2YEb;YK0o#EY}o@rT2kg}4PhaSCqve|dVmHXh*Z@dDl+ z|627{r{u`~C(5JKiD>U?)i(e`^FM=+svgdeF}wo`2bDmSsFr4|T0WQsUVCe`v_EbU zq#?PY_MF*92HK|w3Qf7(I|Z8?sS`Dojkvc=9J)9Ln(oxCxv4#-PZQ%jR06I>i#xrn zrz>l6__JbfQ!MRQtC8+JAYyKghcQExpHm*kkt@99I=C$hzMKRnZSLQe-x#Y#y*64ZR5|PXeyJr9}WGL8GKgXMm2(;@YK5C+o9D|anM;bp|vxfO9_wo6b z_oshI>$D>pfq#2~1>a}E((U9hDau`kf%pQW$4GH{e5uh}8SK!LR`JO!{itP8*yBFQ zx$FLgHV2YPXtC? z2sk5IB3{I69s&guMY(Y|)QK~>Zt<0x(s&W!K0iGOF+U{namE72r zEDKgRcXfEc#b9b0) znZ0wQe>#FL;eA

OQ*8=%>+RcfWL>I$cN~+rARrzJsEZY4*3 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%0A<&JSqr8*u>ptK3FaWd-mw|IhhxP{H~fO*4-6u4 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�xkdAO9Mpy))lnnA9gl0Snp&5^k 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

    Yp}TPA1X#wa_%0ib1*?ES$$#)Q=yjpF2( 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

    xpQqHbNvs_5#~qyG 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℞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%0AD2wS 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

    ^gaP#y792zDYz_ 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�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 z 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

    5i>B*clDdnIs?_ih!+ST*VxlmEru z`@q*d-GBV|Hla~LP^8pc8iYlqZQ90!rJB+bq;0A}xJi?=iRPc=rcKER!a565`n7(^ z2x>BmtqAM3u%Mf;qO;hFvWy}qf{cus-|PK3pZEEk_dWNvX_oJPkKg0*JCELeZl3pj z-tTkX@Ao;M^Z9c>m*zB@x`@%%oqKa=aX>Q`abq6N;XOWa@_?Fe*W~byp183O$>HTA zabq6N;XOKWV@}Q?FHt**d+lA5!+Uh%#$264gKaTh#JNwA2g71-Ff8^4!(ubN%@j2A zjumrOkTFV%gPcrQOq-L{TiU4nSj_oB!sL;U@uK&%O>hD=#krY@CT*U)DS((~D2dcP z9O?;PU{ce2|59WYg(ZFJNo*M1gMbJWWQ7B+BQ`6Q?0W z2Uv~~KGI^n>>3&!likrlTN)wo9Br~ym-A?=BEEn&ZkO|-jGw$H<0mi5_{obhe)6J> zpS&pJCojtQ$%{08XouA9%#-swu=#^}OB>n`(Wx0E5c$$LHJA@it-^~koVM5Fg^zE* zrbWHwG$V-9x?QzQf`2PsJ#^90dv{h@iMYLwia2mIWqNxrn7jfXQ@2BM(jcB~3@TgM< zi}-*Al$(jSw4k8DinrWIyya-%t>?={G%nRHYY~S90!~xi|B!cR?Z{3%y@Sd)snYGE zH}B#_XJ=^po_e1^+kW*vp0@9+_i?n{q29;R_FVYKQABUlx;-?Ww&&wT=Zk2Yqu$5U zcD{NaN81JJeJpJ^;^io!H@{IIjHm5y)%yh6s)L$PJZTN7^O~4EEL~PWBocXjl&7lkEBF-H3 zHXoZM>g~ZWKha5;`LN&=x&-hdURa2b{;wVV3rT;#sk4yuD@_ZjI`sgusxnT4sEgM)0*ju*hE7JJ6||uy!$uZuCpk^m$0nI*LX<`x;@Dk8n@Oq(v{7wb zL~T^ZPdT)?-x0{6&9Bs3+B}CBb(yww%z)W}HtJGh4t3~k)n23NKLdHtq4T|7IKRZ@ z_9C0M$xbiyU<>Po%GxzKhFWqAMU9$+E<5E+{7-*4Cm84rUqf*!D@aaz1a%iLa?liJNQQA;LvGcs@Zt7;D)6E>( zP~5QdyZUZ=lcYFp=*uz=r#I9?JPOIT_ul(_>pco76D?QSmwLCCeHU;q;F3IQu!`&j z6qb*iwqHOSm1h^6h-T45fiAOGY0p3*+NLnISB(q3f)6(w4}Fw}v{fl}0d3rHWtobN zcx9paPRYdoW)2i>Xr|;{|cr(4!;pmNxr4tzS$V z>MHGUsIN2;LL$6Ll%427K22lPcT57b`J3~0vF8H4T00zVr2aWaCZvsAeO&Iy-~IF z)b%`&sx{xphip)%Q0KPbg~riF^)rVy)K^eb@B>Fsj8*$%XF~eKk<6hD9pfW^8}6nz zN~s>8Z)!U_rAXmHcu}xfIriE7jD+vt?RW9QDCSR-@MZ>HW(^WK122ft=6v-Q|2u`e zd=Xw|4H8+37i!R^LcPWRx*!^;p?3D@3caVV@41)d>*A=D@vaOuPNBc|!;9+C_5k&s z9@^g~|21CSczun0 z<`Ruhgg^maG*-XGs~fLAytwS{^JgG91$HvVS@ssePQ{nW?nD5|4 z@C7wbI4{Jj5-%>V;mvluwn8^u6Q%33hvCJA&hosB7cJrE zYCSl8Er1k0&)Q@`q9b2-?<+pf03p3+MuszeY-|pH^H|%yn<{7;Hgx5B_xHOVi_6#vxXBi;2}qn|ypG2EG`zUbXT(0h zXM=b>jrnc|&3SI2+qCI6Z2CRwTaETcu2tu7qtgPICa|a1UNv@!}GVH$!F(UIDc2IJ~G1 z-S){9x40#*23UeTJTB{Cte5Yw@D-`5<0gqVZE8(1cejUJtSG z{|C2|mzI^6pxu-3`Zt2J%wJR!nlia4yen&6;P(Zb$8dyyPJg%Km4MhdGLFF0_`e+9 zC!&JzGDwpq!NO2UeObuY>XBeoB_TQ`q-sruNXXGf1gkDT9k3tg61ACJTo@{J2|kS2 z!pTc&Yq=6loH2e(i4n>>E~AA_jQX{pt3JsG5%BWmn}2f zMYN-c@dxm~ZEk@pLz7yJKN0`irNEWJWDl7aWy!i#((#L&xN?mF;$D& z{1Rlbt1!x*K5usW9^Q-x;R+jMvYfD1Gni`*a9!3DMpz=2Ac4-+RpMvxXLg%Em z3UUCtx=oN{K>7rk3bI|0vq1U<$p;w_q!NTKx>8KBL7~I(AwgO|b_znr#uNyz7R@iQ zf;uv03?K_IIIp=%-Sg3JKv5o8v~I{4Ac`Ex-E@Tb@20+4<| zDnZtYT0a1xZ%%u))_^1A({nM% zdO_%7Qn~0?Er<^juUD%HgnHuHqGx~PxH2$_(h73RS;a`WUU}{ z>78a$uNEC|q+rcVwUp+oL7H8ndP-Lf|O!@_Ihy#$q4cQNG_HSp3I{l?SjyE`+Ed=9whE$t`!WfEU#LI zC~Ja7`L;r)QIHQn3h;^7X8MAEVk+yQT4Qna*d@qeATyBRII?8 zQ@PVj8Tz@f(&h2 zJO;8}$h-tnE@bFi+gpW9Jm$h@kgudwX`ToYpKjVp0eQR1l*s^jS!iAa(k*H&1(|S@ z*+M!pzgm!HkReg)evo&B%&$R`aqvMNQ!RWEBv+8PL5k4>FUtP}DHVjS0DdZZK|ha| zlwrnV5=g6%nFg}Xl~L9+LB0_(IUpNPGh28m$n!#`5+wC>)7F(B=iF@ihxQ&>LZ%gD zqnMF8KrR*W>H?WK%hdcF$dkhQt01d|%qJk-Li0|LO@hQ@aa|^CO$6zlZQ42sgpPPU z&!>Z2C2G-^n&ZzjYb^%p6Ee#{I)%&%5IQFIG_M9}6?>U=AQR70npJdu1~Lw-MEXmS z$3a?z%(EaXgdX~}wY0gWp0_{_7A^b?q*cho;lSc=!q15y@$*0c~#N!^}44-imED$+clvGUWHn}71rt3>C-M|JtVUZWV@*K0LTrZ)~`VlFEML9 z1JWj9@fVQlpegef$i+er{VHc?p(!&4tIlj8a}Y@X5>w__kQAM(!6nr5T3@Or)QgiL zlPSpQAO(WV18Edw5eQxG_cFW?WI(j%a*#I#xd!ALLDqoKsSz*kKLxo=WZgp`16PqP#X z1JWkQVvq+#yq1A%>QtJQpI3nRM6GK;@_uJp|1n6HOH{3OAdR9uKLZJLnYDfm(k*7} zr$IUed5MV7^BPFTLFPL1eUMB+hCrI?%spCM0@f`rn*Evta=qyLG?0E*M$MvUf}|a2 z+R6jjSHz+eB=OIt<_3_Dt4-_8Ah=c5*}E#utssNFW~~Q7GF~zL^E3#Zf%jtiD#!*w z`aymw$iG0^1c^lt&Z;)8j|ZvWX4;wt(&iEs!P7y8gv{9>>2H{ArfW3qRi@@*knBEF z^9qnoL7G6a{$a}83{on{T_EXinKJYPq>Y075oEm}uYz<5@&!n*AaTf)9fBMMlJK@^ zYYIr7AhSU_1X&ESMUcxt`UPnOp$mlG+`A4WQIKDOqzdvB$Xr4G3Q{1*hamNW(2q}c z3UUz0WggDD)D~rH9%PObdM*U%#jQ=Atz{tJzuffL zN|1qxrp!%L3pb*9weA5qQq+1FBnw|N^Ye%736qf{Tz_P1i2Vw^=wm52}m0hc)3vv z^0clMtSBt2L<5K1m6fu79c2EbW$>}@Hjqpaou7fw8GBFj6CfJ|c>&}u(bG3T=&Zh1 z>qC&sh0NEaM-#q6r>-f$YyRWU_WRz#p4uz+)sw7))D5qOjC+MH0OVNrZ=#JTd}X8* z6pe(f9<*bYkfA^JJyJdG3bm`lF^>6EaM2w1W7sH%*?Yv5<1QE zB$t9T3Q`3!AjnN1gE_1xSXNz2>J!G9QN9l{bdJM|`$Hg|^SKt)*i16G0O*aBS3x!{ zG|6WmS-B?JKM_6@ zyE0>Z!Nm(_EvZ{dUotUzdK+YRXg$G-qQcq``juyDegHDQAd_HO73~UrIWAF&^B81? zv<$Vdn=}`2Eh2vc$tqL??SY=9H60c6C_2D^FVS0 zxfCQMNCn6`L4E+zCCE)6eS+Kt5?gFq?*K^_oyB+jTSwRNM~%NfKld$Xr3Df|Lt#I!KEk*&v;QTmrIHkjp@J3bF#E;WE`8H7-_z zlvXkcR+QA%7A`9ps^c~XSC*F0KE-)}B(|#7ZK#!x+o`Ev$g$$8D@tmrd`+4_(03PP zs;^`jB0mQiY%s}VAX{)*Ug;s3--Dcbr#W(80!h8rlz9Ur;X0Fi4zjVyB>p2X|6Fg9 z{Xn{IFv-zGR-5D`ke!+YmsQuTC@wC_ypd&yEG?|`ZPkR@oPk=^KQ?75N-BJDIO*W^ z>nzB$36clWjLT-8%rcNhoG9@~9mvL8OmYno-2UXr+zgU(n@R2fS-;jK_k(2I&V;6; z>Z+>pE?g@1^gIfgfjdm{N01II>^zy5L9*^Nqw^L>3myfhWXM0oB`bVe?q)*%*#Vj4 zdrUF}l6tR6Vkcs5xz8jAfSj*w1#9anDhg{>#s18cISMitY8kS1GDs&5n7ua71}PLW z3qcwmHD!Vz-GW?3dOA&+l^{vD(ber~aaC>MiV|NZE;A5Oqx(9@Wcl56bAQl`% zJDy}hf4vHsL}6f?Nsm!ws%ieZlgwg>=2W^zUY^A3~ zw!dwX`#_Sno8;FZErM*OT7vu?q~I}gE&448ee=(2^CWz=VT+K-0?B;bthEHBQPipd z+4-)i=Ngc}W86~;#u|`3e4Eg-^;3{lLgpcmK37JK<&7ZS+GC_=6G%e8(xYTv0vYo# z+X^lztDIU|QlBSeUW3d*o(w*p3b{mli;>!+^n3uBfR-U!UxEy}GHRc@*HJhFBieij zNd6$}35G5YR+g;v?fB9pv|`L0VnUjaLaiQ6s8*=7aOGA(s_SY?w`)SRPDHKA+B(&$ zuB!H}`@36)ipV$8rCS?6p$mD-x*6IhjQsmDN zNTncg0j%`)8DnI^VIb=SNdoB3*z-$O9llqVK;3>A|&GCig4_x6kRZPRDZpt4PxEg;GI7JBM_vNy#sxx;yatjz z-6S7?d@eM91(G_$l!-eAQ5NJ7kl2}~%yA&62|Y7F3WUsTkRd@X02%W*&yYTpr66SP@jF=j$19lt?}hzGM_tLZ@jA-C4o8QW0Ky8LeNuZyvPCNyETO{6??5|FjBf(&C$&$KdrJ8VbR13))HCQR0=~(3d z?C4mI*XzuJ{oOMje%w3}R`}dtCg+C#t1t=mCwYEnHhVq|e~lG#?D;`BMtQ!trffw? z%}G_&C6z_qVsgwR2XXLBqFO$X@~GMONqb4{5=AijAf zDFaD5+a!%3n}nX*KvJ_!nRbwm|7b>eBS1d#;imxu6KO@I}ZZ3Gyk(m}gBr z{v@o-=bN>T1nChZ1!RL*`^^K{w7{%Y2r_q}A_xFV1&A-#Bv*pO;WsX+g-T{M$XY?x zfdnovWj281EH=p#Ah~%ac@ZS-LX*4+(sYqYJ_Olvu}QuG*?=3;z4q*XEY<**nB-`X zz@;WR86+WSk~2Uy3$hSob%80f1SD;VNoqh^i%il4(vJtMccYONcaMHda|j?WqRA6ckoyPDnkE=LCA{6%yPiJSXgho~SvY%9sh1 zARja4;%f)a*oiVH48UXcu8hjwy^g~Sa4mZ^SXNmUnqBT|yq*brRcWSP{2WITe>2+W z?c?Y<&!jcRA1gkmKiI2%JWE7qA$v8KW9p|n4edf6%U#SK!{tSvw8tKspgp#n%GC1@kPbmU1WDOo%KVFD1R0x*z0AX=%wZtg1vw66ys&;2NcAITtpyzd(APR5B_P#-0Gr zKV{ZB5F{XKod}X7NES%H$b_XJgMwTKk}PVqfeZr^D38C`35whf%<*OwEfl0 zg!4dhx0)m$Bw38*a*);AOqm9dAwg~-J#UyY>p^z(nPekK;BzKCW2>2sX3?>8@sLX~ zliD+OyffdJ|JgJ4TJvM)J?|O&dfoZQpML~?%-)it89U)3p0NXCF&haP-ZQS!Gd5kf z5j#ak{u%T%6$c^C$c4^Gj^vy6|up=yyg&P1iK{j&Sj(u85`ze1cF5v;Q}GC9hA zBuRwgtgH&z8<~($GdYX0Hz;OmWmQ2Zl_;Wm(fKgNl&B7-11@a0iwPfeA4<0j+W;NB+r4#?&>lbiz5HO?dpL7Mh6 z$z`M`!6c0!>+$>|&(^IVTk&`mk30<0hGm>bHiK-KXp;9p>W?zXH$(y^IpAa*)gG+~ z{6k^JeJG8bhfYtEA+z-umLc?gkiaC9oCnf!EECRol^c}v4^F{jl0?Sx3=m*je%c4T z=~(3dcm^0w&gbZy|CI_ED{;4!^VK@%8~2Vj1ALC!D(CSnilt@Cg4KmJweI(|`Dh~P zIMvf=Ie!VfF_&c=`B;1i1wyMUV$T(gk@6BukLjKyn26 z1SDUOamb-kK>{ElL8gN=3UW3`vmgZ^>jbF*=@aBfAj#h~dwLg0rXY`lGzjt{$XY?( z0of?XHz3;tIczGtnqu0T36dzt`5>u+l!43@KFUTVxErRrbv@ zQYy#=AltG{nPQOmB9p8jnPn#VAxL1kN$vy*RhZ-{>N()dJGvEi1B|JkF}U7;=HH%d0-i@ zNfIG*hLGVk2|ay4&Cew(N-9IOlZ%9yZzp=%R;zj%ZGIj*9eXsEajG8-5*Ko7IpjMa zeJ)Y+>SU0lI`$z6WrE}ivViogFl8FDq$-j?^Cjc~SebQ9s}IvkxLv_?heK~I74j-nG6;^=I}U*n8VaTd$H=XQdQ zPIY0Zs5H2|q^7dOT}R`p^ol~9YKq4q+u7?uOQg~UZ#23xWAyr2)go`;B)s#eL$B_h zcw@EphF728u{YNH*&EODM`BCf=&NIIY`|wKLs*Etk)pk^q^_*ISa^eEA3;xZuZ->u zUT>_!V?rE{IR>6WtuB`+yW2oouQoI4Baql@OfqH$&X8ZrgmX+;C$Ap7FP_c99dNdz z?bYfr?A083_~Tk7uePjUuNLDkEYgg^Uj3fu)v`+5sTS_mL($XH8{D2kOL*bFD;es0 z4pRRZAvW55@5c8*)c86qLW}UQYtX@!-1mI6MT&9X&((deEvi{n9SWcQrl9W|f28^z zZT6cDnN9fewm1JQ0_hv;w$SlI0Z1UuB=k&(0zs|-Y1D+hs;rY&XI@~P7j=(whcjyp zXPoLb`};)n_z&`G4lZO+y2bdL@qgrT8q{7bF05HzRK?G_B0a(S(!$zO?3@0+Yp=Gz z8*MzdP(|O}^lg(o4YETM_Mx&xZKh|?W5H;YJ;_Yn9zQ+vKo*|sx;cV= zX@{lBhugFdlkpdM(<_{rmunwhUbmzyB%KKHSJ2b=cig_q^N5LCbJUfKm3uhkdx?S?xUy1@2q+;ovZQ7<&chVLEzG z8ok0kbbdSHTYBQ(<#kpfLVOZ>n)rTnACkt&klFO1>7UaxPqK`NQy7c>{ZFVpNZ<*B)D1x2&$j8mC*( z(}B-+?XlM(lYtW@-X7#bkkUbu_|oB#e==c@Db3_DEKb6X0!BN>T881V)jwd5jgRWF zUu%z*Rfg>x^xh%#h3aXveJ<@Cbd>Q8qsrx!n%nUpJkN*Y;jz+xndBIduCGio9b^L@ z$);+tSCw`0>V;S`&Gv=>-i^$w(f1ddhT+xLtJtggQRg~(o}PPdxe|AIT6uUDdb$OV z1$24}Es@Fs$TWP*-XMu3AWhgqd0t%!l7Q>((ql^Ve?Hd*j@|v;<0s*>0%kjr4N#SV%a~0o&t&8iwWnL(o7yZ1ML|3 zTsIt#rHtGC-XZxK_E_|}?gQ0T_?Qd=IUd6) zm|cy^ai?Gm?#tdFBZ(l*@h15$NaB7>IL8_s&E&DC{-eFaa6Gnl7#_>Njy)EL>aqQ? zR#NjAzBN@BmSpJrY3OO@{=4=V?HzQRov6@H{%q%34#@{eK9D^|XgNqKeuB=M>#hdr z(uBRLtdm#oL0chWl#%6OI?ffy!YkpPVR*HniM^TuucApt;XM3~;njNEslHp$jqL~T z+N-V9)qTxl*vCM|Ph*du}p}*tpn(Ra`;p?)L?{J^pT^*WOz?+S+(M`)3_K zhOVXqDj!>g-*$X<;;mKSTU)=x>34s{H#Ku^0*+r3xmf`IaB5Q=C|RDHVXv74Z0 zTc$~V04w%N3L_g*d2Ud1=h zYD+D@cA}^2@X+O5?WtdYOh3ywz1|8kn8p4fv>jyU9FzPLWc8U$I5U+k^5G#Er??5n zD0||=%=30Xi{=l*hrS!xhtbFTmD-0ZOUr7)*VAansW{p?Yu7%U1et!8ar!(BWb<71 z524v0EoYk~k7}L6gng)Nkq^(s=*I5ED5LGemSOlX{m1OX=%f25+J}`TRS`}~m!qe? z^Hfix9UcDwGC2!e8K=*;fYjq>RVjPbEP4+}haiuF^a=6|$i&5FtzM8^LEZ*w5#*mB z1?6U~12fQw3X@C%*!*J_~nCjg@`hgVo@0<}n}l-CrQ=@E^`<@D`56M5It0f8=aA7W5m!Di+zR zY6_<=m=hL_{jf_bz=^+I?F$ZvO!xil4N{*BGW38+P6cUdXTly+n#p6Gn6+?2t5HTf zdkeJ3qMtYJUBe!WezoE`=`rE2VD^OzX3-rlzXjtbUZURP3b zMah6BB(sWSVpxXA4Ipu`Ciy8yNRWp?QuZ=sHi2x$4<@Mjko3F`lD&^fJ_2dlmx<0g zr(YC{t1eb62CA*fXvKn8!fSQbS(niqgA}j4+c;hs7^m_8nd9}Tj@PP^2)jz(ztGb@ z?x_qpcg+`fI#v$x>SCrMG zojH@3P^140nZy$mK|oR714$BOC&*ku4#YS8as@dGWJjv0XF5n{8WYYRCS zG*`y4Q3=xH66Mt^K)N#78zj^OqW9)bt(!qM%ra%}1<9Xnl1`9rK9+H6Jqgk-WL^N# z_d+-_AAqE#xOdz+WK1UR4HIMnNaFsyYT|gQzEiv!ut>lO2&35XqGJo`B)(fr_tgJ8 zLxXzD^I@+Z?{h5~0ujzxK-LQ~8>CN=e2@V_N@46Kqwrj( zJs;us{&=pVpXSIKmg87x8(j z7tw4jflLa^IJGK4as+7r=@R6JAVU|rnw?r}sMbX$X$5H&C z%De@VDaas5vmpN_JtbzXedl0~y38bpfwV1Ggz_HuHG!m-o8)AW9zjk8DXuVO&H+iN zWWu?j{7f(bhKf zdt++dTU=LBZRbxAJ?(XS8YzGHKH))@aawRCY9&@F|ET7z25Gt6B=>-H2=XhCK0%%a z@zt2MULu(Tc?E(eD+a0EZ9?XC$aJsb=um?`0T~kHYmlTXOqqSp#2lpw$5i#5VtPP4 z=6I)f{NHHDG?V+~e+nkBlnN^p)3pzBOq-ELXp&KQPIz3$l&(~S3YV0Z;351adUiMr zJ>AYdjgW_=@&w4l@*Jh_gjco58$Uw5$Y&w;EW_G!64$TE=;#%}{T<5vX)jYZ#nF7eH z(=vprKzarF0mx2GIO|krpe`5Giyka1^Wm2#aaGXW&K$t1}jDc76i6p)Z0^FW#f$p_gX$mJk$H<)^^2T2g5 z6(muRM?eCaaNLy-Dem;UdE+^p&X(gI;v9?MXWoPCD(*bK==UAe_`)*7cf7Dge^74Z z|B}ZSzTQheeQFdQUtjFaxltEdDzZWe{}DYc;GRZkGfDjgGTA>gefSPYs~}&1l&>~r zVlf@>(1d-cY>^M~b?mS*T0SJT+#>=9h;30`p<$MZu5U zens)m@sMd{8K+O_Ae#l52hu0VMIilxTn;iM$d5oeZZy5x2C`LZd!rJ1}j3A)vqhZ{NC-spRjy|Er9!aVQJ*w1NiAnWjT@)cntbN_i5aome2 z-k1oP_?yCes%lYB@sQrICmD`bPkD}tJDBIF9CoJI(im*&WN)aA)9>|)o~F?iT0v&?S=O^hWIbS6FR-lR3(aBH=@-AG z=W|D7J;Ab`V_DCztan;{&mWQX@s{;m%X+3|eY0h~ctqCwt(;G`tdF;>)34J>&zFzL z`VPx_ie){~vOdP@duT+~2Q2HUmUUVO$(&ELtT&9vy3dMxre!_FvR+_WZyJ$x`V|w= zujyHq^;FAx$gI_{&#N zz7q=y5uF(qS=PHoWIf3marA5V!d6<2)%S_kK5o;9tZ%pao@7~1u&i&k`o4KY);C+$ z<1OoW;Fk2pjJcNe-Vs@kvphf7vYux3eYG{-w~fepyk$MxvYu{PZ?mj#ACdJw%ku%t zI-OA#c{pQ(=Xv+|;%}&>&KoZ+Twa1ju2D)W3o8hD5nLK7t*cy)qY2NJyEfjzy@+rO zVy)F9$qeI6m%CPk%xiw5&2Hb<#zpTtA94H_`<0f<@rv|} zU-#Idlsz9^W@a*HW~8U7hsSG=j-w}yvdt|-M zvcA!>j$0JNtPkKCj@usB`pywqUu#+Ku&l4MtoK^hV{aMBF>JMEeYIshWLeL*tjCYY zdbeeLt7UzYW&I2*?&C*fz16bbX<2WxtZ%paK5<0Ww^-KuE$h9O^-8PnNh7k}V_EOB ztZ%lg=UUcNMr3`RWqpHXz16b5&GLNOh^#kQ)@jBTb4yyIWqq|}J!3@HH(J)WSk}8N z>nWD!vqofngJr$PvfgP~pJ-Xn9+CA;mi29xb^0!yh{X*06#&w5%steQy|%^$yGWCd)c*80QRE>#-T*E$dAqvfgZ2UvF7&v8->jJl{Mb z>#Hs6ZI<ueYpsS=RBDkucBiw5+#|$a<4yz16Z#_ua_3?k>yv`Vm-CoPO3Ql3h^)6**4r)XYc1=4^sKu_Qum_P?v5h8)hQoE8Y@_LW!}lXh;)SL ze&gUjzHY8Y?$kCMH99ff#Zjc!WpiNB4#LG5h;nJCDeAo+s)45U?% zM?g9Rc@kusAb$ecDcZ9YBvX)gL0bNY+rt^IdWv57=_+!7nyJg4L`U25ckBA*8;VYc zjt)JGU?1~i{p95RfYpqIJ0$Th>{b!qXXwSC+ly$?Iq+=UhmSAh(;fBrO-ZH5mvcvW z-<2Nf`x!VRsp80u+LONf=DV4IUPUU@_wA2!X3}%I!fd%SQi|@o{<@!5$M-g;|J3bQ z1Y7)@oB1r`)IJX0XcS}$$Reb@2hoIWnvkNiAd}w4GDPNsbh3eVxE>TId2Ee!k8 zGiS@7+tX+xWeDC#T+cpaZ>U;iJspimHf(#(Q5?<+c30yjRxFhD(vtd}sm&TLA%>S-izu*c@I41NWsW?66vez8syvKey@ zzI);l)sh22dIUKJq*stMki4I>pGnU=kS0O$K-LO!8OTmSt^_H6(A4u|kXAujLADF> zOOWJWn6;h+NfV?Oq*Rc8kPbn<1nCoGpKOf54pZ|4kkx{m2(nR-(?I$KIUgkPAyZEw z$Xrc0GgSmBTjpWcn?{b*Wwgg>yUxsI+J^atGPC@5oSAetOrrU*-lJ9N%yfQ2CwzzI z3!$g=Zcig+CMj)#%zDcksup?Uaaa%gzVIF#X%1(cCLF@!v_bTe{~&Lydy>7;0vvgq z{z!X+euT<$hVK^iH1%PX3DLZ9CuB;ux-w1!9s@~x)g;f5$6SJ6becPLDrHL>_rj^w z3z^NP41N>K=j#?S??7fy%TTpXLE2t3b2a8%h|Vjco#EOW{!Gt^@s47e{CkdRBLcdw@u~M~7mw(eE-A+aco9@QivVaw+LkeU ztMwRkh8H}8bXi3qyn3jcW4_?*GaR9|!ZOW?7b39cTW(mZWy{6r=sb2(&MW}BoD zWbPbAkO}iHa8jX9MEN$z__TG>vmRu%u0`Y#kXAun2H7IWyC6F?AzPGE0ipR{kjXfc z+e4bi;`{MAf*cRhB*>{C8#ICDY3WGlOriNa$TSLa2}r_Ormf{5NrL^g@H1LeRhQAua2;iTBOR() zg)+STDb8@Zr*OQG;nl_KUWQk!6#1>h2hr0!x2Mr&E&2vq@ukWeFobdtNZ+rR1o0!p zh2_B|Z8$)n&y~zkknuenCR5v{V-Z|Zv2q4YZI5UfkZFk57ESP}F9mv5KdNNBQBa`u zkj!b2>DDqt=7IDIvJ4~^4>gFV`h8a21yo#mX>*f91PN=iO%pNP0uGmrd!KUn^Qr01vw8S7GH5x-rx*Z znLru-w~GJkIb283pDA~^)L<0K@U5FT!|CoEoCGuqXL#&5KJIp(svVZ)1?Xw2+tWxH z9?VU3w6}i=1<$W3Xefg z+uWW;%5V~!3YnxDE< zJnVd)^DrBEc(9P-nf6?rhnHE8s|{XO8Z4@+DGAI}v51t1!P!b}Ajr|7T4j}Gp_WRw zmLu>0`B0FDL58Y~D67mAv3LqHan&qCiZ+8x6yyz%xq^HJ64Hb-vj9I{Mx#WHlySM( z=V}?!d62B*<)#0ZpLU$;>{Xc_Czcmz!dwC>hvX(90Zd5vPq5s z>A|hK-pX?ZNcAfwnFG=+$VDLQ1-TNWTaa5oO8;u=xeKI8kVipU1?dIZC`dm@!QV_h zUxG9U5`O{C@(FSh$Ob`Xf#l)lRIjHwAR$3YK$FCO@izMX%}SNV$45+oCvZ*kkdgDKQOJ&2g%R`9-Bse z_my&+iBR7In$X8V)EXQz^;`|oId&f-S8oI96Xa(gzBrbF<}@c>S~C$RUYd}tPSh$r zl4}v^1sR;igmYfy2Ic(9i=#d9Z?vvf=$QKZqOJjAU*?>r@9i8!4cCQp{z;wlMRiM@ zUz3q(-;bUK(o|0)0n(=w#!G>`#7 z3P1w)vFAxSHU z)24k$WEznb>{TLDh*X+nDv=sZikwr7zJzzp?7f5hJbRqan`s{c>CZCB(;$O$OwtRI zd8SF;1=%LZS0Hg`nKJudgebej7%946Tb@JQ(vn%{s-o0cKXAAxiV5`%fOUyx%#0`rVE ztMFWDw)uOIN!2o>`D~CZK?*?XHQ|w>GKxmZTkA2_#hP{0M+!&K-i( zr3Eu~q7dO3I}w*Y)O{(nWfl7AWu7RV0p8&DG}1^R$!p<_M&ZMoh+J)Y^(RCcO>z&& zz%R^PeHf&z!z8~4iF?Q-bhbHrqe)(dOy;$w=50ipO!6*B^2PfaBW@6+Ul1Q2#9olE zWW14*Df)E~WY%dJ>ibb39fF(=vQ3crAaR$NnrWmoUSqbf2r`*khBQ}$jl~WQaa8x zYXv~sUNOl@Af19_g7gX!1Q`_01~TXpZ^rJu-PC**Wa7_IwN&;lBF&m$W>d?-2h3WfkjZdmRC`u{jL$ap+zyg1 z$b%qxf@}mS7i2R?vmiS_HfX|gctEu0TgYs7WmJ3iD?q<4G~06oNI;O2LDB^|A0$^3 zp4AJ4ttF7Dc4d^UYLG3Zrmd?$whMAA$WBdoT&Vn^adGag*xQRW{iu%%j=R4PD^jjlx=7x(CKQCe70TV{=mN6^#6GUbhk<02Oc6-@PYYp(_!lJ4t%mUB#z zDKom?lVoaI_t-H$^1AZ;@5#@#t}S0M7t2*>4kWXTBI!7rA<2{(fp$rzrUm*XnKm_m z2kt0aN>5s9pfrr62ihf>J|oc21kLn4j~3?roLflbb&&R>_A^HAhakOzd<~KrFlF{H zM21f@NdRO>kf|WWX-dW$?`_)8Fz%ZJnUIztvJhmoAj?3y1oOR$a-WD3am8QdNo%Yo!r zBY(0WlcZ%x^8%1`L6(A)Yr-Q}WjKx88*zsH`&3nz(H^-vg8uHtG1`jvhDL7MJ3Ml? zAY~&T%RH<{Zgn9Zk7Av2y#YO4@Afp($R&%nL8k9iGY{_pNy}hAlguL^rGh+3wKQQL zDqG~k5707MM$3n!mHZR?KKmyZf63X8SFqc)e{fc0Nnv^T)V2k^XgR~}JG4Y9Z$PHt zyJn8P4-z=hB>yCDh&=QcK_o)S3X&c7iE$EXfF4Q%FYCIt`>i)S3qp5VaPO z9wAdmdPEB=h=^LNKnjGd>p=oS&l-^W*=Dxf4YIY=Bpo2FSDE?K4bmaVOCa5XYzOHR zWUpdG_-a$n1d#E9B!eUiavI27K`sR;7o-NHL6B=eS_HWrWP>2T2I&>#PaxX`c@1Pp zkWWAo8_ixMlwhqTND@f4Ak#n!1epucs0oiamAy3L4m|z;`Z`eo=Z~M(`_=$=MrGay zJSyA9L|bo6i03mf&aaeKS5?V@S%#jjcY7Lb*1CfHBgR(~5qwcI27{PhKHtqm(oC|B zNQO!7C6Z;54kFnmd7MbDNxF&To8);S#U|+mX~Wcc|ZR9=-ZzR9Z-XJsGAR$5i43hc*%LH>~WszKCiux{sa@9W| z6Z;{{(C7aIDgDSK`{D~9)q(^-HfqALP;I7ITzItgix2MiFSK=kCK(fjpOC++?_W>_ z@^kS3`?(u`#YsKxx3D*VLcO4Q%>CB$%(TP9z7;;b9B142Hf7TC;21$>q~fBbOQLFS zvNU&DnsG?PdfX?C#2>6lRL#Yf=2lDdYD@D5tIfTZH|j0T8!XMOmgas-^EOL!rlq;w z(p+q5&apIaw=`#1nnRZ60!wq2rFn;?Imgnx+R_}dG}l|22QAInmgXi)Go4qESyygp z-f3wLS(-a6&Fd`9+bqqo1K}ej&(hptX>PDIw^*9vEzOOV=8cx-^_FJ3c~FkQ@s{Rv zOEYfo%dAp^Vj<#h!H(HuAEX`S#<_1f1siis3@^hA@d9J0o(b7zNY}w{w zOLMlRd4r|7-_qP`X>PW>k!xu#w=}P}G`Coqd#pC+TbkEen(3;u=zH2mOLK0~8(%fljPPH_bTbipa&Fz-vwU*{BmN!C{=4MOtCQI`MOLLOd<_1f1sinEi(%fum z?y}n4WNBV!Y2IRK?y@w`wc6ZlX-ezg;u{4)kn%7#I+bqpnEzO%O%>|a`R!eif zrFpHTxzW(NN>}6_-RN3o-KDx+r=%U#duiZ^O@azR1!(XeU9|5jtkrs{?vNt zcjmEOJORvWGd~T}^;;>cS+Y>6Ut*x_udGh3CxDMjPG=O70ON|50fXsj^gKI9qV1040(7Eu8^zh*+ zG!D7K`EHUTRBaJzRe#FIp0=NV2N{y~%E^k{k!y@!eh!3Rb%e}C7hN=Q zS2D8~{=#k7DdUE!5>CZwz4i74;D>^#P@~y9&9PwWBg6{pGJr*iIAc5tOo+e_{Yfx zyP}gom*PD_51BapWs6bFPsNMQ>EcN>_}`Y94HUp9_yRR#=$$$zhBvwtKqe1=QU7E7 zI3XQY_&m}{dYr=X%gU>k7^jhV?9@A>iS&di!Jqcnkuj$ld`>0---O%?e@D_oax`|{ z#lAp|om4_rp|P_Ndqy>OR^TtvC<~39z2FixcBaV>-M=UnxOvu%MF3QGj{S3*>7S() zRmH~bynEuGO)2gfGik_Yy*O(?VnJ6NV-S=s_by`$McWfclOWtVdT%5!|=~640x44edt$Y|CDS0M9-gJ zY5yE)`3Jz6zo$Wu8p~K3Me$*o_F++VU2thhVW_UA#CX`!l4ZEk$9psx1~L=D&wZdY z%Xo#yY0oh7(DSn$3(`n=xI+6Gjf+q|2Rj;HPEvmU6o1iZl!eCW-P+HTt9IvT?#;$a z&AoKDCMtv#ntLC_yrJgauCPzlpOnv=@ltc|X@K}6tjq?=1l!%bdOKv)yc&J|bFGdk z=2bjIZc3^#v7-J;xGnE9ca>r{#YfMbE2%9BX&D`5MQ9eKeU>bH66M5Uj3!+0ac3KQ zg+i7o$_E|FQLe#XcAF^5haoy@HqOFdc6TYttMO7%rWq-6l$WACD$41Qu?t0cA5>LQ zJ_-W1EsAmhK8Y4(p4sl#5v;B)sVlBJsivg7s>qAtHHct=8^IXcjMKO^km+Cd8}POquS}^Soo`@2J(xwdlBsH2bz{LPDQGW+KlCIuDgC>eo*p zv%7r?<(Tv#@4L0;2*(#>o$~Nmgj(exdCD%7hZkU1tM)0BtMc2gRD<&HMKnXrHg)(* zwufXW()EbD%CRPp$T?O%mS>yq+DcH1a*VzQre>RYAhsB-=W{SFRE|ZTk=jsuS2;%c zL;Y9zLq~M7aQ?ia^QWjLR2%Z9D~R)Yb*B?|imB8=fAQS1c^K;idiDyY4(Oq{+l69E zK2$M{JT9nDhrul>rnCnkjj~WoX9KI4PLUtFe^D&%(XsdrsO%j32VM8hON2^m!oPO( zEk=RzPavXy$lQcd+}X%|ckG`8k}OCDNTwj?fRuk>&irK{+XT50r1VRcvE%hNI(3X= zk^kG1cq zHnt1-c`|&c{Cp7vY(GB=Zv=k5KR$^*cAkQa@(*MjGk*q|IK(+m=sl2J?zawA#!o&(x3Id)54QOkv!)BdAsPE5qs+ z=TF8?>KC>7M5-prXtkM?o(mtAI<^A7F}v`glA-pTWl4=@dnoQ(wSV%^Ld%?QG1|Q0 zo88A<$xxfWV<{Q!Hm43o&sC1;mVa|hML3;5MyoxRExp##qf(zK)nicKbykf744S$1 zeQ49Wv4<5TtpmOkWX3_*HMqpRj<%J1x<}TFE$f|@^)}1;7g*Fu>wP1#UTRt2Xj!K# zEwb;lTa?!OM`XR;vfg7^@3gERXIUQ@k@ZH)`WDMN9WTqio$a=YDz00!R zZds4Btoy!o$JZWZU4vzPvt@mwWqq<`J#IwSLzeYTmh}ym^@*1Cgb`UUu&iðZX$ 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 Date: Mon, 18 May 2015 12:52:23 +0200 Subject: [PATCH 12/27] credits algorithm --- algorithm.c | 48 ++++++++++++-- algorithm.h | 1 + algorithm/credits.c | 148 +++++++++++++++++++++++++++++++++++++++++++ algorithm/credits.h | 10 +++ algorithm/yescrypt.c | 2 +- driver-opencl.c | 3 + findnonce.c | 4 +- miner.h | 24 ++++++- ocl.c | 2 +- ocl.h | 2 +- sgminer.c | 11 +++- util.c | 2 +- 12 files changed, 241 insertions(+), 16 deletions(-) create mode 100644 algorithm/credits.c create mode 100644 algorithm/credits.h diff --git a/algorithm.c b/algorithm.c index 212ef648f..8302ecd19 100644 --- a/algorithm.c +++ b/algorithm.c @@ -34,6 +34,7 @@ #include "algorithm/Lyra2RE.h" #include "algorithm/pluck.h" #include "algorithm/yescrypt.h" +#include "algorithm/credits.h" #include "compat.h" @@ -42,6 +43,7 @@ bool opt_lyra; const char *algorithm_type_str[] = { "Unknown", + "credits", "Scrypt", "NScrypt", "X11", @@ -209,6 +211,31 @@ static cl_int queue_pluck_kernel(_clState *clState, dev_blk_ctx *blk, __maybe_un return status; } +static cl_int queue_credits_kernel(_clState *clState, dev_blk_ctx *blk, __maybe_unused cl_uint threads) +{ + cl_kernel *kernel = &clState->kernel; + unsigned int num = 0; + cl_ulong le_target; + cl_int status = 0; + + + // le_target = (*(cl_uint *)(blk->work->device_target + 24)); + le_target = (cl_ulong)le64toh(((uint64_t *)blk->work->/*device_*/target)[3]); + // le_target = (cl_uint)((uint32_t *)blk->work->target)[6]; + + + memcpy(clState->cldata, blk->work->data, 168); +// flip168(clState->cldata, blk->work->data); + status = clEnqueueWriteBuffer(clState->commandQueue, clState->CLbuffer0, true, 0, 168, clState->cldata, 0, NULL, NULL); + + CL_SET_ARG(clState->CLbuffer0); + CL_SET_ARG(clState->outputBuffer); + CL_SET_ARG(le_target); + CL_SET_ARG(blk->work->midstate); + + return status; +} + static cl_int queue_yescrypt_kernel(_clState *clState, dev_blk_ctx *blk, __maybe_unused cl_uint threads) { @@ -276,9 +303,9 @@ static cl_int queue_yescrypt_multikernel(_clState *clState, dev_blk_ctx *blk, __ CL_SET_ARG_N(2,clState->buffer2); //mix2_2 //inactive kernel -// num = 0; -// CL_NEXTKERNEL_SET_ARG_N(0, clState->buffer1); -// CL_SET_ARG_N(1, clState->buffer2); + num = 0; + CL_NEXTKERNEL_SET_ARG_N(0, clState->buffer1); + CL_SET_ARG_N(1, clState->buffer2); //mix2_2 num = 0; @@ -287,9 +314,9 @@ static cl_int queue_yescrypt_multikernel(_clState *clState, dev_blk_ctx *blk, __ CL_SET_ARG_N(2, clState->buffer2); //inactive kernel -// num = 0; -// CL_NEXTKERNEL_SET_ARG_N(0, clState->buffer1); -// CL_SET_ARG_N(1, clState->buffer2); + num = 0; + CL_NEXTKERNEL_SET_ARG_N(0, clState->buffer1); + CL_SET_ARG_N(1, clState->buffer2); //mix2_2 @@ -846,13 +873,20 @@ static algorithm_settings_t algos[] = { A_PLUCK("pluck"), #undef A_PLUCK +#define A_CREDITS(a) \ + { a, ALGO_CRE, "", 1, 1, 1, 0, 0, 0xFF, 0xFFFF000000000000ULL, 0x0000ffffUL, 0, -1, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, credits_regenhash, queue_credits_kernel, gen_hash, NULL} + A_CREDITS("credits"), +#undef A_CREDITS + + + #define A_YESCRYPT(a) \ { a, ALGO_YESCRYPT, "", 1, 65536, 65536, 0, 0, 0xFF, 0xFFFF000000000000ULL, 0x0000ffffUL, 0, -1, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, yescrypt_regenhash, queue_yescrypt_kernel, gen_hash, append_neoscrypt_compiler_options} A_YESCRYPT("yescrypt"), #undef A_YESCRYPT #define A_YESCRYPT_MULTI(a) \ - { a, ALGO_YESCRYPT_MULTI, "", 1, 65536, 65536, 0, 0, 0xFF, 0xFFFF000000000000ULL, 0x0000ffffUL, 4,-1,CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE , yescrypt_regenhash, queue_yescrypt_multikernel, gen_hash, append_neoscrypt_compiler_options} + { a, ALGO_YESCRYPT_MULTI, "", 1, 65536, 65536, 0, 0, 0xFF, 0xFFFF000000000000ULL, 0x0000ffffUL, 6,-1,CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE , yescrypt_regenhash, queue_yescrypt_multikernel, gen_hash, append_neoscrypt_compiler_options} A_YESCRYPT_MULTI("yescrypt-multi"), #undef A_YESCRYPT_MULTI diff --git a/algorithm.h b/algorithm.h index 16ead85fe..c412af924 100644 --- a/algorithm.h +++ b/algorithm.h @@ -12,6 +12,7 @@ typedef enum { ALGO_UNK, + ALGO_CRE, ALGO_SCRYPT, ALGO_NSCRYPT, ALGO_X11, diff --git a/algorithm/credits.c b/algorithm/credits.c new file mode 100644 index 000000000..b69514bca --- /dev/null +++ b/algorithm/credits.c @@ -0,0 +1,148 @@ +/*- + * Copyright 2015 djm34 + * 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 "config.h" +#include "miner.h" + +#include +#include +#include + +#include "sph/sph_sha2.h" + +static const uint32_t diff1targ = 0x0000ffff; + + + +inline void credits_hash(void *state, const void *input) +{ + sph_sha256_context sha1, sha2; + uint32_t hash[8], hash2[8]; + + sph_sha256_init(&sha1); + sph_sha256(&sha1, input, 168); + sph_sha256_close(&sha1, hash); + + + sph_sha256_init(&sha2); + sph_sha256(&sha2, hash, 32); + sph_sha256_close(&sha2, hash2); + + memcpy(state, hash2, 32); + +} +static inline void +be32enc_vect(uint32_t *dst, const uint32_t *src, uint32_t len) +{ + uint32_t i; + + for (i = 0; i < len; i++) + dst[i] = htobe32(src[i]); +} + +/* Used externally as confirmation of correct OCL code */ +int credits_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t nonce) +{ + uint32_t tmp_hash7, Htarg = le32toh(((const uint32_t *)ptarget)[7]); + uint32_t data[42], ohash[8]; + printf("coming here credits test\n"); + + be32enc_vect(data, (const uint32_t *)pdata, 42); + data[35] = htobe32(nonce); + credits_hash((unsigned char*)data,(unsigned char*)ohash); + + tmp_hash7 = be32toh(ohash[7]); + + applog(LOG_DEBUG, "htarget %08lx diff1 %08lx hash %08lx", + (long unsigned int)Htarg, + (long unsigned int)diff1targ, + (long unsigned int)tmp_hash7); + + if (tmp_hash7 > diff1targ) + return -1; + + if (tmp_hash7 > Htarg) + return 0; + + return 1; +} + +void credits_regenhash(struct work *work) +{ + uint32_t data[42]; + uint32_t *nonce = (uint32_t *)(work->data + 140); + uint32_t *ohash = (uint32_t *)(work->hash); + + be32enc_vect(data, (const uint32_t *)work->data, 42); + data[35] = htobe32(*nonce); + + credits_hash((unsigned char*)ohash, (unsigned char*)data); + +} + + +bool scanhash_credits(struct thr_info *thr, const unsigned char __maybe_unused *pmidstate, + unsigned char *pdata, unsigned char __maybe_unused *phash1, + unsigned char __maybe_unused *phash, const unsigned char *ptarget, + uint32_t max_nonce, uint32_t *last_nonce, uint32_t n) +{ + uint32_t *nonce = (uint32_t *)(pdata + 140); + uint32_t data[42]; + uint32_t tmp_hash7; + uint32_t Htarg = le32toh(((const uint32_t *)ptarget)[7]); + bool ret = false; + + be32enc_vect(data, (const uint32_t *)pdata, 35); + + + while (1) + { + uint32_t ostate[8]; + + *nonce = ++n; + data[35] = (n); + credits_hash(ostate, data); + tmp_hash7 = (ostate[7]); + + applog(LOG_INFO, "data7 %08lx", (long unsigned int)ostate[7]); + + if (unlikely(tmp_hash7 <= Htarg)) + { + ((uint32_t *)pdata)[35] = htobe32(n); + *last_nonce = n; + ret = true; + break; + } + + if (unlikely((n >= max_nonce) || thr->work_restart)) + { + *last_nonce = n; + break; + } + } + + return ret; +} \ No newline at end of file diff --git a/algorithm/credits.h b/algorithm/credits.h new file mode 100644 index 000000000..9d74ad20d --- /dev/null +++ b/algorithm/credits.h @@ -0,0 +1,10 @@ +#ifndef CREDITS_H +#define CREDITS_H + +#include "miner.h" + + +extern int credits_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t nonce); +extern void credits_regenhash(struct work *work); + +#endif /* CREDITS_H */ diff --git a/algorithm/yescrypt.c b/algorithm/yescrypt.c index 305f3b71d..de00d0f33 100644 --- a/algorithm/yescrypt.c +++ b/algorithm/yescrypt.c @@ -103,7 +103,7 @@ bool scanhash_yescrypt(struct thr_info *thr, const unsigned char __maybe_unused *nonce = ++n; data[19] = (n); - pluckrehash(ostate, data); + yescrypt_hash((unsigned char*)data, (unsigned char*)ostate); tmp_hash7 = (ostate[7]); diff --git a/driver-opencl.c b/driver-opencl.c index a912732b2..f8e686176 100644 --- a/driver-opencl.c +++ b/driver-opencl.c @@ -1462,6 +1462,9 @@ static int64_t opencl_scanhash(struct thr_info *thr, struct work *work, } applog(LOG_DEBUG, "GPU %d found something?", gpu->device_id); postcalc_hash_async(thr, work, thrdata->res); +// postcalc_hash(thr); +// submit_tested_work(thr, work); +// submit_work_async(work); memset(thrdata->res, 0, buffersize); /* This finish flushes the writebuffer set with CL_FALSE in clEnqueueWriteBuffer */ clFinish(clState->commandQueue); diff --git a/findnonce.c b/findnonce.c index 5ef19a510..8489c960c 100644 --- a/findnonce.c +++ b/findnonce.c @@ -214,6 +214,7 @@ static void *postcalc_hash(void *userdata) void postcalc_hash_async(struct thr_info *thr, struct work *work, uint32_t *res) { + struct pc_data *pcd = (struct pc_data *)malloc(sizeof(struct pc_data)); int buffersize; @@ -225,8 +226,7 @@ void postcalc_hash_async(struct thr_info *thr, struct work *work, uint32_t *res) pcd->thr = thr; pcd->work = copy_work(work); buffersize = BUFFERSIZE; - - memcpy(&pcd->res, res, buffersize); + memcpy(&pcd->res, res, buffersize); if (pthread_create(&pcd->pth, NULL, postcalc_hash, (void *)pcd)) { applog(LOG_ERR, "Failed to create postcalc_hash thread"); diff --git a/miner.h b/miner.h index 0d98a8e50..737974e6a 100644 --- a/miner.h +++ b/miner.h @@ -692,6 +692,7 @@ static inline void flip32(void *dest_p, const void *src_p) dest[i] = swab32(src[i]); } + static inline void flip64(void *dest_p, const void *src_p) { uint32_t *dest = (uint32_t *)dest_p; @@ -722,6 +723,17 @@ static inline void flip128(void *dest_p, const void *src_p) dest[i] = swab32(src[i]); } +static inline void flip168(void *dest_p, const void *src_p) +{ + uint32_t *dest = (uint32_t *)dest_p; + const uint32_t *src = (uint32_t *)src_p; + int i; + + for (i = 0; i < 42; i++) + dest[i] = swab32(src[i]); +} + + /* For flipping to the correct endianness if necessary */ #if defined(__BIG_ENDIAN__) || defined(MIPSEB) static inline void endian_flip32(void *dest_p, const void *src_p) @@ -733,6 +745,11 @@ static inline void endian_flip128(void *dest_p, const void *src_p) { flip128(dest_p, src_p); } +static inline void endian_flip168(void *dest_p, const void *src_p) +{ + flip168(dest_p, src_p); +} + #else static inline void endian_flip32(void __maybe_unused *dest_p, const void __maybe_unused *src_p) @@ -743,8 +760,13 @@ static inline void endian_flip128(void __maybe_unused *dest_p, const void __maybe_unused *src_p) { } +static inline void +endian_flip168(void __maybe_unused *dest_p, const void __maybe_unused *src_p) +{ +} #endif + extern double cgpu_runtime(struct cgpu_info *cgpu); extern void _quit(int status); @@ -1405,7 +1427,7 @@ struct pool { #define GETWORK_MODE_GBT 'G' struct work { - unsigned char data[128]; + unsigned char data[168]; unsigned char midstate[32]; unsigned char target[32]; unsigned char hash[32]; diff --git a/ocl.c b/ocl.c index 0757a5c43..685ee98a6 100644 --- a/ocl.c +++ b/ocl.c @@ -709,7 +709,7 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize, algorithm_t *alg - size_t readbufsize = 128; + size_t readbufsize = (!safe_cmp(algorithm->name, "credits"))? 168:128; if (algorithm->rw_buffer_size < 0) { // calc buffer size for neoscrypt diff --git a/ocl.h b/ocl.h index 9fa348d38..30b77eed3 100644 --- a/ocl.h +++ b/ocl.h @@ -25,7 +25,7 @@ typedef struct __clState { cl_mem buffer1; cl_mem buffer2; cl_mem buffer3; - unsigned char cldata[80]; + unsigned char cldata[168]; bool hasBitAlign; bool goffset; cl_uint vwidth; diff --git a/sgminer.c b/sgminer.c index 028ec7e13..9f10659cf 100644 --- a/sgminer.c +++ b/sgminer.c @@ -3023,7 +3023,11 @@ static bool submit_upstream_work(struct work *work, CURL *curl, char *curl_err_s cgpu = get_thr_cgpu(thr_id); - endian_flip128(work->data, work->data); + if (safe_cmp(work->pool->algorithm.name, "credits")) { + endian_flip128(work->data, work->data); } else + { + endian_flip168(work->data, work->data); + } /* build hex string - Make sure to restrict to 80 bytes for Neoscrypt */ hexstr = bin2hex(work->data, ((!safe_cmp(work->pool->algorithm.name, "neoscrypt")) ? 80 : sizeof(work->data))); @@ -7065,7 +7069,10 @@ void inc_hw_errors(struct thr_info *thr) /* Fills in the work nonce and builds the output data in work->hash */ static void rebuild_nonce(struct work *work, uint32_t nonce) { - uint32_t *work_nonce = (uint32_t *)(work->data + 76); +uint32_t nonce_pos = 76; +if (!safe_cmp(work->pool->algorithm.name, "credits")) nonce_pos = 140; + + uint32_t *work_nonce = (uint32_t *)(work->data + nonce_pos); *work_nonce = htole32(nonce); diff --git a/util.c b/util.c index ae62be2df..675cdad52 100644 --- a/util.c +++ b/util.c @@ -674,7 +674,7 @@ bool fulltest(const unsigned char *hash, const unsigned char *target) uint32_t *target32 = (uint32_t *)target; bool rc = true; int i; - + for (i = 28 / 4; i >= 0; i--) { uint32_t h32tmp = le32toh(hash32[i]); uint32_t t32tmp = le32toh(target32[i]); From 394a235a52650a846dee4edfb5583e14aedbcc62 Mon Sep 17 00:00:00 2001 From: djm34 Date: Mon, 18 May 2015 13:14:02 +0200 Subject: [PATCH 13/27] kernel for credits algo --- kernel/credits.cl | 232 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 kernel/credits.cl diff --git a/kernel/credits.cl b/kernel/credits.cl new file mode 100644 index 000000000..4e32e7bdb --- /dev/null +++ b/kernel/credits.cl @@ -0,0 +1,232 @@ +/* +* "yescrypt" kernel implementation. +* +* ==========================(LICENSE BEGIN)============================ +* +* Copyright (c) 2015 djm34 +* +* 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 djm34 +*/ +#if !defined(cl_khr_byte_addressable_store) +#error "Device does not support unaligned stores" +#endif + + +#define ROL32(x, n) rotate(x, (uint) n) +#define SWAP32(a) (as_uint(as_uchar4(a).wzyx)) +#define SWAP64(x) as_ulong(as_uchar8(x).s32107654) /// hmm... + +#define SHR(x, n) ((x) >> n) + +#define S0(x) (ROL32(x, 25) ^ ROL32(x, 14) ^ SHR(x, 3)) +#define S1(x) (ROL32(x, 15) ^ ROL32(x, 13) ^ SHR(x, 10)) + +#define S2(x) (ROL32(x, 30) ^ ROL32(x, 19) ^ ROL32(x, 10)) +#define S3(x) (ROL32(x, 26) ^ ROL32(x, 21) ^ ROL32(x, 7)) + +#define P(a,b,c,d,e,f,g,h,x,K) \ +{ \ + temp1 = h + S3(e) + F1(e,f,g) + (K + x); \ + d += temp1; h = temp1 + S2(a) + F0(a,b,c); \ +} + +#define F0(y, x, z) bitselect(z, y, z ^ x) +#define F1(x, y, z) bitselect(z, y, x) + +#define R0 (W0 = S1(W14) + W9 + S0(W1) + W0) +#define R1 (W1 = S1(W15) + W10 + S0(W2) + W1) +#define R2 (W2 = S1(W0) + W11 + S0(W3) + W2) +#define R3 (W3 = S1(W1) + W12 + S0(W4) + W3) +#define R4 (W4 = S1(W2) + W13 + S0(W5) + W4) +#define R5 (W5 = S1(W3) + W14 + S0(W6) + W5) +#define R6 (W6 = S1(W4) + W15 + S0(W7) + W6) +#define R7 (W7 = S1(W5) + W0 + S0(W8) + W7) +#define R8 (W8 = S1(W6) + W1 + S0(W9) + W8) +#define R9 (W9 = S1(W7) + W2 + S0(W10) + W9) +#define R10 (W10 = S1(W8) + W3 + S0(W11) + W10) +#define R11 (W11 = S1(W9) + W4 + S0(W12) + W11) +#define R12 (W12 = S1(W10) + W5 + S0(W13) + W12) +#define R13 (W13 = S1(W11) + W6 + S0(W14) + W13) +#define R14 (W14 = S1(W12) + W7 + S0(W15) + W14) +#define R15 (W15 = S1(W13) + W8 + S0(W0) + W15) + +#define RD14 (S1(W12) + W7 + S0(W15) + W14) +#define RD15 (S1(W13) + W8 + S0(W0) + W15) + +/// generic sha transform +inline uint8 sha256_Transform(uint16 data, uint8 state) +{ + uint temp1; + uint8 res = state; + uint W0 = data.s0; + uint W1 = data.s1; + uint W2 = data.s2; + uint W3 = data.s3; + uint W4 = data.s4; + uint W5 = data.s5; + uint W6 = data.s6; + uint W7 = data.s7; + uint W8 = data.s8; + uint W9 = data.s9; + uint W10 = data.sA; + uint W11 = data.sB; + uint W12 = data.sC; + uint W13 = data.sD; + uint W14 = data.sE; + uint W15 = data.sF; + +#define v0 res.s0 +#define v1 res.s1 +#define v2 res.s2 +#define v3 res.s3 +#define v4 res.s4 +#define v5 res.s5 +#define v6 res.s6 +#define v7 res.s7 + + P(v0, v1, v2, v3, v4, v5, v6, v7, W0, 0x428A2F98); + P(v7, v0, v1, v2, v3, v4, v5, v6, W1, 0x71374491); + P(v6, v7, v0, v1, v2, v3, v4, v5, W2, 0xB5C0FBCF); + P(v5, v6, v7, v0, v1, v2, v3, v4, W3, 0xE9B5DBA5); + P(v4, v5, v6, v7, v0, v1, v2, v3, W4, 0x3956C25B); + P(v3, v4, v5, v6, v7, v0, v1, v2, W5, 0x59F111F1); + P(v2, v3, v4, v5, v6, v7, v0, v1, W6, 0x923F82A4); + P(v1, v2, v3, v4, v5, v6, v7, v0, W7, 0xAB1C5ED5); + P(v0, v1, v2, v3, v4, v5, v6, v7, W8, 0xD807AA98); + P(v7, v0, v1, v2, v3, v4, v5, v6, W9, 0x12835B01); + P(v6, v7, v0, v1, v2, v3, v4, v5, W10, 0x243185BE); + P(v5, v6, v7, v0, v1, v2, v3, v4, W11, 0x550C7DC3); + P(v4, v5, v6, v7, v0, v1, v2, v3, W12, 0x72BE5D74); + P(v3, v4, v5, v6, v7, v0, v1, v2, W13, 0x80DEB1FE); + P(v2, v3, v4, v5, v6, v7, v0, v1, W14, 0x9BDC06A7); + P(v1, v2, v3, v4, v5, v6, v7, v0, W15, 0xC19BF174); + + P(v0, v1, v2, v3, v4, v5, v6, v7, R0, 0xE49B69C1); + P(v7, v0, v1, v2, v3, v4, v5, v6, R1, 0xEFBE4786); + P(v6, v7, v0, v1, v2, v3, v4, v5, R2, 0x0FC19DC6); + P(v5, v6, v7, v0, v1, v2, v3, v4, R3, 0x240CA1CC); + P(v4, v5, v6, v7, v0, v1, v2, v3, R4, 0x2DE92C6F); + P(v3, v4, v5, v6, v7, v0, v1, v2, R5, 0x4A7484AA); + P(v2, v3, v4, v5, v6, v7, v0, v1, R6, 0x5CB0A9DC); + P(v1, v2, v3, v4, v5, v6, v7, v0, R7, 0x76F988DA); + P(v0, v1, v2, v3, v4, v5, v6, v7, R8, 0x983E5152); + P(v7, v0, v1, v2, v3, v4, v5, v6, R9, 0xA831C66D); + P(v6, v7, v0, v1, v2, v3, v4, v5, R10, 0xB00327C8); + P(v5, v6, v7, v0, v1, v2, v3, v4, R11, 0xBF597FC7); + P(v4, v5, v6, v7, v0, v1, v2, v3, R12, 0xC6E00BF3); + P(v3, v4, v5, v6, v7, v0, v1, v2, R13, 0xD5A79147); + P(v2, v3, v4, v5, v6, v7, v0, v1, R14, 0x06CA6351); + P(v1, v2, v3, v4, v5, v6, v7, v0, R15, 0x14292967); + + P(v0, v1, v2, v3, v4, v5, v6, v7, R0, 0x27B70A85); + P(v7, v0, v1, v2, v3, v4, v5, v6, R1, 0x2E1B2138); + P(v6, v7, v0, v1, v2, v3, v4, v5, R2, 0x4D2C6DFC); + P(v5, v6, v7, v0, v1, v2, v3, v4, R3, 0x53380D13); + P(v4, v5, v6, v7, v0, v1, v2, v3, R4, 0x650A7354); + P(v3, v4, v5, v6, v7, v0, v1, v2, R5, 0x766A0ABB); + P(v2, v3, v4, v5, v6, v7, v0, v1, R6, 0x81C2C92E); + P(v1, v2, v3, v4, v5, v6, v7, v0, R7, 0x92722C85); + P(v0, v1, v2, v3, v4, v5, v6, v7, R8, 0xA2BFE8A1); + P(v7, v0, v1, v2, v3, v4, v5, v6, R9, 0xA81A664B); + P(v6, v7, v0, v1, v2, v3, v4, v5, R10, 0xC24B8B70); + P(v5, v6, v7, v0, v1, v2, v3, v4, R11, 0xC76C51A3); + P(v4, v5, v6, v7, v0, v1, v2, v3, R12, 0xD192E819); + P(v3, v4, v5, v6, v7, v0, v1, v2, R13, 0xD6990624); + P(v2, v3, v4, v5, v6, v7, v0, v1, R14, 0xF40E3585); + P(v1, v2, v3, v4, v5, v6, v7, v0, R15, 0x106AA070); + + P(v0, v1, v2, v3, v4, v5, v6, v7, R0, 0x19A4C116); + P(v7, v0, v1, v2, v3, v4, v5, v6, R1, 0x1E376C08); + P(v6, v7, v0, v1, v2, v3, v4, v5, R2, 0x2748774C); + P(v5, v6, v7, v0, v1, v2, v3, v4, R3, 0x34B0BCB5); + P(v4, v5, v6, v7, v0, v1, v2, v3, R4, 0x391C0CB3); + P(v3, v4, v5, v6, v7, v0, v1, v2, R5, 0x4ED8AA4A); + P(v2, v3, v4, v5, v6, v7, v0, v1, R6, 0x5B9CCA4F); + P(v1, v2, v3, v4, v5, v6, v7, v0, R7, 0x682E6FF3); + P(v0, v1, v2, v3, v4, v5, v6, v7, R8, 0x748F82EE); + P(v7, v0, v1, v2, v3, v4, v5, v6, R9, 0x78A5636F); + P(v6, v7, v0, v1, v2, v3, v4, v5, R10, 0x84C87814); + P(v5, v6, v7, v0, v1, v2, v3, v4, R11, 0x8CC70208); + P(v4, v5, v6, v7, v0, v1, v2, v3, R12, 0x90BEFFFA); + P(v3, v4, v5, v6, v7, v0, v1, v2, R13, 0xA4506CEB); + P(v2, v3, v4, v5, v6, v7, v0, v1, RD14, 0xBEF9A3F7); + P(v1, v2, v3, v4, v5, v6, v7, v0, RD15, 0xC67178F2); +#undef v0 +#undef v1 +#undef v2 +#undef v3 +#undef v4 +#undef v5 +#undef v6 +#undef v7 + return (res + state); +} + + + +static __constant uint8 H256 = { + 0x6A09E667, 0xBB67AE85, 0x3C6EF372, + 0xA54FF53A, 0x510E527F, 0x9B05688C, + 0x1F83D9AB, 0x5BE0CD19 +}; + + +static __constant uint8 pad_data = +{ + 0x00000000, 0x00000000, 0x80000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000540 +}; + +static __constant uint8 pad_state = +{ + 0x80000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000100 +}; + + + +__attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) +__kernel void search(__global const uchar* restrict input, __global uint* restrict output,const ulong target, uint8 midstate ) +{ + + + uint nonce = get_global_id(0); + uint16 in; + uint8 state1; + + in.lo = ((__global const uint8 *)input)[4]; + in.hi = pad_data; + in.hi.s0 = ((__global const uint *)input)[40]; + in.hi.s1 = ((__global const uint *)input)[41]; + in.s3 = nonce; + state1 = sha256_Transform(in, midstate); + in.lo = state1; + in.hi = pad_state; + state1 = sha256_Transform(in,H256); + +if (SWAP64(state1.s67) <= target) + output[atomic_inc(output + 0xFF)] = nonce; + +} + From 907d898a3fc29bf7e22c9511fb03af5724316012 Mon Sep 17 00:00:00 2001 From: djm34 Date: Mon, 18 May 2015 13:15:51 +0200 Subject: [PATCH 14/27] credits update --- kernel/credits.cl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/credits.cl b/kernel/credits.cl index 4e32e7bdb..19cbea67f 100644 --- a/kernel/credits.cl +++ b/kernel/credits.cl @@ -1,5 +1,5 @@ /* -* "yescrypt" kernel implementation. +* "credits" kernel implementation. * * ==========================(LICENSE BEGIN)============================ * From 101b10c5fad127397633aa52024f2443af1404ae Mon Sep 17 00:00:00 2001 From: djm34 Date: Tue, 2 Jun 2015 19:25:02 +0200 Subject: [PATCH 15/27] missing makefile.am for credits --- Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.am b/Makefile.am index 716a68813..89a8547a6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -69,6 +69,7 @@ sgminer_SOURCES += algorithm/fresh.c algorithm/fresh.h sgminer_SOURCES += algorithm/whirlcoin.c algorithm/whirlcoin.h sgminer_SOURCES += algorithm/neoscrypt.c algorithm/neoscrypt.h sgminer_SOURCES += algorithm/pluck.c algorithm/pluck.h +sgminer_SOURCES += algorithm/credits.c algorithm/credits.h sgminer_SOURCES += algorithm/Lyra2RE.c algorithm/Lyra2RE.h algorithm/Lyra2.c algorithm/Lyra2.h algorithm/Sponge.c algorithm/Sponge.h sgminer_SOURCES += algorithm/yescrypt.h algorithm/yescrypt.c algorithm/yescrypt_core.h algorithm/yescrypt-opt.c algorithm/yescryptcommon.c algorithm/sysendian.h From 3e612cf335cd22589c075fe5422a20103c4e2970 Mon Sep 17 00:00:00 2001 From: djm34 Date: Fri, 31 Jul 2015 14:12:37 +0200 Subject: [PATCH 16/27] new vertcoin algorithm: Lyra2REv2 kept old lyra2RE for coins still using it (careful the original lyra2 had a bug, this one is corrected only in the new version) implemented next_diff trick for pools --- Makefile.am | 1 + algorithm.c | 67 ++++- algorithm.h | 1 + algorithm/Lyra2.c | 15 +- algorithm/Lyra2.h | 12 +- algorithm/Lyra2RE.c | 27 ++- algorithm/Lyra2RE.h | 3 +- algorithm/Lyra2RE_old.c | 169 +++++++++++++ algorithm/Lyra2RE_old.h | 10 + algorithm/Lyra2_old.c | 208 ++++++++++++++++ algorithm/Lyra2_old.h | 50 ++++ algorithm/Sponge.c | 129 +++++----- algorithm/Sponge.h | 16 +- algorithm/Sponge_old.c | 405 +++++++++++++++++++++++++++++++ algorithm/Sponge_old.h | 98 ++++++++ driver-opencl.c | 4 +- kernel/Lyra2REv2.cl | 525 ++++++++++++++++++++++++++++++++++++++++ kernel/Lyra2v2.cl | 184 ++++++++++++++ kernel/bmw256.cl | 128 ++++++++++ kernel/cubehash256.cl | 132 ++++++++++ kernel/skein256.cl | 16 +- miner.h | 5 +- ocl.c | 134 +++++++++- sgminer.c | 13 +- util.c | 8 +- 25 files changed, 2239 insertions(+), 121 deletions(-) create mode 100644 algorithm/Lyra2RE_old.c create mode 100644 algorithm/Lyra2RE_old.h create mode 100644 algorithm/Lyra2_old.c create mode 100644 algorithm/Lyra2_old.h create mode 100644 algorithm/Sponge_old.c create mode 100644 algorithm/Sponge_old.h create mode 100644 kernel/Lyra2REv2.cl create mode 100644 kernel/Lyra2v2.cl create mode 100644 kernel/bmw256.cl create mode 100644 kernel/cubehash256.cl diff --git a/Makefile.am b/Makefile.am index 89a8547a6..bf68583ed 100644 --- a/Makefile.am +++ b/Makefile.am @@ -70,6 +70,7 @@ sgminer_SOURCES += algorithm/whirlcoin.c algorithm/whirlcoin.h sgminer_SOURCES += algorithm/neoscrypt.c algorithm/neoscrypt.h sgminer_SOURCES += algorithm/pluck.c algorithm/pluck.h sgminer_SOURCES += algorithm/credits.c algorithm/credits.h +sgminer_SOURCES += algorithm/Lyra2RE_old.c algorithm/Lyra2RE_old.h algorithm/Lyra2_old.c algorithm/Lyra2_old.h algorithm/Sponge_old.c algorithm/Sponge_old.h sgminer_SOURCES += algorithm/Lyra2RE.c algorithm/Lyra2RE.h algorithm/Lyra2.c algorithm/Lyra2.h algorithm/Sponge.c algorithm/Sponge.h sgminer_SOURCES += algorithm/yescrypt.h algorithm/yescrypt.c algorithm/yescrypt_core.h algorithm/yescrypt-opt.c algorithm/yescryptcommon.c algorithm/sysendian.h diff --git a/algorithm.c b/algorithm.c index 8302ecd19..5430d7735 100644 --- a/algorithm.c +++ b/algorithm.c @@ -31,7 +31,8 @@ #include "algorithm/fresh.h" #include "algorithm/whirlcoin.h" #include "algorithm/neoscrypt.h" -#include "algorithm/Lyra2RE.h" +#include "algorithm/Lyra2RE.h" //lyra new version +#include "algorithm/Lyra2RE_old.h" //lyra old version #include "algorithm/pluck.h" #include "algorithm/yescrypt.h" #include "algorithm/credits.h" @@ -59,6 +60,7 @@ const char *algorithm_type_str[] = { "Whirlcoin", "Neoscrypt", "Lyra2RE", + "Lyta2REv2" "pluck", "yescrypt", "yescrypt-multi" @@ -409,6 +411,62 @@ static cl_int queue_lyra2RE_kernel(struct __clState *clState, struct _dev_blk_ct return status; } +static cl_int queue_lyra2REv2_kernel(struct __clState *clState, struct _dev_blk_ctx *blk, __maybe_unused cl_uint threads) +{ + cl_kernel *kernel; + unsigned int num; + cl_int status = 0; + cl_ulong le_target; + + // le_target = *(cl_uint *)(blk->work->device_target + 28); + le_target = *(cl_ulong *)(blk->work->device_target + 24); + flip80(clState->cldata, blk->work->data); + status = clEnqueueWriteBuffer(clState->commandQueue, clState->CLbuffer0, true, 0, 80, clState->cldata, 0, NULL, NULL); + + // blake - search + kernel = &clState->kernel; + num = 0; + // CL_SET_ARG(clState->CLbuffer0); + CL_SET_ARG(clState->buffer1); + CL_SET_ARG(blk->work->blk.ctx_a); + CL_SET_ARG(blk->work->blk.ctx_b); + CL_SET_ARG(blk->work->blk.ctx_c); + CL_SET_ARG(blk->work->blk.ctx_d); + CL_SET_ARG(blk->work->blk.ctx_e); + CL_SET_ARG(blk->work->blk.ctx_f); + CL_SET_ARG(blk->work->blk.ctx_g); + CL_SET_ARG(blk->work->blk.ctx_h); + CL_SET_ARG(blk->work->blk.cty_a); + CL_SET_ARG(blk->work->blk.cty_b); + CL_SET_ARG(blk->work->blk.cty_c); + + // keccak - search1 + kernel = clState->extra_kernels; + CL_SET_ARG_0(clState->buffer1); + // cubehash - search2 + num = 0; + CL_NEXTKERNEL_SET_ARG_0(clState->buffer1); + // lyra - search3 + num = 0; + CL_NEXTKERNEL_SET_ARG_N(0, clState->buffer1); + CL_SET_ARG_N(1, clState->padbuffer8); + // skein -search4 + num = 0; + CL_NEXTKERNEL_SET_ARG_0(clState->buffer1); + // cubehash - search5 + num = 0; + CL_NEXTKERNEL_SET_ARG_0(clState->buffer1); + // bmw - search6 + num = 0; + CL_NEXTKERNEL_SET_ARG(clState->buffer1); + CL_SET_ARG(clState->outputBuffer); + CL_SET_ARG(le_target); + + return status; +} + + + static cl_int queue_darkcoin_mod_kernel(struct __clState *clState, struct _dev_blk_ctx *blk, __maybe_unused cl_uint threads) { @@ -927,7 +985,10 @@ static algorithm_settings_t algos[] = { { "fresh", ALGO_FRESH, "", 1, 256, 256, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 4, 4 * 16 * 4194304, 0, fresh_regenhash, queue_fresh_kernel, gen_hash, NULL}, - { "Lyra2RE", ALGO_LYRA2RE, "", 1, 256, 256, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 4,2 * 8 * 4194304 , 0, lyra2re_regenhash, queue_lyra2RE_kernel, gen_hash, NULL}, + { "Lyra2RE", ALGO_LYRA2RE, "", 1, 256, 256, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 4,2 * 8 * 4194304 , 0, lyra2reold_regenhash, queue_lyra2RE_kernel, gen_hash, NULL}, + + { "Lyra2REv2", ALGO_LYRA2REv2, "", 1, 256, 256, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 6, -1, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, lyra2re_regenhash, queue_lyra2REv2_kernel, gen_hash, append_neoscrypt_compiler_options }, + // kernels starting from this will have difficulty calculated by using fuguecoin algorithm #define A_FUGUE(a, b, c) \ @@ -1035,7 +1096,7 @@ void set_algorithm(algorithm_t* algo, const char* newname_alias) // use old nfactor if it was previously set and is different than the one set by alias if ((old_nfactor > 0) && (old_nfactor != nfactor)) nfactor = old_nfactor; - if (algo->type == ALGO_LYRA2RE) {opt_lyra = true;} + if (algo->type == ALGO_LYRA2RE || algo->type == ALGO_LYRA2REv2 ) { opt_lyra = true; } set_algorithm_nfactor(algo, nfactor); //reapply kernelfile if was set diff --git a/algorithm.h b/algorithm.h index c412af924..e24421de0 100644 --- a/algorithm.h +++ b/algorithm.h @@ -28,6 +28,7 @@ typedef enum { ALGO_WHIRL, ALGO_NEOSCRYPT, ALGO_LYRA2RE, + ALGO_LYRA2REv2, ALGO_PLUCK, ALGO_YESCRYPT, ALGO_YESCRYPT_MULTI, diff --git a/algorithm/Lyra2.c b/algorithm/Lyra2.c index 412aa1f68..aa7d207e4 100644 --- a/algorithm/Lyra2.c +++ b/algorithm/Lyra2.c @@ -58,6 +58,11 @@ int LYRA2(void *K, uint64_t kLen, const void *pwd, uint64_t pwdlen, const void * //========== 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) { @@ -130,16 +135,16 @@ int LYRA2(void *K, uint64_t kLen, const void *pwd, uint64_t pwdlen, const void * ptrWord = wholeMatrix; for (i = 0; i < nBlocksInput; i++) { absorbBlockBlake2Safe(state, ptrWord); //absorbs each block of pad(pwd || salt || basil) - ptrWord += BLOCK_LEN_BLAKE2_SAFE_BYTES; //goes to next 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]); //The locally copied password is most likely overwritten here - reducedDuplexRow1(state, memMatrix[0], memMatrix[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]); + reducedDuplexRowSetup(state, memMatrix[prev], memMatrix[rowa], memMatrix[row], nCols); //updates the value of row* (deterministically picked during Setup)) @@ -172,7 +177,7 @@ int LYRA2(void *K, uint64_t kLen, const void *pwd, uint64_t pwdlen, const void * //------------------------------------------------------------------------------------------ //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]); + reducedDuplexRow(state, memMatrix[prev], memMatrix[rowa], memMatrix[row], nCols); //update prev: it now points to the last row ever computed prev = row; diff --git a/algorithm/Lyra2.h b/algorithm/Lyra2.h index 13c7dbd3b..c79089457 100644 --- a/algorithm/Lyra2.h +++ b/algorithm/Lyra2.h @@ -1,8 +1,8 @@ /** * 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 @@ -37,14 +37,6 @@ typedef unsigned char byte; #define BLOCK_LEN_BYTES (BLOCK_LEN_INT64 * 8) //Block length, in bytes #endif -#ifndef N_COLS - #define N_COLS 8 //Number of columns in the memory matrix: fixed to 64 by default -#endif - -#define ROW_LEN_INT64 (BLOCK_LEN_INT64 * N_COLS) //Total length of a row: N_COLS blocks -#define ROW_LEN_BYTES (ROW_LEN_INT64 * 8) //Number of bytes per row - - int LYRA2(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); #endif /* LYRA2_H_ */ diff --git a/algorithm/Lyra2RE.c b/algorithm/Lyra2RE.c index 24b8210c6..f6d36df83 100644 --- a/algorithm/Lyra2RE.c +++ b/algorithm/Lyra2RE.c @@ -36,6 +36,8 @@ #include "sph/sph_groestl.h" #include "sph/sph_skein.h" #include "sph/sph_keccak.h" +#include "sph/sph_bmw.h" +#include "sph/sph_cubehash.h" #include "Lyra2.h" /* @@ -55,34 +57,37 @@ be32enc_vect(uint32_t *dst, const uint32_t *src, uint32_t len) inline void lyra2rehash(void *state, const void *input) { sph_blake256_context ctx_blake; - sph_groestl256_context ctx_groestl; + sph_bmw256_context ctx_bmw; sph_keccak256_context ctx_keccak; sph_skein256_context ctx_skein; - + sph_cubehash256_context ctx_cube; uint32_t hashA[8], hashB[8]; sph_blake256_init(&ctx_blake); sph_blake256 (&ctx_blake, input, 80); sph_blake256_close (&ctx_blake, hashA); - - - sph_keccak256_init(&ctx_keccak); sph_keccak256 (&ctx_keccak,hashA, 32); sph_keccak256_close(&ctx_keccak, hashB); - LYRA2(hashA, 32, hashB, 32, hashB, 32, 1, 8, 8); + 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, hashA, 32); - sph_skein256_close(&ctx_skein, hashB); + sph_skein256 (&ctx_skein, hashB, 32); + sph_skein256_close(&ctx_skein, hashA); + sph_cubehash256_init(&ctx_cube); + sph_cubehash256(&ctx_cube, hashA, 32); + sph_cubehash256_close(&ctx_cube, hashB); - sph_groestl256_init(&ctx_groestl); - sph_groestl256 (&ctx_groestl, hashB, 32); - sph_groestl256_close(&ctx_groestl, hashA); + sph_bmw256_init(&ctx_bmw); + sph_bmw256 (&ctx_bmw, hashB, 32); + sph_bmw256_close(&ctx_bmw, hashA); //printf("cpu hash %08x %08x %08x %08x\n",hashA[0],hashA[1],hashA[2],hashA[3]); diff --git a/algorithm/Lyra2RE.h b/algorithm/Lyra2RE.h index 8a58e7471..f4698c65a 100644 --- a/algorithm/Lyra2RE.h +++ b/algorithm/Lyra2RE.h @@ -2,7 +2,8 @@ #define LYRA2RE_H #include "miner.h" - +#define LYRA_SCRATCHBUF_SIZE (4 ) // matrix extended to 16 matrix[16][8][8] uint64_t or equivalent +#define LYRA_SECBUF_SIZE (4) //8 uint64 extern int lyra2re_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t nonce); extern void lyra2re_regenhash(struct work *work); diff --git a/algorithm/Lyra2RE_old.c b/algorithm/Lyra2RE_old.c new file mode 100644 index 000000000..f1e9aee5c --- /dev/null +++ b/algorithm/Lyra2RE_old.c @@ -0,0 +1,169 @@ +/*- + * Copyright 2014 James Lovejoy + * Copyright 2014 phm + * 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 "config.h" +#include "miner.h" + +#include +#include +#include + +#include "sph/sph_blake.h" +#include "sph/sph_groestl.h" +#include "sph/sph_skein.h" +#include "sph/sph_keccak.h" +#include "Lyra2_old.h" + +/* + * Encode a length len/4 vector of (uint32_t) into a length len vector of + * (unsigned char) in big-endian form. Assumes len is a multiple of 4. + */ +static inline void +be32enc_vect(uint32_t *dst, const uint32_t *src, uint32_t len) +{ + uint32_t i; + + for (i = 0; i < len; i++) + dst[i] = htobe32(src[i]); +} + + +inline void lyra2rehash_old(void *state, const void *input) +{ + sph_blake256_context ctx_blake; + sph_groestl256_context ctx_groestl; + sph_keccak256_context ctx_keccak; + sph_skein256_context ctx_skein; + + uint32_t hashA[8], hashB[8]; + + sph_blake256_init(&ctx_blake); + sph_blake256 (&ctx_blake, input, 80); + sph_blake256_close (&ctx_blake, hashA); + + + + + sph_keccak256_init(&ctx_keccak); + sph_keccak256 (&ctx_keccak,hashA, 32); + sph_keccak256_close(&ctx_keccak, hashB); + + LYRA2O(hashA, 32, hashB, 32, hashB, 32, 1, 8, 8); + + + sph_skein256_init(&ctx_skein); + sph_skein256 (&ctx_skein, hashA, 32); + sph_skein256_close(&ctx_skein, hashB); + + + sph_groestl256_init(&ctx_groestl); + sph_groestl256 (&ctx_groestl, hashB, 32); + sph_groestl256_close(&ctx_groestl, hashA); + +//printf("cpu hash %08x %08x %08x %08x\n",hashA[0],hashA[1],hashA[2],hashA[3]); + + memcpy(state, hashA, 32); +} + +static const uint32_t diff1targ = 0x0000ffff; + + +/* Used externally as confirmation of correct OCL code */ +int lyra2reold_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t nonce) +{ + uint32_t tmp_hash7, Htarg = le32toh(((const uint32_t *)ptarget)[7]); + uint32_t data[20], ohash[8]; + + be32enc_vect(data, (const uint32_t *)pdata, 19); + data[19] = htobe32(nonce); + lyra2rehash(ohash, data); + tmp_hash7 = be32toh(ohash[7]); + + applog(LOG_DEBUG, "htarget %08lx diff1 %08lx hash %08lx", + (long unsigned int)Htarg, + (long unsigned int)diff1targ, + (long unsigned int)tmp_hash7); + if (tmp_hash7 > diff1targ) + return -1; + if (tmp_hash7 > Htarg) + return 0; + return 1; +} + +void lyra2reold_regenhash(struct work *work) +{ + uint32_t data[20]; + uint32_t *nonce = (uint32_t *)(work->data + 76); + uint32_t *ohash = (uint32_t *)(work->hash); + + be32enc_vect(data, (const uint32_t *)work->data, 19); + data[19] = htobe32(*nonce); + lyra2rehash(ohash, data); +} + +bool scanhash_lyra2reold(struct thr_info *thr, const unsigned char __maybe_unused *pmidstate, + unsigned char *pdata, unsigned char __maybe_unused *phash1, + unsigned char __maybe_unused *phash, const unsigned char *ptarget, + uint32_t max_nonce, uint32_t *last_nonce, uint32_t n) +{ + uint32_t *nonce = (uint32_t *)(pdata + 76); + uint32_t data[20]; + uint32_t tmp_hash7; + uint32_t Htarg = le32toh(((const uint32_t *)ptarget)[7]); + bool ret = false; + + be32enc_vect(data, (const uint32_t *)pdata, 19); + + while(1) { + uint32_t ostate[8]; + + *nonce = ++n; + data[19] = (n); + lyra2rehash(ostate, data); + tmp_hash7 = (ostate[7]); + + applog(LOG_INFO, "data7 %08lx", + (long unsigned int)data[7]); + + if (unlikely(tmp_hash7 <= Htarg)) { + ((uint32_t *)pdata)[19] = htobe32(n); + *last_nonce = n; + ret = true; + break; + } + + if (unlikely((n >= max_nonce) || thr->work_restart)) { + *last_nonce = n; + break; + } + } + + return ret; +} + + + diff --git a/algorithm/Lyra2RE_old.h b/algorithm/Lyra2RE_old.h new file mode 100644 index 000000000..0788dfb35 --- /dev/null +++ b/algorithm/Lyra2RE_old.h @@ -0,0 +1,10 @@ +#ifndef LYRA2REOLD_H +#define LYRA2REOLD_H + +#include "miner.h" + +extern int lyra2reold_test(unsigned char *pdata, const unsigned char *ptarget, + uint32_t nonce); +extern void lyra2reold_regenhash(struct work *work); + +#endif /* LYRA2RE_H */ diff --git a/algorithm/Lyra2_old.c b/algorithm/Lyra2_old.c new file mode 100644 index 000000000..f78c49032 --- /dev/null +++ b/algorithm/Lyra2_old.c @@ -0,0 +1,208 @@ +/** + * Implementation of 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. + */ +#include +#include +#include +#include +#include "Lyra2_old.h" +#include "Sponge_old.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 LYRA2O(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 + 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++) { + absorbBlockBlake2SafeO(state, ptrWord); //absorbs each block of pad(pwd || salt || basil) + ptrWord += BLOCK_LEN_BLAKE2_SAFE_BYTES; //goes to next block of pad(pwd || salt || basil) + } + + //Initializes M[0] and M[1] + reducedSqueezeRow0O(state, memMatrix[0]); //The locally copied password is most likely overwritten here + reducedDuplexRow1O(state, memMatrix[0], memMatrix[1]); + + do { + //M[row] = rand; //M[row*] = M[row*] XOR rotW(rand) + reducedDuplexRowSetupO(state, memMatrix[prev], memMatrix[rowa], memMatrix[row]); + + + //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] + reducedDuplexRowO(state, memMatrix[prev], memMatrix[rowa], memMatrix[row]); + + //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 + absorbBlockO(state, memMatrix[rowa]); + + //Squeezes the key + squeezeO(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/algorithm/Lyra2_old.h b/algorithm/Lyra2_old.h new file mode 100644 index 000000000..9dbe56682 --- /dev/null +++ b/algorithm/Lyra2_old.h @@ -0,0 +1,50 @@ +/** + * 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 LYRA2OLD_H_ +#define LYRA2OLD_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 8 //512 bits (=64 bytes, =8 uint64_t) +#define BLOCK_LEN_BLAKE2_SAFE_BYTES (BLOCK_LEN_BLAKE2_SAFE_INT64 * 8) //same as above, in bytes + + +#ifdef BLOCK_LEN_BITS + #define BLOCK_LEN_INT64 (BLOCK_LEN_BITS/64) //Block length: 768 bits (=96 bytes, =12 uint64_t) + #define BLOCK_LEN_BYTES (BLOCK_LEN_BITS/8) //Block length, in bytes +#else //default block lenght: 768 bits + #define BLOCK_LEN_INT64 12 //Block length: 768 bits (=96 bytes, =12 uint64_t) + #define BLOCK_LEN_BYTES (BLOCK_LEN_INT64 * 8) //Block length, in bytes +#endif + +#ifndef N_COLS + #define N_COLS 8 //Number of columns in the memory matrix: fixed to 64 by default +#endif + +#define ROW_LEN_INT64 (BLOCK_LEN_INT64 * N_COLS) //Total length of a row: N_COLS blocks +#define ROW_LEN_BYTES (ROW_LEN_INT64 * 8) //Number of bytes per row + + +int LYRA2O(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); + +#endif /* LYRA2_H_ */ diff --git a/algorithm/Sponge.c b/algorithm/Sponge.c index 0aa5aace3..8ece6f99d 100644 --- a/algorithm/Sponge.c +++ b/algorithm/Sponge.c @@ -1,9 +1,9 @@ /** - * A simple implementation of Blake2b's internal permutation + * A simple implementation of Blake2b's internal permutation * in the form of a sponge. - * + * * 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 @@ -27,19 +27,19 @@ /** - * Initializes the Sponge State. The first 512 bits are set to zeros and the remainder + * Initializes the Sponge State. The first 512 bits are set to zeros and the remainder * receive Blake2b's IV as per Blake2b's specification. Note: Even though sponges * typically have their internal state initialized with zeros, Blake2b's G function - * has a fixed point: if the internal state and message are both filled with zeros. the - * resulting permutation will always be a block filled with zeros; this happens because - * Blake2b does not use the constants originally employed in Blake2 inside its G function, + * has a fixed point: if the internal state and message are both filled with zeros. the + * resulting permutation will always be a block filled with zeros; this happens because + * Blake2b does not use the constants originally employed in Blake2 inside its G function, * relying on the IV for avoiding possible fixed points. - * + * * @param state The 1024-bit array to be initialized */ inline void initState(uint64_t state[/*16*/]) { //First 512 bis are zeros - memset(state, 0, 64); + memset(state, 0, 64); //Remainder BLOCK_LEN_BLAKE2_SAFE_BYTES are reserved to the IV state[8] = blake2b_IV[0]; state[9] = blake2b_IV[1]; @@ -53,7 +53,7 @@ inline void initState(uint64_t state[/*16*/]) { /** * Execute Blake2b's G function, with all 12 rounds. - * + * * @param v A 1024-bit (16 uint64_t) array to be processed by Blake2b's G function */ inline static void blake2bLyra(uint64_t *v) { @@ -80,10 +80,10 @@ inline static void reducedBlake2bLyra(uint64_t *v) { } /** - * Performs a squeeze operation, using Blake2b's G function as the + * Performs a squeeze operation, using Blake2b's G function as the * internal permutation - * - * @param state The current state of the sponge + * + * @param state The current state of the sponge * @param out Array that will receive the data squeezed * @param len The number of bytes to be squeezed into the "out" array */ @@ -105,8 +105,8 @@ inline void squeeze(uint64_t *state, byte *out, unsigned int len) { /** * Performs an absorb operation for a single block (BLOCK_LEN_INT64 words * of type uint64_t), using Blake2b's G function as the internal permutation - * - * @param state The current state of the sponge + * + * @param state The current state of the sponge * @param in The block to be absorbed (BLOCK_LEN_INT64 words) */ inline void absorbBlock(uint64_t *state, const uint64_t *in) { @@ -129,15 +129,16 @@ inline void absorbBlock(uint64_t *state, const uint64_t *in) { } /** - * Performs an absorb operation for a single block (BLOCK_LEN_BLAKE2_SAFE_INT64 + * Performs an absorb operation for a single block (BLOCK_LEN_BLAKE2_SAFE_INT64 * words of type uint64_t), using Blake2b's G function as the internal permutation - * - * @param state The current state of the sponge + * + * @param state The current state of the sponge * @param in The block to be absorbed (BLOCK_LEN_BLAKE2_SAFE_INT64 words) */ inline void absorbBlockBlake2Safe(uint64_t *state, const uint64_t *in) { //XORs the first BLOCK_LEN_BLAKE2_SAFE_INT64 words of "in" with the current state - state[0] ^= in[0]; + + state[0] ^= in[0]; state[1] ^= in[1]; state[2] ^= in[2]; state[3] ^= in[3]; @@ -146,23 +147,25 @@ inline void absorbBlockBlake2Safe(uint64_t *state, const uint64_t *in) { state[6] ^= in[6]; state[7] ^= in[7]; + //Applies the transformation f to the sponge's state blake2bLyra(state); + } -/** - * Performs a reduced squeeze operation for a single row, from the highest to - * the lowest index, using the reduced-round Blake2b's G function as the +/** + * Performs a reduced squeeze operation for a single row, from the highest to + * the lowest index, using the reduced-round Blake2b's G function as the * internal permutation - * - * @param state The current state of the sponge + * + * @param state The current state of the sponge * @param rowOut Row to receive the data squeezed */ -inline void reducedSqueezeRow0(uint64_t* state, uint64_t* rowOut) { - uint64_t* ptrWord = rowOut + (N_COLS-1)*BLOCK_LEN_INT64; //In Lyra2: pointer to M[0][C-1] +inline void reducedSqueezeRow0(uint64_t* state, uint64_t* rowOut, uint64_t nCols) { + uint64_t* ptrWord = rowOut + (nCols-1)*BLOCK_LEN_INT64; //In Lyra2: pointer to M[0][C-1] int i; - //M[row][C-1-col] = H.reduced_squeeze() - for (i = 0; i < N_COLS; i++) { + //M[row][C-1-col] = H.reduced_squeeze() + for (i = 0; i < nCols; i++) { ptrWord[0] = state[0]; ptrWord[1] = state[1]; ptrWord[2] = state[2]; @@ -184,21 +187,21 @@ inline void reducedSqueezeRow0(uint64_t* state, uint64_t* rowOut) { } } -/** - * Performs a reduced duplex operation for a single row, from the highest to - * the lowest index, using the reduced-round Blake2b's G function as the +/** + * Performs a reduced duplex operation for a single row, from the highest to + * the lowest index, using the reduced-round Blake2b's G function as the * internal permutation - * - * @param state The current state of the sponge + * + * @param state The current state of the sponge * @param rowIn Row to feed the sponge * @param rowOut Row to receive the sponge's output */ -inline void reducedDuplexRow1(uint64_t *state, uint64_t *rowIn, uint64_t *rowOut) { +inline void reducedDuplexRow1(uint64_t *state, uint64_t *rowIn, uint64_t *rowOut, uint64_t nCols) { uint64_t* ptrWordIn = rowIn; //In Lyra2: pointer to prev - uint64_t* ptrWordOut = rowOut + (N_COLS-1)*BLOCK_LEN_INT64; //In Lyra2: pointer to row + uint64_t* ptrWordOut = rowOut + (nCols-1)*BLOCK_LEN_INT64; //In Lyra2: pointer to row int i; - for (i = 0; i < N_COLS; i++) { + for (i = 0; i < nCols; i++) { //Absorbing "M[prev][col]" state[0] ^= (ptrWordIn[0]); @@ -230,8 +233,8 @@ inline void reducedDuplexRow1(uint64_t *state, uint64_t *rowIn, uint64_t *rowOut ptrWordOut[9] = ptrWordIn[9] ^ state[9]; ptrWordOut[10] = ptrWordIn[10] ^ state[10]; ptrWordOut[11] = ptrWordIn[11] ^ state[11]; - - + + //Input: next column (i.e., next block in sequence) ptrWordIn += BLOCK_LEN_INT64; //Output: goes to previous column @@ -240,26 +243,26 @@ inline void reducedDuplexRow1(uint64_t *state, uint64_t *rowIn, uint64_t *rowOut } /** - * Performs a duplexing operation over "M[rowInOut][col] [+] M[rowIn][col]" (i.e., + * Performs a duplexing operation over "M[rowInOut][col] [+] M[rowIn][col]" (i.e., * the wordwise addition of two columns, ignoring carries between words). The - * output of this operation, "rand", is then used to make - * "M[rowOut][(N_COLS-1)-col] = M[rowIn][col] XOR rand" and - * "M[rowInOut][col] = M[rowInOut][col] XOR rotW(rand)", where rotW is a 64-bit + * output of this operation, "rand", is then used to make + * "M[rowOut][(N_COLS-1)-col] = M[rowIn][col] XOR rand" and + * "M[rowInOut][col] = M[rowInOut][col] XOR rotW(rand)", where rotW is a 64-bit * rotation to the left and N_COLS is a system parameter. * - * @param state The current state of the sponge + * @param state The current state of the sponge * @param rowIn Row used only as input * @param rowInOut Row used as input and to receive output after rotation * @param rowOut Row receiving the output * */ -inline void reducedDuplexRowSetup(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOut, uint64_t *rowOut) { +inline void reducedDuplexRowSetup(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOut, uint64_t *rowOut, uint64_t nCols) { uint64_t* ptrWordIn = rowIn; //In Lyra2: pointer to prev uint64_t* ptrWordInOut = rowInOut; //In Lyra2: pointer to row* - uint64_t* ptrWordOut = rowOut + (N_COLS-1)*BLOCK_LEN_INT64; //In Lyra2: pointer to row + uint64_t* ptrWordOut = rowOut + (nCols-1)*BLOCK_LEN_INT64; //In Lyra2: pointer to row int i; - for (i = 0; i < N_COLS; i++) { + for (i = 0; i < nCols; i++) { //Absorbing "M[prev] [+] M[row*]" state[0] ^= (ptrWordIn[0] + ptrWordInOut[0]); state[1] ^= (ptrWordIn[1] + ptrWordInOut[1]); @@ -290,7 +293,7 @@ inline void reducedDuplexRowSetup(uint64_t *state, uint64_t *rowIn, uint64_t *ro ptrWordOut[9] = ptrWordIn[9] ^ state[9]; ptrWordOut[10] = ptrWordIn[10] ^ state[10]; ptrWordOut[11] = ptrWordIn[11] ^ state[11]; - + //M[row*][col] = M[row*][col] XOR rotW(rand) ptrWordInOut[0] ^= state[11]; ptrWordInOut[1] ^= state[0]; @@ -314,26 +317,26 @@ inline void reducedDuplexRowSetup(uint64_t *state, uint64_t *rowIn, uint64_t *ro } /** - * Performs a duplexing operation over "M[rowInOut][col] [+] M[rowIn][col]" (i.e., + * Performs a duplexing operation over "M[rowInOut][col] [+] M[rowIn][col]" (i.e., * the wordwise addition of two columns, ignoring carries between words). The - * output of this operation, "rand", is then used to make - * "M[rowOut][col] = M[rowOut][col] XOR rand" and - * "M[rowInOut][col] = M[rowInOut][col] XOR rotW(rand)", where rotW is a 64-bit + * output of this operation, "rand", is then used to make + * "M[rowOut][col] = M[rowOut][col] XOR rand" and + * "M[rowInOut][col] = M[rowInOut][col] XOR rotW(rand)", where rotW is a 64-bit * rotation to the left. * - * @param state The current state of the sponge + * @param state The current state of the sponge * @param rowIn Row used only as input * @param rowInOut Row used as input and to receive output after rotation * @param rowOut Row receiving the output * */ -inline void reducedDuplexRow(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOut, uint64_t *rowOut) { +inline void reducedDuplexRow(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOut, uint64_t *rowOut, uint64_t nCols) { uint64_t* ptrWordInOut = rowInOut; //In Lyra2: pointer to row* uint64_t* ptrWordIn = rowIn; //In Lyra2: pointer to prev uint64_t* ptrWordOut = rowOut; //In Lyra2: pointer to row int i; - for (i = 0; i < N_COLS; i++) { + for (i = 0; i < nCols; i++) { //Absorbing "M[prev] [+] M[row*]" state[0] ^= (ptrWordIn[0] + ptrWordInOut[0]); @@ -392,10 +395,10 @@ inline void reducedDuplexRow(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOu /** * Performs a duplex operation over "M[rowInOut] [+] M[rowIn]", writing the output "rand" - * on M[rowOut] and making "M[rowInOut] = M[rowInOut] XOR rotW(rand)", where rotW is a 64-bit + * on M[rowOut] and making "M[rowInOut] = M[rowInOut] XOR rotW(rand)", where rotW is a 64-bit * rotation to the left. * - * @param state The current state of the sponge + * @param state The current state of the sponge * @param rowIn Row used only as input * @param rowInOut Row used as input and to receive output after rotation * @param rowOut Row receiving the output @@ -465,10 +468,10 @@ inline void reducedDuplexRowSetupOLD(uint64_t *state, uint64_t *rowIn, uint64_t /** * Performs a duplex operation over "M[rowInOut] XOR M[rowIn]", writing the output "rand" - * on M[rowOut] and making "M[rowInOut] = M[rowInOut] XOR rotW(rand)", where rotW is a 64-bit + * on M[rowOut] and making "M[rowInOut] = M[rowInOut] XOR rotW(rand)", where rotW is a 64-bit * rotation to the left. * - * @param state The current state of the sponge + * @param state The current state of the sponge * @param rowIn Row used only as input * @param rowInOut Row used as input and to receive output after rotation * @param rowOut Row receiving the output @@ -539,10 +542,10 @@ inline void reducedDuplexRowSetupv5(uint64_t *state, uint64_t *rowIn, uint64_t * /** * Performs a duplex operation over "M[rowInOut] XOR M[rowIn]", writing the output "rand" - * on M[rowOut] and making "M[rowInOut] = M[rowInOut] XOR rotW(rand)", where rotW is a 64-bit + * on M[rowOut] and making "M[rowInOut] = M[rowInOut] XOR rotW(rand)", where rotW is a 64-bit * rotation to the left. * - * @param state The current state of the sponge + * @param state The current state of the sponge * @param rowIn Row used only as input * @param rowInOut Row used as input and to receive output after rotation * @param rowOut Row receiving the output @@ -668,10 +671,10 @@ inline void reducedDuplexRowSetupv5c(uint64_t *state, uint64_t *rowIn, uint64_t /** * Performs a duplex operation over "M[rowInOut] XOR M[rowIn]", using the output "rand" - * to make "M[rowOut][col] = M[rowOut][col] XOR rand" and "M[rowInOut] = M[rowInOut] XOR rotW(rand)", + * to make "M[rowOut][col] = M[rowOut][col] XOR rand" and "M[rowInOut] = M[rowInOut] XOR rotW(rand)", * where rotW is a 64-bit rotation to the left. * - * @param state The current state of the sponge + * @param state The current state of the sponge * @param rowIn Row used only as input * @param rowInOut Row used as input and to receive output after rotation * @param rowOut Row receiving the output @@ -717,7 +720,7 @@ inline void reducedDuplexRowd(uint64_t *state, uint64_t *rowIn, uint64_t *rowInO ptrWordOut[11] ^= state[11]; //M[rowInOut][col] = M[rowInOut][col] XOR rotW(rand) - + //Goes to next block ptrWordOut += BLOCK_LEN_INT64; diff --git a/algorithm/Sponge.h b/algorithm/Sponge.h index 3fcff0d7e..4ea1dc939 100644 --- a/algorithm/Sponge.h +++ b/algorithm/Sponge.h @@ -1,10 +1,10 @@ /** - * Header file for Blake2b's internal permutation in the form of a sponge. - * This code is based on the original Blake2b's implementation provided by + * Header file for Blake2b's internal permutation in the form of a sponge. + * This code is based on the original Blake2b's implementation provided by * Samuel Neves (https://blake2.net/) - * + * * 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 @@ -78,16 +78,16 @@ void initState(uint64_t state[/*16*/]); //---- Squeezes void squeeze(uint64_t *state, unsigned char *out, unsigned int len); -void reducedSqueezeRow0(uint64_t* state, uint64_t* row); +void reducedSqueezeRow0(uint64_t* state, uint64_t* row, uint64_t nCols); //---- Absorbs void absorbBlock(uint64_t *state, const uint64_t *in); void absorbBlockBlake2Safe(uint64_t *state, const uint64_t *in); //---- Duplexes -void reducedDuplexRow1(uint64_t *state, uint64_t *rowIn, uint64_t *rowOut); -void reducedDuplexRowSetup(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOut, uint64_t *rowOut); -void reducedDuplexRow(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOut, uint64_t *rowOut); +void reducedDuplexRow1(uint64_t *state, uint64_t *rowIn, uint64_t *rowOut, uint64_t nCols); +void reducedDuplexRowSetup(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOut, uint64_t *rowOut, uint64_t nCols); +void reducedDuplexRow(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOut, uint64_t *rowOut, uint64_t nCols); //---- Misc void printArray(unsigned char *array, unsigned int size, char *name); diff --git a/algorithm/Sponge_old.c b/algorithm/Sponge_old.c new file mode 100644 index 000000000..aa6c3017a --- /dev/null +++ b/algorithm/Sponge_old.c @@ -0,0 +1,405 @@ +/** + * A simple implementation of Blake2b's internal permutation + * in the form of a sponge. + * + * 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. + */ +#include +#include +#include +#include "Sponge_old.h" +#include "Lyra2_old.h" + + + +/** + * Initializes the Sponge State. The first 512 bits are set to zeros and the remainder + * receive Blake2b's IV as per Blake2b's specification. Note: Even though sponges + * typically have their internal state initialized with zeros, Blake2b's G function + * has a fixed point: if the internal state and message are both filled with zeros. the + * resulting permutation will always be a block filled with zeros; this happens because + * Blake2b does not use the constants originally employed in Blake2 inside its G function, + * relying on the IV for avoiding possible fixed points. + * + * @param state The 1024-bit array to be initialized + */ +inline void initStateO(uint64_t state[/*16*/]) { + //First 512 bis are zeros + memset(state, 0, 64); + //Remainder BLOCK_LEN_BLAKE2_SAFE_BYTES are reserved to the IV + state[8] = blake2b_IV[0]; + state[9] = blake2b_IV[1]; + state[10] = blake2b_IV[2]; + state[11] = blake2b_IV[3]; + state[12] = blake2b_IV[4]; + state[13] = blake2b_IV[5]; + state[14] = blake2b_IV[6]; + state[15] = blake2b_IV[7]; +} + +/** + * Execute Blake2b's G function, with all 12 rounds. + * + * @param v A 1024-bit (16 uint64_t) array to be processed by Blake2b's G function + */ +inline static void blake2bLyra(uint64_t *v) { + ROUND_LYRA(0); + ROUND_LYRA(1); + ROUND_LYRA(2); + ROUND_LYRA(3); + ROUND_LYRA(4); + ROUND_LYRA(5); + ROUND_LYRA(6); + ROUND_LYRA(7); + ROUND_LYRA(8); + ROUND_LYRA(9); + ROUND_LYRA(10); + ROUND_LYRA(11); +} + +/** + * Executes a reduced version of Blake2b's G function with only one round + * @param v A 1024-bit (16 uint64_t) array to be processed by Blake2b's G function + */ +inline static void reducedBlake2bLyra(uint64_t *v) { + ROUND_LYRA(0); +} + +/** + * Performs a squeeze operation, using Blake2b's G function as the + * internal permutation + * + * @param state The current state of the sponge + * @param out Array that will receive the data squeezed + * @param len The number of bytes to be squeezed into the "out" array + */ +inline void squeezeO(uint64_t *state, byte *out, unsigned int len) { + int fullBlocks = len / BLOCK_LEN_BYTES; + byte *ptr = out; + int i; + //Squeezes full blocks + for (i = 0; i < fullBlocks; i++) { + memcpy(ptr, state, BLOCK_LEN_BYTES); + blake2bLyra(state); + ptr += BLOCK_LEN_BYTES; + } + + //Squeezes remaining bytes + memcpy(ptr, state, (len % BLOCK_LEN_BYTES)); +} + +/** + * Performs an absorb operation for a single block (BLOCK_LEN_INT64 words + * of type uint64_t), using Blake2b's G function as the internal permutation + * + * @param state The current state of the sponge + * @param in The block to be absorbed (BLOCK_LEN_INT64 words) + */ +inline void absorbBlockO(uint64_t *state, const uint64_t *in) { + //XORs the first BLOCK_LEN_INT64 words of "in" with the current state + state[0] ^= in[0]; + state[1] ^= in[1]; + state[2] ^= in[2]; + state[3] ^= in[3]; + state[4] ^= in[4]; + state[5] ^= in[5]; + state[6] ^= in[6]; + state[7] ^= in[7]; + state[8] ^= in[8]; + state[9] ^= in[9]; + state[10] ^= in[10]; + state[11] ^= in[11]; + + //Applies the transformation f to the sponge's state + blake2bLyra(state); +} + +/** + * Performs an absorb operation for a single block (BLOCK_LEN_BLAKE2_SAFE_INT64 + * words of type uint64_t), using Blake2b's G function as the internal permutation + * + * @param state The current state of the sponge + * @param in The block to be absorbed (BLOCK_LEN_BLAKE2_SAFE_INT64 words) + */ +inline void absorbBlockBlake2SafeO(uint64_t *state, const uint64_t *in) { + //XORs the first BLOCK_LEN_BLAKE2_SAFE_INT64 words of "in" with the current state + state[0] ^= in[0]; + state[1] ^= in[1]; + state[2] ^= in[2]; + state[3] ^= in[3]; + state[4] ^= in[4]; + state[5] ^= in[5]; + state[6] ^= in[6]; + state[7] ^= in[7]; + + //Applies the transformation f to the sponge's state + blake2bLyra(state); +} + +/** + * Performs a reduced squeeze operation for a single row, from the highest to + * the lowest index, using the reduced-round Blake2b's G function as the + * internal permutation + * + * @param state The current state of the sponge + * @param rowOut Row to receive the data squeezed + */ +inline void reducedSqueezeRow0O(uint64_t* state, uint64_t* rowOut) { + uint64_t* ptrWord = rowOut + (N_COLS-1)*BLOCK_LEN_INT64; //In Lyra2: pointer to M[0][C-1] + int i; + //M[row][C-1-col] = H.reduced_squeeze() + for (i = 0; i < N_COLS; i++) { + ptrWord[0] = state[0]; + ptrWord[1] = state[1]; + ptrWord[2] = state[2]; + ptrWord[3] = state[3]; + ptrWord[4] = state[4]; + ptrWord[5] = state[5]; + ptrWord[6] = state[6]; + ptrWord[7] = state[7]; + ptrWord[8] = state[8]; + ptrWord[9] = state[9]; + ptrWord[10] = state[10]; + ptrWord[11] = state[11]; + + //Goes to next block (column) that will receive the squeezed data + ptrWord -= BLOCK_LEN_INT64; + + //Applies the reduced-round transformation f to the sponge's state + reducedBlake2bLyra(state); + } +} + +/** + * Performs a reduced duplex operation for a single row, from the highest to + * the lowest index, using the reduced-round Blake2b's G function as the + * internal permutation + * + * @param state The current state of the sponge + * @param rowIn Row to feed the sponge + * @param rowOut Row to receive the sponge's output + */ +inline void reducedDuplexRow1O(uint64_t *state, uint64_t *rowIn, uint64_t *rowOut) { + uint64_t* ptrWordIn = rowIn; //In Lyra2: pointer to prev + uint64_t* ptrWordOut = rowOut + (N_COLS-1)*BLOCK_LEN_INT64; //In Lyra2: pointer to row + int i; + + for (i = 0; i < N_COLS; i++) { + + //Absorbing "M[prev][col]" + state[0] ^= (ptrWordIn[0]); + state[1] ^= (ptrWordIn[1]); + state[2] ^= (ptrWordIn[2]); + state[3] ^= (ptrWordIn[3]); + state[4] ^= (ptrWordIn[4]); + state[5] ^= (ptrWordIn[5]); + state[6] ^= (ptrWordIn[6]); + state[7] ^= (ptrWordIn[7]); + state[8] ^= (ptrWordIn[8]); + state[9] ^= (ptrWordIn[9]); + state[10] ^= (ptrWordIn[10]); + state[11] ^= (ptrWordIn[11]); + + //Applies the reduced-round transformation f to the sponge's state + reducedBlake2bLyra(state); + + //M[row][C-1-col] = M[prev][col] XOR rand + ptrWordOut[0] = ptrWordIn[0] ^ state[0]; + ptrWordOut[1] = ptrWordIn[1] ^ state[1]; + ptrWordOut[2] = ptrWordIn[2] ^ state[2]; + ptrWordOut[3] = ptrWordIn[3] ^ state[3]; + ptrWordOut[4] = ptrWordIn[4] ^ state[4]; + ptrWordOut[5] = ptrWordIn[5] ^ state[5]; + ptrWordOut[6] = ptrWordIn[6] ^ state[6]; + ptrWordOut[7] = ptrWordIn[7] ^ state[7]; + ptrWordOut[8] = ptrWordIn[8] ^ state[8]; + ptrWordOut[9] = ptrWordIn[9] ^ state[9]; + ptrWordOut[10] = ptrWordIn[10] ^ state[10]; + ptrWordOut[11] = ptrWordIn[11] ^ state[11]; + + + //Input: next column (i.e., next block in sequence) + ptrWordIn += BLOCK_LEN_INT64; + //Output: goes to previous column + ptrWordOut -= BLOCK_LEN_INT64; + } +} + +/** + * Performs a duplexing operation over "M[rowInOut][col] [+] M[rowIn][col]" (i.e., + * the wordwise addition of two columns, ignoring carries between words). The + * output of this operation, "rand", is then used to make + * "M[rowOut][(N_COLS-1)-col] = M[rowIn][col] XOR rand" and + * "M[rowInOut][col] = M[rowInOut][col] XOR rotW(rand)", where rotW is a 64-bit + * rotation to the left and N_COLS is a system parameter. + * + * @param state The current state of the sponge + * @param rowIn Row used only as input + * @param rowInOut Row used as input and to receive output after rotation + * @param rowOut Row receiving the output + * + */ +inline void reducedDuplexRowSetupO(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOut, uint64_t *rowOut) { + uint64_t* ptrWordIn = rowIn; //In Lyra2: pointer to prev + uint64_t* ptrWordInOut = rowInOut; //In Lyra2: pointer to row* + uint64_t* ptrWordOut = rowOut + (N_COLS-1)*BLOCK_LEN_INT64; //In Lyra2: pointer to row + int i; + + for (i = 0; i < N_COLS; i++) { + //Absorbing "M[prev] [+] M[row*]" + state[0] ^= (ptrWordIn[0] + ptrWordInOut[0]); + state[1] ^= (ptrWordIn[1] + ptrWordInOut[1]); + state[2] ^= (ptrWordIn[2] + ptrWordInOut[2]); + state[3] ^= (ptrWordIn[3] + ptrWordInOut[3]); + state[4] ^= (ptrWordIn[4] + ptrWordInOut[4]); + state[5] ^= (ptrWordIn[5] + ptrWordInOut[5]); + state[6] ^= (ptrWordIn[6] + ptrWordInOut[6]); + state[7] ^= (ptrWordIn[7] + ptrWordInOut[7]); + state[8] ^= (ptrWordIn[8] + ptrWordInOut[8]); + state[9] ^= (ptrWordIn[9] + ptrWordInOut[9]); + state[10] ^= (ptrWordIn[10] + ptrWordInOut[10]); + state[11] ^= (ptrWordIn[11] + ptrWordInOut[11]); + + //Applies the reduced-round transformation f to the sponge's state + reducedBlake2bLyra(state); + + //M[row][col] = M[prev][col] XOR rand + ptrWordOut[0] = ptrWordIn[0] ^ state[0]; + ptrWordOut[1] = ptrWordIn[1] ^ state[1]; + ptrWordOut[2] = ptrWordIn[2] ^ state[2]; + ptrWordOut[3] = ptrWordIn[3] ^ state[3]; + ptrWordOut[4] = ptrWordIn[4] ^ state[4]; + ptrWordOut[5] = ptrWordIn[5] ^ state[5]; + ptrWordOut[6] = ptrWordIn[6] ^ state[6]; + ptrWordOut[7] = ptrWordIn[7] ^ state[7]; + ptrWordOut[8] = ptrWordIn[8] ^ state[8]; + ptrWordOut[9] = ptrWordIn[9] ^ state[9]; + ptrWordOut[10] = ptrWordIn[10] ^ state[10]; + ptrWordOut[11] = ptrWordIn[11] ^ state[11]; + + //M[row*][col] = M[row*][col] XOR rotW(rand) + ptrWordInOut[0] ^= state[11]; + ptrWordInOut[1] ^= state[0]; + ptrWordInOut[2] ^= state[1]; + ptrWordInOut[3] ^= state[2]; + ptrWordInOut[4] ^= state[3]; + ptrWordInOut[5] ^= state[4]; + ptrWordInOut[6] ^= state[5]; + ptrWordInOut[7] ^= state[6]; + ptrWordInOut[8] ^= state[7]; + ptrWordInOut[9] ^= state[8]; + ptrWordInOut[10] ^= state[9]; + ptrWordInOut[11] ^= state[10]; + + //Inputs: next column (i.e., next block in sequence) + ptrWordInOut += BLOCK_LEN_INT64; + ptrWordIn += BLOCK_LEN_INT64; + //Output: goes to previous column + ptrWordOut -= BLOCK_LEN_INT64; + } +} + +/** + * Performs a duplexing operation over "M[rowInOut][col] [+] M[rowIn][col]" (i.e., + * the wordwise addition of two columns, ignoring carries between words). The + * output of this operation, "rand", is then used to make + * "M[rowOut][col] = M[rowOut][col] XOR rand" and + * "M[rowInOut][col] = M[rowInOut][col] XOR rotW(rand)", where rotW is a 64-bit + * rotation to the left. + * + * @param state The current state of the sponge + * @param rowIn Row used only as input + * @param rowInOut Row used as input and to receive output after rotation + * @param rowOut Row receiving the output + * + */ +inline void reducedDuplexRowO(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOut, uint64_t *rowOut) { + uint64_t* ptrWordInOut = rowInOut; //In Lyra2: pointer to row* + uint64_t* ptrWordIn = rowIn; //In Lyra2: pointer to prev + uint64_t* ptrWordOut = rowOut; //In Lyra2: pointer to row + int i; + + for (i = 0; i < N_COLS; i++) { + + //Absorbing "M[prev] [+] M[row*]" + state[0] ^= (ptrWordIn[0] + ptrWordInOut[0]); + state[1] ^= (ptrWordIn[1] + ptrWordInOut[1]); + state[2] ^= (ptrWordIn[2] + ptrWordInOut[2]); + state[3] ^= (ptrWordIn[3] + ptrWordInOut[3]); + state[4] ^= (ptrWordIn[4] + ptrWordInOut[4]); + state[5] ^= (ptrWordIn[5] + ptrWordInOut[5]); + state[6] ^= (ptrWordIn[6] + ptrWordInOut[6]); + state[7] ^= (ptrWordIn[7] + ptrWordInOut[7]); + state[8] ^= (ptrWordIn[8] + ptrWordInOut[8]); + state[9] ^= (ptrWordIn[9] + ptrWordInOut[9]); + state[10] ^= (ptrWordIn[10] + ptrWordInOut[10]); + state[11] ^= (ptrWordIn[11] + ptrWordInOut[11]); + + //Applies the reduced-round transformation f to the sponge's state + reducedBlake2bLyra(state); + + //M[rowOut][col] = M[rowOut][col] XOR rand + ptrWordOut[0] ^= state[0]; + ptrWordOut[1] ^= state[1]; + ptrWordOut[2] ^= state[2]; + ptrWordOut[3] ^= state[3]; + ptrWordOut[4] ^= state[4]; + ptrWordOut[5] ^= state[5]; + ptrWordOut[6] ^= state[6]; + ptrWordOut[7] ^= state[7]; + ptrWordOut[8] ^= state[8]; + ptrWordOut[9] ^= state[9]; + ptrWordOut[10] ^= state[10]; + ptrWordOut[11] ^= state[11]; + + //M[rowInOut][col] = M[rowInOut][col] XOR rotW(rand) + ptrWordInOut[0] ^= state[11]; + ptrWordInOut[1] ^= state[0]; + ptrWordInOut[2] ^= state[1]; + ptrWordInOut[3] ^= state[2]; + ptrWordInOut[4] ^= state[3]; + ptrWordInOut[5] ^= state[4]; + ptrWordInOut[6] ^= state[5]; + ptrWordInOut[7] ^= state[6]; + ptrWordInOut[8] ^= state[7]; + ptrWordInOut[9] ^= state[8]; + ptrWordInOut[10] ^= state[9]; + ptrWordInOut[11] ^= state[10]; + + //Goes to next block + ptrWordOut += BLOCK_LEN_INT64; + ptrWordInOut += BLOCK_LEN_INT64; + ptrWordIn += BLOCK_LEN_INT64; + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + Prints an array of unsigned chars + */ +void printArrayO(unsigned char *array, unsigned int size, char *name) { + int i; + printf("%s: ", name); + for (i = 0; i < size; i++) { + printf("%2x|", array[i]); + } + printf("\n"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/algorithm/Sponge_old.h b/algorithm/Sponge_old.h new file mode 100644 index 000000000..f8b7de250 --- /dev/null +++ b/algorithm/Sponge_old.h @@ -0,0 +1,98 @@ +/** + * Header file for Blake2b's internal permutation in the form of a sponge. + * This code is based on the original Blake2b's implementation provided by + * Samuel Neves (https://blake2.net/) + * + * 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 SPONGEOLD_H_ +#define SPONGEOLD_H_ + +#include + +#if defined(__GNUC__) +#define ALIGN __attribute__ ((aligned(32))) +#elif defined(_MSC_VER) +#define ALIGN __declspec(align(32)) +#else +#define ALIGN +#endif + + +/*Blake2b IV Array*/ +static const uint64_t blake2b_IV[8] = +{ + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, + 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, + 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL +}; + +/*Blake2b's rotation*/ +static inline uint64_t rotr64( const uint64_t w, const unsigned c ){ + return ( w >> c ) | ( w << ( 64 - c ) ); +} + +/*Blake2b's G function*/ +#define G(r,i,a,b,c,d) \ + do { \ + a = a + b; \ + d = rotr64(d ^ a, 32); \ + c = c + d; \ + b = rotr64(b ^ c, 24); \ + a = a + b; \ + d = rotr64(d ^ a, 16); \ + c = c + d; \ + b = rotr64(b ^ c, 63); \ + } while(0) + + +/*One Round of the Blake2b's compression function*/ +#define ROUND_LYRA(r) \ + 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]); + + +//---- Housekeeping +void initStateO(uint64_t state[/*16*/]); + +//---- Squeezes +void squeezeO(uint64_t *state, unsigned char *out, unsigned int len); +void reducedSqueezeRow0O(uint64_t* state, uint64_t* row); + +//---- Absorbs +void absorbBlockO(uint64_t *state, const uint64_t *in); +void absorbBlockBlake2Safe(uint64_t *state, const uint64_t *in); + +//---- Duplexes +void reducedDuplexRow1O(uint64_t *state, uint64_t *rowIn, uint64_t *rowOut); +void reducedDuplexRowSetupO(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOut, uint64_t *rowOut); +void reducedDuplexRowO(uint64_t *state, uint64_t *rowIn, uint64_t *rowInOut, uint64_t *rowOut); + +//---- Misc +void printArrayO(unsigned char *array, unsigned int size, char *name); + +//////////////////////////////////////////////////////////////////////////////////////////////// + + +#endif /* SPONGE_H_ */ diff --git a/driver-opencl.c b/driver-opencl.c index f8e686176..5b01fc963 100644 --- a/driver-opencl.c +++ b/driver-opencl.c @@ -258,14 +258,14 @@ char *set_gpu_threads(const char *_arg) if (nextptr == NULL) return "Invalid parameters for set_gpu_threads"; val = atoi(nextptr); - if (val < 1 || val > 10) + if (val < 1 || val > 20) // gpu_threads increase max value to 20 return "Invalid value passed to set_gpu_threads"; gpus[device++].threads = val; while ((nextptr = strtok(NULL, ",")) != NULL) { val = atoi(nextptr); - if (val < 1 || val > 10) + if (val < 1 || val > 20) // gpu_threads increase max value to 20 return "Invalid value passed to set_gpu_threads"; gpus[device++].threads = val; diff --git a/kernel/Lyra2REv2.cl b/kernel/Lyra2REv2.cl new file mode 100644 index 000000000..c1adbc371 --- /dev/null +++ b/kernel/Lyra2REv2.cl @@ -0,0 +1,525 @@ +/* + * Lyra2RE kernel implementation. + * + * ==========================(LICENSE BEGIN)============================ + * Copyright (c) 2014 djm34 + * Copyright (c) 2014 James Lovejoy + * + * 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 djm34 + */ +// typedef unsigned int uint; +#pragma OPENCL EXTENSION cl_amd_printf : enable + +#ifndef LYRA2RE_CL +#define LYRA2RE_CL + +#if __ENDIAN_LITTLE__ +#define SPH_LITTLE_ENDIAN 1 +#else +#define SPH_BIG_ENDIAN 1 +#endif + +#define SPH_UPTR sph_u64 + +typedef unsigned int sph_u32; +typedef int sph_s32; +#ifndef __OPENCL_VERSION__ +typedef unsigned long sph_u64; +typedef long sph_s64; +#else +typedef unsigned long sph_u64; +typedef long sph_s64; +#endif + + +#define SPH_64 1 +#define SPH_64_TRUE 1 + +#define SPH_C32(x) ((sph_u32)(x ## U)) +#define SPH_T32(x) ((x) & SPH_C32(0xFFFFFFFF)) + +#define SPH_C64(x) ((sph_u64)(x ## UL)) +#define SPH_T64(x) ((x) & SPH_C64(0xFFFFFFFFFFFFFFFF)) + +//#define SPH_ROTL32(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) +//#define SPH_ROTR32(x, n) (((x) >> (n)) | ((x) << (32 - (n)))) +//#define SPH_ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n)))) +//#define SPH_ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n)))) + +#define SPH_ROTL32(x,n) rotate(x,(uint)n) //faster with driver 14.6 +#define SPH_ROTR32(x,n) rotate(x,(uint)(32-n)) +#define SPH_ROTL64(x,n) rotate(x,(ulong)n) +#define SPH_ROTR64(x,n) rotate(x,(ulong)(64-n)) +static inline sph_u64 ror64(sph_u64 vw, unsigned a) { + uint2 result; + uint2 v = as_uint2(vw); + unsigned n = (unsigned)(64 - a); + if (n == 32) { return as_ulong((uint2)(v.y, v.x)); } + if (n < 32) { + result.y = ((v.y << (n)) | (v.x >> (32 - n))); + result.x = ((v.x << (n)) | (v.y >> (32 - n))); + } + else { + result.y = ((v.x << (n - 32)) | (v.y >> (64 - n))); + result.x = ((v.y << (n - 32)) | (v.x >> (64 - n))); + } + return as_ulong(result); +} + +//#define SPH_ROTR64(l,n) ror64(l,n) +#define memshift 3 +#include "blake256.cl" +#include "Lyra2v2.cl" +#include "keccak1600.cl" +#include "skein256.cl" +#include "cubehash.cl" +#include "bmw256.cl" + +#define SWAP4(x) as_uint(as_uchar4(x).wzyx) +#define SWAP8(x) as_ulong(as_uchar8(x).s76543210) +//#define SWAP8(x) as_ulong(as_uchar8(x).s32107654) +#if SPH_BIG_ENDIAN + #define DEC64E(x) (x) + #define DEC64BE(x) (*(const __global sph_u64 *) (x)); + #define DEC64LE(x) SWAP8(*(const __global sph_u64 *) (x)); + #define DEC32LE(x) (*(const __global sph_u32 *) (x)); +#else + #define DEC64E(x) SWAP8(x) + #define DEC64BE(x) SWAP8(*(const __global sph_u64 *) (x)); + #define DEC64LE(x) (*(const __global sph_u64 *) (x)); +#define DEC32LE(x) SWAP4(*(const __global sph_u32 *) (x)); +#endif + +typedef union { + unsigned char h1[32]; + uint h4[8]; + ulong h8[4]; +} hash_t; + +__attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) +__kernel void search( + __global uchar* hashes, + // precalc hash from fisrt part of message + const uint h0, + const uint h1, + const uint h2, + const uint h3, + const uint h4, + const uint h5, + const uint h6, + const uint h7, + // last 12 bytes of original message + const uint in16, + const uint in17, + const uint in18 +) +{ + uint gid = get_global_id(0); + __global hash_t *hash = (__global hash_t *)(hashes + (4 * sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))); + + +// __global hash_t *hash = &(hashes[gid-get_global_offset(0)]); + + unsigned int h[8]; + unsigned int m[16]; + unsigned int v[16]; + + +h[0]=h0; +h[1]=h1; +h[2]=h2; +h[3]=h3; +h[4]=h4; +h[5]=h5; +h[6]=h6; +h[7]=h7; +// compress 2nd round + m[0] = in16; + m[1] = in17; + m[2] = in18; + m[3] = SWAP4(gid); + + for (int i = 4; i < 16; i++) {m[i] = c_Padding[i];} + + for (int i = 0; i < 8; i++) {v[i] = h[i];} + + v[8] = c_u256[0]; + v[9] = c_u256[1]; + v[10] = c_u256[2]; + v[11] = c_u256[3]; + v[12] = c_u256[4] ^ 640; + v[13] = c_u256[5] ^ 640; + v[14] = c_u256[6]; + v[15] = c_u256[7]; + + for (int r = 0; r < 14; r++) { + GS(0, 4, 0x8, 0xC, 0x0); + GS(1, 5, 0x9, 0xD, 0x2); + GS(2, 6, 0xA, 0xE, 0x4); + GS(3, 7, 0xB, 0xF, 0x6); + GS(0, 5, 0xA, 0xF, 0x8); + GS(1, 6, 0xB, 0xC, 0xA); + GS(2, 7, 0x8, 0xD, 0xC); + GS(3, 4, 0x9, 0xE, 0xE); + } + + for (int i = 0; i < 16; i++) { + int j = i & 7; + h[j] ^= v[i];} + +for (int i=0;i<8;i++) {hash->h4[i]=SWAP4(h[i]);} + +barrier(CLK_LOCAL_MEM_FENCE); + +} + +// keccak256 + + +__attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) +__kernel void search1(__global uchar* hashes) +{ + uint gid = get_global_id(0); + // __global hash_t *hash = &(hashes[gid-get_global_offset(0)]); + + __global hash_t *hash = (__global hash_t *)(hashes + (4 * sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))); + + sph_u64 keccak_gpu_state[25]; + + for (int i = 0; i<25; i++) { + if (i<4) { keccak_gpu_state[i] = hash->h8[i]; } + else { keccak_gpu_state[i] = 0; } + } + keccak_gpu_state[4] = 0x0000000000000001; + keccak_gpu_state[16] = 0x8000000000000000; + + keccak_block(keccak_gpu_state); + for (int i = 0; i<4; i++) { hash->h8[i] = keccak_gpu_state[i]; } +barrier(CLK_LOCAL_MEM_FENCE); + + + +} + +// cubehash256 + +__attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) +__kernel void search2(__global uchar* hashes) +{ + uint gid = get_global_id(0); + __global hash_t *hash = (__global hash_t *)(hashes + (4 * sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))); + + + sph_u32 x0 = 0xEA2BD4B4; sph_u32 x1 = 0xCCD6F29F; sph_u32 x2 = 0x63117E71; + sph_u32 x3 = 0x35481EAE; sph_u32 x4 = 0x22512D5B; sph_u32 x5 = 0xE5D94E63; + sph_u32 x6 = 0x7E624131; sph_u32 x7 = 0xF4CC12BE; sph_u32 x8 = 0xC2D0B696; + sph_u32 x9 = 0x42AF2070; sph_u32 xa = 0xD0720C35; sph_u32 xb = 0x3361DA8C; + sph_u32 xc = 0x28CCECA4; sph_u32 xd = 0x8EF8AD83; sph_u32 xe = 0x4680AC00; + sph_u32 xf = 0x40E5FBAB; + + sph_u32 xg = 0xD89041C3; sph_u32 xh = 0x6107FBD5; + sph_u32 xi = 0x6C859D41; sph_u32 xj = 0xF0B26679; sph_u32 xk = 0x09392549; + sph_u32 xl = 0x5FA25603; sph_u32 xm = 0x65C892FD; sph_u32 xn = 0x93CB6285; + sph_u32 xo = 0x2AF2B5AE; sph_u32 xp = 0x9E4B4E60; sph_u32 xq = 0x774ABFDD; + sph_u32 xr = 0x85254725; sph_u32 xs = 0x15815AEB; sph_u32 xt = 0x4AB6AAD6; + sph_u32 xu = 0x9CDAF8AF; sph_u32 xv = 0xD6032C0A; + + x0 ^= (hash->h4[0]); + x1 ^= (hash->h4[1]); + x2 ^= (hash->h4[2]); + x3 ^= (hash->h4[3]); + x4 ^= (hash->h4[4]); + x5 ^= (hash->h4[5]); + x6 ^= (hash->h4[6]); + x7 ^= (hash->h4[7]); + + + SIXTEEN_ROUNDS; + x0 ^= 0x80; + SIXTEEN_ROUNDS; + xv ^= 0x01; + for (int i = 0; i < 10; ++i) SIXTEEN_ROUNDS; + + hash->h4[0] = x0; + hash->h4[1] = x1; + hash->h4[2] = x2; + hash->h4[3] = x3; + hash->h4[4] = x4; + hash->h4[5] = x5; + hash->h4[6] = x6; + hash->h4[7] = x7; + + + barrier(CLK_GLOBAL_MEM_FENCE); + +} + + +/// lyra2 algo + + +__attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) +__kernel void search3(__global uchar* hashes,__global uchar* matrix ) +{ + uint gid = get_global_id(0); + // __global hash_t *hash = &(hashes[gid-get_global_offset(0)]); + __global hash_t *hash = (__global hash_t *)(hashes + (4 * sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))); + __global ulong4 *DMatrix = (__global ulong4 *)(matrix + (4 * memshift * 4 * 4 * sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))); + +// uint offset = (4 * memshift * 4 * 4 * sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))/32; + ulong4 state[4]; + + state[0].x = hash->h8[0]; //password + state[0].y = hash->h8[1]; //password + state[0].z = hash->h8[2]; //password + state[0].w = hash->h8[3]; //password + state[1] = state[0]; + state[2] = (ulong4)(0x6a09e667f3bcc908UL, 0xbb67ae8584caa73bUL, 0x3c6ef372fe94f82bUL, 0xa54ff53a5f1d36f1UL); + state[3] = (ulong4)(0x510e527fade682d1UL, 0x9b05688c2b3e6c1fUL, 0x1f83d9abfb41bd6bUL, 0x5be0cd19137e2179UL); + for (int i = 0; i<12; i++) { round_lyra(state); } + + state[0] ^= (ulong4)(0x20,0x20,0x20,0x01); + state[1] ^= (ulong4)(0x04,0x04,0x80,0x0100000000000000); + + for (int i = 0; i<12; i++) { round_lyra(state); } + + + uint ps1 = (memshift * 3); +//#pragma unroll 4 + for (int i = 0; i < 4; i++) + { + uint s1 = ps1 - memshift * i; + for (int j = 0; j < 3; j++) + (DMatrix)[j+s1] = state[j]; + + round_lyra(state); + } + + reduceDuplexf(state,DMatrix); + + reduceDuplexRowSetupf(1, 0, 2,state, DMatrix); + reduceDuplexRowSetupf(2, 1, 3, state,DMatrix); + + + uint rowa; + uint prev = 3; + for (uint i = 0; i<4; i++) { + rowa = state[0].x & 3; + reduceDuplexRowf(prev, rowa, i, state, DMatrix); + prev = i; + } + + + + uint shift = (memshift * 4 * rowa); + + for (int j = 0; j < 3; j++) + state[j] ^= (DMatrix)[j+shift]; + + for (int i = 0; i < 12; i++) + round_lyra(state); +////////////////////////////////////// + + + for (int i = 0; i<4; i++) {hash->h8[i] = ((ulong*)state)[i];} +barrier(CLK_LOCAL_MEM_FENCE); + + + +} + +//skein256 + +__attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) +__kernel void search4(__global uchar* hashes) +{ + uint gid = get_global_id(0); + // __global hash_t *hash = &(hashes[gid-get_global_offset(0)]); + __global hash_t *hash = (__global hash_t *)(hashes + (4 * sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))); + + + sph_u64 h[9]; + sph_u64 t[3]; + sph_u64 dt0,dt1,dt2,dt3; + sph_u64 p0, p1, p2, p3, p4, p5, p6, p7; + h[8] = skein_ks_parity; + + for (int i = 0; i<8; i++) { + h[i] = SKEIN_IV512_256[i]; + h[8] ^= h[i];} + + t[0]=t12[0]; + t[1]=t12[1]; + t[2]=t12[2]; + + dt0=hash->h8[0]; + dt1=hash->h8[1]; + dt2=hash->h8[2]; + dt3=hash->h8[3]; + + p0 = h[0] + dt0; + p1 = h[1] + dt1; + p2 = h[2] + dt2; + p3 = h[3] + dt3; + p4 = h[4]; + p5 = h[5] + t[0]; + p6 = h[6] + t[1]; + p7 = h[7]; + + #pragma unroll + for (int i = 1; i<19; i+=2) {Round_8_512(p0,p1,p2,p3,p4,p5,p6,p7,i);} + p0 ^= dt0; + p1 ^= dt1; + p2 ^= dt2; + p3 ^= dt3; + + h[0] = p0; + h[1] = p1; + h[2] = p2; + h[3] = p3; + h[4] = p4; + h[5] = p5; + h[6] = p6; + h[7] = p7; + h[8] = skein_ks_parity; + + for (int i = 0; i<8; i++) { h[8] ^= h[i]; } + + t[0] = t12[3]; + t[1] = t12[4]; + t[2] = t12[5]; + p5 += t[0]; //p5 already equal h[5] + p6 += t[1]; + + #pragma unroll + for (int i = 1; i<19; i+=2) { Round_8_512(p0, p1, p2, p3, p4, p5, p6, p7, i); } + + hash->h8[0] = p0; + hash->h8[1] = p1; + hash->h8[2] = p2; + hash->h8[3] = p3; + barrier(CLK_LOCAL_MEM_FENCE); + +} + +//cubehash + +__attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) +__kernel void search5(__global uchar* hashes) +{ + uint gid = get_global_id(0); + __global hash_t *hash = (__global hash_t *)(hashes + (4 * sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))); + + sph_u32 x0 = 0xEA2BD4B4; sph_u32 x1 = 0xCCD6F29F; sph_u32 x2 = 0x63117E71; + sph_u32 x3 = 0x35481EAE; sph_u32 x4 = 0x22512D5B; sph_u32 x5 = 0xE5D94E63; + sph_u32 x6 = 0x7E624131; sph_u32 x7 = 0xF4CC12BE; sph_u32 x8 = 0xC2D0B696; + sph_u32 x9 = 0x42AF2070; sph_u32 xa = 0xD0720C35; sph_u32 xb = 0x3361DA8C; + sph_u32 xc = 0x28CCECA4; sph_u32 xd = 0x8EF8AD83; sph_u32 xe = 0x4680AC00; + sph_u32 xf = 0x40E5FBAB; + + sph_u32 xg = 0xD89041C3; sph_u32 xh = 0x6107FBD5; + sph_u32 xi = 0x6C859D41; sph_u32 xj = 0xF0B26679; sph_u32 xk = 0x09392549; + sph_u32 xl = 0x5FA25603; sph_u32 xm = 0x65C892FD; sph_u32 xn = 0x93CB6285; + sph_u32 xo = 0x2AF2B5AE; sph_u32 xp = 0x9E4B4E60; sph_u32 xq = 0x774ABFDD; + sph_u32 xr = 0x85254725; sph_u32 xs = 0x15815AEB; sph_u32 xt = 0x4AB6AAD6; + sph_u32 xu = 0x9CDAF8AF; sph_u32 xv = 0xD6032C0A; + + x0 ^= (hash->h4[0]); + x1 ^= (hash->h4[1]); + x2 ^= (hash->h4[2]); + x3 ^= (hash->h4[3]); + x4 ^= (hash->h4[4]); + x5 ^= (hash->h4[5]); + x6 ^= (hash->h4[6]); + x7 ^= (hash->h4[7]); + + + SIXTEEN_ROUNDS; + x0 ^= 0x80; + SIXTEEN_ROUNDS; + xv ^= 0x01; + for (int i = 0; i < 10; ++i) SIXTEEN_ROUNDS; + + hash->h4[0] = x0; + hash->h4[1] = x1; + hash->h4[2] = x2; + hash->h4[3] = x3; + hash->h4[4] = x4; + hash->h4[5] = x5; + hash->h4[6] = x6; + hash->h4[7] = x7; + + + barrier(CLK_GLOBAL_MEM_FENCE); + +} + + + +__attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) +__kernel void search6(__global uchar* hashes, __global uint* output, const ulong target) +{ + uint gid = get_global_id(0); + __global hash_t *hash = (__global hash_t *)(hashes + (4 * sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))); + + uint dh[16] = { + (0x40414243), (0x44454647), + (0x48494A4B), (0x4C4D4E4F), + (0x50515253), (0x54555657), + (0x58595A5B), (0x5C5D5E5F), + (0x60616263), (0x64656667), + (0x68696A6B), (0x6C6D6E6F), + (0x70717273), (0x74757677), + (0x78797A7B), (0x7C7D7E7F) + }; + uint final_s[16] = { + (0xaaaaaaa0), (0xaaaaaaa1), (0xaaaaaaa2), + (0xaaaaaaa3), (0xaaaaaaa4), (0xaaaaaaa5), + (0xaaaaaaa6), (0xaaaaaaa7), (0xaaaaaaa8), + (0xaaaaaaa9), (0xaaaaaaaa), (0xaaaaaaab), + (0xaaaaaaac), (0xaaaaaaad), (0xaaaaaaae), + (0xaaaaaaaf) + }; + + uint message[16]; + for (int i = 0; i<8; i++) message[i] = hash->h4[i]; + for (int i = 9; i<14; i++) message[i] = 0; + message[8]= 0x80; + message[14]=0x100; + message[15]=0; + + Compression256(message, dh); + Compression256(dh, final_s); + barrier(CLK_LOCAL_MEM_FENCE); + + + bool result = ( ((ulong*)final_s)[7] <= target); + if (result) { + output[atomic_inc(output + 0xFF)] = SWAP4(gid); + } + +} + + +#endif // LYRA2RE_CL \ No newline at end of file diff --git a/kernel/Lyra2v2.cl b/kernel/Lyra2v2.cl new file mode 100644 index 000000000..f9f9161de --- /dev/null +++ b/kernel/Lyra2v2.cl @@ -0,0 +1,184 @@ +/* +* Lyra2 kernel implementation. +* +* ==========================(LICENSE BEGIN)============================ +* Copyright (c) 2014 djm34 +* +* +* 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 djm34 +*/ + + + +#define ROTL64(x,n) rotate(x,(ulong)n) +#define ROTR64(x,n) rotate(x,(ulong)(64-n)) +#define SWAP32(x) as_ulong(as_uint2(x).s10) +#define SWAP24(x) as_ulong(as_uchar8(x).s34567012) +#define SWAP16(x) as_ulong(as_uchar8(x).s23456701) + +#define G(a,b,c,d) \ + do { \ + a += b; d ^= a; d = SWAP32(d); \ + c += d; b ^= c; b = ROTR64(b,24); \ + a += b; d ^= a; d = ROTR64(d,16); \ + c += d; b ^= c; b = ROTR64(b, 63); \ +\ + } while (0) + +#define G_old(a,b,c,d) \ + do { \ + a += b; d ^= a; d = ROTR64(d, 32); \ + c += d; b ^= c; b = ROTR64(b, 24); \ + a += b; d ^= a; d = ROTR64(d, 16); \ + c += d; b ^= c; b = ROTR64(b, 63); \ +\ + } while (0) + + +/*One Round of the Blake2b's compression function*/ + +#define round_lyra(s) \ + do { \ + G(s[0].x, s[1].x, s[2].x, s[3].x); \ + G(s[0].y, s[1].y, s[2].y, s[3].y); \ + G(s[0].z, s[1].z, s[2].z, s[3].z); \ + G(s[0].w, s[1].w, s[2].w, s[3].w); \ + G(s[0].x, s[1].y, s[2].z, s[3].w); \ + G(s[0].y, s[1].z, s[2].w, s[3].x); \ + G(s[0].z, s[1].w, s[2].x, s[3].y); \ + G(s[0].w, s[1].x, s[2].y, s[3].z); \ + } while(0) + + + +void reduceDuplexf(ulong4* state ,__global ulong4* DMatrix) +{ + + ulong4 state1[3]; + uint ps1 = 0; + uint ps2 = (memshift * 3 + memshift * 4); +//#pragma unroll 4 + for (int i = 0; i < 4; i++) + { + uint s1 = ps1 + i*memshift; + uint s2 = ps2 - i*memshift; + + for (int j = 0; j < 3; j++) state1[j] = (DMatrix)[j + s1]; + + for (int j = 0; j < 3; j++) state[j] ^= state1[j]; + round_lyra(state); + for (int j = 0; j < 3; j++) state1[j] ^= state[j]; + + for (int j = 0; j < 3; j++) (DMatrix)[j + s2] = state1[j]; + } + +} + + + +void reduceDuplexRowf(uint rowIn,uint rowInOut,uint rowOut,ulong4 * state, __global ulong4 * DMatrix) +{ + +ulong4 state1[3], state2[3]; +uint ps1 = (memshift * 4 * rowIn); +uint ps2 = (memshift * 4 * rowInOut); +uint ps3 = (memshift * 4 * rowOut); + + + for (int i = 0; i < 4; i++) + { + uint s1 = ps1 + i*memshift; + uint s2 = ps2 + i*memshift; + uint s3 = ps3 + i*memshift; + + + for (int j = 0; j < 3; j++) state1[j] = (DMatrix)[j + s1]; + + for (int j = 0; j < 3; j++) state2[j] = (DMatrix)[j + s2]; + + for (int j = 0; j < 3; j++) state1[j] += state2[j]; + + for (int j = 0; j < 3; j++) state[j] ^= state1[j]; + + + round_lyra(state); + + ((ulong*)state2)[0] ^= ((ulong*)state)[11]; + for (int j = 0; j < 11; j++) + ((ulong*)state2)[j + 1] ^= ((ulong*)state)[j]; + + if (rowInOut != rowOut) { + for (int j = 0; j < 3; j++) + (DMatrix)[j + s2] = state2[j]; + for (int j = 0; j < 3; j++) + (DMatrix)[j + s3] ^= state[j]; + } + else { + for (int j = 0; j < 3; j++) + state2[j] ^= state[j]; + for (int j = 0; j < 3; j++) + (DMatrix)[j + s2] = state2[j]; + } + + } + } + + + + +void reduceDuplexRowSetupf(uint rowIn, uint rowInOut, uint rowOut, ulong4 *state, __global ulong4* DMatrix) { + + ulong4 state2[3], state1[3]; + uint ps1 = (memshift * 4 * rowIn); + uint ps2 = (memshift * 4 * rowInOut); + uint ps3 = (memshift * 3 + memshift * 4 * rowOut); + + for (int i = 0; i < 4; i++) + { + uint s1 = ps1 + i*memshift; + uint s2 = ps2 + i*memshift; + uint s3 = ps3 - i*memshift; + + for (int j = 0; j < 3; j++) state1[j] = (DMatrix)[j + s1]; + + for (int j = 0; j < 3; j++) state2[j] = (DMatrix)[j + s2]; + for (int j = 0; j < 3; j++) { + ulong4 tmp = state1[j] + state2[j]; + state[j] ^= tmp; + } + round_lyra(state); + + for (int j = 0; j < 3; j++) { + state1[j] ^= state[j]; + (DMatrix)[j + s3] = state1[j]; + } + + ((ulong*)state2)[0] ^= ((ulong*)state)[11]; + for (int j = 0; j < 11; j++) + ((ulong*)state2)[j + 1] ^= ((ulong*)state)[j]; + for (int j = 0; j < 3; j++) + (DMatrix)[j + s2] = state2[j]; + } + } + diff --git a/kernel/bmw256.cl b/kernel/bmw256.cl new file mode 100644 index 000000000..9d6253408 --- /dev/null +++ b/kernel/bmw256.cl @@ -0,0 +1,128 @@ +#define shl(x, n) ((x) << (n)) +#define shr(x, n) ((x) >> (n)) +//#define SHR(x, n) SHR2(x, n) +//#define SHL(x, n) SHL2(x, n) + + +#define SPH_ROTL32(x,n) rotate(x,(uint)n) +#define ss0(x) (shr((x), 1) ^ shl((x), 3) ^ SPH_ROTL32((x), 4) ^ SPH_ROTL32((x), 19)) +#define ss1(x) (shr((x), 1) ^ shl((x), 2) ^ SPH_ROTL32((x), 8) ^ SPH_ROTL32((x), 23)) +#define ss2(x) (shr((x), 2) ^ shl((x), 1) ^ SPH_ROTL32((x), 12) ^ SPH_ROTL32((x), 25)) +#define ss3(x) (shr((x), 2) ^ shl((x), 2) ^ SPH_ROTL32((x), 15) ^ SPH_ROTL32((x), 29)) +#define ss4(x) (shr((x), 1) ^ (x)) +#define ss5(x) (shr((x), 2) ^ (x)) +#define rs1(x) SPH_ROTL32((x), 3) +#define rs2(x) SPH_ROTL32((x), 7) +#define rs3(x) SPH_ROTL32((x), 13) +#define rs4(x) SPH_ROTL32((x), 16) +#define rs5(x) SPH_ROTL32((x), 19) +#define rs6(x) SPH_ROTL32((x), 23) +#define rs7(x) SPH_ROTL32((x), 27) + +/* Message expansion function 1 */ +static uint expand32_1(int i, uint *M32, uint *H, uint *Q) +{ + + return (ss1(Q[i - 16]) + ss2(Q[i - 15]) + ss3(Q[i - 14]) + ss0(Q[i - 13]) + + ss1(Q[i - 12]) + ss2(Q[i - 11]) + ss3(Q[i - 10]) + ss0(Q[i - 9]) + + ss1(Q[i - 8]) + ss2(Q[i - 7]) + ss3(Q[i - 6]) + ss0(Q[i - 5]) + + ss1(Q[i - 4]) + ss2(Q[i - 3]) + ss3(Q[i - 2]) + ss0(Q[i - 1]) + + ((i*(0x05555555ul) + SPH_ROTL32(M32[(i - 16) % 16], ((i - 16) % 16) + 1) + SPH_ROTL32(M32[(i - 13) % 16], ((i - 13) % 16) + 1) - SPH_ROTL32(M32[(i - 6) % 16], ((i - 6) % 16) + 1)) ^ H[(i - 16 + 7) % 16])); + +} + +/* Message expansion function 2 */ +static uint expand32_2(int i, uint *M32, uint *H, uint *Q) +{ + + return (Q[i - 16] + rs1(Q[i - 15]) + Q[i - 14] + rs2(Q[i - 13]) + + Q[i - 12] + rs3(Q[i - 11]) + Q[i - 10] + rs4(Q[i - 9]) + + Q[i - 8] + rs5(Q[i - 7]) + Q[i - 6] + rs6(Q[i - 5]) + + Q[i - 4] + rs7(Q[i - 3]) + ss4(Q[i - 2]) + ss5(Q[i - 1]) + + ((i*(0x05555555ul) + SPH_ROTL32(M32[(i - 16) % 16], ((i - 16) % 16) + 1) + SPH_ROTL32(M32[(i - 13) % 16], ((i - 13) % 16) + 1) - SPH_ROTL32(M32[(i - 6) % 16], ((i - 6) % 16) + 1)) ^ H[(i - 16 + 7) % 16])); + +} + +static void Compression256(uint *M32, uint *H) +{ + + int i; + uint XL32, XH32, Q[32]; + + + Q[0] = (M32[5] ^ H[5]) - (M32[7] ^ H[7]) + (M32[10] ^ H[10]) + (M32[13] ^ H[13]) + (M32[14] ^ H[14]); + Q[1] = (M32[6] ^ H[6]) - (M32[8] ^ H[8]) + (M32[11] ^ H[11]) + (M32[14] ^ H[14]) - (M32[15] ^ H[15]); + Q[2] = (M32[0] ^ H[0]) + (M32[7] ^ H[7]) + (M32[9] ^ H[9]) - (M32[12] ^ H[12]) + (M32[15] ^ H[15]); + Q[3] = (M32[0] ^ H[0]) - (M32[1] ^ H[1]) + (M32[8] ^ H[8]) - (M32[10] ^ H[10]) + (M32[13] ^ H[13]); + Q[4] = (M32[1] ^ H[1]) + (M32[2] ^ H[2]) + (M32[9] ^ H[9]) - (M32[11] ^ H[11]) - (M32[14] ^ H[14]); + Q[5] = (M32[3] ^ H[3]) - (M32[2] ^ H[2]) + (M32[10] ^ H[10]) - (M32[12] ^ H[12]) + (M32[15] ^ H[15]); + Q[6] = (M32[4] ^ H[4]) - (M32[0] ^ H[0]) - (M32[3] ^ H[3]) - (M32[11] ^ H[11]) + (M32[13] ^ H[13]); + Q[7] = (M32[1] ^ H[1]) - (M32[4] ^ H[4]) - (M32[5] ^ H[5]) - (M32[12] ^ H[12]) - (M32[14] ^ H[14]); + Q[8] = (M32[2] ^ H[2]) - (M32[5] ^ H[5]) - (M32[6] ^ H[6]) + (M32[13] ^ H[13]) - (M32[15] ^ H[15]); + Q[9] = (M32[0] ^ H[0]) - (M32[3] ^ H[3]) + (M32[6] ^ H[6]) - (M32[7] ^ H[7]) + (M32[14] ^ H[14]); + Q[10] = (M32[8] ^ H[8]) - (M32[1] ^ H[1]) - (M32[4] ^ H[4]) - (M32[7] ^ H[7]) + (M32[15] ^ H[15]); + Q[11] = (M32[8] ^ H[8]) - (M32[0] ^ H[0]) - (M32[2] ^ H[2]) - (M32[5] ^ H[5]) + (M32[9] ^ H[9]); + Q[12] = (M32[1] ^ H[1]) + (M32[3] ^ H[3]) - (M32[6] ^ H[6]) - (M32[9] ^ H[9]) + (M32[10] ^ H[10]); + Q[13] = (M32[2] ^ H[2]) + (M32[4] ^ H[4]) + (M32[7] ^ H[7]) + (M32[10] ^ H[10]) + (M32[11] ^ H[11]); + Q[14] = (M32[3] ^ H[3]) - (M32[5] ^ H[5]) + (M32[8] ^ H[8]) - (M32[11] ^ H[11]) - (M32[12] ^ H[12]); + Q[15] = (M32[12] ^ H[12]) - (M32[4] ^ H[4]) - (M32[6] ^ H[6]) - (M32[9] ^ H[9]) + (M32[13] ^ H[13]); + + /* Diffuse the differences in every word in a bijective manner with ssi, and then add the values of the previous double pipe.*/ + Q[0] = ss0(Q[0]) + H[1]; + Q[1] = ss1(Q[1]) + H[2]; + Q[2] = ss2(Q[2]) + H[3]; + Q[3] = ss3(Q[3]) + H[4]; + Q[4] = ss4(Q[4]) + H[5]; + Q[5] = ss0(Q[5]) + H[6]; + Q[6] = ss1(Q[6]) + H[7]; + Q[7] = ss2(Q[7]) + H[8]; + Q[8] = ss3(Q[8]) + H[9]; + Q[9] = ss4(Q[9]) + H[10]; + Q[10] = ss0(Q[10]) + H[11]; + Q[11] = ss1(Q[11]) + H[12]; + Q[12] = ss2(Q[12]) + H[13]; + Q[13] = ss3(Q[13]) + H[14]; + Q[14] = ss4(Q[14]) + H[15]; + Q[15] = ss0(Q[15]) + H[0]; + + /* This is the Message expansion or f_1 in the documentation. */ + /* It has 16 rounds. */ + /* Blue Midnight Wish has two tunable security parameters. */ + /* The parameters are named EXPAND_1_ROUNDS and EXPAND_2_ROUNDS. */ + /* The following relation for these parameters should is satisfied: */ + /* EXPAND_1_ROUNDS + EXPAND_2_ROUNDS = 16 */ + + for (i = 0; i<2; i++) + Q[i + 16] = expand32_1(i + 16, M32, H, Q); + + for (i = 2; i<16; i++) + Q[i + 16] = expand32_2(i + 16, M32, H, Q); + + /* Blue Midnight Wish has two temporary cummulative variables that accumulate via XORing */ + /* 16 new variables that are prooduced in the Message Expansion part. */ + XL32 = Q[16] ^ Q[17] ^ Q[18] ^ Q[19] ^ Q[20] ^ Q[21] ^ Q[22] ^ Q[23]; + XH32 = XL32^Q[24] ^ Q[25] ^ Q[26] ^ Q[27] ^ Q[28] ^ Q[29] ^ Q[30] ^ Q[31]; + + + /* This part is the function f_2 - in the documentation */ + + /* Compute the double chaining pipe for the next message block. */ + H[0] = (shl(XH32, 5) ^ shr(Q[16], 5) ^ M32[0]) + (XL32 ^ Q[24] ^ Q[0]); + H[1] = (shr(XH32, 7) ^ shl(Q[17], 8) ^ M32[1]) + (XL32 ^ Q[25] ^ Q[1]); + H[2] = (shr(XH32, 5) ^ shl(Q[18], 5) ^ M32[2]) + (XL32 ^ Q[26] ^ Q[2]); + H[3] = (shr(XH32, 1) ^ shl(Q[19], 5) ^ M32[3]) + (XL32 ^ Q[27] ^ Q[3]); + H[4] = (shr(XH32, 3) ^ Q[20] ^ M32[4]) + (XL32 ^ Q[28] ^ Q[4]); + H[5] = (shl(XH32, 6) ^ shr(Q[21], 6) ^ M32[5]) + (XL32 ^ Q[29] ^ Q[5]); + H[6] = (shr(XH32, 4) ^ shl(Q[22], 6) ^ M32[6]) + (XL32 ^ Q[30] ^ Q[6]); + H[7] = (shr(XH32, 11) ^ shl(Q[23], 2) ^ M32[7]) + (XL32 ^ Q[31] ^ Q[7]); + + H[8] = SPH_ROTL32(H[4], 9) + (XH32 ^ Q[24] ^ M32[8]) + (shl(XL32, 8) ^ Q[23] ^ Q[8]); + H[9] = SPH_ROTL32(H[5], 10) + (XH32 ^ Q[25] ^ M32[9]) + (shr(XL32, 6) ^ Q[16] ^ Q[9]); + H[10] = SPH_ROTL32(H[6], 11) + (XH32 ^ Q[26] ^ M32[10]) + (shl(XL32, 6) ^ Q[17] ^ Q[10]); + H[11] = SPH_ROTL32(H[7], 12) + (XH32 ^ Q[27] ^ M32[11]) + (shl(XL32, 4) ^ Q[18] ^ Q[11]); + H[12] = SPH_ROTL32(H[0], 13) + (XH32 ^ Q[28] ^ M32[12]) + (shr(XL32, 3) ^ Q[19] ^ Q[12]); + H[13] = SPH_ROTL32(H[1], 14) + (XH32 ^ Q[29] ^ M32[13]) + (shr(XL32, 4) ^ Q[20] ^ Q[13]); + H[14] = SPH_ROTL32(H[2], 15) + (XH32 ^ Q[30] ^ M32[14]) + (shr(XL32, 7) ^ Q[21] ^ Q[14]); + H[15] = SPH_ROTL32(H[3], 16) + (XH32 ^ Q[31] ^ M32[15]) + (shr(XL32, 2) ^ Q[22] ^ Q[15]); + +} diff --git a/kernel/cubehash256.cl b/kernel/cubehash256.cl new file mode 100644 index 000000000..9bc4c6545 --- /dev/null +++ b/kernel/cubehash256.cl @@ -0,0 +1,132 @@ +// cubehash256 +// djm34 2015 based on ccminer cubehash512 + +#define CUBEHASH_ROUNDS 16 /* this is r for CubeHashr/b */ +#define CUBEHASH_BLOCKBYTES 32 /* this is b for CubeHashr/b */ + + +#define LROT(x, bits) rotate( x,(uint) bits) + + +#define ROTATEUPWARDS7(a) LROT(a,7) +#define ROTATEUPWARDS11(a) LROT(a,11) + +#define SWAP(a,b) { uint u = a; a = b; b = u; } + +inline void rrounds(uint x[2][2][2][2][2]) +{ + int r; + int j; + int k; + int l; + int m; + +//#pragma unroll 2 + for (r = 0; r < CUBEHASH_ROUNDS; ++r) { + + /* "add x_0jklm into x_1jklmn modulo 2^32" */ +//#pragma unroll 2 + for (j = 0; j < 2; ++j) +//#pragma unroll 2 + for (k = 0; k < 2; ++k) +//#pragma unroll 2 + for (l = 0; l < 2; ++l) +//#pragma unroll 2 + for (m = 0; m < 2; ++m) + x[1][j][k][l][m] += x[0][j][k][l][m]; + + /* "rotate x_0jklm upwards by 7 bits" */ +//#pragma unroll 2 + for (j = 0; j < 2; ++j) +//#pragma unroll 2 + for (k = 0; k < 2; ++k) +//#pragma unroll 2 + for (l = 0; l < 2; ++l) +//#pragma unroll 2 + for (m = 0; m < 2; ++m) + x[0][j][k][l][m] = ROTATEUPWARDS7(x[0][j][k][l][m]); + + /* "swap x_00klm with x_01klm" */ +//#pragma unroll 2 + for (k = 0; k < 2; ++k) +//#pragma unroll 2 + for (l = 0; l < 2; ++l) +//#pragma unroll 2 + for (m = 0; m < 2; ++m) + SWAP(x[0][0][k][l][m], x[0][1][k][l][m]) + + /* "xor x_1jklm into x_0jklm" */ +//#pragma unroll 2 + for (j = 0; j < 2; ++j) +//#pragma unroll 2 + for (k = 0; k < 2; ++k) +//#pragma unroll 2 + for (l = 0; l < 2; ++l) +//#pragma unroll 2 + for (m = 0; m < 2; ++m) + x[0][j][k][l][m] ^= x[1][j][k][l][m]; + + /* "swap x_1jk0m with x_1jk1m" */ +//#pragma unroll 2 + for (j = 0; j < 2; ++j) +//#pragma unroll 2 + for (k = 0; k < 2; ++k) +//#pragma unroll 2 + for (m = 0; m < 2; ++m) + SWAP(x[1][j][k][0][m], x[1][j][k][1][m]) + + /* "add x_0jklm into x_1jklm modulo 2^32" */ +//#pragma unroll 2 + for (j = 0; j < 2; ++j) +//#pragma unroll 2 + for (k = 0; k < 2; ++k) +//#pragma unroll 2 + for (l = 0; l < 2; ++l) +//#pragma unroll 2 + for (m = 0; m < 2; ++m) + x[1][j][k][l][m] += x[0][j][k][l][m]; + + /* "rotate x_0jklm upwards by 11 bits" */ +//#pragma unroll 2 + for (j = 0; j < 2; ++j) +//#pragma unroll 2 + for (k = 0; k < 2; ++k) +//#pragma unroll 2 + for (l = 0; l < 2; ++l) +//#pragma unroll 2 + for (m = 0; m < 2; ++m) + x[0][j][k][l][m] = ROTATEUPWARDS11(x[0][j][k][l][m]); + + /* "swap x_0j0lm with x_0j1lm" */ +//#pragma unroll 2 + for (j = 0; j < 2; ++j) +//#pragma unroll 2 + for (l = 0; l < 2; ++l) +//#pragma unroll 2 + for (m = 0; m < 2; ++m) + SWAP(x[0][j][0][l][m], x[0][j][1][l][m]) + + /* "xor x_1jklm into x_0jklm" */ +//#pragma unroll 2 + for (j = 0; j < 2; ++j) +//#pragma unroll 2 + for (k = 0; k < 2; ++k) +//#pragma unroll 2 + for (l = 0; l < 2; ++l) +//#pragma unroll 2 + for (m = 0; m < 2; ++m) + x[0][j][k][l][m] ^= x[1][j][k][l][m]; + + /* "swap x_1jkl0 with x_1jkl1" */ +//#pragma unroll 2 + for (j = 0; j < 2; ++j) +//#pragma unroll 2 + for (k = 0; k < 2; ++k) +//#pragma unroll 2 + for (l = 0; l < 2; ++l) + SWAP(x[1][j][k][l][0], x[1][j][k][l][1]) + + } +} + + diff --git a/kernel/skein256.cl b/kernel/skein256.cl index afbe75719..a7d85faf4 100644 --- a/kernel/skein256.cl +++ b/kernel/skein256.cl @@ -48,14 +48,14 @@ __constant static const sph_u64 SKEIN_IV512_256[8] = { __constant static const int ROT256[8][4] = { - 46, 36, 19, 37, - 33, 27, 14, 42, - 17, 49, 36, 39, - 44, 9, 54, 56, - 39, 30, 34, 24, - 13, 50, 10, 17, - 25, 29, 39, 43, - 8, 35, 56, 22, + {46, 36, 19, 37}, + {33, 27, 14, 42}, + {17, 49, 36, 39}, + {44, 9, 54, 56}, + {39, 30, 34, 24}, + {13, 50, 10, 17}, + {25, 29, 39, 43}, + {8, 35, 56, 22} }; __constant static const sph_u64 skein_ks_parity = 0x1BD11BDAA9FC1A22; diff --git a/miner.h b/miner.h index 737974e6a..09e8d4222 100644 --- a/miner.h +++ b/miner.h @@ -1156,8 +1156,8 @@ extern struct pool *add_pool(void); extern bool add_pool_details(struct pool *pool, bool live, char *url, char *user, char *pass, char *name, char *desc, char *profile, char *algo); #define MAX_GPUDEVICES 16 -#define MAX_DEVICES 4096 - +//#define MAX_DEVICES 4096 +#define MAX_DEVICES 8192 #define MIN_INTENSITY 4 #define MIN_INTENSITY_STR "4" #define MAX_INTENSITY 31 @@ -1267,6 +1267,7 @@ struct stratum_work { size_t cb_len; size_t header_len; int merkles; + double next_diff; double diff; }; diff --git a/ocl.c b/ocl.c index 685ee98a6..d1e8d7e5b 100644 --- a/ocl.c +++ b/ocl.c @@ -37,6 +37,7 @@ #include "algorithm/neoscrypt.h" #include "algorithm/pluck.h" #include "algorithm/yescrypt.h" +#include "algorithm/Lyra2RE.h" /* FIXME: only here for global config vars, replace with configuration.h * or similar as soon as config is in a struct instead of littered all @@ -599,6 +600,88 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize, algorithm_t *alg applog(LOG_DEBUG, "GPU %d: computing max. global thread count to %u", gpu, (unsigned)(cgpu->thread_concurrency)); + } + else if ( !safe_cmp(cgpu->algorithm.name, "lyra2REv2") ) { + size_t glob_thread_count; + long max_int; + unsigned char type = 0; + + // determine which intensity type to use + if (cgpu->rawintensity > 0) { + glob_thread_count = cgpu->rawintensity; + max_int = glob_thread_count; + type = 2; + } + else if (cgpu->xintensity > 0) { + glob_thread_count = clState->compute_shaders * ((cgpu->algorithm.xintensity_shift) ? (1UL << (cgpu->algorithm.xintensity_shift + cgpu->xintensity)) : cgpu->xintensity); + max_int = cgpu->xintensity; + type = 1; + } + else { + glob_thread_count = 1UL << (cgpu->algorithm.intensity_shift + cgpu->intensity); + max_int = ((cgpu->dynamic) ? MAX_INTENSITY : cgpu->intensity); + } + + glob_thread_count = ((glob_thread_count < cgpu->work_size) ? cgpu->work_size : glob_thread_count); + + // if TC * scratchbuf size is too big for memory... reduce to max + if ((glob_thread_count * LYRA_SCRATCHBUF_SIZE) >= (uint64_t)cgpu->max_alloc) { + + /* Selected intensity will not run on this GPU. Not enough memory. + * Adapt the memory setting. */ + // depending on intensity type used, reduce the intensity until it fits into the GPU max_alloc + switch (type) { + //raw intensity + case 2: + while ((glob_thread_count * LYRA_SCRATCHBUF_SIZE) > (uint64_t)cgpu->max_alloc) { + --glob_thread_count; + } + + max_int = glob_thread_count; + cgpu->rawintensity = glob_thread_count; + break; + + //x intensity + case 1: + glob_thread_count = cgpu->max_alloc / LYRA_SCRATCHBUF_SIZE; + max_int = glob_thread_count / clState->compute_shaders; + + while (max_int && ((clState->compute_shaders * (1UL << max_int)) > glob_thread_count)) { + --max_int; + } + + /* Check if max_intensity is >0. */ + if (max_int < MIN_XINTENSITY) { + applog(LOG_ERR, "GPU %d: Max xintensity is below minimum.", gpu); + max_int = MIN_XINTENSITY; + } + + cgpu->xintensity = max_int; + glob_thread_count = clState->compute_shaders * (1UL << max_int); + break; + + default: + glob_thread_count = cgpu->max_alloc / LYRA_SCRATCHBUF_SIZE; + while (max_int && ((1UL << max_int) & glob_thread_count) == 0) { + --max_int; + } + + /* Check if max_intensity is >0. */ + if (max_int < MIN_INTENSITY) { + applog(LOG_ERR, "GPU %d: Max intensity is below minimum.", gpu); + max_int = MIN_INTENSITY; + } + + cgpu->intensity = max_int; + glob_thread_count = 1UL << max_int; + break; + } + } + + // TC is glob thread count + cgpu->thread_concurrency = glob_thread_count; + + applog(LOG_DEBUG, "GPU %d: computing max. global thread count to %u", gpu, (unsigned)(cgpu->thread_concurrency)); } else if (!cgpu->opt_tc) { unsigned int sixtyfours; @@ -689,12 +772,17 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize, algorithm_t *alg if (clState->n_extra_kernels > 0) { unsigned int i; char kernel_name[9]; // max: search99 + 0x0 + char kernel_name2[10]; // max: search99 + 0x0 clState->extra_kernels = (cl_kernel *)malloc(sizeof(cl_kernel) * clState->n_extra_kernels); for (i = 0; i < clState->n_extra_kernels; i++) { - snprintf(kernel_name, 9, "%s%d", "search", i + 1); - clState->extra_kernels[i] = clCreateKernel(clState->program, kernel_name, &status); + if (i+1<100){ + snprintf(kernel_name, 9, "%s%d", "search", i + 1); + clState->extra_kernels[i] = clCreateKernel(clState->program, kernel_name, &status); + }else { + snprintf(kernel_name2, 10, "%s%d", "search", i + 1); + clState->extra_kernels[i] = clCreateKernel(clState->program, kernel_name2, &status);} if (status != CL_SUCCESS) { applog(LOG_DEBUG, "Error %d: Creating ExtraKernel #%d from program. (clCreateKernel)", status, i); return NULL; @@ -739,6 +827,21 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize, algorithm_t *alg + } + else if (!safe_cmp(algorithm->name, "lyra2REv2") ) { + /* The scratch/pad-buffer needs 32kBytes memory per thread. */ + bufsize = 4 * 4 * 12 * sizeof(unsigned long long) * cgpu->thread_concurrency; + buf1size = 4 * sizeof(unsigned long long) * cgpu->thread_concurrency; //matrix + + /* This is the input buffer. For yescrypt this is guaranteed to be + * 80 bytes only. */ + readbufsize = 80; + + applog(LOG_DEBUG, "lyra2REv2 buffer sizes: %lu RW, %lu RW", (unsigned long)bufsize, (unsigned long)buf1size); + // scrypt/n-scrypt + + + } else if (!safe_cmp(algorithm->name, "pluck")) { /* The scratch/pad-buffer needs 32kBytes memory per thread. */ @@ -798,7 +901,25 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize, algorithm_t *alg } -} + } + + else if (!safe_cmp(algorithm->name, "lyra2REv2") ) { + // need additionnal buffers + clState->buffer1 = clCreateBuffer(clState->context, CL_MEM_READ_WRITE, buf1size, NULL, &status); + if (status != CL_SUCCESS && !clState->buffer1) { + applog(LOG_DEBUG, "Error %d: clCreateBuffer (buffer1), decrease TC or increase LG", status); + return NULL; + } + + } + else { + clState->buffer1 = clCreateBuffer(clState->context, CL_MEM_READ_WRITE, bufsize, NULL, &status); // we don't need that much just tired... + if (status != CL_SUCCESS && !clState->buffer1) { + applog(LOG_DEBUG, "Error %d: clCreateBuffer (buffer1), decrease TC or increase LG", status); + return NULL; + } + + } /* This buffer is weird and might work to some degree even if * the create buffer call has apparently failed, so check if we @@ -808,6 +929,13 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize, algorithm_t *alg applog(LOG_ERR, "Error %d: clCreateBuffer (padbuffer8), decrease TC or increase LG", status); return NULL; } + +// clState->buffer1 = clCreateBuffer(clState->context, CL_MEM_READ_WRITE, bufsize/8, NULL, &status); // we don't need that much just tired... +// if (status != CL_SUCCESS && !clState->buffer1) { +// applog(LOG_DEBUG, "Error %d: clCreateBuffer (buffer1), decrease TC or increase LG", status); +// return NULL; +// } + } applog(LOG_DEBUG, "Using read buffer sized %lu", (unsigned long)readbufsize); diff --git a/sgminer.c b/sgminer.c index 9f10659cf..fe64a4142 100644 --- a/sgminer.c +++ b/sgminer.c @@ -2265,7 +2265,12 @@ static bool gbt_decode(struct pool *pool, json_t *res_val) static bool getwork_decode(json_t *res_val, struct work *work) { - if (unlikely(!jobj_binary(res_val, "data", work->data, sizeof(work->data), true))) { + + size_t worklen = 128; + worklen = ((!safe_cmp(work->pool->algorithm.name, "credits")) ? sizeof(work->data) : worklen); + + + if (unlikely(!jobj_binary(res_val, "data", work->data, worklen, true))) { if (opt_morenotices) applog(LOG_ERR, "%s: JSON inval data", isnull(get_pool_name(work->pool), "")); return false; @@ -3030,7 +3035,11 @@ static bool submit_upstream_work(struct work *work, CURL *curl, char *curl_err_s } /* build hex string - Make sure to restrict to 80 bytes for Neoscrypt */ - hexstr = bin2hex(work->data, ((!safe_cmp(work->pool->algorithm.name, "neoscrypt")) ? 80 : sizeof(work->data))); + + int worksize_default = 128; + hexstr = bin2hex(work->data, (!safe_cmp(work->pool->algorithm.name, "neoscrypt") ? 80 : worksize_default)); + hexstr = bin2hex(work->data, (!safe_cmp(work->pool->algorithm.name, "credits") ? sizeof(work->data) : worksize_default)); + /* build JSON-RPC request */ if (work->gbt) { diff --git a/util.c b/util.c index 675cdad52..756ff7f05 100644 --- a/util.c +++ b/util.c @@ -1560,6 +1560,8 @@ static bool parse_notify(struct pool *pool, json_t *val) pool->swork.nbit = nbit; pool->swork.ntime = ntime; pool->swork.clean = clean; + pool->swork.diff = pool->swork.next_diff; + alloc_len = pool->swork.cb_len = cb1_len + pool->n1_len + pool->n2size + cb2_len; pool->nonce2_offset = cb1_len + pool->n1_len; @@ -1668,8 +1670,8 @@ static bool parse_diff(struct pool *pool, json_t *val) return false; cg_wlock(&pool->data_lock); - old_diff = pool->swork.diff; - pool->swork.diff = diff; + old_diff = pool->swork.next_diff; + pool->swork.next_diff = diff; cg_wunlock(&pool->data_lock); if (old_diff != diff) { @@ -2560,7 +2562,7 @@ bool initiate_stratum(struct pool *pool) if (!pool->stratum_url) pool->stratum_url = pool->sockaddr_url; pool->stratum_active = true; - pool->swork.diff = 1; + pool->swork.next_diff = pool->swork.diff = 1; if (opt_protocol) { applog(LOG_DEBUG, "%s confirmed mining.subscribe with extranonce1 %s extran2size %d", get_pool_name(pool), pool->nonce1, pool->n2size); From e59445006de48718fd888e5e479f0fbee6696595 Mon Sep 17 00:00:00 2001 From: djm34 Date: Fri, 31 Jul 2015 14:25:19 +0200 Subject: [PATCH 17/27] usage example best performance are obtained for small worksize and large number of threads --- example.bat | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/example.bat b/example.bat index db97f5631..a1f93d202 100644 --- a/example.bat +++ b/example.bat @@ -1,12 +1,16 @@ rem setx GPU_MAX_HEAP_SIZE 100 -rem setx GPU_USE_SYNC_OBJECTS 1 -rem setx GPU_MAX_ALLOC_PERCENT 100 +setx GPU_USE_SYNC_OBJECTS 1 +setx GPU_MAX_ALLOC_PERCENT 100 del *.bin - -@rem sgminer.exe --no-submit-stale --kernel Lyra2RE -o stratum+tcp://pool.verters.com:4444 -u djm34t.user -p password --gpu-platform 2 +@rem sgminer.exe +@rem pause +@rem sgminer.exe --no-submit-stale --kernel Lyra2RE -o stratum+tcp://pool.verters.com:4444 -u djm34t.user -p password --gpu-platform 1 -I 17 -g 16 -w 32 +sgminer.exe --kernel Lyra2REv2 -o http://127.0.0.1:7785/ -u Dominique -p MyPass --gpu-platform 1 -I 18 -g 8 -w 32 @rem sgminer.exe --no-submit-stale --kernel pluck -o stratum+tcp://sup.suprnova.cc:7777 -u djm34.2 -p password --gpu-platform 2 --thread-concurrency 8192 -w 4 -I 12 @rem sgminer.exe --no-submit-stale --kernel yescrypt -o stratum+tcp://mine2.bsty.nonce-pool.com:4095 -u djm34.1 -p password --gpu-platform 1 -w 32 --thread-concurrency 512 --text-only --debug -sgminer.exe --no-submit-stale --kernel yescrypt -o stratum+tcp://mine2.bsty.nonce-pool.com:4095 -u djm34.1 -p password --gpu-platform 1 -w 8 --thread-concurrency 1024 -I 9 +@rem sgminer.exe --no-submit-stale --kernel yescrypt -o stratum+tcp://mine2.bsty.nonce-pool.com:4095 -u djm34.1 -p password --gpu-platform 1 -w 8 --thread-concurrency 1024 -I 9 + +@rem sgminer.exe --no-submit-stale --kernel nscrypto -o http://127.0.0.1:9989/ -u dom -p password --gpu-platform 1 -I 20 +@rem sgminer.exe --no-submit-stale --kernel nscrypto -o stratum+tcp://drop.suprnova.cc:7890 -u djm34.1 -p password --gpu-platform 0 -I 18 --device 0 --remove-disabled --text-only --debug -@rem sgminer.exe --no-submit-stale --kernel yescrypt-multi -o stratum+tcp://mine2.bsty.nonce-pool.com:4095 -u djm34.1 -p password --gpu-platform 0 -w 4 -g 2 pause \ No newline at end of file From 22e79a594566fbdcc2a4023afd54e45ce50efc4e Mon Sep 17 00:00:00 2001 From: djm34 Date: Fri, 31 Jul 2015 15:51:01 +0200 Subject: [PATCH 18/27] bug fix on original lyra --- algorithm/Lyra2RE_old.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/algorithm/Lyra2RE_old.c b/algorithm/Lyra2RE_old.c index f1e9aee5c..b3f3b4fd9 100644 --- a/algorithm/Lyra2RE_old.c +++ b/algorithm/Lyra2RE_old.c @@ -100,7 +100,7 @@ int lyra2reold_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t be32enc_vect(data, (const uint32_t *)pdata, 19); data[19] = htobe32(nonce); - lyra2rehash(ohash, data); + lyra2rehash_old(ohash, data); tmp_hash7 = be32toh(ohash[7]); applog(LOG_DEBUG, "htarget %08lx diff1 %08lx hash %08lx", @@ -122,7 +122,7 @@ void lyra2reold_regenhash(struct work *work) be32enc_vect(data, (const uint32_t *)work->data, 19); data[19] = htobe32(*nonce); - lyra2rehash(ohash, data); + lyra2rehash_old(ohash, data); } bool scanhash_lyra2reold(struct thr_info *thr, const unsigned char __maybe_unused *pmidstate, From 297a5e4eaa1efed60f182f85aaad4a43fefbd68c Mon Sep 17 00:00:00 2001 From: djm34 Date: Tue, 4 Aug 2015 11:47:27 +0200 Subject: [PATCH 19/27] correct typo --- algorithm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/algorithm.c b/algorithm.c index 5430d7735..04221c2bd 100644 --- a/algorithm.c +++ b/algorithm.c @@ -60,7 +60,7 @@ const char *algorithm_type_str[] = { "Whirlcoin", "Neoscrypt", "Lyra2RE", - "Lyta2REv2" + "Lyra2REv2" "pluck", "yescrypt", "yescrypt-multi" From 09bc88214e0cd6da44433988c981224b97727913 Mon Sep 17 00:00:00 2001 From: djm34 Date: Fri, 7 Aug 2015 11:37:36 +0200 Subject: [PATCH 20/27] assign correct size to the buffer --- algorithm/Lyra2RE.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/algorithm/Lyra2RE.h b/algorithm/Lyra2RE.h index f4698c65a..ca4a04fb8 100644 --- a/algorithm/Lyra2RE.h +++ b/algorithm/Lyra2RE.h @@ -2,8 +2,8 @@ #define LYRA2RE_H #include "miner.h" -#define LYRA_SCRATCHBUF_SIZE (4 ) // matrix extended to 16 matrix[16][8][8] uint64_t or equivalent -#define LYRA_SECBUF_SIZE (4) //8 uint64 +#define LYRA_SCRATCHBUF_SIZE (1536) // matrix size [12][4][4] uint64_t or equivalent +#define LYRA_SECBUF_SIZE (4) // (not used) extern int lyra2re_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t nonce); extern void lyra2re_regenhash(struct work *work); From 5c19cba4f24bedc0a95657ba48378c93fa71cdf5 Mon Sep 17 00:00:00 2001 From: djm34 Date: Sat, 8 Aug 2015 16:15:52 +0200 Subject: [PATCH 21/27] replace sizeof(unsigned long long) by 8 in ocl.c --- kernel/Lyra2REv2.cl | 4 ++-- ocl.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/Lyra2REv2.cl b/kernel/Lyra2REv2.cl index c1adbc371..88cbc7b8d 100644 --- a/kernel/Lyra2REv2.cl +++ b/kernel/Lyra2REv2.cl @@ -48,8 +48,8 @@ typedef int sph_s32; typedef unsigned long sph_u64; typedef long sph_s64; #else -typedef unsigned long sph_u64; -typedef long sph_s64; +typedef unsigned long long sph_u64; +typedef long long sph_s64; #endif diff --git a/ocl.c b/ocl.c index d1e8d7e5b..138561239 100644 --- a/ocl.c +++ b/ocl.c @@ -830,8 +830,8 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize, algorithm_t *alg } else if (!safe_cmp(algorithm->name, "lyra2REv2") ) { /* The scratch/pad-buffer needs 32kBytes memory per thread. */ - bufsize = 4 * 4 * 12 * sizeof(unsigned long long) * cgpu->thread_concurrency; - buf1size = 4 * sizeof(unsigned long long) * cgpu->thread_concurrency; //matrix + bufsize = LYRA_SCRATCHBUF_SIZE * cgpu->thread_concurrency; + buf1size = 4* 8 * cgpu->thread_concurrency; //matrix /* This is the input buffer. For yescrypt this is guaranteed to be * 80 bytes only. */ From 499837e15eaadf60c2479fb7c58dac04c5f89f55 Mon Sep 17 00:00:00 2001 From: djm34 Date: Sat, 8 Aug 2015 16:18:27 +0200 Subject: [PATCH 22/27] same here shouldn't change anything --- kernel/Lyra2REv2.cl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/Lyra2REv2.cl b/kernel/Lyra2REv2.cl index 88cbc7b8d..a4344fb9a 100644 --- a/kernel/Lyra2REv2.cl +++ b/kernel/Lyra2REv2.cl @@ -285,7 +285,7 @@ __kernel void search3(__global uchar* hashes,__global uchar* matrix ) uint gid = get_global_id(0); // __global hash_t *hash = &(hashes[gid-get_global_offset(0)]); __global hash_t *hash = (__global hash_t *)(hashes + (4 * sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))); - __global ulong4 *DMatrix = (__global ulong4 *)(matrix + (4 * memshift * 4 * 4 * sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))); + __global ulong4 *DMatrix = (__global ulong4 *)(matrix + (4 * memshift * 4 * 4 * 8 * (get_global_id(0) % MAX_GLOBAL_THREADS))); // uint offset = (4 * memshift * 4 * 4 * sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))/32; ulong4 state[4]; From b6608e9d1eb50cdf5d185f7622109839e3e39acc Mon Sep 17 00:00:00 2001 From: djm34 Date: Sat, 8 Aug 2015 16:55:00 +0200 Subject: [PATCH 23/27] remove long long type --- kernel/Lyra2REv2.cl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/Lyra2REv2.cl b/kernel/Lyra2REv2.cl index a4344fb9a..afe21223e 100644 --- a/kernel/Lyra2REv2.cl +++ b/kernel/Lyra2REv2.cl @@ -48,8 +48,8 @@ typedef int sph_s32; typedef unsigned long sph_u64; typedef long sph_s64; #else -typedef unsigned long long sph_u64; -typedef long long sph_s64; +typedef unsigned long sph_u64; +typedef long sph_s64; #endif From 9726ba699e55c647ba03d225766ec1792d5a36ea Mon Sep 17 00:00:00 2001 From: djm34 Date: Sat, 8 Aug 2015 17:51:25 +0200 Subject: [PATCH 24/27] long long type at the right place this time --- kernel/Lyra2REv2.cl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/Lyra2REv2.cl b/kernel/Lyra2REv2.cl index afe21223e..fb2a261bf 100644 --- a/kernel/Lyra2REv2.cl +++ b/kernel/Lyra2REv2.cl @@ -45,8 +45,8 @@ typedef unsigned int sph_u32; typedef int sph_s32; #ifndef __OPENCL_VERSION__ -typedef unsigned long sph_u64; -typedef long sph_s64; +typedef unsigned long long sph_u64; +typedef long long sph_s64; #else typedef unsigned long sph_u64; typedef long sph_s64; From 3df7d7cf150904ab9781c56eba6a148489a7f3c7 Mon Sep 17 00:00:00 2001 From: djm34 Date: Tue, 11 Aug 2015 04:08:45 +0200 Subject: [PATCH 25/27] algo cleaning --- kernel/Lyra2REv2.cl | 32 ++++++++++++++++---------------- kernel/bmw256.cl | 39 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 52 insertions(+), 19 deletions(-) diff --git a/kernel/Lyra2REv2.cl b/kernel/Lyra2REv2.cl index fb2a261bf..fd4b11255 100644 --- a/kernel/Lyra2REv2.cl +++ b/kernel/Lyra2REv2.cl @@ -45,8 +45,8 @@ typedef unsigned int sph_u32; typedef int sph_s32; #ifndef __OPENCL_VERSION__ -typedef unsigned long long sph_u64; -typedef long long sph_s64; +typedef unsigned long sph_u64; +typedef long sph_s64; #else typedef unsigned long sph_u64; typedef long sph_s64; @@ -484,22 +484,22 @@ __kernel void search6(__global uchar* hashes, __global uint* output, const ulong __global hash_t *hash = (__global hash_t *)(hashes + (4 * sizeof(ulong)* (get_global_id(0) % MAX_GLOBAL_THREADS))); uint dh[16] = { - (0x40414243), (0x44454647), - (0x48494A4B), (0x4C4D4E4F), - (0x50515253), (0x54555657), - (0x58595A5B), (0x5C5D5E5F), - (0x60616263), (0x64656667), - (0x68696A6B), (0x6C6D6E6F), - (0x70717273), (0x74757677), - (0x78797A7B), (0x7C7D7E7F) + 0x40414243, 0x44454647, + 0x48494A4B, 0x4C4D4E4F, + 0x50515253, 0x54555657, + 0x58595A5B, 0x5C5D5E5F, + 0x60616263, 0x64656667, + 0x68696A6B, 0x6C6D6E6F, + 0x70717273, 0x74757677, + 0x78797A7B, 0x7C7D7E7F }; uint final_s[16] = { - (0xaaaaaaa0), (0xaaaaaaa1), (0xaaaaaaa2), - (0xaaaaaaa3), (0xaaaaaaa4), (0xaaaaaaa5), - (0xaaaaaaa6), (0xaaaaaaa7), (0xaaaaaaa8), - (0xaaaaaaa9), (0xaaaaaaaa), (0xaaaaaaab), - (0xaaaaaaac), (0xaaaaaaad), (0xaaaaaaae), - (0xaaaaaaaf) + 0xaaaaaaa0, 0xaaaaaaa1, 0xaaaaaaa2, + 0xaaaaaaa3, 0xaaaaaaa4, 0xaaaaaaa5, + 0xaaaaaaa6, 0xaaaaaaa7, 0xaaaaaaa8, + 0xaaaaaaa9, 0xaaaaaaaa, 0xaaaaaaab, + 0xaaaaaaac, 0xaaaaaaad, 0xaaaaaaae, + 0xaaaaaaaf }; uint message[16]; diff --git a/kernel/bmw256.cl b/kernel/bmw256.cl index 9d6253408..313752b92 100644 --- a/kernel/bmw256.cl +++ b/kernel/bmw256.cl @@ -1,3 +1,36 @@ +/* +* bmw256 kernel implementation. +* +* ==========================(LICENSE BEGIN)============================ +* Copyright (c) 2015 djm34 +* +* +* 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 djm34 +*/ + + + #define shl(x, n) ((x) << (n)) #define shr(x, n) ((x) >> (n)) //#define SHR(x, n) SHR2(x, n) @@ -20,7 +53,7 @@ #define rs7(x) SPH_ROTL32((x), 27) /* Message expansion function 1 */ -static uint expand32_1(int i, uint *M32, uint *H, uint *Q) +uint expand32_1(int i, uint *M32, uint *H, uint *Q) { return (ss1(Q[i - 16]) + ss2(Q[i - 15]) + ss3(Q[i - 14]) + ss0(Q[i - 13]) @@ -32,7 +65,7 @@ static uint expand32_1(int i, uint *M32, uint *H, uint *Q) } /* Message expansion function 2 */ -static uint expand32_2(int i, uint *M32, uint *H, uint *Q) +uint expand32_2(int i, uint *M32, uint *H, uint *Q) { return (Q[i - 16] + rs1(Q[i - 15]) + Q[i - 14] + rs2(Q[i - 13]) @@ -43,7 +76,7 @@ static uint expand32_2(int i, uint *M32, uint *H, uint *Q) } -static void Compression256(uint *M32, uint *H) +void Compression256(uint *M32, uint *H) { int i; From 2a67516c5ee4c549abfe829999120bde82ac7cf7 Mon Sep 17 00:00:00 2001 From: djm34 Date: Sat, 15 Aug 2015 14:44:02 +0200 Subject: [PATCH 26/27] modified default difficulty for lyra2re original; algo aliases --- algorithm.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/algorithm.c b/algorithm.c index 04221c2bd..8b7630301 100644 --- a/algorithm.c +++ b/algorithm.c @@ -985,7 +985,7 @@ static algorithm_settings_t algos[] = { { "fresh", ALGO_FRESH, "", 1, 256, 256, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 4, 4 * 16 * 4194304, 0, fresh_regenhash, queue_fresh_kernel, gen_hash, NULL}, - { "Lyra2RE", ALGO_LYRA2RE, "", 1, 256, 256, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 4,2 * 8 * 4194304 , 0, lyra2reold_regenhash, queue_lyra2RE_kernel, gen_hash, NULL}, + { "Lyra2RE", ALGO_LYRA2RE, "", 1, 128, 128, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 4,2 * 8 * 4194304 , 0, lyra2reold_regenhash, queue_lyra2RE_kernel, gen_hash, NULL}, { "Lyra2REv2", ALGO_LYRA2REv2, "", 1, 256, 256, 0, 0, 0xFF, 0xFFFFULL, 0x0000ffffUL, 6, -1, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, lyra2re_regenhash, queue_lyra2REv2_kernel, gen_hash, append_neoscrypt_compiler_options }, @@ -1071,6 +1071,15 @@ static const char *lookup_algorithm_alias(const char *lookup_alias, uint8_t *nfa ALGO_ALIAS("nist5", "talkcoin-mod"); ALGO_ALIAS("keccak", "maxcoin"); ALGO_ALIAS("whirlpool", "whirlcoin"); + ALGO_ALIAS("Lyra2REv2", "Lyra2REv2"); + ALGO_ALIAS("lyra2rev2", "Lyra2REv2"); + ALGO_ALIAS("lyra2v2", "Lyra2REv2"); + ALGO_ALIAS("Lyra2RE", "Lyra2RE"); + ALGO_ALIAS("lyra2re", "Lyra2RE"); + ALGO_ALIAS("lyra2", "Lyra2RE"); + + + #undef ALGO_ALIAS #undef ALGO_ALIAS_NF From 889a5c9afc8e2aee6c39cee7884946be212d5bcf Mon Sep 17 00:00:00 2001 From: djm34 Date: Mon, 17 Aug 2015 12:09:00 +0200 Subject: [PATCH 27/27] correct problem with older cards --- kernel/bmw256.cl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/bmw256.cl b/kernel/bmw256.cl index 313752b92..19c85cbc9 100644 --- a/kernel/bmw256.cl +++ b/kernel/bmw256.cl @@ -124,10 +124,11 @@ void Compression256(uint *M32, uint *H) /* The parameters are named EXPAND_1_ROUNDS and EXPAND_2_ROUNDS. */ /* The following relation for these parameters should is satisfied: */ /* EXPAND_1_ROUNDS + EXPAND_2_ROUNDS = 16 */ - +#pragma unroll for (i = 0; i<2; i++) Q[i + 16] = expand32_1(i + 16, M32, H, Q); +#pragma unroll for (i = 2; i<16; i++) Q[i + 16] = expand32_2(i + 16, M32, H, Q);