From db273f267142b062442c034ea367fd81901ba926 Mon Sep 17 00:00:00 2001 From: tevador Date: Sat, 22 Apr 2023 19:14:46 +0200 Subject: [PATCH] introduce RandomX v2 with double-hashing --- src/randomx.cpp | 11 +++++++++++ src/randomx.h | 11 +++++++++++ src/tests/benchmark.cpp | 32 +++++++++++++++++++++++++------- src/tests/tests.cpp | 24 ++++++++++++++++++++++++ vcxproj/randomx.vcxproj | 2 +- vcxproj/randomx.vcxproj.filters | 2 +- 6 files changed, 73 insertions(+), 9 deletions(-) diff --git a/src/randomx.cpp b/src/randomx.cpp index 7daaa46..537dde2 100644 --- a/src/randomx.cpp +++ b/src/randomx.cpp @@ -400,4 +400,15 @@ extern "C" { machine->run(machine->tempHash); machine->getFinalResult(output, RANDOMX_HASH_SIZE); } + + void randomx_calculate_hash_v2(const void* input, size_t inputSize, const void* v1_in, void* v2_out) { + assert(inputSize == 0 || input != nullptr); + assert(v1_in != nullptr); + assert(v2_out != nullptr); + blake2b_state state; + blake2b_init(&state, RANDOMX_HASH_SIZE); + blake2b_update(&state, input, inputSize); + blake2b_update(&state, v1_in, RANDOMX_HASH_SIZE); + blake2b_final(&state, v2_out, RANDOMX_HASH_SIZE); + } } diff --git a/src/randomx.h b/src/randomx.h index 64d1806..d7e2d99 100644 --- a/src/randomx.h +++ b/src/randomx.h @@ -260,6 +260,17 @@ RANDOMX_EXPORT void randomx_calculate_hash_first(randomx_vm* machine, const void RANDOMX_EXPORT void randomx_calculate_hash_next(randomx_vm* machine, const void* nextInput, size_t nextInputSize, void* output); RANDOMX_EXPORT void randomx_calculate_hash_last(randomx_vm* machine, void* output); +/** + * Calculate V2 hash from the V1 hash and its input. + * + * @param input is a pointer to memory that was hashed by V1. Must not be NULL. + * @param inputSize is the number of bytes in the input. + * @param v1_in is the V1 hash (RANDOMX_HASH_SIZE bytes). + * @param output is a pointer to memory where the V2 hash will be stored. Must not + * be NULL and at least RANDOMX_HASH_SIZE bytes must be available for writing. +*/ +RANDOMX_EXPORT void randomx_calculate_hash_v2(const void* input, size_t inputSize, const void* v1_in, void* v2_out); + #if defined(__cplusplus) } #endif diff --git a/src/tests/benchmark.cpp b/src/tests/benchmark.cpp index 36b0259..df37168 100644 --- a/src/tests/benchmark.cpp +++ b/src/tests/benchmark.cpp @@ -96,6 +96,7 @@ void printUsage(const char* executable) { std::cout << " --avx2 use optimized Argon2 for AVX2 CPUs" << std::endl; std::cout << " --auto select the best options for the current CPU" << std::endl; std::cout << " --noBatch calculate hashes one by one (default: batch)" << std::endl; + std::cout << " --v2 calculate v2 hashes (default: v1)" << std::endl; } struct MemoryException : public std::exception { @@ -113,7 +114,7 @@ struct DatasetAllocException : public MemoryException { using MineFunc = void(randomx_vm * vm, std::atomic & atomicNonce, AtomicHash & result, uint32_t noncesCount, int thread, int cpuid); -template +template void mine(randomx_vm* vm, std::atomic& atomicNonce, AtomicHash& result, uint32_t noncesCount, int thread, int cpuid = -1) { if (cpuid >= 0) { int rc = set_thread_affinity(cpuid); @@ -138,6 +139,9 @@ void mine(randomx_vm* vm, std::atomic& atomicNonce, AtomicHash& result } store32(noncePtr, nonce); (batch ? randomx_calculate_hash_next : randomx_calculate_hash)(vm, blockTemplate, sizeof(blockTemplate), &hash); + if (v2) { + randomx_calculate_hash_v2(blockTemplate, sizeof(blockTemplate), &hash, &hash); + } result.xorWith(hash); if (!batch) { nonce = atomicNonce.fetch_add(1); @@ -146,7 +150,7 @@ void mine(randomx_vm* vm, std::atomic& atomicNonce, AtomicHash& result } int main(int argc, char** argv) { - bool softAes, miningMode, verificationMode, help, largePages, jit, secure; + bool softAes, miningMode, verificationMode, help, largePages, jit, secure, v2; bool ssse3, avx2, autoFlags, noBatch; int noncesCount, threadCount, initThreadCount; uint64_t threadAffinity; @@ -172,10 +176,11 @@ int main(int argc, char** argv) { readOption("--avx2", argc, argv, avx2); readOption("--auto", argc, argv, autoFlags); readOption("--noBatch", argc, argv, noBatch); + readOption("--v2", argc, argv, v2); store32(&seed, seedValue); - std::cout << "RandomX benchmark v1.1.11" << std::endl; + std::cout << "RandomX benchmark v1.1.12" << std::endl; if (help) { printUsage(argv[0]); @@ -280,11 +285,24 @@ int main(int argc, char** argv) { MineFunc* func; if (noBatch) { - func = &mine; + if (v2) { + std::cout << " - v2 hashes" << std::endl; + func = &mine; + } + else { + func = &mine; + } } else { - func = &mine; - std::cout << " - batch mode" << std::endl; + if (v2) { + //TODO: support batch mode with v2 + std::cout << " - v2 hashes" << std::endl; + func = &mine; + } + else { + std::cout << " - batch mode" << std::endl; + func = &mine; + } } std::cout << "Initializing"; @@ -376,7 +394,7 @@ int main(int argc, char** argv) { randomx_release_cache(cache); std::cout << "Calculated result: "; result.print(std::cout); - if (noncesCount == 1000 && seedValue == 0) + if (noncesCount == 1000 && seedValue == 0 && !v2) std::cout << "Reference result: 10b649a3f15c7c7f88277812f2e74b337a0f20ce909af09199cccb960771cfa1" << std::endl; if (!miningMode) { std::cout << "Performance: " << 1000 * elapsed / noncesCount << " ms per hash" << std::endl; diff --git a/src/tests/tests.cpp b/src/tests/tests.cpp index 412585b..8df2d90 100644 --- a/src/tests/tests.cpp +++ b/src/tests/tests.cpp @@ -34,6 +34,14 @@ void calcStringHash(const char(&key)[K], const char(&input)[H], void* output) { randomx_calculate_hash(vm, input, H - 1, output); } +template +void calcStringHashV2(const char(&key)[K], const char(&input)[H], void* output) { + initCache(key); + assert(vm != nullptr); + randomx_calculate_hash(vm, input, H - 1, output); + randomx_calculate_hash_v2(input, H - 1, output, output); +} + template void calcHexHash(const char(&key)[K], const char(&hex)[H], void* output) { initCache(key); @@ -1082,6 +1090,22 @@ int main() { assert(rx_get_rounding_mode() == RoundToNearest); }); + if (RANDOMX_HAVE_COMPILER) { + randomx_destroy_vm(vm); + vm = nullptr; +#ifdef RANDOMX_FORCE_SECURE + vm = randomx_create_vm(RANDOMX_FLAG_DEFAULT | RANDOMX_FLAG_SECURE, cache, nullptr); +#else + vm = randomx_create_vm(RANDOMX_FLAG_DEFAULT, cache, nullptr); +#endif + } + + runTest("RandomX v2 hash test", stringsEqual(RANDOMX_ARGON_SALT, "RandomX\x03"), []() { + char hash[RANDOMX_HASH_SIZE]; + calcStringHashV2("test key 000", "This is a test", &hash); + assert(equalsHex(hash, "d53ccf348b75291b7be76f0a7ac8208bbced734b912f6fca60539ab6f86be919")); + }); + randomx_destroy_vm(vm); vm = nullptr; diff --git a/vcxproj/randomx.vcxproj b/vcxproj/randomx.vcxproj index e0625c8..fcc66c9 100644 --- a/vcxproj/randomx.vcxproj +++ b/vcxproj/randomx.vcxproj @@ -156,7 +156,7 @@ SET ERRORLEVEL = 0 - + diff --git a/vcxproj/randomx.vcxproj.filters b/vcxproj/randomx.vcxproj.filters index eb4462a..eef048a 100644 --- a/vcxproj/randomx.vcxproj.filters +++ b/vcxproj/randomx.vcxproj.filters @@ -72,7 +72,7 @@ Source Files - + Source Files