From 5e6a69e16fb79e49dd28253fd169800a6ff29ccd Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 3 Mar 2019 14:09:00 +0700 Subject: [PATCH] Prepare for cn/r. --- CMakeLists.txt | 4 + algo/cryptonight/cryptonight.c | 33 +++++- algo/cryptonight/cryptonight.h | 36 ++++++- algo/cryptonight/cryptonight_r_av1.c | 146 +++++++++++++++++++++++++++ algo/cryptonight/cryptonight_r_av2.c | 135 +++++++++++++++++++++++++ algo/cryptonight/cryptonight_r_av3.c | 92 +++++++++++++++++ algo/cryptonight/cryptonight_r_av4.c | 135 +++++++++++++++++++++++++ options.c | 18 +++- options.h | 6 +- version.h | 9 +- xmrig.c | 2 +- 11 files changed, 595 insertions(+), 21 deletions(-) create mode 100644 algo/cryptonight/cryptonight_r_av1.c create mode 100644 algo/cryptonight/cryptonight_r_av2.c create mode 100644 algo/cryptonight/cryptonight_r_av3.c create mode 100644 algo/cryptonight/cryptonight_r_av4.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 51b8b167d..6607478dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,10 @@ set(SOURCES algo/cryptonight/cryptonight_av2.c algo/cryptonight/cryptonight_av3.c algo/cryptonight/cryptonight_av4.c + algo/cryptonight/cryptonight_r_av1.c + algo/cryptonight/cryptonight_r_av2.c + algo/cryptonight/cryptonight_r_av3.c + algo/cryptonight/cryptonight_r_av4.c util.c options.c stratum.c diff --git a/algo/cryptonight/cryptonight.c b/algo/cryptonight/cryptonight.c index 62dbdc507..1a14134da 100644 --- a/algo/cryptonight/cryptonight.c +++ b/algo/cryptonight/cryptonight.c @@ -6,7 +6,8 @@ * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , * Copyright 2018 Lee Clagett - * Copyright 2016-2018 XMRig , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -56,6 +57,11 @@ void cryptonight_av4_v0(const uint8_t *input, size_t size, uint8_t *output, stru void cryptonight_av4_v1(const uint8_t *input, size_t size, uint8_t *output, struct cryptonight_ctx **ctx); void cryptonight_av4_v2(const uint8_t *input, size_t size, uint8_t *output, struct cryptonight_ctx **ctx); +void cryptonight_r_av1(const uint8_t *input, size_t size, uint8_t *output, struct cryptonight_ctx **ctx); +void cryptonight_r_av2(const uint8_t *input, size_t size, uint8_t *output, struct cryptonight_ctx **ctx); +void cryptonight_r_av3(const uint8_t *input, size_t size, uint8_t *output, struct cryptonight_ctx **ctx); +void cryptonight_r_av4(const uint8_t *input, size_t size, uint8_t *output, struct cryptonight_ctx **ctx); + #ifndef XMRIG_NO_AEON void cryptonight_lite_av1_v0(const uint8_t *input, size_t size, uint8_t *output, struct cryptonight_ctx **ctx); @@ -97,7 +103,7 @@ static bool self_test() { const size_t size = opt_algo == ALGO_CRYPTONIGHT ? MEMORY : MEMORY_LITE; bool result = false; - for (int i = 0; i < count; ++i) { + for (size_t i = 0; i < count; ++i) { ctx[i] = _mm_malloc(sizeof(struct cryptonight_ctx), 16); ctx[i]->memory = _mm_malloc(size, 16); } @@ -115,7 +121,7 @@ static bool self_test() { # endif - for (int i = 0; i < count; ++i) { + for (size_t i = 0; i < count; ++i) { _mm_free(ctx[i]->memory); _mm_free(ctx[i]); } @@ -177,6 +183,11 @@ cn_hash_fun cryptonight_hash_fn(enum Algo algorithm, enum AlgoVariant av, enum V cryptonight_av3_v2, cryptonight_av4_v2, + cryptonight_r_av1, + cryptonight_r_av2, + cryptonight_r_av3, + cryptonight_r_av4, + # ifndef XMRIG_NO_AEON cryptonight_lite_av1_v0, cryptonight_lite_av2_v0, @@ -190,6 +201,10 @@ cn_hash_fun cryptonight_hash_fn(enum Algo algorithm, enum AlgoVariant av, enum V NULL, NULL, NULL, + NULL, + NULL, + NULL, + NULL, # else NULL, NULL, @@ -203,6 +218,10 @@ cn_hash_fun cryptonight_hash_fn(enum Algo algorithm, enum AlgoVariant av, enum V NULL, NULL, NULL, + NULL, + NULL, + NULL, + NULL, # endif # ifndef XMRIG_NO_ASM cryptonight_single_hash_asm_intel, @@ -267,6 +286,10 @@ static inline enum Variant cryptonight_variant(uint8_t version) return VARIANT_1; } + if (version >= 10) { + return VARIANT_4; + } + if (version >= 8) { return VARIANT_2; } @@ -276,7 +299,7 @@ static inline enum Variant cryptonight_variant(uint8_t version) #ifndef BUILD_TEST -int scanhash_cryptonight(int thr_id, uint32_t *hash, const uint8_t *restrict blob, size_t blob_size, uint32_t target, uint32_t max_nonce, unsigned long *restrict hashes_done, struct cryptonight_ctx **restrict ctx) { +int scanhash_cryptonight(int thr_id, uint32_t *hash, uint8_t *restrict blob, size_t blob_size, uint32_t target, uint32_t max_nonce, unsigned long *restrict hashes_done, struct cryptonight_ctx **restrict ctx) { uint32_t *nonceptr = (uint32_t*) (((char*) blob) + 39); enum Variant variant = cryptonight_variant(blob[0]); @@ -296,7 +319,7 @@ int scanhash_cryptonight(int thr_id, uint32_t *hash, const uint8_t *restrict blo } -int scanhash_cryptonight_double(int thr_id, uint32_t *hash, const uint8_t *restrict blob, size_t blob_size, uint32_t target, uint32_t max_nonce, unsigned long *restrict hashes_done, struct cryptonight_ctx **restrict ctx) { +int scanhash_cryptonight_double(int thr_id, uint32_t *hash, uint8_t *restrict blob, size_t blob_size, uint32_t target, uint32_t max_nonce, unsigned long *restrict hashes_done, struct cryptonight_ctx **restrict ctx) { int rc = 0; uint32_t *nonceptr0 = (uint32_t*) (((char*) blob) + 39); uint32_t *nonceptr1 = (uint32_t*) (((char*) blob) + 39 + blob_size); diff --git a/algo/cryptonight/cryptonight.h b/algo/cryptonight/cryptonight.h index 74646ef5b..da6a8ecfc 100644 --- a/algo/cryptonight/cryptonight.h +++ b/algo/cryptonight/cryptonight.h @@ -6,7 +6,8 @@ * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , * Copyright 2018 Lee Clagett - * Copyright 2016-2018 XMRig , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -38,9 +39,35 @@ #define MEMORY_LITE 1048576 /* 1 MiB */ +#if defined _MSC_VER || defined XMRIG_ARM +#define ABI_ATTRIBUTE +#else +#define ABI_ATTRIBUTE __attribute__((ms_abi)) +#endif + + +struct cryptonight_ctx; +typedef void(*cn_mainloop_fun_ms_abi)(struct cryptonight_ctx*) ABI_ATTRIBUTE; +typedef void(*cn_mainloop_double_fun_ms_abi)(struct cryptonight_ctx*, struct cryptonight_ctx*) ABI_ATTRIBUTE; + + +struct cryptonight_r_data { + int variant; + uint64_t height; +}; + + struct cryptonight_ctx { uint8_t state[224] __attribute__((aligned(16))); - uint8_t* memory __attribute__((aligned(16))); + uint8_t *memory __attribute__((aligned(16))); + + uint8_t unused[40]; + const uint32_t *saes_table; + + cn_mainloop_fun_ms_abi generated_code; + cn_mainloop_double_fun_ms_abi generated_code_double; + struct cryptonight_r_data generated_code_data; + struct cryptonight_r_data generated_code_double_data; }; @@ -52,7 +79,8 @@ extern void (* const extra_hashes[4])(const void *, size_t, char *); cn_hash_fun cryptonight_hash_fn(enum Algo algorithm, enum AlgoVariant av, enum Variant variant); bool cryptonight_init(int av); -int scanhash_cryptonight(int thr_id, uint32_t *hash, const uint8_t *restrict blob, size_t blob_size, uint32_t target, uint32_t max_nonce, unsigned long *restrict hashes_done, struct cryptonight_ctx **restrict ctx); -int scanhash_cryptonight_double(int thr_id, uint32_t *hash, const uint8_t *restrict blob, size_t blob_size, uint32_t target, uint32_t max_nonce, unsigned long *restrict hashes_done, struct cryptonight_ctx **restrict ctx); +int scanhash_cryptonight(int thr_id, uint32_t *hash, uint8_t *blob, size_t blob_size, uint32_t target, uint32_t max_nonce, unsigned long *hashes_done, struct cryptonight_ctx **ctx); +int scanhash_cryptonight_double(int thr_id, uint32_t *hash, uint8_t *blob, size_t blob_size, uint32_t target, uint32_t max_nonce, unsigned long *hashes_done, struct cryptonight_ctx **ctx); + #endif /* XMRIG_CRYPTONIGHT_H */ diff --git a/algo/cryptonight/cryptonight_r_av1.c b/algo/cryptonight/cryptonight_r_av1.c new file mode 100644 index 000000000..145022d8a --- /dev/null +++ b/algo/cryptonight/cryptonight_r_av1.c @@ -0,0 +1,146 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017 fireice-uk + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "crypto/c_keccak.h" +#include "cryptonight.h" +#include "cryptonight_aesni.h" +#include "cryptonight_monero.h" + + +void cryptonight_r_av1(const uint8_t *restrict input, size_t size, uint8_t *restrict output, struct cryptonight_ctx **restrict ctx) +{ + keccak(input, size, ctx[0]->state, 200); + + cn_explode_scratchpad((__m128i*) ctx[0]->state, (__m128i*) ctx[0]->memory); + + const uint8_t* l0 = ctx[0]->memory; + uint64_t* h0 = (uint64_t*) ctx[0]->state; + + VARIANT2_INIT(0); + VARIANT2_SET_ROUNDING_MODE(); + + uint64_t al0 = h0[0] ^ h0[4]; + uint64_t ah0 = h0[1] ^ h0[5]; + __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); + __m128i bx1 = _mm_set_epi64x(h0[9] ^ h0[11], h0[8] ^ h0[10]); + + uint64_t idx0 = al0; + + for (size_t i = 0; __builtin_expect(i < 0x80000, 1); i++) { + __m128i cx = _mm_load_si128((__m128i *) &l0[idx0 & 0x1FFFF0]); + const __m128i ax0 = _mm_set_epi64x(ah0, al0); + + cx = _mm_aesenc_si128(cx, ax0); + + VARIANT2_SHUFFLE(l0, idx0 & 0x1FFFF0, ax0, bx0, bx1); + _mm_store_si128((__m128i *) &l0[idx0 & 0x1FFFF0], _mm_xor_si128(bx0, cx)); + + idx0 = _mm_cvtsi128_si64(cx); + + uint64_t hi, lo, cl, ch; + cl = ((uint64_t*) &l0[idx0 & 0x1FFFF0])[0]; + ch = ((uint64_t*) &l0[idx0 & 0x1FFFF0])[1]; + + VARIANT2_INTEGER_MATH(0, cl, cx); + lo = _umul128(idx0, cl, &hi); + VARIANT2_SHUFFLE2(l0, idx0 & 0x1FFFF0, ax0, bx0, bx1, hi, lo); + + al0 += hi; + ah0 += lo; + + ((uint64_t*)&l0[idx0 & 0x1FFFF0])[0] = al0; + ((uint64_t*)&l0[idx0 & 0x1FFFF0])[1] = ah0; + + al0 ^= cl; + ah0 ^= ch; + idx0 = al0; + + bx1 = bx0; + bx0 = cx; + } + + cn_implode_scratchpad((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state); + + keccakf(h0, 24); + extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); +} + + +#ifndef XMRIG_NO_ASM +extern void cnv2_mainloop_ivybridge_asm(struct cryptonight_ctx *ctx); +extern void cnv2_mainloop_ryzen_asm(struct cryptonight_ctx *ctx); +extern void cnv2_double_mainloop_sandybridge_asm(struct cryptonight_ctx* ctx0, struct cryptonight_ctx* ctx1); + + +void cryptonight_single_hash_asm_intel(const uint8_t *restrict input, size_t size, uint8_t *restrict output, struct cryptonight_ctx **restrict ctx) +{ + keccak(input, size, ctx[0]->state, 200); + cn_explode_scratchpad((__m128i*) ctx[0]->state, (__m128i*) ctx[0]->memory); + + cnv2_mainloop_ivybridge_asm(ctx[0]); + + cn_implode_scratchpad((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state); + keccakf((uint64_t*) ctx[0]->state, 24); + extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); +} + + +void cryptonight_single_hash_asm_ryzen(const uint8_t *restrict input, size_t size, uint8_t *restrict output, struct cryptonight_ctx **restrict ctx) +{ + keccak(input, size, ctx[0]->state, 200); + cn_explode_scratchpad((__m128i*) ctx[0]->state, (__m128i*) ctx[0]->memory); + + cnv2_mainloop_ryzen_asm(ctx[0]); + + cn_implode_scratchpad((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state); + keccakf((uint64_t*) ctx[0]->state, 24); + extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); +} + + +void cryptonight_double_hash_asm(const uint8_t *restrict input, size_t size, uint8_t *restrict output, struct cryptonight_ctx **restrict ctx) +{ + keccak(input, size, ctx[0]->state, 200); + keccak(input + size, size, ctx[1]->state, 200); + + cn_explode_scratchpad((__m128i*) ctx[0]->state, (__m128i*) ctx[0]->memory); + cn_explode_scratchpad((__m128i*) ctx[1]->state, (__m128i*) ctx[1]->memory); + + cnv2_double_mainloop_sandybridge_asm(ctx[0], ctx[1]); + + cn_implode_scratchpad((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state); + cn_implode_scratchpad((__m128i*) ctx[1]->memory, (__m128i*) ctx[1]->state); + + keccakf((uint64_t*) ctx[0]->state, 24); + keccakf((uint64_t*) ctx[1]->state, 24); + + extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); + extra_hashes[ctx[1]->state[0] & 3](ctx[1]->state, 200, output + 32); +} +#endif diff --git a/algo/cryptonight/cryptonight_r_av2.c b/algo/cryptonight/cryptonight_r_av2.c new file mode 100644 index 000000000..507ce4210 --- /dev/null +++ b/algo/cryptonight/cryptonight_r_av2.c @@ -0,0 +1,135 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017 fireice-uk + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "crypto/c_keccak.h" +#include "cryptonight.h" +#include "cryptonight_aesni.h" +#include "cryptonight_monero.h" + + +void cryptonight_r_av2(const uint8_t *restrict input, size_t size, uint8_t *restrict output, struct cryptonight_ctx **restrict ctx) +{ + keccak(input, size, ctx[0]->state, 200); + keccak(input + size, size, ctx[1]->state, 200); + + const uint8_t* l0 = ctx[0]->memory; + const uint8_t* l1 = ctx[1]->memory; + uint64_t* h0 = (uint64_t*) ctx[0]->state; + uint64_t* h1 = (uint64_t*) ctx[1]->state; + + VARIANT2_INIT(0); + VARIANT2_INIT(1); + VARIANT2_SET_ROUNDING_MODE(); + + cn_explode_scratchpad((__m128i*) h0, (__m128i*) l0); + cn_explode_scratchpad((__m128i*) h1, (__m128i*) l1); + + uint64_t al0 = h0[0] ^ h0[4]; + uint64_t al1 = h1[0] ^ h1[4]; + uint64_t ah0 = h0[1] ^ h0[5]; + uint64_t ah1 = h1[1] ^ h1[5]; + + __m128i bx00 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); + __m128i bx01 = _mm_set_epi64x(h0[9] ^ h0[11], h0[8] ^ h0[10]); + __m128i bx10 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); + __m128i bx11 = _mm_set_epi64x(h1[9] ^ h1[11], h1[8] ^ h1[10]); + + uint64_t idx0 = al0; + uint64_t idx1 = al1; + + for (size_t i = 0; __builtin_expect(i < 0x80000, 1); i++) { + __m128i cx0 = _mm_load_si128((__m128i *) &l0[idx0 & 0x1FFFF0]); + __m128i cx1 = _mm_load_si128((__m128i *) &l1[idx1 & 0x1FFFF0]); + + const __m128i ax0 = _mm_set_epi64x(ah0, al0); + const __m128i ax1 = _mm_set_epi64x(ah1, al1); + + cx0 = _mm_aesenc_si128(cx0, ax0); + cx1 = _mm_aesenc_si128(cx1, ax1); + + VARIANT2_SHUFFLE(l0, idx0 & 0x1FFFF0, ax0, bx00, bx01); + _mm_store_si128((__m128i *) &l0[idx0 & 0x1FFFF0], _mm_xor_si128(bx00, cx0)); + + VARIANT2_SHUFFLE(l1, idx1 & 0x1FFFF0, ax1, bx10, bx11); + _mm_store_si128((__m128i *) &l1[idx1 & 0x1FFFF0], _mm_xor_si128(bx10, cx1)); + + idx0 = _mm_cvtsi128_si64(cx0); + idx1 = _mm_cvtsi128_si64(cx1); + + uint64_t hi, lo, cl, ch; + cl = ((uint64_t*) &l0[idx0 & 0x1FFFF0])[0]; + ch = ((uint64_t*) &l0[idx0 & 0x1FFFF0])[1]; + + VARIANT2_INTEGER_MATH(0, cl, cx0); + lo = _umul128(idx0, cl, &hi); + VARIANT2_SHUFFLE2(l0, idx0 & 0x1FFFF0, ax0, bx00, bx01, hi, lo); + + al0 += hi; + ah0 += lo; + + ((uint64_t*)&l0[idx0 & 0x1FFFF0])[0] = al0; + ((uint64_t*)&l0[idx0 & 0x1FFFF0])[1] = ah0; + + al0 ^= cl; + ah0 ^= ch; + idx0 = al0; + + cl = ((uint64_t*) &l1[idx1 & 0x1FFFF0])[0]; + ch = ((uint64_t*) &l1[idx1 & 0x1FFFF0])[1]; + + VARIANT2_INTEGER_MATH(1, cl, cx1); + lo = _umul128(idx1, cl, &hi); + VARIANT2_SHUFFLE2(l1, idx1 & 0x1FFFF0, ax1, bx10, bx11, hi, lo); + + al1 += hi; + ah1 += lo; + + ((uint64_t*)&l1[idx1 & 0x1FFFF0])[0] = al1; + ((uint64_t*)&l1[idx1 & 0x1FFFF0])[1] = ah1; + + al1 ^= cl; + ah1 ^= ch; + idx1 = al1; + + bx01 = bx00; + bx11 = bx10; + + bx00 = cx0; + bx10 = cx1; + } + + cn_implode_scratchpad((__m128i*) l0, (__m128i*) h0); + cn_implode_scratchpad((__m128i*) l1, (__m128i*) h1); + + keccakf(h0, 24); + keccakf(h1, 24); + + extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); + extra_hashes[ctx[1]->state[0] & 3](ctx[1]->state, 200, output + 32); +} diff --git a/algo/cryptonight/cryptonight_r_av3.c b/algo/cryptonight/cryptonight_r_av3.c new file mode 100644 index 000000000..46b0de386 --- /dev/null +++ b/algo/cryptonight/cryptonight_r_av3.c @@ -0,0 +1,92 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017 fireice-uk + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "crypto/c_keccak.h" +#include "cryptonight.h" +#include "cryptonight_monero.h" +#include "cryptonight_softaes.h" + + +void cryptonight_r_av3(const uint8_t *restrict input, size_t size, uint8_t *restrict output, struct cryptonight_ctx **restrict ctx) +{ + keccak(input, size, ctx[0]->state, 200); + + cn_explode_scratchpad((__m128i*) ctx[0]->state, (__m128i*) ctx[0]->memory); + + const uint8_t* l0 = ctx[0]->memory; + uint64_t* h0 = (uint64_t*) ctx[0]->state; + + VARIANT2_INIT(0); + VARIANT2_SET_ROUNDING_MODE(); + + uint64_t al0 = h0[0] ^ h0[4]; + uint64_t ah0 = h0[1] ^ h0[5]; + __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); + __m128i bx1 = _mm_set_epi64x(h0[9] ^ h0[11], h0[8] ^ h0[10]); + + uint64_t idx0 = al0; + + for (size_t i = 0; __builtin_expect(i < 0x80000, 1); i++) { + __m128i cx = _mm_load_si128((__m128i *) &l0[idx0 & 0x1FFFF0]); + const __m128i ax0 = _mm_set_epi64x(ah0, al0); + + cx = soft_aesenc(cx, ax0); + + VARIANT2_SHUFFLE(l0, idx0 & 0x1FFFF0, ax0, bx0, bx1); + _mm_store_si128((__m128i *) &l0[idx0 & 0x1FFFF0], _mm_xor_si128(bx0, cx)); + + idx0 = _mm_cvtsi128_si64(cx); + + uint64_t hi, lo, cl, ch; + cl = ((uint64_t*) &l0[idx0 & 0x1FFFF0])[0]; + ch = ((uint64_t*) &l0[idx0 & 0x1FFFF0])[1]; + + VARIANT2_INTEGER_MATH(0, cl, cx); + lo = _umul128(idx0, cl, &hi); + VARIANT2_SHUFFLE2(l0, idx0 & 0x1FFFF0, ax0, bx0, bx1, hi, lo); + + al0 += hi; + ah0 += lo; + + ((uint64_t*)&l0[idx0 & 0x1FFFF0])[0] = al0; + ((uint64_t*)&l0[idx0 & 0x1FFFF0])[1] = ah0; + + al0 ^= cl; + ah0 ^= ch; + idx0 = al0; + + bx1 = bx0; + bx0 = cx; + } + + cn_implode_scratchpad((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state); + + keccakf(h0, 24); + extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); +} diff --git a/algo/cryptonight/cryptonight_r_av4.c b/algo/cryptonight/cryptonight_r_av4.c new file mode 100644 index 000000000..bfaa678f6 --- /dev/null +++ b/algo/cryptonight/cryptonight_r_av4.c @@ -0,0 +1,135 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017 fireice-uk + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "crypto/c_keccak.h" +#include "cryptonight.h" +#include "cryptonight_monero.h" +#include "cryptonight_softaes.h" + + +void cryptonight_r_av4(const uint8_t *restrict input, size_t size, uint8_t *restrict output, struct cryptonight_ctx **restrict ctx) +{ + keccak(input, size, ctx[0]->state, 200); + keccak(input + size, size, ctx[1]->state, 200); + + const uint8_t* l0 = ctx[0]->memory; + const uint8_t* l1 = ctx[1]->memory; + uint64_t* h0 = (uint64_t*) ctx[0]->state; + uint64_t* h1 = (uint64_t*) ctx[1]->state; + + VARIANT2_INIT(0); + VARIANT2_INIT(1); + VARIANT2_SET_ROUNDING_MODE(); + + cn_explode_scratchpad((__m128i*) h0, (__m128i*) l0); + cn_explode_scratchpad((__m128i*) h1, (__m128i*) l1); + + uint64_t al0 = h0[0] ^ h0[4]; + uint64_t al1 = h1[0] ^ h1[4]; + uint64_t ah0 = h0[1] ^ h0[5]; + uint64_t ah1 = h1[1] ^ h1[5]; + + __m128i bx00 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); + __m128i bx01 = _mm_set_epi64x(h0[9] ^ h0[11], h0[8] ^ h0[10]); + __m128i bx10 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); + __m128i bx11 = _mm_set_epi64x(h1[9] ^ h1[11], h1[8] ^ h1[10]); + + uint64_t idx0 = al0; + uint64_t idx1 = al1; + + for (size_t i = 0; __builtin_expect(i < 0x80000, 1); i++) { + __m128i cx0 = _mm_load_si128((__m128i *) &l0[idx0 & 0x1FFFF0]); + __m128i cx1 = _mm_load_si128((__m128i *) &l1[idx1 & 0x1FFFF0]); + + const __m128i ax0 = _mm_set_epi64x(ah0, al0); + const __m128i ax1 = _mm_set_epi64x(ah1, al1); + + cx0 = soft_aesenc(cx0, ax0); + cx1 = soft_aesenc(cx1, ax1); + + VARIANT2_SHUFFLE(l0, idx0 & 0x1FFFF0, ax0, bx00, bx01); + _mm_store_si128((__m128i *) &l0[idx0 & 0x1FFFF0], _mm_xor_si128(bx00, cx0)); + + VARIANT2_SHUFFLE(l1, idx1 & 0x1FFFF0, ax1, bx10, bx11); + _mm_store_si128((__m128i *) &l1[idx1 & 0x1FFFF0], _mm_xor_si128(bx10, cx1)); + + idx0 = _mm_cvtsi128_si64(cx0); + idx1 = _mm_cvtsi128_si64(cx1); + + uint64_t hi, lo, cl, ch; + cl = ((uint64_t*) &l0[idx0 & 0x1FFFF0])[0]; + ch = ((uint64_t*) &l0[idx0 & 0x1FFFF0])[1]; + + VARIANT2_INTEGER_MATH(0, cl, cx0); + lo = _umul128(idx0, cl, &hi); + VARIANT2_SHUFFLE2(l0, idx0 & 0x1FFFF0, ax0, bx00, bx01, hi, lo); + + al0 += hi; + ah0 += lo; + + ((uint64_t*)&l0[idx0 & 0x1FFFF0])[0] = al0; + ((uint64_t*)&l0[idx0 & 0x1FFFF0])[1] = ah0; + + al0 ^= cl; + ah0 ^= ch; + idx0 = al0; + + cl = ((uint64_t*) &l1[idx1 & 0x1FFFF0])[0]; + ch = ((uint64_t*) &l1[idx1 & 0x1FFFF0])[1]; + + VARIANT2_INTEGER_MATH(1, cl, cx1); + lo = _umul128(idx1, cl, &hi); + VARIANT2_SHUFFLE2(l1, idx1 & 0x1FFFF0, ax1, bx10, bx11, hi, lo); + + al1 += hi; + ah1 += lo; + + ((uint64_t*)&l1[idx1 & 0x1FFFF0])[0] = al1; + ((uint64_t*)&l1[idx1 & 0x1FFFF0])[1] = ah1; + + al1 ^= cl; + ah1 ^= ch; + idx1 = al1; + + bx01 = bx00; + bx11 = bx10; + + bx00 = cx0; + bx10 = cx1; + } + + cn_implode_scratchpad((__m128i*) l0, (__m128i*) h0); + cn_implode_scratchpad((__m128i*) l1, (__m128i*) h1); + + keccakf(h0, 24); + keccakf(h1, 24); + + extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); + extra_hashes[ctx[1]->state[0] & 3](ctx[1]->state, 200, output + 32); +} diff --git a/options.c b/options.c index 8fe9bff81..eaa4355a3 100644 --- a/options.c +++ b/options.c @@ -4,8 +4,9 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -74,6 +75,8 @@ static struct AlgoData const algorithms[] = { { "cryptonight/0", "cn/0", ALGO_CRYPTONIGHT, VARIANT_0 }, { "cryptonight/1", "cn/1", ALGO_CRYPTONIGHT, VARIANT_1 }, { "cryptonight/2", "cn/2", ALGO_CRYPTONIGHT, VARIANT_2 }, + { "cryptonight/4", "cn/4", ALGO_CRYPTONIGHT, VARIANT_4 }, + { "cryptonight/r", "cn/r", ALGO_CRYPTONIGHT, VARIANT_4 }, # ifndef XMRIG_NO_AEON { "cryptonight-lite", "cn-lite", ALGO_CRYPTONIGHT_LITE, VARIANT_AUTO }, @@ -88,7 +91,7 @@ static char const usage[] = "\ Usage: " APP_ID " [OPTIONS]\n\ Options:\n\ -a, --algo=ALGO cryptonight (default) or cryptonight-lite\n\ - --variant=N cryptonight variant: 0-2\n\ + --variant=N cryptonight variant: 0-4\n\ -o, --url=URL URL of mining server\n\ -b, --backup-url=URL URL of backup mining server\n\ -O, --userpass=U:P username:password pair for mining server\n\ @@ -156,6 +159,7 @@ static const char *variant_names[] = { "0", "1", "2", + "4" }; @@ -380,9 +384,13 @@ static void parse_arg(int key, char *arg) { case 1021: /* --variant */ v = atoi(arg); - if (v > VARIANT_AUTO && v < VARIANT_MAX) { + if (v == 4 || strcasecmp(arg, "r") == 0) { + opt_variant = VARIANT_4; + } + else if (v > VARIANT_AUTO && v < VARIANT_MAX) { opt_variant = v; } + break; case 1006: /* --nicehash */ @@ -397,7 +405,7 @@ static void parse_arg(int key, char *arg) { static void parse_config(json_t *config, char *ref) { - int i; + size_t i; char buf[16]; json_t *val; diff --git a/options.h b/options.h index 7117130b8..19e37883e 100644 --- a/options.h +++ b/options.h @@ -4,8 +4,9 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -44,6 +45,7 @@ enum Variant { VARIANT_0 = 0, VARIANT_1 = 1, VARIANT_2 = 2, + VARIANT_4 = 3, VARIANT_MAX }; diff --git a/version.h b/version.h index c99cea7ea..b49ccd92a 100644 --- a/version.h +++ b/version.h @@ -5,7 +5,8 @@ * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , - * Copyright 2016-2018 XMRig , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,13 +28,13 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "Monero (XMR) CPU miner" -#define APP_VERSION "0.9.0-dev" +#define APP_VERSION "0.10.0-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" -#define APP_COPYRIGHT "Copyright (C) 2016-2018 xmrig.com" +#define APP_COPYRIGHT "Copyright (C) 2016-2019 xmrig.com" #define APP_VER_MAJOR 0 -#define APP_VER_MINOR 9 +#define APP_VER_MINOR 10 #define APP_VER_BUILD 0 #define APP_VER_REV 0 diff --git a/xmrig.c b/xmrig.c index d79808db0..7ae8b3202 100644 --- a/xmrig.c +++ b/xmrig.c @@ -307,7 +307,7 @@ static void *miner_thread(void *userdata) { gettimeofday(&tv_start, NULL); /* scan nonces for a proof-of-work hash */ - const int rc = scanhash_cryptonight(thr_id, hash, (const uint8_t *) work.blob, work.blob_size, work.target, max_nonce, &hashes_done, persistentctx); + const int rc = scanhash_cryptonight(thr_id, hash, (uint8_t *) work.blob, work.blob_size, work.target, max_nonce, &hashes_done, persistentctx); stats_add_hashes(thr_id, &tv_start, hashes_done); if (!rc) {