From 6cb9858f5aa66580b810ae8893ec3cf4244226ab Mon Sep 17 00:00:00 2001 From: codeofalltrades Date: Tue, 26 Jan 2021 00:19:49 -0600 Subject: [PATCH 01/12] Cherry picked commit 'Add a missing function to calculate a batch of hashes' from https://github.com/tevador/RandomX/commit/01381ccef32da29ef4c64209980eb2b1415fc6a4 --- src/crypto/randomx/randomx.cpp | 10 ++++++++++ src/crypto/randomx/randomx.h | 9 ++++++--- src/test/randomx_tests.cpp | 25 ++++++++++++++++++++++--- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/crypto/randomx/randomx.cpp b/src/crypto/randomx/randomx.cpp index bede273671..41c1836757 100644 --- a/src/crypto/randomx/randomx.cpp +++ b/src/crypto/randomx/randomx.cpp @@ -524,4 +524,14 @@ extern "C" { blake2b(machine->tempHash, sizeof(machine->tempHash), nextInput, nextInputSize, nullptr, 0); machine->hashAndFill(output, RANDOMX_HASH_SIZE, machine->tempHash); } + + void randomx_calculate_hash_last(randomx_vm* machine, void* output) { + machine->resetRoundingMode(); + for (int chain = 0; chain < RANDOMX_PROGRAM_COUNT - 1; ++chain) { + machine->run(machine->tempHash); + blake2b(machine->tempHash, sizeof(machine->tempHash), machine->getRegisterFile(), sizeof(randomx::RegisterFile), nullptr, 0); + } + machine->run(machine->tempHash); + machine->getFinalResult(output, RANDOMX_HASH_SIZE); + } } diff --git a/src/crypto/randomx/randomx.h b/src/crypto/randomx/randomx.h index ce266ec4dd..c47c0399e1 100644 --- a/src/crypto/randomx/randomx.h +++ b/src/crypto/randomx/randomx.h @@ -239,9 +239,11 @@ RANDOMX_EXPORT void randomx_destroy_vm(randomx_vm *machine); RANDOMX_EXPORT void randomx_calculate_hash(randomx_vm *machine, const void *input, size_t inputSize, void *output); /** - * Paired functions used to calculate multiple RandomX hashes more efficiently. - * randomx_calculate_hash_first is called for the first input value. - * randomx_calculate_hash_next will output the hash value of the previous input. + * Set of functions used to calculate multiple RandomX hashes more efficiently. + * randomx_calculate_hash_first will begin a hash calculation. + * randomx_calculate_hash_next will output the hash value of the previous input + * and begin the calculation of the next hash. + * randomx_calculate_hash_last will output the hash value of the previous input. * * @param machine is a pointer to a randomx_vm structure. Must not be NULL. * @param tempHash an array of 8 64-bit values used to store intermediate data between calls to randomx_calculate_hash_first and randomx_calculate_hash_next. @@ -254,6 +256,7 @@ RANDOMX_EXPORT void randomx_calculate_hash(randomx_vm *machine, const void *inpu */ RANDOMX_EXPORT void randomx_calculate_hash_first(randomx_vm* machine, const void* input, size_t inputSize); 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); #if defined(__cplusplus) } diff --git a/src/test/randomx_tests.cpp b/src/test/randomx_tests.cpp index 20d2edb7fa..0858050cdb 100644 --- a/src/test/randomx_tests.cpp +++ b/src/test/randomx_tests.cpp @@ -1141,9 +1141,6 @@ BOOST_AUTO_TEST_CASE(randomx_run_tests) runTest("Hash test 2e (compiler)", RANDOMX_HAVE_COMPILER && stringsEqual(RANDOMX_ARGON_SALT, "RandomX\x03"), test_e); - randomx_destroy_vm(vm); - vm = nullptr; - randomx_release_cache(cache); cache = randomx_alloc_cache(RANDOMX_FLAG_ARGON2_SSSE3); @@ -1167,6 +1164,28 @@ BOOST_AUTO_TEST_CASE(randomx_run_tests) assert(cacheMemory[33554431] == 0x1f47f056d05cd99b); }); + runTest("Hash batch test", RANDOMX_HAVE_COMPILER && stringsEqual(RANDOMX_ARGON_SALT, "RandomX\x03"), []() { + char hash1[RANDOMX_HASH_SIZE]; + char hash2[RANDOMX_HASH_SIZE]; + char hash3[RANDOMX_HASH_SIZE]; + initCache("test key 000"); + char input1[] = "This is a test"; + char input2[] = "Lorem ipsum dolor sit amet"; + char input3[] = "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua"; + + randomx_calculate_hash_first(vm, input1, sizeof(input1) - 1); + randomx_calculate_hash_next(vm, input2, sizeof(input2) - 1, &hash1); + randomx_calculate_hash_next(vm, input3, sizeof(input3) - 1, &hash2); + randomx_calculate_hash_last(vm, &hash3); + + assert(equalsHex(hash1, "639183aae1bf4c9a35884cb46b09cad9175f04efd7684e7262a0ac1c2f0b4e3f")); + assert(equalsHex(hash2, "300a0adb47603dedb42228ccb2b211104f4da45af709cd7547cd049e9489c969")); + assert(equalsHex(hash3, "c36d4ed4191e617309867ed66a443be4075014e2b061bcdaf9ce7b721d2b77a8")); + }); + + randomx_destroy_vm(vm); + vm = nullptr; + if (cache != nullptr) randomx_release_cache(cache); From c6a8be7d586306e8f2b5f1cd480ecc8c45b39dec Mon Sep 17 00:00:00 2001 From: codeofalltrades Date: Tue, 26 Jan 2021 00:29:12 -0600 Subject: [PATCH 02/12] Cherry picked commit 'Preserve floating point state when calling randomx_calculate_hash' from https://github.com/tevador/RandomX/commit/6a764e90d033923e947a311c026203faa4a1cb13 --- src/crypto/randomx/randomx.cpp | 5 ++++- src/crypto/randomx/randomx.h | 2 ++ src/test/randomx_tests.cpp | 13 ++++++++++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/crypto/randomx/randomx.cpp b/src/crypto/randomx/randomx.cpp index 41c1836757..83b26c6b92 100644 --- a/src/crypto/randomx/randomx.cpp +++ b/src/crypto/randomx/randomx.cpp @@ -39,7 +39,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include "utiltime.h" #include "logging.h" - +#include extern "C" { randomx_flags randomx_get_flags() { @@ -493,6 +493,8 @@ extern "C" { assert(machine != nullptr); assert(inputSize == 0 || input != nullptr); assert(output != nullptr); + fenv_t fpstate; + fegetenv(&fpstate); alignas(16) uint64_t tempHash[8]; int blakeResult = blake2b(tempHash, sizeof(tempHash), input, inputSize, nullptr, 0); assert(blakeResult == 0); @@ -505,6 +507,7 @@ extern "C" { } machine->run(&tempHash); machine->getFinalResult(output, RANDOMX_HASH_SIZE); + fesetenv(&fpstate); } void randomx_calculate_hash_first(randomx_vm* machine, const void* input, size_t inputSize) { diff --git a/src/crypto/randomx/randomx.h b/src/crypto/randomx/randomx.h index c47c0399e1..740b60a86d 100644 --- a/src/crypto/randomx/randomx.h +++ b/src/crypto/randomx/randomx.h @@ -245,6 +245,8 @@ RANDOMX_EXPORT void randomx_calculate_hash(randomx_vm *machine, const void *inpu * and begin the calculation of the next hash. * randomx_calculate_hash_last will output the hash value of the previous input. * + * WARNING: These functions may alter the floating point rounding mode of the calling thread. + * * @param machine is a pointer to a randomx_vm structure. Must not be NULL. * @param tempHash an array of 8 64-bit values used to store intermediate data between calls to randomx_calculate_hash_first and randomx_calculate_hash_next. * @param input is a pointer to memory to be hashed. Must not be NULL. diff --git a/src/test/randomx_tests.cpp b/src/test/randomx_tests.cpp index 0858050cdb..f003bd0dce 100644 --- a/src/test/randomx_tests.cpp +++ b/src/test/randomx_tests.cpp @@ -18,8 +18,8 @@ #include "crypto/randomx/intrin_portable.h" #include "crypto/randomx/jit_compiler.hpp" #include "crypto/randomx/aes_hash.hpp" - #include "crypto/randomx/utility.hpp" +#include #include @@ -1164,6 +1164,10 @@ BOOST_AUTO_TEST_CASE(randomx_run_tests) assert(cacheMemory[33554431] == 0x1f47f056d05cd99b); }); + if (cache != nullptr) + randomx_release_cache(cache); + cache = randomx_alloc_cache(RANDOMX_FLAG_DEFAULT); + runTest("Hash batch test", RANDOMX_HAVE_COMPILER && stringsEqual(RANDOMX_ARGON_SALT, "RandomX\x03"), []() { char hash1[RANDOMX_HASH_SIZE]; char hash2[RANDOMX_HASH_SIZE]; @@ -1183,6 +1187,13 @@ BOOST_AUTO_TEST_CASE(randomx_run_tests) assert(equalsHex(hash3, "c36d4ed4191e617309867ed66a443be4075014e2b061bcdaf9ce7b721d2b77a8")); }); + runTest("Preserve rounding mode", RANDOMX_FREQ_CFROUND > 0, []() { + fesetround(FE_TONEAREST); + char hash[RANDOMX_HASH_SIZE]; + calcStringHash("test key 000", "Lorem ipsum dolor sit amet", &hash); + assert(fegetround() == FE_TONEAREST); + }); + randomx_destroy_vm(vm); vm = nullptr; From 2fc40535e190c76d7ec14d8c9d2c69dfd1b45316 Mon Sep 17 00:00:00 2001 From: codeofalltrades Date: Tue, 26 Jan 2021 08:33:50 -0600 Subject: [PATCH 03/12] Cherry picked commit 'fix test 92 not failing properly on GCC/amd64' from https://github.com/tevador/RandomX/commit/148b923f71f3954ceaa37e7aff896d105bb7faa5 --- src/crypto/randomx/instructions_portable.cpp | 15 +++++++++++++++ src/crypto/randomx/intrin_portable.h | 6 ++++++ src/test/randomx_tests.cpp | 7 +++---- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/crypto/randomx/instructions_portable.cpp b/src/crypto/randomx/instructions_portable.cpp index d34494d8e1..b6540b8205 100644 --- a/src/crypto/randomx/instructions_portable.cpp +++ b/src/crypto/randomx/instructions_portable.cpp @@ -157,6 +157,21 @@ void rx_set_rounding_mode(uint32_t mode) { } } +uint32_t rx_get_rounding_mode() { + switch (fegetround()) { + case FE_DOWNWARD: + return RoundDown; + case FE_UPWARD: + return RoundUp; + case FE_TOWARDZERO: + return RoundToZero; + case FE_TONEAREST: + return RoundToNearest; + default: + UNREACHABLE; + } +} + #endif #ifdef RANDOMX_USE_X87 diff --git a/src/crypto/randomx/intrin_portable.h b/src/crypto/randomx/intrin_portable.h index ec5dbfcf63..fcb2298f5c 100644 --- a/src/crypto/randomx/intrin_portable.h +++ b/src/crypto/randomx/intrin_portable.h @@ -173,6 +173,10 @@ FORCE_INLINE void rx_set_rounding_mode(uint32_t mode) { _mm_setcsr(rx_mxcsr_default | (mode << 13)); } +FORCE_INLINE uint32_t rx_get_rounding_mode() { + return (_mm_getcsr() >> 13) & 3; +} + #elif defined(__PPC64__) && defined(__ALTIVEC__) && defined(__VSX__) //sadly only POWER7 and newer will be able to use SIMD acceleration. Earlier processors cant use doubles or 64 bit integers with SIMD #include #include @@ -736,6 +740,8 @@ void rx_reset_float_state(); void rx_set_rounding_mode(uint32_t mode); +uint32_t rx_get_rounding_mode(); + #endif double loadDoublePortable(const void* addr); diff --git a/src/test/randomx_tests.cpp b/src/test/randomx_tests.cpp index f003bd0dce..c090654002 100644 --- a/src/test/randomx_tests.cpp +++ b/src/test/randomx_tests.cpp @@ -19,7 +19,6 @@ #include "crypto/randomx/jit_compiler.hpp" #include "crypto/randomx/aes_hash.hpp" #include "crypto/randomx/utility.hpp" -#include #include @@ -1188,10 +1187,10 @@ BOOST_AUTO_TEST_CASE(randomx_run_tests) }); runTest("Preserve rounding mode", RANDOMX_FREQ_CFROUND > 0, []() { - fesetround(FE_TONEAREST); + rx_set_rounding_mode(RoundToNearest); char hash[RANDOMX_HASH_SIZE]; - calcStringHash("test key 000", "Lorem ipsum dolor sit amet", &hash); - assert(fegetround() == FE_TONEAREST); + assert(equalsHex(hash, "300a0adb47603dedb42228ccb2b211104f4da45af709cd7547cd049e9489c969")); + assert(rx_get_rounding_mode() == RoundToNearest); }); randomx_destroy_vm(vm); From f3d70c32c2231db8b622de4f5ffae79832b1c2b9 Mon Sep 17 00:00:00 2001 From: codeofalltrades Date: Tue, 26 Jan 2021 09:00:34 -0600 Subject: [PATCH 04/12] Cherry picked commit 'fix potential use-after-free when reallocating cache' from https://github.com/tevador/RandomX/commit/32ab5dea5460a98c6a8f5475be58f940daa235ad --- src/crypto/randomx/randomx.cpp | 2 +- src/crypto/randomx/virtual_machine.hpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/crypto/randomx/randomx.cpp b/src/crypto/randomx/randomx.cpp index 83b26c6b92..35bab0024e 100644 --- a/src/crypto/randomx/randomx.cpp +++ b/src/crypto/randomx/randomx.cpp @@ -472,7 +472,7 @@ extern "C" { void randomx_vm_set_cache(randomx_vm *machine, randomx_cache* cache) { assert(machine != nullptr); assert(cache != nullptr && cache->isInitialized()); - if (machine->cacheKey != cache->cacheKey) { + if (machine->cacheKey != cache->cacheKey || machine->getMemory() != cache->memory) { machine->setCache(cache); machine->cacheKey = cache->cacheKey; } diff --git a/src/crypto/randomx/virtual_machine.hpp b/src/crypto/randomx/virtual_machine.hpp index 986216a56c..6f71b0b1d0 100644 --- a/src/crypto/randomx/virtual_machine.hpp +++ b/src/crypto/randomx/virtual_machine.hpp @@ -54,6 +54,9 @@ class randomx_vm { { return program; } + const uint8_t* getMemory() const { + return mem.memory; + } protected: void initialize(); alignas(64) randomx::Program program; From f027b9750dd1ed6c0026f7b3bf958e6e3b0ebda8 Mon Sep 17 00:00:00 2001 From: codeofalltrades Date: Tue, 26 Jan 2021 10:14:41 -0600 Subject: [PATCH 05/12] Cherry picked commit 'Fix compilation and JIT support on NetBSD:' from https://github.com/tevador/RandomX/commit/708a4e50c53f89d3b91aff749ce24b01c293dbe3 --- src/crypto/randomx/jit_compiler.hpp | 4 ++++ src/crypto/randomx/randomx.cpp | 5 +++++ src/crypto/randomx/virtual_memory.cpp | 7 +++++++ 3 files changed, 16 insertions(+) diff --git a/src/crypto/randomx/jit_compiler.hpp b/src/crypto/randomx/jit_compiler.hpp index 03b6050852..514d0c604d 100644 --- a/src/crypto/randomx/jit_compiler.hpp +++ b/src/crypto/randomx/jit_compiler.hpp @@ -35,3 +35,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #else #include "crypto/randomx/jit_compiler_fallback.hpp" #endif + +#if defined(__OpenBSD__) || defined(__NetBSD__) +#define RANDOMX_FORCE_SECURE +#endif \ No newline at end of file diff --git a/src/crypto/randomx/randomx.cpp b/src/crypto/randomx/randomx.cpp index 35bab0024e..aceddec48a 100644 --- a/src/crypto/randomx/randomx.cpp +++ b/src/crypto/randomx/randomx.cpp @@ -45,6 +45,11 @@ extern "C" { randomx_flags randomx_get_flags() { randomx_flags flags = RANDOMX_HAVE_COMPILER ? RANDOMX_FLAG_JIT : RANDOMX_FLAG_DEFAULT; randomx::Cpu cpu; +#ifdef RANDOMX_FORCE_SECURE + if (flags == RANDOMX_FLAG_JIT) { + flags |= RANDOMX_FLAG_SECURE; + } +#endif if (HAVE_AES && cpu.hasAes()) { flags |= RANDOMX_FLAG_HARD_AES; } diff --git a/src/crypto/randomx/virtual_memory.cpp b/src/crypto/randomx/virtual_memory.cpp index 6c74f18979..e884c68612 100644 --- a/src/crypto/randomx/virtual_memory.cpp +++ b/src/crypto/randomx/virtual_memory.cpp @@ -94,6 +94,11 @@ void* allocMemoryPages(std::size_t bytes) { if (mem == nullptr) throw std::runtime_error(getErrorMessage("allocMemoryPages - VirtualAlloc")); #else + #if defined(__NetBSD__) + #define RESERVED_FLAGS PROT_MPROTECT(PROT_EXEC) + #else + #define RESERVED_FLAGS 0 + #endif mem = mmap(nullptr, bytes, PAGE_READWRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); if (mem == MAP_FAILED) throw std::runtime_error("allocMemoryPages - mmap failed"); @@ -141,6 +146,8 @@ void* allocLargePagesMemory(std::size_t bytes) { mem = mmap(nullptr, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0); #elif defined(__FreeBSD__) mem = mmap(nullptr, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER, -1, 0); +#elif defined(__OpenBSD__) || defined(__NetBSD__) + mem = MAP_FAILED; // OpenBSD does not support huge pages #else mem = mmap(nullptr, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, -1, 0); #endif From ad53bda4306c5ba874a0f33e8a00b39c7e512701 Mon Sep 17 00:00:00 2001 From: codeofalltrades Date: Tue, 26 Jan 2021 10:28:44 -0600 Subject: [PATCH 06/12] Cherry picked commit 'virtual_memory: add MAP_JIT on macOS' from https://github.com/tevador/RandomX/commit/7c172f746f94d2f98e0927d2f0e1c3ba3e95e062 --- src/crypto/randomx/virtual_memory.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/crypto/randomx/virtual_memory.cpp b/src/crypto/randomx/virtual_memory.cpp index e884c68612..cd937a02d6 100644 --- a/src/crypto/randomx/virtual_memory.cpp +++ b/src/crypto/randomx/virtual_memory.cpp @@ -99,7 +99,17 @@ void* allocMemoryPages(std::size_t bytes) { #else #define RESERVED_FLAGS 0 #endif - mem = mmap(nullptr, bytes, PAGE_READWRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + #ifdef __APPLE__ + #include + #ifdef TARGET_OS_OSX + #define MEXTRA MAP_JIT + #else + #define MEXTRA 0 + #endif + #else + #define MEXTRA 0 + #endif + mem = mmap(nullptr, bytes, PAGE_READWRITE | RESERVED_FLAGS, MAP_ANONYMOUS | MAP_PRIVATE | MEXTRA, -1, 0); if (mem == MAP_FAILED) throw std::runtime_error("allocMemoryPages - mmap failed"); #endif From 86aea92e9baf7aa9186d0151cea4b84c83bc8c51 Mon Sep 17 00:00:00 2001 From: codeofalltrades Date: Tue, 26 Jan 2021 11:57:45 -0600 Subject: [PATCH 07/12] Cherry picked commit 'Fix function names for clang on Apple' from https://github.com/tevador/RandomX/commit/e43267fa866c71b5bb0a4c7f6aa185012da5cd3a --- src/crypto/randomx/jit_compiler_a64_static.S | 98 +++++++++++--------- 1 file changed, 52 insertions(+), 46 deletions(-) diff --git a/src/crypto/randomx/jit_compiler_a64_static.S b/src/crypto/randomx/jit_compiler_a64_static.S index d16cfda62c..5ae3842837 100644 --- a/src/crypto/randomx/jit_compiler_a64_static.S +++ b/src/crypto/randomx/jit_compiler_a64_static.S @@ -25,26 +25,32 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#if defined(__APPLE__) +#define DECL(x) _##x +#else +#define DECL(x) x +#endif + .arch armv8-a .text - .global randomx_program_aarch64 - .global randomx_program_aarch64_main_loop - .global randomx_program_aarch64_vm_instructions - .global randomx_program_aarch64_imul_rcp_literals_end - .global randomx_program_aarch64_vm_instructions_end - .global randomx_program_aarch64_cacheline_align_mask1 - .global randomx_program_aarch64_cacheline_align_mask2 - .global randomx_program_aarch64_update_spMix1 - .global randomx_program_aarch64_vm_instructions_end_light - .global randomx_program_aarch64_light_cacheline_align_mask - .global randomx_program_aarch64_light_dataset_offset - .global randomx_init_dataset_aarch64 - .global randomx_init_dataset_aarch64_end - .global randomx_calc_dataset_item_aarch64 - .global randomx_calc_dataset_item_aarch64_prefetch - .global randomx_calc_dataset_item_aarch64_mix - .global randomx_calc_dataset_item_aarch64_store_result - .global randomx_calc_dataset_item_aarch64_end + .global DECL(randomx_program_aarch64) + .global DECL(randomx_program_aarch64_main_loop) + .global DECL(randomx_program_aarch64_vm_instructions) + .global DECL(randomx_program_aarch64_imul_rcp_literals_end) + .global DECL(randomx_program_aarch64_vm_instructions_end) + .global DECL(randomx_program_aarch64_cacheline_align_mask1) + .global DECL(randomx_program_aarch64_cacheline_align_mask2) + .global DECL(randomx_program_aarch64_update_spMix1) + .global DECL(randomx_program_aarch64_vm_instructions_end_light) + .global DECL(randomx_program_aarch64_light_cacheline_align_mask) + .global DECL(randomx_program_aarch64_light_dataset_offset) + .global DECL(randomx_init_dataset_aarch64) + .global DECL(randomx_init_dataset_aarch64_end) + .global DECL(randomx_calc_dataset_item_aarch64) + .global DECL(randomx_calc_dataset_item_aarch64_prefetch) + .global DECL(randomx_calc_dataset_item_aarch64_mix) + .global DECL(randomx_calc_dataset_item_aarch64_store_result) + .global DECL(randomx_calc_dataset_item_aarch64_end) #include "configuration.h" @@ -100,8 +106,8 @@ # v30 -> E 'or' mask = 0x3*00000000******3*00000000****** # v31 -> scale mask = 0x81f000000000000081f0000000000000 - .balign 4 -randomx_program_aarch64: + .balign 4 +DECL(randomx_program_aarch64): # Save callee-saved registers sub sp, sp, 192 stp x16, x17, [sp] @@ -189,7 +195,7 @@ randomx_program_aarch64: ldr q14, literal_v14 ldr q15, literal_v15 -randomx_program_aarch64_main_loop: +DECL(randomx_program_aarch64_main_loop): # spAddr0 = spMix1 & ScratchpadL3Mask64; # spAddr1 = (spMix1 >> 32) & ScratchpadL3Mask64; lsr x18, x10, 32 @@ -262,7 +268,7 @@ randomx_program_aarch64_main_loop: orr v23.16b, v23.16b, v30.16b # Execute VM instructions -randomx_program_aarch64_vm_instructions: +DECL(randomx_program_aarch64_vm_instructions): # buffer for generated instructions # FDIV_M is the largest instruction taking up to 12 ARMv8 instructions @@ -281,7 +287,7 @@ literal_x27: .fill 1,8,0 literal_x28: .fill 1,8,0 literal_x29: .fill 1,8,0 literal_x30: .fill 1,8,0 -randomx_program_aarch64_imul_rcp_literals_end: +DECL(randomx_program_aarch64_imul_rcp_literals_end): literal_v0: .fill 2,8,0 literal_v1: .fill 2,8,0 @@ -300,14 +306,14 @@ literal_v13: .fill 2,8,0 literal_v14: .fill 2,8,0 literal_v15: .fill 2,8,0 -randomx_program_aarch64_vm_instructions_end: +DECL(randomx_program_aarch64_vm_instructions_end): # mx ^= r[readReg2] ^ r[readReg3]; eor x9, x9, x18 # Calculate dataset pointer for dataset prefetch mov w18, w9 -randomx_program_aarch64_cacheline_align_mask1: +DECL(randomx_program_aarch64_cacheline_align_mask1): # Actual mask will be inserted by JIT compiler and x18, x18, 1 add x18, x18, x1 @@ -320,12 +326,12 @@ randomx_program_aarch64_cacheline_align_mask1: # Calculate dataset pointer for dataset read mov w10, w9 -randomx_program_aarch64_cacheline_align_mask2: +DECL(randomx_program_aarch64_cacheline_align_mask2): # Actual mask will be inserted by JIT compiler and x10, x10, 1 add x10, x10, x1 -randomx_program_aarch64_xor_with_dataset_line: +DECL(randomx_program_aarch64_xor_with_dataset_line): # xor integer registers with dataset data ldp x18, x19, [x10] eor x4, x4, x18 @@ -340,7 +346,7 @@ randomx_program_aarch64_xor_with_dataset_line: eor x14, x14, x18 eor x15, x15, x19 -randomx_program_aarch64_update_spMix1: +DECL(randomx_program_aarch64_update_spMix1): # JIT compiler will replace it with "eor x10, config.readReg0, config.readReg1" eor x10, x0, x0 @@ -361,8 +367,8 @@ randomx_program_aarch64_update_spMix1: stp q18, q19, [x16, 32] subs x3, x3, 1 - bne randomx_program_aarch64_main_loop - + bne DECL(randomx_program_aarch64_main_loop) + # Restore x0 ldr x0, [sp], 16 @@ -395,7 +401,7 @@ randomx_program_aarch64_update_spMix1: ret -randomx_program_aarch64_vm_instructions_end_light: +DECL(randomx_program_aarch64_vm_instructions_end_light): sub sp, sp, 96 stp x0, x1, [sp, 64] stp x2, x30, [sp, 80] @@ -412,26 +418,26 @@ randomx_program_aarch64_vm_instructions_end_light: # x1 -> pointer to output mov x1, sp -randomx_program_aarch64_light_cacheline_align_mask: +DECL(randomx_program_aarch64_light_cacheline_align_mask): # Actual mask will be inserted by JIT compiler and w2, w9, 1 # x2 -> item number lsr x2, x2, 6 -randomx_program_aarch64_light_dataset_offset: +DECL(randomx_program_aarch64_light_dataset_offset): # Apply dataset offset (filled in by JIT compiler) add x2, x2, 0 add x2, x2, 0 - bl randomx_calc_dataset_item_aarch64 + bl DECL(randomx_calc_dataset_item_aarch64) mov x10, sp ldp x0, x1, [sp, 64] ldp x2, x30, [sp, 80] add sp, sp, 96 - b randomx_program_aarch64_xor_with_dataset_line + b DECL(randomx_program_aarch64_xor_with_dataset_line) @@ -442,26 +448,26 @@ randomx_program_aarch64_light_dataset_offset: # x2 -> start item # x3 -> end item -randomx_init_dataset_aarch64: +DECL(randomx_init_dataset_aarch64): # Save x30 (return address) str x30, [sp, -16]! # Load pointer to cache memory ldr x0, [x0] -randomx_init_dataset_aarch64_main_loop: - bl randomx_calc_dataset_item_aarch64 +DECL(randomx_init_dataset_aarch64_main_loop): + bl DECL(randomx_calc_dataset_item_aarch64) add x1, x1, 64 add x2, x2, 1 cmp x2, x3 - bne randomx_init_dataset_aarch64_main_loop + bne DECL(randomx_init_dataset_aarch64_main_loop) # Restore x30 (return address) ldr x30, [sp], 16 ret -randomx_init_dataset_aarch64_end: +DECL(randomx_init_dataset_aarch64_end): # Input parameters # @@ -479,7 +485,7 @@ randomx_init_dataset_aarch64_end: # x12 -> temporary # x13 -> temporary -randomx_calc_dataset_item_aarch64: +DECL(randomx_calc_dataset_item_aarch64): sub sp, sp, 112 stp x0, x1, [sp] stp x2, x3, [sp, 16] @@ -526,7 +532,7 @@ randomx_calc_dataset_item_aarch64: ldr x12, superscalarAdd7 eor x7, x0, x12 - b randomx_calc_dataset_item_aarch64_prefetch + b DECL(randomx_calc_dataset_item_aarch64_prefetch) superscalarMul0: .quad 6364136223846793005 superscalarAdd1: .quad 9298411001130361340 @@ -539,7 +545,7 @@ superscalarAdd7: .quad 9549104520008361294 # Prefetch -> SuperScalar hash -> Mix will be repeated N times -randomx_calc_dataset_item_aarch64_prefetch: +DECL(randomx_calc_dataset_item_aarch64_prefetch): # Actual mask will be inserted by JIT compiler and x11, x10, 1 add x11, x8, x11, lsl 6 @@ -547,7 +553,7 @@ randomx_calc_dataset_item_aarch64_prefetch: # Generated SuperScalar hash program goes here -randomx_calc_dataset_item_aarch64_mix: +DECL(randomx_calc_dataset_item_aarch64_mix): ldp x12, x13, [x11] eor x0, x0, x12 eor x1, x1, x13 @@ -561,7 +567,7 @@ randomx_calc_dataset_item_aarch64_mix: eor x6, x6, x12 eor x7, x7, x13 -randomx_calc_dataset_item_aarch64_store_result: +DECL(randomx_calc_dataset_item_aarch64_store_result): stp x0, x1, [x9] stp x2, x3, [x9, 16] stp x4, x5, [x9, 32] @@ -578,4 +584,4 @@ randomx_calc_dataset_item_aarch64_store_result: ret -randomx_calc_dataset_item_aarch64_end: +DECL(randomx_calc_dataset_item_aarch64_end): From 8a9c139f3099881bc4aa00af42aac68acf7cbb39 Mon Sep 17 00:00:00 2001 From: codeofalltrades Date: Tue, 26 Jan 2021 12:05:45 -0600 Subject: [PATCH 08/12] Cherry picked commit 'Optimized Argon2 (SSSE3/AVX2)' from https://github.com/tevador/RandomX/commit/900a936816e228920debb16d1044f7d9f71b2945 --- src/crypto/randomx/argon2.h | 138 +++++++++++++++---------------- src/crypto/randomx/argon2_avx2.c | 10 +-- 2 files changed, 69 insertions(+), 79 deletions(-) diff --git a/src/crypto/randomx/argon2.h b/src/crypto/randomx/argon2.h index 91fb941639..86bd85f5dc 100644 --- a/src/crypto/randomx/argon2.h +++ b/src/crypto/randomx/argon2.h @@ -42,7 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * Argon2 input parameter restrictions */ - /* Minimum and maximum number of lanes (degree of parallelism) */ +/* Minimum and maximum number of lanes (degree of parallelism) */ #define ARGON2_MIN_LANES UINT32_C(1) #define ARGON2_MAX_LANES UINT32_C(0xFFFFFF) @@ -95,63 +95,63 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* Error codes */ typedef enum Argon2_ErrorCodes { - ARGON2_OK = 0, + ARGON2_OK = 0, - ARGON2_OUTPUT_PTR_NULL = -1, + ARGON2_OUTPUT_PTR_NULL = -1, - ARGON2_OUTPUT_TOO_SHORT = -2, - ARGON2_OUTPUT_TOO_LONG = -3, + ARGON2_OUTPUT_TOO_SHORT = -2, + ARGON2_OUTPUT_TOO_LONG = -3, - ARGON2_PWD_TOO_SHORT = -4, - ARGON2_PWD_TOO_LONG = -5, + ARGON2_PWD_TOO_SHORT = -4, + ARGON2_PWD_TOO_LONG = -5, - ARGON2_SALT_TOO_SHORT = -6, - ARGON2_SALT_TOO_LONG = -7, + ARGON2_SALT_TOO_SHORT = -6, + ARGON2_SALT_TOO_LONG = -7, - ARGON2_AD_TOO_SHORT = -8, - ARGON2_AD_TOO_LONG = -9, + ARGON2_AD_TOO_SHORT = -8, + ARGON2_AD_TOO_LONG = -9, - ARGON2_SECRET_TOO_SHORT = -10, - ARGON2_SECRET_TOO_LONG = -11, + ARGON2_SECRET_TOO_SHORT = -10, + ARGON2_SECRET_TOO_LONG = -11, - ARGON2_TIME_TOO_SMALL = -12, - ARGON2_TIME_TOO_LARGE = -13, + ARGON2_TIME_TOO_SMALL = -12, + ARGON2_TIME_TOO_LARGE = -13, - ARGON2_MEMORY_TOO_LITTLE = -14, - ARGON2_MEMORY_TOO_MUCH = -15, + ARGON2_MEMORY_TOO_LITTLE = -14, + ARGON2_MEMORY_TOO_MUCH = -15, - ARGON2_LANES_TOO_FEW = -16, - ARGON2_LANES_TOO_MANY = -17, + ARGON2_LANES_TOO_FEW = -16, + ARGON2_LANES_TOO_MANY = -17, - ARGON2_PWD_PTR_MISMATCH = -18, /* NULL ptr with non-zero length */ - ARGON2_SALT_PTR_MISMATCH = -19, /* NULL ptr with non-zero length */ - ARGON2_SECRET_PTR_MISMATCH = -20, /* NULL ptr with non-zero length */ - ARGON2_AD_PTR_MISMATCH = -21, /* NULL ptr with non-zero length */ + ARGON2_PWD_PTR_MISMATCH = -18, /* NULL ptr with non-zero length */ + ARGON2_SALT_PTR_MISMATCH = -19, /* NULL ptr with non-zero length */ + ARGON2_SECRET_PTR_MISMATCH = -20, /* NULL ptr with non-zero length */ + ARGON2_AD_PTR_MISMATCH = -21, /* NULL ptr with non-zero length */ - ARGON2_MEMORY_ALLOCATION_ERROR = -22, + ARGON2_MEMORY_ALLOCATION_ERROR = -22, - ARGON2_FREE_MEMORY_CBK_NULL = -23, - ARGON2_ALLOCATE_MEMORY_CBK_NULL = -24, + ARGON2_FREE_MEMORY_CBK_NULL = -23, + ARGON2_ALLOCATE_MEMORY_CBK_NULL = -24, - ARGON2_INCORRECT_PARAMETER = -25, - ARGON2_INCORRECT_TYPE = -26, + ARGON2_INCORRECT_PARAMETER = -25, + ARGON2_INCORRECT_TYPE = -26, - ARGON2_OUT_PTR_MISMATCH = -27, + ARGON2_OUT_PTR_MISMATCH = -27, - ARGON2_THREADS_TOO_FEW = -28, - ARGON2_THREADS_TOO_MANY = -29, + ARGON2_THREADS_TOO_FEW = -28, + ARGON2_THREADS_TOO_MANY = -29, - ARGON2_MISSING_ARGS = -30, + ARGON2_MISSING_ARGS = -30, - ARGON2_ENCODING_FAIL = -31, + ARGON2_ENCODING_FAIL = -31, - ARGON2_DECODING_FAIL = -32, + ARGON2_DECODING_FAIL = -32, - ARGON2_THREAD_FAIL = -33, + ARGON2_THREAD_FAIL = -33, - ARGON2_DECODING_LENGTH_FAIL = -34, + ARGON2_DECODING_LENGTH_FAIL = -34, - ARGON2_VERIFY_MISMATCH = -35 + ARGON2_VERIFY_MISMATCH = -35 } argon2_error_codes; /* Memory allocator types --- for external allocation */ @@ -186,46 +186,46 @@ typedef void(*deallocate_fptr)(uint8_t *memory, size_t bytes_to_allocate); Argon2_Context(out,8,pwd,32,salt,16,NULL,0,NULL,0,5,1<<20,4,4,NULL,NULL,true,false,false,false) */ typedef struct Argon2_Context { - uint8_t *out; /* output array */ - uint32_t outlen; /* digest length */ + uint8_t *out; /* output array */ + uint32_t outlen; /* digest length */ - uint8_t *pwd; /* password array */ - uint32_t pwdlen; /* password length */ + uint8_t *pwd; /* password array */ + uint32_t pwdlen; /* password length */ - uint8_t *salt; /* salt array */ - uint32_t saltlen; /* salt length */ + uint8_t *salt; /* salt array */ + uint32_t saltlen; /* salt length */ - uint8_t *secret; /* key array */ - uint32_t secretlen; /* key length */ + uint8_t *secret; /* key array */ + uint32_t secretlen; /* key length */ - uint8_t *ad; /* associated data array */ - uint32_t adlen; /* associated data length */ + uint8_t *ad; /* associated data array */ + uint32_t adlen; /* associated data length */ - uint32_t t_cost; /* number of passes */ - uint32_t m_cost; /* amount of memory requested (KB) */ - uint32_t lanes; /* number of lanes */ - uint32_t threads; /* maximum number of threads */ + uint32_t t_cost; /* number of passes */ + uint32_t m_cost; /* amount of memory requested (KB) */ + uint32_t lanes; /* number of lanes */ + uint32_t threads; /* maximum number of threads */ - uint32_t version; /* version number */ + uint32_t version; /* version number */ - allocate_fptr allocate_cbk; /* pointer to memory allocator */ - deallocate_fptr free_cbk; /* pointer to memory deallocator */ + allocate_fptr allocate_cbk; /* pointer to memory allocator */ + deallocate_fptr free_cbk; /* pointer to memory deallocator */ - uint32_t flags; /* array of bool options */ + uint32_t flags; /* array of bool options */ } argon2_context; /* Argon2 primitive type */ typedef enum Argon2_type { - Argon2_d = 0, - Argon2_i = 1, - Argon2_id = 2 + Argon2_d = 0, + Argon2_i = 1, + Argon2_id = 2 } argon2_type; /* Version of the algorithm */ typedef enum Argon2_version { - ARGON2_VERSION_10 = 0x10, - ARGON2_VERSION_13 = 0x13, - ARGON2_VERSION_NUMBER = ARGON2_VERSION_13 + ARGON2_VERSION_10 = 0x10, + ARGON2_VERSION_13 = 0x13, + ARGON2_VERSION_NUMBER = ARGON2_VERSION_13 } argon2_version; //Argon2 instance - forward declaration @@ -236,7 +236,7 @@ typedef struct Argon2_position_t argon2_position_t; //Argon2 implementation function typedef void randomx_argon2_impl(const argon2_instance_t* instance, - argon2_position_t position); + argon2_position_t position); #if defined(__cplusplus) extern "C" { @@ -251,17 +251,11 @@ extern "C" { * @pre all block pointers must be valid */ void randomx_argon2_fill_segment_ref(const argon2_instance_t* instance, - argon2_position_t position); + argon2_position_t position); - randomx_argon2_impl *randomx_argon2_impl_ssse3(); - -#if defined (__AVX2__) - randomx_argon2_impl *randomx_argon2_impl_avx2(); -#else -inline randomx_argon2_impl *randomx_argon2_impl_avx2() { return NULL; } -#endif +randomx_argon2_impl *randomx_argon2_impl_ssse3(); +randomx_argon2_impl *randomx_argon2_impl_avx2(); #if defined(__cplusplus) } -#endif - +#endif \ No newline at end of file diff --git a/src/crypto/randomx/argon2_avx2.c b/src/crypto/randomx/argon2_avx2.c index 6ad39cb49f..f33657357c 100644 --- a/src/crypto/randomx/argon2_avx2.c +++ b/src/crypto/randomx/argon2_avx2.c @@ -39,20 +39,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "crypto/randomx/argon2.h" void randomx_argon2_fill_segment_avx2(const argon2_instance_t* instance, - argon2_position_t position); + argon2_position_t position); -#if defined(__AVX2__) randomx_argon2_impl* randomx_argon2_impl_avx2() { - #if defined(__AVX2__) - return &randomx_argon2_fill_segment_avx2; + return &randomx_argon2_fill_segment_avx2; #endif - return NULL; + return NULL; } -#endif #if defined(__AVX2__) -#include #include "crypto/randomx/argon2_core.h" From 08d26075e78d1beac25ee92b9f524a55dd74568b Mon Sep 17 00:00:00 2001 From: codeofalltrades Date: Tue, 26 Jan 2021 12:07:23 -0600 Subject: [PATCH 09/12] Cherry picked commit 'Fixes for cmake build with visual studio' from https://github.com/tevador/RandomX/commit/01914b49cd7845b9349598d7f3d56bfee14c92d0 --- src/crypto/randomx/dataset.hpp | 89 +++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/src/crypto/randomx/dataset.hpp b/src/crypto/randomx/dataset.hpp index fca2eef850..b5ef76abf4 100644 --- a/src/crypto/randomx/dataset.hpp +++ b/src/crypto/randomx/dataset.hpp @@ -38,57 +38,66 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* Global scope for C binding */ struct randomx_dataset { - uint8_t* memory = nullptr; - randomx::DatasetDeallocFunc* dealloc; + uint8_t* memory = nullptr; + randomx::DatasetDeallocFunc* dealloc; }; /* Global scope for C binding */ struct randomx_cache { - uint8_t* memory = nullptr; - randomx::CacheDeallocFunc* dealloc; - randomx::JitCompiler* jit; - randomx::CacheInitializeFunc* initialize; - randomx::DatasetInitFunc* datasetInit; - randomx::SuperscalarProgram programs[RANDOMX_CACHE_ACCESSES]; - std::vector reciprocalCache; - std::string cacheKey; - randomx_argon2_impl* argonImpl; - - bool isInitialized() { - return programs[0].getSize() != 0; - } + uint8_t* memory = nullptr; + randomx::CacheDeallocFunc* dealloc; + randomx::JitCompiler* jit; + randomx::CacheInitializeFunc* initialize; + randomx::DatasetInitFunc* datasetInit; + randomx::SuperscalarProgram programs[RANDOMX_CACHE_ACCESSES]; + std::vector reciprocalCache; + std::string cacheKey; + randomx_argon2_impl* argonImpl; + + bool isInitialized() { + return programs[0].getSize() != 0; + } }; //A pointer to a standard-layout struct object points to its initial member static_assert(std::is_standard_layout(), "randomx_dataset must be a standard-layout struct"); + //the following assert fails when compiling Debug in Visual Studio (JIT mode will crash in Debug) +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && defined(_DEBUG) +#define TO_STR(x) #x +#define STR(x) TO_STR(x) +#pragma message ( __FILE__ "(" STR(__LINE__) ") warning: check std::is_standard_layout() is disabled for Debug configuration. JIT mode will crash." ) +#undef STR +#undef TO_STR +#else static_assert(std::is_standard_layout(), "randomx_cache must be a standard-layout struct"); +#endif namespace randomx { - using DefaultAllocator = AlignedAllocator; - - template - void deallocDataset(randomx_dataset* dataset) { - if (dataset->memory != nullptr) - Allocator::freeMemory(dataset->memory, DatasetSize); - } - - template - void deallocCache(randomx_cache* cache); - - void initCache(randomx_cache*, const void*, size_t); - void initCacheCompile(randomx_cache*, const void*, size_t); - void initDatasetItem(randomx_cache* cache, uint8_t* out, uint64_t blockNumber); - void initDataset(randomx_cache* cache, uint8_t* dataset, uint32_t startBlock, uint32_t endBlock); - - inline randomx_argon2_impl* selectArgonImpl(randomx_flags flags) { - if (flags & RANDOMX_FLAG_ARGON2_AVX2) { - return randomx_argon2_impl_avx2(); - } - if (flags & RANDOMX_FLAG_ARGON2_SSSE3) { - return randomx_argon2_impl_ssse3(); - } - return &randomx_argon2_fill_segment_ref; - } + using DefaultAllocator = AlignedAllocator; + + template + void deallocDataset(randomx_dataset* dataset) { + if (dataset->memory != nullptr) + Allocator::freeMemory(dataset->memory, DatasetSize); + } + + template + void deallocCache(randomx_cache* cache); + + void initCache(randomx_cache*, const void*, size_t); + void initCacheCompile(randomx_cache*, const void*, size_t); + void initDatasetItem(randomx_cache* cache, uint8_t* out, uint64_t blockNumber); + void initDataset(randomx_cache* cache, uint8_t* dataset, uint32_t startBlock, uint32_t endBlock); + + inline randomx_argon2_impl* selectArgonImpl(randomx_flags flags) { + if (flags & RANDOMX_FLAG_ARGON2_AVX2) { + return randomx_argon2_impl_avx2(); + } + if (flags & RANDOMX_FLAG_ARGON2_SSSE3) { + return randomx_argon2_impl_ssse3(); + } + return &randomx_argon2_fill_segment_ref; + } } From 9bc9a3dad44f922882da8d8628d21b75e28f8152 Mon Sep 17 00:00:00 2001 From: codeofalltrades Date: Tue, 26 Jan 2021 12:08:32 -0600 Subject: [PATCH 10/12] Cherry picked commit 'Fix symbol collisions with blake2b' from https://github.com/tevador/RandomX/commit/7567cef4c6192fb5356bbdd7db802be77be0439b --- src/crypto/randomx/blake2/blake2.h | 124 ++++++++++++++--------------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/src/crypto/randomx/blake2/blake2.h b/src/crypto/randomx/blake2/blake2.h index 2db10519d7..9cea9874cc 100644 --- a/src/crypto/randomx/blake2/blake2.h +++ b/src/crypto/randomx/blake2/blake2.h @@ -42,72 +42,72 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. extern "C" { #endif - enum blake2b_constant { - BLAKE2B_BLOCKBYTES = 128, - BLAKE2B_OUTBYTES = 64, - BLAKE2B_KEYBYTES = 64, - BLAKE2B_SALTBYTES = 16, - BLAKE2B_PERSONALBYTES = 16 - }; +enum blake2b_constant { + BLAKE2B_BLOCKBYTES = 128, + BLAKE2B_OUTBYTES = 64, + BLAKE2B_KEYBYTES = 64, + BLAKE2B_SALTBYTES = 16, + BLAKE2B_PERSONALBYTES = 16 +}; #pragma pack(push, 1) - typedef struct __blake2b_param { - uint8_t digest_length; /* 1 */ - uint8_t key_length; /* 2 */ - uint8_t fanout; /* 3 */ - uint8_t depth; /* 4 */ - uint32_t leaf_length; /* 8 */ - uint64_t node_offset; /* 16 */ - uint8_t node_depth; /* 17 */ - uint8_t inner_length; /* 18 */ - uint8_t reserved[14]; /* 32 */ - uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ - uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ - } blake2b_param; +typedef struct __blake2b_param { + uint8_t digest_length; /* 1 */ + uint8_t key_length; /* 2 */ + uint8_t fanout; /* 3 */ + uint8_t depth; /* 4 */ + uint32_t leaf_length; /* 8 */ + uint64_t node_offset; /* 16 */ + uint8_t node_depth; /* 17 */ + uint8_t inner_length; /* 18 */ + uint8_t reserved[14]; /* 32 */ + uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ + uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ +} blake2b_param; #pragma pack(pop) - typedef struct __blake2b_state { - uint64_t h[8]; - uint64_t t[2]; - uint64_t f[2]; - uint8_t buf[BLAKE2B_BLOCKBYTES]; - unsigned buflen; - unsigned outlen; - uint8_t last_node; - } blake2b_state; - - /* Ensure param structs have not been wrongly padded */ - /* Poor man's static_assert */ - enum { - blake2_size_check_0 = 1 / !!(CHAR_BIT == 8), - blake2_size_check_2 = - 1 / !!(sizeof(blake2b_param) == sizeof(uint64_t) * CHAR_BIT) - }; - - //randomx namespace - #define blake2b_init randomx_blake2b_init - #define blake2b_init_key randomx_blake2b_init_key - #define blake2b_init_param randomx_blake2b_init_param - #define blake2b_update randomx_blake2b_update - #define blake2b_final randomx_blake2b_final - #define blake2b randomx_blake2b - #define blake2b_long randomx_blake2b_long - - /* Streaming API */ - int blake2b_init(blake2b_state *S, size_t outlen); - int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key, - size_t keylen); - int blake2b_init_param(blake2b_state *S, const blake2b_param *P); - int blake2b_update(blake2b_state *S, const void *in, size_t inlen); - int blake2b_final(blake2b_state *S, void *out, size_t outlen); - - /* Simple API */ - int blake2b(void *out, size_t outlen, const void *in, size_t inlen, - const void *key, size_t keylen); - - /* Argon2 Team - Begin Code */ - int rxa2_blake2b_long(void *out, size_t outlen, const void *in, size_t inlen); - /* Argon2 Team - End Code */ +typedef struct __blake2b_state { + uint64_t h[8]; + uint64_t t[2]; + uint64_t f[2]; + uint8_t buf[BLAKE2B_BLOCKBYTES]; + unsigned buflen; + unsigned outlen; + uint8_t last_node; +} blake2b_state; + +/* Ensure param structs have not been wrongly padded */ +/* Poor man's static_assert */ +enum { + blake2_size_check_0 = 1 / !!(CHAR_BIT == 8), + blake2_size_check_2 = + 1 / !!(sizeof(blake2b_param) == sizeof(uint64_t) * CHAR_BIT) +}; + +//randomx namespace +#define blake2b_init randomx_blake2b_init +#define blake2b_init_key randomx_blake2b_init_key +#define blake2b_init_param randomx_blake2b_init_param +#define blake2b_update randomx_blake2b_update +#define blake2b_final randomx_blake2b_final +#define blake2b randomx_blake2b +#define blake2b_long randomx_blake2b_long + +/* Streaming API */ +int blake2b_init(blake2b_state *S, size_t outlen); +int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key, + size_t keylen); +int blake2b_init_param(blake2b_state *S, const blake2b_param *P); +int blake2b_update(blake2b_state *S, const void *in, size_t inlen); +int blake2b_final(blake2b_state *S, void *out, size_t outlen); + +/* Simple API */ +int blake2b(void *out, size_t outlen, const void *in, size_t inlen, + const void *key, size_t keylen); + +/* Argon2 Team - Begin Code */ +int blake2b_long(void *out, size_t outlen, const void *in, size_t inlen); +/* Argon2 Team - End Code */ #if defined(__cplusplus) } From ab7897c2fed29ad8322b5ee728d2505a06bd8493 Mon Sep 17 00:00:00 2001 From: codeofalltrades Date: Tue, 26 Jan 2021 12:09:39 -0600 Subject: [PATCH 11/12] Cherry picked commit 'Add a missing function to calculate a batch of hashes' from https://github.com/tevador/RandomX/commit/01381ccef32da29ef4c64209980eb2b1415fc6a4 --- src/crypto/randomx/randomx.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/crypto/randomx/randomx.h b/src/crypto/randomx/randomx.h index 740b60a86d..141e1e732a 100644 --- a/src/crypto/randomx/randomx.h +++ b/src/crypto/randomx/randomx.h @@ -39,15 +39,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endif typedef enum { - RANDOMX_FLAG_DEFAULT = 0, - RANDOMX_FLAG_LARGE_PAGES = 1, - RANDOMX_FLAG_HARD_AES = 2, - RANDOMX_FLAG_FULL_MEM = 4, - RANDOMX_FLAG_JIT = 8, - RANDOMX_FLAG_SECURE = 16, - RANDOMX_FLAG_ARGON2_SSSE3 = 32, - RANDOMX_FLAG_ARGON2_AVX2 = 64, - RANDOMX_FLAG_ARGON2 = 96 + RANDOMX_FLAG_DEFAULT = 0, + RANDOMX_FLAG_LARGE_PAGES = 1, + RANDOMX_FLAG_HARD_AES = 2, + RANDOMX_FLAG_FULL_MEM = 4, + RANDOMX_FLAG_JIT = 8, + RANDOMX_FLAG_SECURE = 16, + RANDOMX_FLAG_ARGON2_SSSE3 = 32, + RANDOMX_FLAG_ARGON2_AVX2 = 64, + RANDOMX_FLAG_ARGON2 = 96 } randomx_flags; typedef struct randomx_dataset randomx_dataset; @@ -83,6 +83,7 @@ extern "C" { * RANDOMX_FLAG_FULL_MEM * RANDOMX_FLAG_SECURE * These flags must be added manually if desired. + * On OpenBSD RANDOMX_FLAG_SECURE is enabled by default in JIT mode as W^X is enforced by the OS. */ RANDOMX_EXPORT randomx_flags randomx_get_flags(void); @@ -248,7 +249,6 @@ RANDOMX_EXPORT void randomx_calculate_hash(randomx_vm *machine, const void *inpu * WARNING: These functions may alter the floating point rounding mode of the calling thread. * * @param machine is a pointer to a randomx_vm structure. Must not be NULL. - * @param tempHash an array of 8 64-bit values used to store intermediate data between calls to randomx_calculate_hash_first and randomx_calculate_hash_next. * @param input is a pointer to memory to be hashed. Must not be NULL. * @param inputSize is the number of bytes to be hashed. * @param nextInput is a pointer to memory to be hashed for the next hash. Must not be NULL. From 7fedd6706210cdfe1eab6c34d0d75018d779c600 Mon Sep 17 00:00:00 2001 From: codeofalltrades Date: Tue, 26 Jan 2021 14:30:49 -0600 Subject: [PATCH 12/12] Update cherry picked code to match this implementation --- src/crypto/randomx/argon2.h | 7 ++++++- src/crypto/randomx/argon2_avx2.c | 8 ++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/crypto/randomx/argon2.h b/src/crypto/randomx/argon2.h index 86bd85f5dc..facfa4c660 100644 --- a/src/crypto/randomx/argon2.h +++ b/src/crypto/randomx/argon2.h @@ -254,7 +254,12 @@ void randomx_argon2_fill_segment_ref(const argon2_instance_t* instance, argon2_position_t position); randomx_argon2_impl *randomx_argon2_impl_ssse3(); -randomx_argon2_impl *randomx_argon2_impl_avx2(); + +#if defined (__AVX2__) + randomx_argon2_impl *randomx_argon2_impl_avx2(); +#else + inline randomx_argon2_impl *randomx_argon2_impl_avx2() { return NULL; } +#endif #if defined(__cplusplus) } diff --git a/src/crypto/randomx/argon2_avx2.c b/src/crypto/randomx/argon2_avx2.c index f33657357c..db5249021c 100644 --- a/src/crypto/randomx/argon2_avx2.c +++ b/src/crypto/randomx/argon2_avx2.c @@ -41,14 +41,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. void randomx_argon2_fill_segment_avx2(const argon2_instance_t* instance, argon2_position_t position); +#if defined(__AVX2__) randomx_argon2_impl* randomx_argon2_impl_avx2() { + #if defined(__AVX2__) - return &randomx_argon2_fill_segment_avx2; + return &randomx_argon2_fill_segment_avx2; #endif - return NULL; + return NULL; } +#endif #if defined(__AVX2__) +#include #include "crypto/randomx/argon2_core.h"