diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e1673ea..068642bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,6 +57,7 @@ set(HEADERS_CRYPTO src/crypto/c_keccak.h src/crypto/c_skein.h src/crypto/CryptoNight.h + src/crypto/CryptoNight_monero.h src/crypto/CryptoNight_test.h src/crypto/groestl_tables.h src/crypto/hash.h diff --git a/src/Mem.cpp b/src/Mem.cpp index 4437c673..1943b22a 100644 --- a/src/Mem.cpp +++ b/src/Mem.cpp @@ -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 Lee Clagett + * Copyright 2016-2018 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 @@ -46,10 +47,10 @@ cryptonight_ctx *Mem::create(int threadId) } # endif - cryptonight_ctx *ctx = reinterpret_cast(&m_memory[MEMORY - sizeof(cryptonight_ctx) * (threadId + 1)]); + cryptonight_ctx *ctx = reinterpret_cast(&m_memory[MONERO_MEMORY - sizeof(cryptonight_ctx) * (threadId + 1)]); const int ratio = m_doubleHash ? 2 : 1; - ctx->memory = &m_memory[MEMORY * (threadId * ratio + 1)]; + ctx->memory = &m_memory[MONERO_MEMORY * (threadId * ratio + 1)]; return ctx; } @@ -72,15 +73,15 @@ cryptonight_ctx *Mem::createLite(int threadId) { cryptonight_ctx *ctx; if (!m_doubleHash) { - const size_t offset = MEMORY * (threadId + 1); + const size_t offset = MONERO_MEMORY * (threadId + 1); - ctx = reinterpret_cast(&m_memory[offset + MEMORY_LITE]); + ctx = reinterpret_cast(&m_memory[offset + AEON_MEMORY]); ctx->memory = &m_memory[offset]; return ctx; } - ctx = reinterpret_cast(&m_memory[MEMORY - sizeof(cryptonight_ctx) * (threadId + 1)]); - ctx->memory = &m_memory[MEMORY * (threadId + 1)]; + ctx = reinterpret_cast(&m_memory[MONERO_MEMORY - sizeof(cryptonight_ctx) * (threadId + 1)]); + ctx->memory = &m_memory[MONERO_MEMORY * (threadId + 1)]; return ctx; } diff --git a/src/Mem_unix.cpp b/src/Mem_unix.cpp index 43ffa664..ec4017da 100644 --- a/src/Mem_unix.cpp +++ b/src/Mem_unix.cpp @@ -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 Lee Clagett + * Copyright 2016-2018 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 @@ -46,7 +47,7 @@ bool Mem::allocate(int algo, int threads, bool doubleHash, bool enabled) m_doubleHash = doubleHash; const int ratio = (doubleHash && algo != Options::ALGO_CRYPTONIGHT_LITE) ? 2 : 1; - const size_t size = MEMORY * (threads * ratio + 1); + const size_t size = MONERO_MEMORY * (threads * ratio + 1); if (!enabled) { m_memory = static_cast(_mm_malloc(size, 16)); @@ -83,7 +84,7 @@ bool Mem::allocate(int algo, int threads, bool doubleHash, bool enabled) void Mem::release() { - const int size = MEMORY * (m_threads + 1); + const int size = MONERO_MEMORY * (m_threads + 1); if (m_flags & HugepagesEnabled) { if (m_flags & Lock) { diff --git a/src/Mem_win.cpp b/src/Mem_win.cpp index a4f92cfe..79c6d12e 100644 --- a/src/Mem_win.cpp +++ b/src/Mem_win.cpp @@ -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 Lee Clagett + * Copyright 2016-2018 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 @@ -151,7 +152,7 @@ bool Mem::allocate(int algo, int threads, bool doubleHash, bool enabled) m_doubleHash = doubleHash; const int ratio = (doubleHash && algo != Options::ALGO_CRYPTONIGHT_LITE) ? 2 : 1; - const size_t size = MEMORY * (threads * ratio + 1); + const size_t size = MONERO_MEMORY * (threads * ratio + 1); if (!enabled) { m_memory = static_cast(_mm_malloc(size, 16)); diff --git a/src/crypto/CryptoNight.cpp b/src/crypto/CryptoNight.cpp index 8de52c5a..cdba4051 100644 --- a/src/crypto/CryptoNight.cpp +++ b/src/crypto/CryptoNight.cpp @@ -25,33 +25,6 @@ #include "crypto/CryptoNight.h" -// VARIANT ALTERATIONS -#define VARIANT1_CHECK() \ - if (MONERO && version > 6 && size < 43) \ - { \ - return false; \ - } - -#define VARIANT1_INIT(part) \ - const uint64_t tweak1_2_##part =\ - (MONERO && version > 6) ? \ - (*reinterpret_cast(reinterpret_cast(input) + 35 + part * size) ^ \ - *(reinterpret_cast(ctx->state##part) + 24)) : 0; - -#define VARIANT1_1(p) \ - do if(version > 6) \ - { \ - const uint8_t tmp = reinterpret_cast(p)[11]; \ - static const uint32_t table = 0x75310; \ - const uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1; \ - ((uint8_t*)(p))[11] = tmp ^ ((table >> index) & 0x30); \ - } while(0) - -#define VARIANT1_2(p, part) \ - do if(MONERO && version > 6) { \ - (p) ^= tweak1_2_##part ; \ - } while(0) - #if defined(XMRIG_ARM) # include "crypto/CryptoNight_arm.h" @@ -66,66 +39,58 @@ -bool (*cryptonight_hash_ctx)(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t) = nullptr; +void (*cryptonight_hash_ctx)(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t) = nullptr; -static bool cryptonight_av1_aesni(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx, uint8_t version) { +static void cryptonight_av1_aesni(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx, uint8_t version) { # if !defined(XMRIG_ARMv7) - return cryptonight_hash<0x80000, MEMORY, 0x1FFFF0, false, true>(input, size, output, ctx, version); -# else - return false; + cryptonight_hash(input, size, output, ctx, version); # endif } -static bool cryptonight_av2_aesni_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t version) { +static void cryptonight_av2_aesni_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t version) { # if !defined(XMRIG_ARMv7) - return cryptonight_double_hash<0x80000, MEMORY, 0x1FFFF0, false, true>(input, size, output, ctx, version); -# else - return false; + cryptonight_double_hash(input, size, output, ctx, version); # endif } -static bool cryptonight_av3_softaes(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t version) { - return cryptonight_hash<0x80000, MEMORY, 0x1FFFF0, true, true>(input, size, output, ctx, version); +static void cryptonight_av3_softaes(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t version) { + cryptonight_hash(input, size, output, ctx, version); } -static bool cryptonight_av4_softaes_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t version) { - return cryptonight_double_hash<0x80000, MEMORY, 0x1FFFF0, true, true>(input, size, output, ctx, version); +static void cryptonight_av4_softaes_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t version) { + cryptonight_double_hash(input, size, output, ctx, version); } #ifndef XMRIG_NO_AEON -static bool cryptonight_lite_av1_aesni(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t version) { +static void cryptonight_lite_av1_aesni(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t version) { # if !defined(XMRIG_ARMv7) - return cryptonight_hash<0x40000, MEMORY_LITE, 0xFFFF0, false, false>(input, size, output, ctx, version); -# else - return false; + cryptonight_hash(input, size, output, ctx, version); # endif } -static bool cryptonight_lite_av2_aesni_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t version) { +static void cryptonight_lite_av2_aesni_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t version) { # if !defined(XMRIG_ARMv7) - return cryptonight_double_hash<0x40000, MEMORY_LITE, 0xFFFF0, false, false>(input, size, output, ctx, version); -# else - return false; + cryptonight_double_hash(input, size, output, ctx, version); # endif } -static bool cryptonight_lite_av3_softaes(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t version) { - return cryptonight_hash<0x40000, MEMORY_LITE, 0xFFFF0, true, false>(input, size, output, ctx, version); +static void cryptonight_lite_av3_softaes(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t version) { + cryptonight_hash(input, size, output, ctx, version); } -static bool cryptonight_lite_av4_softaes_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t version) { - return cryptonight_double_hash<0x40000, MEMORY_LITE, 0xFFFF0, true, false>(input, size, output, ctx, version); +static void cryptonight_lite_av4_softaes_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t version) { + cryptonight_double_hash(input, size, output, ctx, version); } -bool (*cryptonight_variations[8])(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t) = { +void (*cryptonight_variations[8])(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t) = { cryptonight_av1_aesni, cryptonight_av2_aesni_double, cryptonight_av3_softaes, @@ -136,7 +101,7 @@ bool (*cryptonight_variations[8])(const void *input, size_t size, void *output, cryptonight_lite_av4_softaes_double }; #else -bool (*cryptonight_variations[4])(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t) = { +void (*cryptonight_variations[4])(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t) = { cryptonight_av1_aesni, cryptonight_av2_aesni_double, cryptonight_av3_softaes, @@ -147,8 +112,9 @@ bool (*cryptonight_variations[4])(const void *input, size_t size, void *output, bool CryptoNight::hash(const Job &job, JobResult &result, cryptonight_ctx *ctx) { - const bool rc = cryptonight_hash_ctx(job.blob(), job.size(), result.result, ctx, job.version()); - return rc && *reinterpret_cast(result.result + 24) < job.target(); + cryptonight_hash_ctx(job.blob(), job.size(), result.result, ctx, job.version()); + + return *reinterpret_cast(result.result + 24) < job.target(); } @@ -170,9 +136,9 @@ bool CryptoNight::init(int algo, int variant) } -bool CryptoNight::hash(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, uint8_t version) +void CryptoNight::hash(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, uint8_t version) { - return cryptonight_hash_ctx(input, size, output, ctx, version); + cryptonight_hash_ctx(input, size, output, ctx, version); } @@ -183,17 +149,17 @@ bool CryptoNight::selfTest(int algo) { char output[64]; - struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) _mm_malloc(sizeof(struct cryptonight_ctx), 16); - ctx->memory = (uint8_t *) _mm_malloc(MEMORY * 2, 16); + struct cryptonight_ctx *ctx = static_cast(_mm_malloc(sizeof(cryptonight_ctx), 16)); + ctx->memory = static_cast(_mm_malloc(MONERO_MEMORY * 2, 16)); - const bool rc = cryptonight_hash_ctx(test_input, 76, output, ctx, 0); + cryptonight_hash_ctx(test_input, 76, output, ctx, 0); _mm_free(ctx->memory); _mm_free(ctx); # ifndef XMRIG_NO_AEON - return rc && memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output1 : test_output0, (Options::i()->doubleHash() ? 64 : 32)) == 0; + return memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output1 : test_output0, (Options::i()->doubleHash() ? 64 : 32)) == 0; # else - return rc && memcmp(output, test_output0, (Options::i()->doubleHash() ? 64 : 32)) == 0; + return memcmp(output, test_output0, (Options::i()->doubleHash() ? 64 : 32)) == 0; # endif } diff --git a/src/crypto/CryptoNight.h b/src/crypto/CryptoNight.h index 6fa4719c..06bb9888 100644 --- a/src/crypto/CryptoNight.h +++ b/src/crypto/CryptoNight.h @@ -32,9 +32,13 @@ #include "align.h" +#define AEON_MEMORY 1048576 +#define AEON_MASK 0xFFFF0 +#define AEON_ITER 0x40000 -#define MEMORY 2097152 /* 2 MiB */ -#define MEMORY_LITE 1048576 /* 1 MiB */ +#define MONERO_MEMORY 2097152 +#define MONERO_MASK 0x1FFFF0 +#define MONERO_ITER 0x80000 struct cryptonight_ctx { @@ -53,7 +57,7 @@ class CryptoNight public: static bool hash(const Job &job, JobResult &result, cryptonight_ctx *ctx); static bool init(int algo, int variant); - static bool hash(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, uint8_t version); + static void hash(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, uint8_t version); private: static bool selfTest(int algo); diff --git a/src/crypto/CryptoNight_monero.h b/src/crypto/CryptoNight_monero.h new file mode 100644 index 00000000..9bf3db84 --- /dev/null +++ b/src/crypto/CryptoNight_monero.h @@ -0,0 +1,57 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2016-2018 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 . + */ + +#ifndef __CRYPTONIGHT_MONERO_H__ +#define __CRYPTONIGHT_MONERO_H__ + + +// VARIANT ALTERATIONS +#define VARIANT1_INIT(part) \ + uint64_t tweak1_2_##part = 0; \ + if (MONERO) { \ + if (version > 6) { \ + tweak1_2_##part = (*reinterpret_cast(reinterpret_cast(input) + 35 + part * size) ^ \ + *(reinterpret_cast(ctx->state##part) + 24)); \ + } \ + } + +#define VARIANT1_1(p) \ + if (MONERO) { \ + if (version > 6) { \ + const uint8_t tmp = reinterpret_cast(p)[11]; \ + static const uint32_t table = 0x75310; \ + const uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1; \ + ((uint8_t*)(p))[11] = tmp ^ ((table >> index) & 0x30); \ + } \ + } + +#define VARIANT1_2(p, part) \ + if (MONERO) { \ + if (version > 6) { \ + (p) ^= tweak1_2_##part; \ + } \ + } + + +#endif /* __CRYPTONIGHT_MONERO_H__ */ diff --git a/src/crypto/CryptoNight_x86.h b/src/crypto/CryptoNight_x86.h index c2f02645..d39948e8 100644 --- a/src/crypto/CryptoNight_x86.h +++ b/src/crypto/CryptoNight_x86.h @@ -35,6 +35,7 @@ #include "crypto/CryptoNight.h" +#include "crypto/CryptoNight_monero.h" #include "crypto/soft_aes.h" @@ -313,7 +314,6 @@ inline bool cryptonight_hash(const void *__restrict__ input, size_t size, void * { keccak(static_cast(input), (int) size, ctx->state0, 200); - VARIANT1_CHECK(); VARIANT1_INIT(0); cn_explode_scratchpad((__m128i*) ctx->state0, (__m128i*) ctx->memory); @@ -374,7 +374,6 @@ inline bool cryptonight_double_hash(const void *__restrict__ input, size_t size, keccak((const uint8_t *) input, (int) size, ctx->state0, 200); keccak((const uint8_t *) input + size, (int) size, ctx->state1, 200); - VARIANT1_CHECK(); VARIANT1_INIT(0); VARIANT1_INIT(1); diff --git a/src/workers/DoubleWorker.cpp b/src/workers/DoubleWorker.cpp index aac503f1..d2960320 100644 --- a/src/workers/DoubleWorker.cpp +++ b/src/workers/DoubleWorker.cpp @@ -86,15 +86,15 @@ void DoubleWorker::start() *Job::nonce(m_state->blob) = ++m_state->nonce1; *Job::nonce(m_state->blob + m_state->job.size()) = ++m_state->nonce2; - if (CryptoNight::hash(m_state->blob, m_state->job.size(), m_hash, m_ctx, m_state->job.version())) { - if (*reinterpret_cast(m_hash + 24) < m_state->job.target()) { - Workers::submit(JobResult(m_state->job.poolId(), m_state->job.id(), m_state->nonce1, m_hash, m_state->job.diff())); - } + CryptoNight::hash(m_state->blob, m_state->job.size(), m_hash, m_ctx, m_state->job.version()); - if (*reinterpret_cast(m_hash + 32 + 24) < m_state->job.target()) { - Workers::submit(JobResult(m_state->job.poolId(), m_state->job.id(), m_state->nonce2, m_hash + 32, m_state->job.diff())); - } - } // print on error ? + if (*reinterpret_cast(m_hash + 24) < m_state->job.target()) { + Workers::submit(JobResult(m_state->job.poolId(), m_state->job.id(), m_state->nonce1, m_hash, m_state->job.diff())); + } + + if (*reinterpret_cast(m_hash + 32 + 24) < m_state->job.target()) { + Workers::submit(JobResult(m_state->job.poolId(), m_state->job.id(), m_state->nonce2, m_hash + 32, m_state->job.diff())); + } std::this_thread::yield(); }