diff --git a/algorithm.c b/algorithm.c index 212ef648..8302ecd1 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 16ead85f..c412af92 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 00000000..b69514bc --- /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 00000000..9d74ad20 --- /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 305f3b71..de00d0f3 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 a912732b..f8e68617 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 5ef19a51..8489c960 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 0d98a8e5..737974e6 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 0757a5c4..685ee98a 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 9fa348d3..30b77eed 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 028ec7e1..9f10659c 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 ae62be2d..675cdad5 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]);