diff --git a/src/backend/cpu/CpuWorker.cpp b/src/backend/cpu/CpuWorker.cpp index 4109a6cf..2897a315 100644 --- a/src/backend/cpu/CpuWorker.cpp +++ b/src/backend/cpu/CpuWorker.cpp @@ -25,6 +25,7 @@ #include "backend/cpu/CpuWorker.h" #include "base/tools/Alignment.h" #include "base/tools/Chrono.h" +#include "base/tools/bswap_64.h" #include "core/config/Config.h" #include "core/Miner.h" #include "crypto/cn/CnCtx.h" @@ -38,6 +39,10 @@ #include "crypto/ghostrider/ghostrider.h" #include "net/JobResults.h" +extern "C" { +#include "crypto/ghostrider/sph_sha2.h" +} + #ifdef XMRIG_ALGO_RANDOMX # include "crypto/randomx/randomx.h" @@ -260,6 +265,8 @@ void xmrig::CpuWorker::start() # ifdef XMRIG_ALGO_RANDOMX bool first = true; alignas(16) uint64_t tempHash[8] = {}; + sph_sha256_context sha256_ctx_cache, sha256_ctx; + alignas(16) uint64_t dsha256[4] = {}; # endif while (!Nonce::isOutdated(Nonce::CPU, m_job.sequence())) { @@ -293,7 +300,32 @@ void xmrig::CpuWorker::start() # ifdef XMRIG_ALGO_RANDOMX uint8_t* miner_signature_ptr = m_job.blob() + m_job.nonceOffset() + m_job.nonceSize(); - if (job.algorithm().family() == Algorithm::RANDOM_X) { + if (job.algorithm().id() == Algorithm::RX_VEIL) { + if (first) { + // Init sha256 context cache until nonceOffset + sph_sha256_init(&sha256_ctx_cache); + sph_sha256(&sha256_ctx_cache, job.blob(), m_job.nonceOffset()); + sha256d(dsha256, m_job.blob(), job.size()); + } + + if (first) { + first = false; + randomx_calculate_hash_first(m_vm, tempHash, dsha256, 32); + } + + if (!nextRound()) { + break; + } + + // Compute header double-sha256 + memcpy(&sha256_ctx, &sha256_ctx_cache, sizeof(sha256_ctx)); + sph_sha256(&sha256_ctx, m_job.blob() + m_job.nonceOffset(), job.size() - m_job.nonceOffset()); + sph_sha256_close(&sha256_ctx, dsha256); + sph_sha256_full(dsha256, dsha256, 32); + + randomx_calculate_hash_next(m_vm, tempHash, dsha256, 32, m_hash); + } + else if (job.algorithm().family() == Algorithm::RANDOM_X) { if (first) { first = false; if (job.hasMinerSignature()) { @@ -354,19 +386,35 @@ void xmrig::CpuWorker::start() } if (valid) { - for (size_t i = 0; i < N; ++i) { - const uint64_t value = *reinterpret_cast(m_hash + (i * 32) + 24); + if (job.algorithm().id() == Algorithm::RX_VEIL) { + const uint64_t value = bswap_64(*reinterpret_cast(m_hash)); # ifdef XMRIG_FEATURE_BENCHMARK if (m_benchSize) { - if (current_job_nonces[i] < m_benchSize) { + if (current_job_nonces[0] < m_benchSize) { BenchState::add(value); } } else # endif if (value < job.target()) { - JobResults::submit(job, current_job_nonces[i], m_hash + (i * 32), job.hasMinerSignature() ? miner_signature_saved : nullptr); + JobResults::submit(job, current_job_nonces[0], m_hash, nullptr); + } + } else { + for (size_t i = 0; i < N; ++i) { + const uint64_t value = *reinterpret_cast(m_hash + (i * 32) + 24); + +# ifdef XMRIG_FEATURE_BENCHMARK + if (m_benchSize) { + if (current_job_nonces[i] < m_benchSize) { + BenchState::add(value); + } + } + else +# endif + if (value < job.target()) { + JobResults::submit(job, current_job_nonces[i], m_hash + (i * 32), job.hasMinerSignature() ? miner_signature_saved : nullptr); + } } } m_count += N; diff --git a/src/backend/cuda/CudaWorker.cpp b/src/backend/cuda/CudaWorker.cpp index 5c51b9a6..40010f4e 100644 --- a/src/backend/cuda/CudaWorker.cpp +++ b/src/backend/cuda/CudaWorker.cpp @@ -69,7 +69,9 @@ xmrig::CudaWorker::CudaWorker(size_t id, const CudaLaunchData &data) : switch (m_algorithm.family()) { case Algorithm::RANDOM_X: # ifdef XMRIG_ALGO_RANDOMX - m_runner = new CudaRxRunner(id, data); + if (m_algorithm.id() != Algorithm::RX_VEIL) { + m_runner = new CudaRxRunner(id, data); + } # endif break; diff --git a/src/backend/opencl/OclWorker.cpp b/src/backend/opencl/OclWorker.cpp index cd49a50e..57551338 100644 --- a/src/backend/opencl/OclWorker.cpp +++ b/src/backend/opencl/OclWorker.cpp @@ -76,11 +76,13 @@ xmrig::OclWorker::OclWorker(size_t id, const OclLaunchData &data) : switch (m_algorithm.family()) { case Algorithm::RANDOM_X: # ifdef XMRIG_ALGO_RANDOMX - if (data.thread.isAsm() && data.device.vendorId() == OCL_VENDOR_AMD) { - m_runner = new OclRxJitRunner(id, data); - } - else { - m_runner = new OclRxVmRunner(id, data); + if (m_algorithm.id() != Algorithm::RX_VEIL) { + if (data.thread.isAsm() && data.device.vendorId() == OCL_VENDOR_AMD) { + m_runner = new OclRxJitRunner(id, data); + } + else { + m_runner = new OclRxVmRunner(id, data); + } } # endif break; diff --git a/src/base/crypto/Algorithm.cpp b/src/base/crypto/Algorithm.cpp index 6a20a5b5..7d00d73a 100644 --- a/src/base/crypto/Algorithm.cpp +++ b/src/base/crypto/Algorithm.cpp @@ -77,6 +77,7 @@ const char *Algorithm::kCN_UPX2 = "cn/upx2"; #ifdef XMRIG_ALGO_RANDOMX const char *Algorithm::kRX = "rx"; const char *Algorithm::kRX_0 = "rx/0"; +const char *Algorithm::kRX_VEIL = "rx/veil"; const char *Algorithm::kRX_WOW = "rx/wow"; const char *Algorithm::kRX_ARQ = "rx/arq"; const char *Algorithm::kRX_GRAFT = "rx/graft"; @@ -149,6 +150,7 @@ static const std::map kAlgorithmNames = { # ifdef XMRIG_ALGO_RANDOMX ALGO_NAME(RX_0), + ALGO_NAME(RX_VEIL), ALGO_NAME(RX_WOW), ALGO_NAME(RX_ARQ), ALGO_NAME(RX_GRAFT), @@ -264,6 +266,8 @@ static const std::map kAlgorithmAlias ALGO_ALIAS(RX_0, "rx/test"), ALGO_ALIAS(RX_0, "randomx"), ALGO_ALIAS(RX_0, "rx"), + ALGO_ALIAS_AUTO(RX_VEIL), ALGO_ALIAS(RX_VEIL, "randomx/veil"), + ALGO_ALIAS(RX_VEIL, "randomveil"), ALGO_ALIAS_AUTO(RX_WOW), ALGO_ALIAS(RX_WOW, "randomx/wow"), ALGO_ALIAS(RX_WOW, "randomwow"), ALGO_ALIAS_AUTO(RX_ARQ), ALGO_ALIAS(RX_ARQ, "randomx/arq"), @@ -368,7 +372,7 @@ std::vector xmrig::Algorithm::all(const std::function +#include "base/tools/bswap_64.h" #include "base/tools/String.h" #include "base/net/stratum/Job.h" @@ -80,7 +81,12 @@ public: } inline const uint8_t *result() const { return m_result; } - inline uint64_t actualDiff() const { return Job::toDiff(reinterpret_cast(m_result)[3]); } + inline uint64_t actualDiff() const { + if (algorithm.id() == Algorithm::RX_VEIL) { + return Job::toDiff(bswap_64(*reinterpret_cast(m_result))); + } + return Job::toDiff(reinterpret_cast(m_result)[3]); + } inline uint8_t *result() { return m_result; } inline const uint8_t *headerHash() const { return m_headerHash; } inline const uint8_t *mixHash() const { return m_mixHash; }