From 5f95f86b458de4af9278c6b7fd5cd7b47ebe252f Mon Sep 17 00:00:00 2001 From: dmac Date: Mon, 27 Nov 2023 08:52:23 -0800 Subject: [PATCH] Add arweave packing/mining specific methods --- .gitignore | 1 + CMakeLists.txt | 3 +- src/arweave/randomx_long_with_entropy.cpp | 125 ++++++++++++++++++++++ src/arweave/randomx_long_with_entropy.h | 22 ++++ 4 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 src/arweave/randomx_long_with_entropy.cpp create mode 100644 src/arweave/randomx_long_with_entropy.h diff --git a/.gitignore b/.gitignore index ec94c2c6..c9013fdc 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ x64/ Release/ Debug/ build/ +.DS_Store diff --git a/CMakeLists.txt b/CMakeLists.txt index ebbdff2b..86378064 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,7 +54,8 @@ src/instructions_portable.cpp src/reciprocal.c src/virtual_machine.cpp src/vm_compiled_light.cpp -src/blake2/blake2b.c) +src/blake2/blake2b.c +src/arweave/randomx_long_with_entropy.cpp) if(NOT ARCH_ID) # allow cross compiling diff --git a/src/arweave/randomx_long_with_entropy.cpp b/src/arweave/randomx_long_with_entropy.cpp new file mode 100644 index 00000000..02e722ae --- /dev/null +++ b/src/arweave/randomx_long_with_entropy.cpp @@ -0,0 +1,125 @@ +#include +#include "randomx_long_with_entropy.h" +#include "../vm_interpreted.hpp" +#include "../vm_interpreted_light.hpp" +#include "../vm_compiled.hpp" +#include "../vm_compiled_light.hpp" +#include "../blake2/blake2.h" +// #include "feistel_msgsize_key_cipher.h" + +// NOTE. possible optimisation with outputEntropySize +// can improve performance for less memcpy (has almost no impact because randomx is too long 99+%) + +extern "C" { + void randomx_calculate_hash_long(randomx_vm *machine, const unsigned char *input, const size_t inputSize, unsigned char *output, const int randomxProgramCount) { + assert(machine != nullptr); + assert(inputSize == 0 || input != nullptr); + assert(output != nullptr); + alignas(16) uint64_t tempHash[8]; + int blakeResult = blake2b(tempHash, sizeof(tempHash), input, inputSize, nullptr, 0); + assert(blakeResult == 0); + machine->initScratchpad(&tempHash); + machine->resetRoundingMode(); + for (int chain = 0; chain < randomxProgramCount - 1; ++chain) { + machine->run(&tempHash); + blakeResult = blake2b(tempHash, sizeof(tempHash), machine->getRegisterFile(), sizeof(randomx::RegisterFile), nullptr, 0); + assert(blakeResult == 0); + } + machine->run(&tempHash); + machine->getFinalResult(output, RANDOMX_HASH_SIZE); + } + + void randomx_calculate_hash_long_with_entropy(randomx_vm *machine, const unsigned char *input, const size_t inputSize, unsigned char *output, unsigned char *outputEntropy, const int randomxProgramCount) { + assert(machine != nullptr); + assert(inputSize == 0 || input != nullptr); + assert(output != nullptr); + alignas(16) uint64_t tempHash[8]; + int blakeResult = blake2b(tempHash, sizeof(tempHash), input, inputSize, nullptr, 0); + assert(blakeResult == 0); + machine->initScratchpad(&tempHash); + machine->resetRoundingMode(); + for (int chain = 0; chain < randomxProgramCount - 1; ++chain) { + machine->run(&tempHash); + blakeResult = blake2b(tempHash, sizeof(tempHash), machine->getRegisterFile(), sizeof(randomx::RegisterFile), nullptr, 0); + assert(blakeResult == 0); + } + machine->run(&tempHash); + machine->getFinalResult(output, RANDOMX_HASH_SIZE); + memcpy(outputEntropy, machine->getScratchpad(), RANDOMX_ENTROPY_SIZE); + } + +const unsigned char *randomx_calculate_hash_long_with_entropy_get_entropy(randomx_vm *machine, const unsigned char *input, const size_t inputSize, const int randomxProgramCount) { + assert(machine != nullptr); + assert(inputSize == 0 || input != nullptr); + alignas(16) uint64_t tempHash[8]; + int blakeResult = blake2b(tempHash, sizeof(tempHash), input, inputSize, nullptr, 0); + assert(blakeResult == 0); + machine->initScratchpad(&tempHash); + machine->resetRoundingMode(); + for (int chain = 0; chain < randomxProgramCount - 1; ++chain) { + machine->run(&tempHash); + blakeResult = blake2b(tempHash, sizeof(tempHash), machine->getRegisterFile(), sizeof(randomx::RegisterFile), nullptr, 0); + assert(blakeResult == 0); + } + machine->run(&tempHash); + unsigned char output[64]; + machine->getFinalResult(output, RANDOMX_HASH_SIZE); + return (const unsigned char*)machine->getScratchpad(); + } + + void randomx_calculate_hash_long_with_entropy_first(randomx_vm* machine, const void* input, size_t inputSize) { + blake2b(machine->tempHash, sizeof(machine->tempHash), input, inputSize, nullptr, 0); + machine->initScratchpad(machine->tempHash); + } + + void randomx_calculate_hash_long_with_entropy_next(randomx_vm* machine, const void* nextInput, size_t nextInputSize, void* output, void *outputEntropy, const int randomxProgramCount) { + machine->resetRoundingMode(); + for (int chain = 0; chain < randomxProgramCount - 1; ++chain) { + machine->run(machine->tempHash); + blake2b(machine->tempHash, sizeof(machine->tempHash), machine->getRegisterFile(), sizeof(randomx::RegisterFile), nullptr, 0); + } + machine->run(machine->tempHash); + + // Finish current hash and fill the scratchpad for the next hash at the same time + blake2b(machine->tempHash, sizeof(machine->tempHash), nextInput, nextInputSize, nullptr, 0); + memcpy(outputEntropy, machine->getScratchpad(), RANDOMX_ENTROPY_SIZE); + machine->hashAndFill(output, RANDOMX_HASH_SIZE, machine->tempHash); + } + + void randomx_calculate_hash_long_with_entropy_last(randomx_vm* machine, void* output, void *outputEntropy, const int randomxProgramCount) { + machine->resetRoundingMode(); + for (int chain = 0; chain < randomxProgramCount - 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); + memcpy(outputEntropy, machine->getScratchpad(), RANDOMX_ENTROPY_SIZE); + } + + // feistel_encrypt accepts padded message with 2*FEISTEL_BLOCK_LENGTH = 64 bytes + RANDOMX_EXPORT void randomx_encrypt_chunk(randomx_vm *machine, const unsigned char *input, const size_t inputSize, const unsigned char *inChunk, const size_t inChunkSize, unsigned char *outChunk, const int randomxProgramCount) { + assert(inChunkSize <= RANDOMX_ENTROPY_SIZE); + assert(inChunkSize % (2*FEISTEL_BLOCK_LENGTH) == 0); + + const unsigned char* entropy = randomx_calculate_hash_long_with_entropy_get_entropy(machine, input, inputSize, randomxProgramCount); + // feistel_encrypt((const unsigned char*)inChunk, inChunkSize, outputEntropy, (unsigned char*)outChunk); + memcpy(outChunk, entropy, RANDOMX_ENTROPY_SIZE); + } + + RANDOMX_EXPORT void randomx_decrypt_chunk(randomx_vm *machine, const unsigned char *input, const size_t inputSize, const unsigned char *inChunk, const size_t inChunkSize, unsigned char *outChunk, const int randomxProgramCount) { + assert(inChunkSize <= RANDOMX_ENTROPY_SIZE); + assert(inChunkSize % (2*FEISTEL_BLOCK_LENGTH) == 0); + + // const unsigned char *outputEntropy = randomx_calculate_hash_long_with_entropy_get_entropy(machine, input, inputSize, randomxProgramCount); + + // feistel_decrypt((const unsigned char*)inChunk, inChunkSize, outputEntropy, (unsigned char*)outChunk); + outChunk = (unsigned char*) randomx_calculate_hash_long_with_entropy_get_entropy(machine, input, inputSize, randomxProgramCount); + } + + RANDOMX_EXPORT void randomx_calculate_entropy(randomx_vm *machine, const unsigned char *input, const size_t inputSize, const size_t outEntropySize, unsigned char *outEntropy, const int randomxProgramCount) { + assert(outEntropySize <= ScratchpadSize); + const unsigned char* entropy = randomx_calculate_hash_long_with_entropy_get_entropy(machine, input, inputSize, randomxProgramCount); + memcpy(outEntropy, entropy, outEntropySize); + } +} diff --git a/src/arweave/randomx_long_with_entropy.h b/src/arweave/randomx_long_with_entropy.h new file mode 100644 index 00000000..540c91dc --- /dev/null +++ b/src/arweave/randomx_long_with_entropy.h @@ -0,0 +1,22 @@ +#include "../randomx.h" + +#define RANDOMX_ENTROPY_SIZE (256*1024) + +#if defined(__cplusplus) +extern "C" { +#endif + +RANDOMX_EXPORT void randomx_calculate_hash_long(randomx_vm *machine, const unsigned char *input, const size_t inputSize, unsigned char *output, const int randomxProgramCount); +RANDOMX_EXPORT void randomx_calculate_hash_long_with_entropy(randomx_vm *machine, const unsigned char *input, const size_t inputSize, unsigned char *output, unsigned char *outputEntropy, const int randomxProgramCount); +RANDOMX_EXPORT void randomx_calculate_hash_long_with_entropy_first(randomx_vm* machine, const void* input, size_t inputSize); +RANDOMX_EXPORT void randomx_calculate_hash_long_with_entropy_next(randomx_vm* machine, const void* nextInput, size_t nextInputSize, void* output, void *outputEntropy, const int randomxProgramCount); +RANDOMX_EXPORT void randomx_calculate_hash_long_with_entropy_last(randomx_vm* machine, void* output, void *outputEntropy, const int randomxProgramCount); + +RANDOMX_EXPORT void randomx_encrypt_chunk(randomx_vm *machine, const unsigned char *input, const size_t inputSize, const unsigned char *inChunk, const size_t inChunkSize, unsigned char *outChunk, const int randomxProgramCount); +RANDOMX_EXPORT void randomx_decrypt_chunk(randomx_vm *machine, const unsigned char *input, const size_t inputSize, const unsigned char *inChunk, const size_t outChunkSize, unsigned char *outChunk, const int randomxProgramCount); + +RANDOMX_EXPORT void randomx_calculate_entropy(randomx_vm *machine, const unsigned char *input, const size_t inputSize, const size_t outEntropySize, unsigned char *outEntropy, const int randomxProgramCount); + +#if defined(__cplusplus) +} +#endif