diff --git a/Makefile.am b/Makefile.am index cf346a1d5..db6e107bc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -55,6 +55,7 @@ cpuminer_SOURCES = \ algo/bmw256.c \ algo/c11.c \ algo/cryptonight.c \ + algo/cryptolight.c \ algo/drop.c \ algo/fresh.c \ algo/groestl.c \ diff --git a/NEWS b/NEWS index a63983363..3fa5446c0 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,9 @@ +Version 1.2 +- Add cryptonight-light (Aeon) + +TODO: +- Lyra2v2, arm compat, multipool config + version 1.1 (Tanguy Pruvot) - Add basic API remote control (quit/seturl) - Add GroestlCoin, Diamond and Myriad variants diff --git a/README.md b/README.md index 12900cef8..7a0cbd85e 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ Algorithms * ✓ __blake__ (Saffron [SFR] Blake-256) * ✓ __bmw__ (Midnight [MDT] BMW-256) * ✓ __cryptonight__ (Bytecoin [BCN], Monero) + * ✓ __cryptonight-light__ (Aeon) * ✓ __dmd-gr__ (Diamond-Groestl) * ✓ __fresh__ (FreshCoin) * ✓ __groestl__ (Groestlcoin) diff --git a/algo/cryptolight.c b/algo/cryptolight.c new file mode 100644 index 000000000..79db0ec97 --- /dev/null +++ b/algo/cryptolight.c @@ -0,0 +1,349 @@ +// Copyright (c) 2012-2013 The Cryptonote developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "miner.h" + +#if defined(__arm__) || defined(_MSC_VER) +#ifndef NOASM +#define NOASM +#endif +#endif + +#include "crypto/oaes_lib.h" +#include "crypto/c_keccak.h" +#include "crypto/c_groestl.h" +#include "crypto/c_blake256.h" +#include "crypto/c_jh.h" +#include "crypto/c_skein.h" +#include "crypto/int-util.h" +#include "crypto/hash-ops.h" + +#if USE_INT128 + +#if __GNUC__ == 4 && __GNUC_MINOR__ >= 4 && __GNUC_MINOR__ < 6 +typedef unsigned int uint128_t __attribute__ ((__mode__ (TI))); +#elif defined (_MSC_VER) +/* only for mingw64 on windows */ +#undef USE_INT128 +#define USE_INT128 (0) +#else +typedef __uint128_t uint128_t; +#endif + +#endif + +#define LITE 1 +#if LITE /* cryptonight-light */ +#define MEMORY (1 << 20) +#define ITER (1 << 19) +#else +#define MEMORY (1 << 21) /* 2 MiB */ +#define ITER (1 << 20) +#endif + +#define AES_BLOCK_SIZE 16 +#define AES_KEY_SIZE 32 /*16*/ +#define INIT_SIZE_BLK 8 +#define INIT_SIZE_BYTE (INIT_SIZE_BLK * AES_BLOCK_SIZE) + +#pragma pack(push, 1) +union cn_slow_hash_state { + union hash_state hs; + struct { + uint8_t k[64]; + uint8_t init[INIT_SIZE_BYTE]; + }; +}; +#pragma pack(pop) + +static void do_blake_hash(const void* input, size_t len, char* output) { + blake256_hash((uint8_t*)output, input, len); +} + +static void do_groestl_hash(const void* input, size_t len, char* output) { + groestl(input, len * 8, (uint8_t*)output); +} + +static void do_jh_hash(const void* input, size_t len, char* output) { + int r = jh_hash(HASH_SIZE * 8, input, 8 * len, (uint8_t*)output); + assert(likely(SUCCESS == r)); +} + +static void do_skein_hash(const void* input, size_t len, char* output) { + int r = skein_hash(8 * HASH_SIZE, input, 8 * len, (uint8_t*)output); + assert(likely(SKEIN_SUCCESS == r)); +} + +extern int aesb_single_round(const uint8_t *in, uint8_t*out, const uint8_t *expandedKey); +extern int aesb_pseudo_round_mut(uint8_t *val, uint8_t *expandedKey); +#if !defined(_MSC_VER) && !defined(NOASM) +extern int fast_aesb_single_round(const uint8_t *in, uint8_t*out, const uint8_t *expandedKey); +extern int fast_aesb_pseudo_round_mut(uint8_t *val, uint8_t *expandedKey); +#else +#define fast_aesb_single_round aesb_single_round +#define fast_aesb_pseudo_round_mut aesb_pseudo_round_mut +#endif + +#if defined(NOASM) || !defined(__x86_64__) +static uint64_t mul128(uint64_t multiplier, uint64_t multiplicand, uint64_t* product_hi) { + // multiplier = ab = a * 2^32 + b + // multiplicand = cd = c * 2^32 + d + // ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d + uint64_t a = hi_dword(multiplier); + uint64_t b = lo_dword(multiplier); + uint64_t c = hi_dword(multiplicand); + uint64_t d = lo_dword(multiplicand); + + uint64_t ac = a * c; + uint64_t ad = a * d; + uint64_t bc = b * c; + uint64_t bd = b * d; + + uint64_t adbc = ad + bc; + uint64_t adbc_carry = adbc < ad ? 1 : 0; + + // multiplier * multiplicand = product_hi * 2^64 + product_lo + uint64_t product_lo = bd + (adbc << 32); + uint64_t product_lo_carry = product_lo < bd ? 1 : 0; + *product_hi = ac + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry; + assert(ac <= *product_hi); + + return product_lo; +} +#else +extern uint64_t mul128(uint64_t multiplier, uint64_t multiplicand, uint64_t* product_hi); +#endif + +static void (* const extra_hashes[4])(const void *, size_t, char *) = { + do_blake_hash, do_groestl_hash, do_jh_hash, do_skein_hash +}; + + +static inline size_t e2i(const uint8_t* a) { +#if !LITE + return ((uint32_t *)a)[0] & 0x1FFFF0; +#else + return ((uint32_t *)a)[0] & 0xFFFF0; +#endif +} + +static inline void mul_sum_xor_dst(const uint8_t* a, uint8_t* c, uint8_t* dst) { + uint64_t hi, lo = mul128(((uint64_t*) a)[0], ((uint64_t*) dst)[0], &hi) + ((uint64_t*) c)[1]; + hi += ((uint64_t*) c)[0]; + + ((uint64_t*) c)[0] = ((uint64_t*) dst)[0] ^ hi; + ((uint64_t*) c)[1] = ((uint64_t*) dst)[1] ^ lo; + ((uint64_t*) dst)[0] = hi; + ((uint64_t*) dst)[1] = lo; +} + +static inline void xor_blocks(uint8_t* a, const uint8_t* b) { +#if USE_INT128 + *((uint128_t*) a) ^= *((uint128_t*) b); +#else + ((uint64_t*) a)[0] ^= ((uint64_t*) b)[0]; + ((uint64_t*) a)[1] ^= ((uint64_t*) b)[1]; +#endif +} + +static inline void xor_blocks_dst(const uint8_t* a, const uint8_t* b, uint8_t* dst) { +#if USE_INT128 + *((uint128_t*) dst) = *((uint128_t*) a) ^ *((uint128_t*) b); +#else + ((uint64_t*) dst)[0] = ((uint64_t*) a)[0] ^ ((uint64_t*) b)[0]; + ((uint64_t*) dst)[1] = ((uint64_t*) a)[1] ^ ((uint64_t*) b)[1]; +#endif +} + +struct cryptonight_ctx { + uint8_t _ALIGN(16) long_state[MEMORY]; + union cn_slow_hash_state state; + uint8_t _ALIGN(16) text[INIT_SIZE_BYTE]; + uint8_t _ALIGN(16) a[AES_BLOCK_SIZE]; + uint8_t _ALIGN(16) b[AES_BLOCK_SIZE]; + uint8_t _ALIGN(16) c[AES_BLOCK_SIZE]; + oaes_ctx* aes_ctx; +}; + +static void cryptolight_hash_ctx(void* output, const void* input, int len, struct cryptonight_ctx* ctx) +{ + hash_process(&ctx->state.hs, (const uint8_t*) input, len); + ctx->aes_ctx = (oaes_ctx*) oaes_alloc(); + size_t i, j; + memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE); + + oaes_key_import_data(ctx->aes_ctx, ctx->state.hs.b, AES_KEY_SIZE); + for (i = 0; likely(i < MEMORY); i += INIT_SIZE_BYTE) { + aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 0], ctx->aes_ctx->key->exp_data); + aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 1], ctx->aes_ctx->key->exp_data); + aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 2], ctx->aes_ctx->key->exp_data); + aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 3], ctx->aes_ctx->key->exp_data); + aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 4], ctx->aes_ctx->key->exp_data); + aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 5], ctx->aes_ctx->key->exp_data); + aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 6], ctx->aes_ctx->key->exp_data); + aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 7], ctx->aes_ctx->key->exp_data); + memcpy(&ctx->long_state[i], ctx->text, INIT_SIZE_BYTE); + } + + xor_blocks_dst(&ctx->state.k[0], &ctx->state.k[32], ctx->a); + xor_blocks_dst(&ctx->state.k[16], &ctx->state.k[48], ctx->b); + + for (i = 0; likely(i < ITER / 4); ++i) { + /* Dependency chain: address -> read value ------+ + * written value <-+ hard function (AES or MUL) <+ + * next address <-+ + */ + /* Iteration 1 */ + j = e2i(ctx->a); + aesb_single_round(&ctx->long_state[j], ctx->c, ctx->a); + xor_blocks_dst(ctx->c, ctx->b, &ctx->long_state[j]); + /* Iteration 2 */ + mul_sum_xor_dst(ctx->c, ctx->a, &ctx->long_state[e2i(ctx->c)]); + /* Iteration 3 */ + j = e2i(ctx->a); + aesb_single_round(&ctx->long_state[j], ctx->b, ctx->a); + xor_blocks_dst(ctx->b, ctx->c, &ctx->long_state[j]); + /* Iteration 4 */ + mul_sum_xor_dst(ctx->b, ctx->a, &ctx->long_state[e2i(ctx->b)]); + } + + memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE); + oaes_key_import_data(ctx->aes_ctx, &ctx->state.hs.b[32], AES_KEY_SIZE); + for (i = 0; likely(i < MEMORY); i += INIT_SIZE_BYTE) { + xor_blocks(&ctx->text[0 * AES_BLOCK_SIZE], &ctx->long_state[i + 0 * AES_BLOCK_SIZE]); + aesb_pseudo_round_mut(&ctx->text[0 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data); + xor_blocks(&ctx->text[1 * AES_BLOCK_SIZE], &ctx->long_state[i + 1 * AES_BLOCK_SIZE]); + aesb_pseudo_round_mut(&ctx->text[1 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data); + xor_blocks(&ctx->text[2 * AES_BLOCK_SIZE], &ctx->long_state[i + 2 * AES_BLOCK_SIZE]); + aesb_pseudo_round_mut(&ctx->text[2 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data); + xor_blocks(&ctx->text[3 * AES_BLOCK_SIZE], &ctx->long_state[i + 3 * AES_BLOCK_SIZE]); + aesb_pseudo_round_mut(&ctx->text[3 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data); + xor_blocks(&ctx->text[4 * AES_BLOCK_SIZE], &ctx->long_state[i + 4 * AES_BLOCK_SIZE]); + aesb_pseudo_round_mut(&ctx->text[4 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data); + xor_blocks(&ctx->text[5 * AES_BLOCK_SIZE], &ctx->long_state[i + 5 * AES_BLOCK_SIZE]); + aesb_pseudo_round_mut(&ctx->text[5 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data); + xor_blocks(&ctx->text[6 * AES_BLOCK_SIZE], &ctx->long_state[i + 6 * AES_BLOCK_SIZE]); + aesb_pseudo_round_mut(&ctx->text[6 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data); + xor_blocks(&ctx->text[7 * AES_BLOCK_SIZE], &ctx->long_state[i + 7 * AES_BLOCK_SIZE]); + aesb_pseudo_round_mut(&ctx->text[7 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data); + } + memcpy(ctx->state.init, ctx->text, INIT_SIZE_BYTE); + hash_permutation(&ctx->state.hs); + /*memcpy(hash, &state, 32);*/ + extra_hashes[ctx->state.hs.b[0] & 3](&ctx->state, 200, output); + oaes_free((OAES_CTX **) &ctx->aes_ctx); +} + +void cryptolight_hash(void* output, const void* input, int len) { + struct cryptonight_ctx *ctx = (struct cryptonight_ctx*)malloc(sizeof(struct cryptonight_ctx)); + cryptolight_hash_ctx(output, input, len, ctx); + free(ctx); +} + +static void cryptolight_hash_ctx_aes_ni(void* output, const void* input, int len, struct cryptonight_ctx* ctx) +{ + hash_process(&ctx->state.hs, (const uint8_t*)input, len); + ctx->aes_ctx = (oaes_ctx*) oaes_alloc(); + size_t i, j; + memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE); + + oaes_key_import_data(ctx->aes_ctx, ctx->state.hs.b, AES_KEY_SIZE); + for (i = 0; likely(i < MEMORY); i += INIT_SIZE_BYTE) { + fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 0], ctx->aes_ctx->key->exp_data); + fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 1], ctx->aes_ctx->key->exp_data); + fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 2], ctx->aes_ctx->key->exp_data); + fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 3], ctx->aes_ctx->key->exp_data); + fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 4], ctx->aes_ctx->key->exp_data); + fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 5], ctx->aes_ctx->key->exp_data); + fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 6], ctx->aes_ctx->key->exp_data); + fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 7], ctx->aes_ctx->key->exp_data); + memcpy(&ctx->long_state[i], ctx->text, INIT_SIZE_BYTE); + } + + xor_blocks_dst(&ctx->state.k[0], &ctx->state.k[32], ctx->a); + xor_blocks_dst(&ctx->state.k[16], &ctx->state.k[48], ctx->b); + + for (i = 0; likely(i < ITER / 4); ++i) { + /* Dependency chain: address -> read value ------+ + * written value <-+ hard function (AES or MUL) <+ + * next address <-+ + */ + /* Iteration 1 */ + j = e2i(ctx->a); + fast_aesb_single_round(&ctx->long_state[j], ctx->c, ctx->a); + xor_blocks_dst(ctx->c, ctx->b, &ctx->long_state[j]); + /* Iteration 2 */ + mul_sum_xor_dst(ctx->c, ctx->a, &ctx->long_state[e2i(ctx->c)]); + /* Iteration 3 */ + j = e2i(ctx->a); + fast_aesb_single_round(&ctx->long_state[j], ctx->b, ctx->a); + xor_blocks_dst(ctx->b, ctx->c, &ctx->long_state[j]); + /* Iteration 4 */ + mul_sum_xor_dst(ctx->b, ctx->a, &ctx->long_state[e2i(ctx->b)]); + } + + memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE); + oaes_key_import_data(ctx->aes_ctx, &ctx->state.hs.b[32], AES_KEY_SIZE); + for (i = 0; likely(i < MEMORY); i += INIT_SIZE_BYTE) { + xor_blocks(&ctx->text[0 * AES_BLOCK_SIZE], &ctx->long_state[i + 0 * AES_BLOCK_SIZE]); + fast_aesb_pseudo_round_mut(&ctx->text[0 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data); + xor_blocks(&ctx->text[1 * AES_BLOCK_SIZE], &ctx->long_state[i + 1 * AES_BLOCK_SIZE]); + fast_aesb_pseudo_round_mut(&ctx->text[1 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data); + xor_blocks(&ctx->text[2 * AES_BLOCK_SIZE], &ctx->long_state[i + 2 * AES_BLOCK_SIZE]); + fast_aesb_pseudo_round_mut(&ctx->text[2 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data); + xor_blocks(&ctx->text[3 * AES_BLOCK_SIZE], &ctx->long_state[i + 3 * AES_BLOCK_SIZE]); + fast_aesb_pseudo_round_mut(&ctx->text[3 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data); + xor_blocks(&ctx->text[4 * AES_BLOCK_SIZE], &ctx->long_state[i + 4 * AES_BLOCK_SIZE]); + fast_aesb_pseudo_round_mut(&ctx->text[4 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data); + xor_blocks(&ctx->text[5 * AES_BLOCK_SIZE], &ctx->long_state[i + 5 * AES_BLOCK_SIZE]); + fast_aesb_pseudo_round_mut(&ctx->text[5 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data); + xor_blocks(&ctx->text[6 * AES_BLOCK_SIZE], &ctx->long_state[i + 6 * AES_BLOCK_SIZE]); + fast_aesb_pseudo_round_mut(&ctx->text[6 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data); + xor_blocks(&ctx->text[7 * AES_BLOCK_SIZE], &ctx->long_state[i + 7 * AES_BLOCK_SIZE]); + fast_aesb_pseudo_round_mut(&ctx->text[7 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data); + } + memcpy(ctx->state.init, ctx->text, INIT_SIZE_BYTE); + hash_permutation(&ctx->state.hs); + /*memcpy(hash, &state, 32);*/ + extra_hashes[ctx->state.hs.b[0] & 3](&ctx->state, 200, output); + oaes_free((OAES_CTX **) &ctx->aes_ctx); +} + +int scanhash_cryptolight(int thr_id, uint32_t *pdata, const uint32_t *ptarget, + uint32_t max_nonce, uint64_t *hashes_done) +{ + uint32_t *nonceptr = (uint32_t*) (((char*)pdata) + 39); + uint32_t n = *nonceptr - 1; + const uint32_t first_nonce = n + 1; + //const uint32_t Htarg = ptarget[7]; + uint32_t _ALIGN(32) hash[HASH_SIZE / 4]; + + struct cryptonight_ctx *ctx = (struct cryptonight_ctx*)malloc(sizeof(struct cryptonight_ctx)); + + if (aes_ni_supported) { + do { + *nonceptr = ++n; + cryptolight_hash_ctx_aes_ni(hash, pdata, 76, ctx); + if (unlikely(hash[7] < ptarget[7])) { + *hashes_done = n - first_nonce + 1; + free(ctx); + return true; + } + } while (likely((n <= max_nonce && !work_restart[thr_id].restart))); + } else { + do { + *nonceptr = ++n; + cryptolight_hash_ctx(hash, pdata, 76, ctx); + if (unlikely(hash[7] < ptarget[7])) { + *hashes_done = n - first_nonce + 1; + free(ctx); + return true; + } + } while (likely((n <= max_nonce && !work_restart[thr_id].restart))); + } + + free(ctx); + *hashes_done = n - first_nonce + 1; + return 0; +} diff --git a/algo/cryptonight.c b/algo/cryptonight.c index 53f36f2c9..46d051bf6 100644 --- a/algo/cryptonight.c +++ b/algo/cryptonight.c @@ -63,7 +63,7 @@ static void do_blake_hash(const void* input, size_t len, char* output) { blake256_hash((uint8_t*)output, input, len); } -void do_groestl_hash(const void* input, size_t len, char* output) { +static void do_groestl_hash(const void* input, size_t len, char* output) { groestl(input, len * 8, (uint8_t*)output); } @@ -168,7 +168,8 @@ struct cryptonight_ctx { oaes_ctx* aes_ctx; }; -void cryptonight_hash_ctx(void* output, const void* input, int len, struct cryptonight_ctx* ctx) { +static void cryptonight_hash_ctx(void* output, const void* input, int len, struct cryptonight_ctx* ctx) +{ hash_process(&ctx->state.hs, (const uint8_t*) input, len); ctx->aes_ctx = (oaes_ctx*) oaes_alloc(); size_t i, j; @@ -242,7 +243,8 @@ void cryptonight_hash(void* output, const void* input, int len) { free(ctx); } -void cryptonight_hash_ctx_aes_ni(void* output, const void* input, int len, struct cryptonight_ctx* ctx) { +static void cryptonight_hash_ctx_aes_ni(void* output, const void* input, int len, struct cryptonight_ctx* ctx) +{ hash_process(&ctx->state.hs, (const uint8_t*)input, len); ctx->aes_ctx = (oaes_ctx*) oaes_alloc(); size_t i, j; diff --git a/compat/cpuminer-config.h b/compat/cpuminer-config.h index 691f1b2c6..a54fa7c7f 100644 --- a/compat/cpuminer-config.h +++ b/compat/cpuminer-config.h @@ -94,7 +94,7 @@ #define PACKAGE_NAME "cpuminer-multi" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "cpuminer-multi 1.1-git" +#define PACKAGE_STRING "cpuminer-multi 1.2" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "cpuminer-multi" @@ -103,7 +103,7 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "1.1-git" +#define PACKAGE_VERSION "1.2-dev" /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be @@ -132,7 +132,7 @@ #define USE_XOP 1 /* Version number of package */ -#define VERSION "1.1-git" +#define VERSION "1.2-dev" /* Define to `unsigned int' if does not define. */ /* #undef size_t */ diff --git a/configure.ac b/configure.ac index b07ea88d8..7f686e6e9 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([cpuminer-multi], [1.1]) +AC_INIT([cpuminer-multi], [1.2-dev]) AC_PREREQ([2.59c]) AC_CANONICAL_SYSTEM diff --git a/cpu-miner.c b/cpu-miner.c index a771cfc99..42a020c7b 100644 --- a/cpu-miner.c +++ b/cpu-miner.c @@ -85,6 +85,7 @@ enum algos { ALGO_BLAKE2S, /* Blake2s */ ALGO_BMW, /* BMW 256 */ ALGO_C11, /* C11 Chaincoin/Flaxcoin X11 variant */ + ALGO_CRYPTOLIGHT, /* cryptonight-light (Aeon) */ ALGO_CRYPTONIGHT, /* CryptoNight */ ALGO_DMD_GR, /* Diamond */ ALGO_DROP, /* Dropcoin */ @@ -123,6 +124,7 @@ static const char *algo_names[] = { "blake2s", "bmw", "c11", + "cryptolight", "cryptonight", "dmd-gr", "drop", @@ -254,7 +256,8 @@ Options:\n\ blake2s Blake-2 S\n\ bmw BMW 256\n\ c11/flax C11\n\ - cryptonight CryptoNight\n\ + cryptolight Cryptonight-light\n\ + cryptonight Monero\n\ dmd-gr Diamond-Groestl\n\ drop Dropcoin\n\ fresh Fresh\n\ @@ -895,6 +898,7 @@ static int share_result(int result, struct work *work, const char *reason) switch (opt_algo) { case ALGO_AXIOM: + case ALGO_CRYPTOLIGHT: case ALGO_CRYPTONIGHT: case ALGO_PLUCK: sprintf(s, hashrate >= 1e6 ? "%.0f" : "%.2f", hashrate); @@ -954,8 +958,10 @@ static bool submit_upstream_work(CURL *curl, struct work *work) bin2hex(noncestr, (const unsigned char *)work->data + 39, 4); switch(opt_algo) { + case ALGO_CRYPTOLIGHT: + cryptolight_hash(hash, work->data, 76); + break; case ALGO_CRYPTONIGHT: - default: cryptonight_hash(hash, work->data, 76); } char *hashhex = abin2hex(hash, 32); @@ -1056,8 +1062,10 @@ static bool submit_upstream_work(CURL *curl, struct work *work) bin2hex(noncestr, (const unsigned char *)work->data + 39, 4); switch(opt_algo) { + case ALGO_CRYPTOLIGHT: + cryptolight_hash(hash, work->data, 76); + break; case ALGO_CRYPTONIGHT: - default: cryptonight_hash(hash, work->data, 76); } hashhex = abin2hex(&hash[0], 32); @@ -1828,6 +1836,7 @@ static void *miner_thread(void *userdata) max64 = 0xF; break; case ALGO_AXIOM: + case ALGO_CRYPTOLIGHT: case ALGO_CRYPTONIGHT: max64 = 0x40LL; break; @@ -1933,6 +1942,12 @@ static void *miner_thread(void *userdata) case ALGO_C11: rc = scanhash_c11(thr_id, work.data, work.target, max_nonce, &hashes_done); break; + case ALGO_CRYPTOLIGHT: + rc = scanhash_cryptolight(thr_id, work.data, work.target, max_nonce, &hashes_done); + break; + case ALGO_CRYPTONIGHT: + rc = scanhash_cryptonight(thr_id, work.data, work.target, max_nonce, &hashes_done); + break; case ALGO_DROP: rc = scanhash_drop(thr_id, &work, max_nonce, &hashes_done); break; @@ -2008,11 +2023,6 @@ static void *miner_thread(void *userdata) rc = scanhash_pentablake(thr_id, work.data, work.target, max_nonce, &hashes_done); break; - case ALGO_CRYPTONIGHT: - rc = scanhash_cryptonight(thr_id, work.data, work.target, - max_nonce, &hashes_done); - break; - default: /* should never happen */ goto out; @@ -2030,6 +2040,7 @@ static void *miner_thread(void *userdata) if (!opt_quiet) { switch(opt_algo) { case ALGO_AXIOM: + case ALGO_CRYPTOLIGHT: case ALGO_CRYPTONIGHT: case ALGO_PLUCK: applog(LOG_INFO, "CPU #%d: %.2f H/s", thr_id, thr_hashrates[thr_id]); @@ -2047,6 +2058,7 @@ static void *miner_thread(void *userdata) hashrate += thr_hashrates[i]; if (i == opt_n_threads) { switch(opt_algo) { + case ALGO_CRYPTOLIGHT: case ALGO_CRYPTONIGHT: sprintf(s, "%.3f", hashrate); applog(LOG_NOTICE, "Total: %s H/s", s); @@ -2460,6 +2472,8 @@ void parse_arg(int key, char *arg) // some aliases... if (!strcasecmp("blake2", arg)) i = opt_algo = ALGO_BLAKE2S; + else if (!strcasecmp("cryptonight-light", arg)) + i = opt_algo = ALGO_CRYPTOLIGHT; else if (!strcasecmp("flax", arg)) i = opt_algo = ALGO_C11; else if (!strcasecmp("diamond", arg)) @@ -2942,7 +2956,7 @@ int main(int argc, char *argv[]) { if (opt_algo == ALGO_QUARK) { init_quarkhash_contexts(); - } else if(opt_algo == ALGO_CRYPTONIGHT) { + } else if(opt_algo == ALGO_CRYPTONIGHT || opt_algo == ALGO_CRYPTOLIGHT) { jsonrpc_2 = true; opt_extranonce = false; aes_ni_supported = has_aes_ni(); diff --git a/cpuminer.vcxproj b/cpuminer.vcxproj index 51ae2036e..1c5b8b77d 100644 --- a/cpuminer.vcxproj +++ b/cpuminer.vcxproj @@ -207,6 +207,7 @@ + diff --git a/cpuminer.vcxproj.filters b/cpuminer.vcxproj.filters index 50ed6bb49..8b45d6f7e 100644 --- a/cpuminer.vcxproj.filters +++ b/cpuminer.vcxproj.filters @@ -170,6 +170,9 @@ algo + + algo + algo @@ -508,4 +511,4 @@ res - \ No newline at end of file + diff --git a/crypto/oaes_lib.c b/crypto/oaes_lib.c index 77030c823..4cc7ae3bc 100644 --- a/crypto/oaes_lib.c +++ b/crypto/oaes_lib.c @@ -64,7 +64,7 @@ static int ftime(struct timeb* tb) { return -1; tb->time = tv.tv_sec; - tb->millitm = (tv.tv_usec + 500) / 1000; + tb->millitm = (unsigned short) ((tv.tv_usec + 500) / 1000); if (tb->millitm == 1000) { ++tb->time; diff --git a/m4/.gitignore b/m4/.gitignore new file mode 100644 index 000000000..e69de29bb diff --git a/miner.h b/miner.h index 9466397ed..c6d4a32a6 100644 --- a/miner.h +++ b/miner.h @@ -287,7 +287,8 @@ int scanhash_x15(int thr_id, uint32_t *pdata, const uint32_t *ptarget, int scanhash_zr5(int thr_id, struct work *work, uint32_t max_nonce, uint64_t *hashes_done); -void cryptonight_hash(void* output, const void* input, int input_len); +int scanhash_cryptolight(int thr_id, uint32_t *pdata, const uint32_t *ptarget, + uint32_t max_nonce, uint64_t *hashes_done); int scanhash_cryptonight(int thr_id, uint32_t *pdata, const uint32_t *ptarget, uint32_t max_nonce, uint64_t *hashes_done); @@ -514,6 +515,7 @@ void blakecoinhash(void *state, const void *input); void blake2s_hash(void *output, const void *input); void bmwhash(void *output, const void *input); void c11hash(void *output, const void *input); +void cryptolight_hash(void* output, const void* input, int len); void cryptonight_hash(void* output, const void* input, int len); void droplp_hash(void *output, const void *input); void groestlhash(void *output, const void *input); diff --git a/util.c b/util.c index 2aee3ce64..14734898b 100644 --- a/util.c +++ b/util.c @@ -2020,6 +2020,9 @@ void print_hash_tests(void) c11hash(&hash[0], &buf[0]); printpfx("c11", hash); + cryptolight_hash(&hash[0], &buf[0], 76); + printpfx("cryptolight", hash); + cryptonight_hash(&hash[0], &buf[0], 76); printpfx("cryptonight", hash);