diff --git a/src/randomx.cpp b/src/randomx.cpp index 898425c..31289ff 100644 --- a/src/randomx.cpp +++ b/src/randomx.cpp @@ -380,4 +380,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/randomx.h b/src/randomx.h index d582cf0..48aaf8e 100644 --- a/src/randomx.h +++ b/src/randomx.h @@ -240,9 +240,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 input is a pointer to memory to be hashed. Must not be NULL. @@ -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/tests/tests.cpp b/src/tests/tests.cpp index 962a120..b425f19 100644 --- a/src/tests/tests.cpp +++ b/src/tests/tests.cpp @@ -1026,9 +1026,6 @@ int main() { runTest("Hash test 2e (compiler)", RANDOMX_HAVE_COMPILER && stringsEqual(RANDOMX_ARGON_SALT, "RandomX\x03"), test_e); - randomx_destroy_vm(vm); - vm = nullptr; - auto flags = randomx_get_flags(); randomx_release_cache(cache); @@ -1054,6 +1051,28 @@ int main() { 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);