diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f839b5..bf11cc1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,21 +1,21 @@ # Copyright (c) 2019, The Monero Project -# +# # All rights reserved. -# +# # Redistribution and use in source and binary forms, with or without modification, are # permitted provided that the following conditions are met: -# +# # 1. Redistributions of source code must retain the above copyright notice, this list of # conditions and the following disclaimer. -# +# # 2. Redistributions in binary form must reproduce the above copyright notice, this list # of conditions and the following disclaimer in the documentation and/or other # materials provided with the distribution. -# +# # 3. Neither the name of the copyright holder nor the names of its contributors may be # used to endorse or promote products derived from this software without specific # prior written permission. -# +# # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL @@ -34,6 +34,7 @@ set(CMAKE_VERBOSE_MAKEFILE ON) set(randomx_sources src/aes_hash.cpp +src/aes_hash_bindgen.cpp src/argon2_ref.c src/argon2_ssse3.c src/argon2_avx2.c diff --git a/src/aes_hash_bindgen.cpp b/src/aes_hash_bindgen.cpp new file mode 100644 index 0000000..22f3ff2 --- /dev/null +++ b/src/aes_hash_bindgen.cpp @@ -0,0 +1,38 @@ +#include "aes_hash.hpp" +#include "aes_hash_bindgen.h" + +extern "C" { + + void hashAes1Rx4_soft(const void *input, size_t inputSize, void *hash) { + hashAes1Rx4(input, inputSize, hash); + } + + void hashAes1Rx4_hard(const void *input, size_t inputSize, void *hash) { + hashAes1Rx4(input, inputSize, hash); + } + + void fillAes1Rx4_soft(void *state, size_t outputSize, void *buffer) { + fillAes1Rx4(state, outputSize, buffer); + } + + void fillAes1Rx4_hard(void *state, size_t outputSize, void *buffer) { + fillAes1Rx4(state, outputSize, buffer); + } + + void fillAes4Rx4_soft(void *state, size_t outputSize, void *buffer) { + fillAes4Rx4(state, outputSize, buffer); + } + + void fillAes4Rx4_hard(void *state, size_t outputSize, void *buffer) { + fillAes4Rx4(state, outputSize, buffer); + } + + void hashAndFillAes1Rx4_soft(void *scratchpad, size_t scratchpadSize, void *hash, void* fill_state) { + hashAndFillAes1Rx4(scratchpad, scratchpadSize, hash, fill_state); + } + + void hashAndFillAes1Rx4_hard(void *scratchpad, size_t scratchpadSize, void *hash, void* fill_state) { + hashAndFillAes1Rx4(scratchpad, scratchpadSize, hash, fill_state); + } + +} diff --git a/src/aes_hash_bindgen.h b/src/aes_hash_bindgen.h new file mode 100644 index 0000000..421c894 --- /dev/null +++ b/src/aes_hash_bindgen.h @@ -0,0 +1,25 @@ +#ifndef AES_HASH_BINDGEN_H +#define AES_HASH_BINDGEN_H +#endif + +#include "stddef.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +void hashAes1Rx4_soft(const void *input, size_t inputSize, void *hash); +void hashAes1Rx4_hard(const void *input, size_t inputSize, void *hash); + +void fillAes1Rx4_soft(void *state, size_t outputSize, void *buffer); +void fillAes1Rx4_hard(void *state, size_t outputSize, void *buffer); + +void fillAes4Rx4_soft(void *state, size_t outputSize, void *buffer); +void fillAes4Rx4_hard(void *state, size_t outputSize, void *buffer); + +void hashAndFillAes1Rx4_soft(void *scratchpad, size_t scratchpadSize, void *hash, void* fill_state); +void hashAndFillAes1Rx4_hard(void *scratchpad, size_t scratchpadSize, void *hash, void* fill_state); + +#if defined(__cplusplus) +} +#endif diff --git a/src/randomx.cpp b/src/randomx.cpp index e4dda9a..381317d 100644 --- a/src/randomx.cpp +++ b/src/randomx.cpp @@ -33,6 +33,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "vm_compiled.hpp" #include "vm_compiled_light.hpp" #include "blake2/blake2.h" +#include "aes_hash_bindgen.h" #include "cpu.hpp" #include #include @@ -138,6 +139,11 @@ extern "C" { } } + void *randomx_get_cache_memory(randomx_cache *cache) { + assert(cache != nullptr); + return cache->memory; + } + void randomx_release_cache(randomx_cache* cache) { assert(cache != nullptr); cache->dealloc(cache); @@ -393,6 +399,72 @@ extern "C" { #endif } + const unsigned char *randomx_calculate_hash_scratchpad(randomx_vm *machine, const void *input, size_t inputSize, const int randomxProgramCount) + { + assert(machine != nullptr); + assert(inputSize == 0 || input != nullptr); + +#ifdef USE_CSR_INTRINSICS + const unsigned int fpstate = _mm_getcsr(); +#else + fenv_t fpstate; + fegetenv(&fpstate); +#endif + + 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); + +#ifdef USE_CSR_INTRINSICS + _mm_setcsr(fpstate); +#else + fesetenv(&fpstate); +#endif + + return (const unsigned char*)machine->getScratchpad(); + } + + void randomx_calculate_hash_with_scratchpad_with_presets(randomx_vm *machine, unsigned char *inHash, const int randomxProgramCount) { + + assert(machine != nullptr); + +#ifdef USE_CSR_INTRINSICS + const unsigned int fpstate = _mm_getcsr(); +#else + fenv_t fpstate; + fegetenv(&fpstate); +#endif + + alignas(16) uint64_t tempHash[8]; + memcpy(tempHash, inHash, sizeof(tempHash)); + int blakeResult; + for (int chain = 0; chain < randomxProgramCount; ++chain) { + machine->run(tempHash); + blakeResult = randomx_blake2b(tempHash, sizeof(tempHash), machine->getRegisterFile(), sizeof(randomx::RegisterFile), nullptr, 0); + assert(blakeResult == 0); + } + memcpy(inHash, tempHash, sizeof(tempHash)); + +#ifdef USE_CSR_INTRINSICS + _mm_setcsr(fpstate); +#else + fesetenv(&fpstate); +#endif + } + + unsigned char *randomx_get_scratchpad(randomx_vm *machine) { + assert(machine != nullptr); + return (unsigned char*)machine->getScratchpad(); + } + void randomx_calculate_hash_first(randomx_vm* machine, const void* input, size_t inputSize) { blake2b(machine->tempHash, sizeof(machine->tempHash), input, inputSize, nullptr, 0); machine->initScratchpad(machine->tempHash); diff --git a/src/randomx.h b/src/randomx.h index 7c5fd97..cf5e63c 100644 --- a/src/randomx.h +++ b/src/randomx.h @@ -119,6 +119,16 @@ RANDOMX_EXPORT randomx_cache *randomx_alloc_cache(randomx_flags flags); */ RANDOMX_EXPORT void randomx_init_cache(randomx_cache *cache, const void *key, size_t keySize); +/** + * Returns a pointer to the internal memory buffer of the cache structure. The size + * of the internal memory buffer is RANDOMX_ARGON_MEMORY * ArgonBlockSize. + * + * @param cache is a pointer to a previously allocated randomx_cache structure. Must not be NULL. + * + * @return Pointer to the internal memory buffer of the cache structure. +*/ +RANDOMX_EXPORT void *randomx_get_cache_memory(randomx_cache *cache); + /** * Releases all memory occupied by the randomx_cache structure. * @@ -180,6 +190,14 @@ RANDOMX_EXPORT void randomx_release_dataset(randomx_dataset *dataset); * @return the size of the scratchpad in bytes. */ RANDOMX_EXPORT unsigned long randomx_get_scratchpad_size(void); +/** + * Returns a pointer to the scratchpad memory of the virtual machine. + * + * @param machine is a pointer to a randomx_vm structure. Must not be NULL. + * + * @return Pointer to the scratchpad memory of the virtual machine. +*/ +RANDOMX_EXPORT unsigned char *randomx_get_scratchpad(randomx_vm *machine); /** * Creates and initializes a RandomX virtual machine. @@ -246,6 +264,28 @@ 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); + +/** + * Calculates a RandomX long hash value. + * Long hash is effectively the vm scratchpad taken after finalizing the regular hash. + * + * @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. + * @param inputSize is the number of bytes to be hashed. + * @param randomxProgramCount a custom number of RandomX iterations. +*/ +RANDOMX_EXPORT const unsigned char *randomx_calculate_hash_scratchpad(randomx_vm *machine, const void *input, size_t inputSize, const int randomxProgramCount); + +/** + * Calculates a RandomX long hash value. + * Long hash is effectively the vm scratchpad taken after finalizing the regular hash. + * + * @param machine is a pointer to a randomx_vm structure. Must not be NULL. + * @param inHash is a pointer to the initial hash value. Must not be NULL. + * @param randomxProgramCount is the number of RandomX iterations. +*/ +RANDOMX_EXPORT void randomx_calculate_hash_with_scratchpad_with_presets(randomx_vm *machine, unsigned char *inHash, const int randomxProgramCount); + /** * Set of functions used to calculate multiple RandomX hashes more efficiently. * randomx_calculate_hash_first will begin a hash calculation.