diff --git a/doc/configuration.md b/doc/configuration.md index a53b57e..27b7c66 100644 --- a/doc/configuration.md +++ b/doc/configuration.md @@ -33,7 +33,7 @@ Not all of the parameters can be changed safely and most parameters have some co This parameter determines the amount of memory needed in the light mode. Memory is specified in KiB (1 KiB = 1024 bytes). #### Permitted values -Integer powers of 2 in the range 1 - 2097152. +Integer powers of 2 in the range 8 - 2097152. #### Notes Lower sizes will reduce the memory-hardness of the algorithm. @@ -43,7 +43,7 @@ Lower sizes will reduce the memory-hardness of the algorithm. Determines the number of passes of Argon2 that are used to generate the Cache. #### Permitted values -Any positive integer. +Any positive 32-bit integer. #### Notes The time needed to initialize the Cache is proportional to the value of this constant. @@ -53,7 +53,7 @@ The time needed to initialize the Cache is proportional to the value of this con The number of parallel lanes for Cache initialization. #### Permitted values -Any positive integer. +Integers in the range 1 - 16777215. #### Notes This parameter determines how many threads can be used for Cache initialization. @@ -63,7 +63,7 @@ This parameter determines how many threads can be used for Cache initialization. Salt value for Cache initialization. #### Permitted values -Any string of byte values. +A string of at least 8 characters. #### Note Every implementation should choose a unique salt value. diff --git a/doc/specs.md b/doc/specs.md index fdb55e4..2d7da8a 100644 --- a/doc/specs.md +++ b/doc/specs.md @@ -329,7 +329,7 @@ Floating point registers `f0`-`f3` are the "additive" registers, which can be th Floating point registers `e0`-`e3` are the "multiplicative" registers, which can be the destination of floating point multiplication, division and square root instructions. Their value is always positive. -`ma` and `mx` are the memory registers. Both are 32 bits wide. `ma` contains the memory address of the next Dataset read and `mx` contains the address of the next Dataset prefetch. +`ma` and `mx` are the memory registers. Both are 32 bits wide. `ma` contains the memory address of the next Dataset read and `mx` contains the address of the next Dataset prefetch. The values of `ma` and `mx` registers are always aligned to be a multiple of 64. The 2-bit `fprc` register determines the rounding mode of all floating point operations according to Table 4.3.1. The four rounding modes are defined by the IEEE 754 standard. @@ -422,7 +422,7 @@ Bits 0-3 of quadword 12 are used to select 4 address registers for program execu #### 4.5.5 Dataset offset -The `datasetOffset` is calculated by bitwise AND of quadword 13 and the value `RANDOMX_DATASET_EXTRA_SIZE / 64`. The result is multiplied by `64`. This offset is used when reading values from the Dataset. +The `datasetOffset` is calculated as the remainder of dividing quadword 13 by `RANDOMX_DATASET_EXTRA_SIZE / 64 + 1`. The result is multiplied by `64`. This offset is used when reading values from the Dataset. #### 4.5.6 Group E register masks @@ -882,7 +882,7 @@ The Dataset is a read-only memory structure that is used during program executio In order to allow PoW verification with a lower amount of memory, the Dataset is constructed in two steps using an intermediate structure called the "Cache", which can be used to calculate Dataset items on the fly. -The whole Dataset is constructed from the key value `K`, which is an input parameter of RandomX. The whole Dataset needs to be recalculated everytime the key value changes. Fig. 7.1 shows the process of Dataset construction. +The whole Dataset is constructed from the key value `K`, which is an input parameter of RandomX. The whole Dataset needs to be recalculated everytime the key value changes. Fig. 7.1 shows the process of Dataset construction. Note: the maximum supported length of `K` is 60 bytes. Using a longer key results in implementation-defined behavior. *Figure 7.1 - Dataset construction* diff --git a/src/aes_hash.cpp b/src/aes_hash.cpp index 896395e..1aff37f 100644 --- a/src/aes_hash.cpp +++ b/src/aes_hash.cpp @@ -29,6 +29,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "soft_aes.h" #include +//NOTE: The functions below were tuned for maximum performance +//and are not cryptographically secure outside of the scope of RandomX. +//It's not recommended to use them as general hash functions and PRNGs. + +//AesHash1R: +//state0, state1, state2, state3 = Blake2b-512("RandomX AesHash1R state") +//xkey0, xkey1 = Blake2b-256("RandomX AesHash1R xkeys") + #define AES_HASH_1R_STATE0 0xd7983aad, 0xcc82db47, 0x9fa856de, 0x92b52c0d #define AES_HASH_1R_STATE1 0xace78057, 0xf59e125a, 0x15c7b798, 0x338d996e #define AES_HASH_1R_STATE2 0xe8a07ce4, 0x5079506b, 0xae62c7d0, 0x6a770017 @@ -103,6 +111,9 @@ void hashAes1Rx4(const void *input, size_t inputSize, void *hash) { template void hashAes1Rx4(const void *input, size_t inputSize, void *hash); template void hashAes1Rx4(const void *input, size_t inputSize, void *hash); +//AesGenerator1R: +//key0, key1, key2, key3 = Blake2b-512("RandomX AesGenerator1R keys") + #define AES_GEN_1R_KEY0 0xb4f44917, 0xdbb5552b, 0x62716609, 0x6daca553 #define AES_GEN_1R_KEY1 0x0da1dc4e, 0x1725d378, 0x846a710d, 0x6d7caf07 #define AES_GEN_1R_KEY2 0x3e20e345, 0xf4c0794f, 0x9f947ec6, 0x3f1262f1 @@ -160,6 +171,10 @@ void fillAes1Rx4(void *state, size_t outputSize, void *buffer) { template void fillAes1Rx4(void *state, size_t outputSize, void *buffer); template void fillAes1Rx4(void *state, size_t outputSize, void *buffer); +//AesGenerator4R: +//key0, key1, key2, key3 = Blake2b-512("RandomX AesGenerator4R keys 0-3") +//key4, key5, key6, key7 = Blake2b-512("RandomX AesGenerator4R keys 4-7") + #define AES_GEN_4R_KEY0 0x99e5d23f, 0x2f546d2b, 0xd1833ddb, 0x6421aadd #define AES_GEN_4R_KEY1 0xa5dfcde5, 0x06f79d53, 0xb6913f55, 0xb20e3450 #define AES_GEN_4R_KEY2 0x171c02bf, 0x0aa4679f, 0x515e7baf, 0x5c3ed904 diff --git a/src/argon2_core.c b/src/argon2_core.c index e917422..977705e 100644 --- a/src/argon2_core.c +++ b/src/argon2_core.c @@ -263,19 +263,6 @@ int rxa2_validate_inputs(const argon2_context *context) { return ARGON2_INCORRECT_PARAMETER; } - if (NULL == context->out) { - return ARGON2_OUTPUT_PTR_NULL; - } - - /* Validate output length */ - if (ARGON2_MIN_OUTLEN > context->outlen) { - return ARGON2_OUTPUT_TOO_SHORT; - } - - if (ARGON2_MAX_OUTLEN < context->outlen) { - return ARGON2_OUTPUT_TOO_LONG; - } - /* Validate password (required param) */ if (NULL == context->pwd) { if (0 != context->pwdlen) { diff --git a/src/common.hpp b/src/common.hpp index d349abd..a96fe06 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -37,9 +37,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace randomx { - static_assert(RANDOMX_ARGON_MEMORY > 0, "RANDOMX_ARGON_MEMORY must be greater than 0."); + static_assert(RANDOMX_ARGON_MEMORY >= 8, "RANDOMX_ARGON_MEMORY must be at least 8."); static_assert(RANDOMX_ARGON_MEMORY <= 2097152, "RANDOMX_ARGON_MEMORY must not exceed 2097152."); static_assert((RANDOMX_ARGON_MEMORY & (RANDOMX_ARGON_MEMORY - 1)) == 0, "RANDOMX_ARGON_MEMORY must be a power of 2."); + static_assert(RANDOMX_ARGON_ITERATIONS > 0 && RANDOMX_ARGON_ITERATIONS < UINT32_MAX, "RANDOMX_ARGON_ITERATIONS must be a positive 32-bit integer."); + static_assert(RANDOMX_ARGON_LANES > 0 && RANDOMX_ARGON_LANES <= 16777215, "RANDOMX_ARGON_LANES out of range"); static_assert(RANDOMX_DATASET_BASE_SIZE >= 64, "RANDOMX_DATASET_BASE_SIZE must be at least 64."); static_assert((RANDOMX_DATASET_BASE_SIZE & (RANDOMX_DATASET_BASE_SIZE - 1)) == 0, "RANDOMX_DATASET_BASE_SIZE must be a power of 2."); static_assert(RANDOMX_DATASET_BASE_SIZE <= 4294967296ULL, "RANDOMX_DATASET_BASE_SIZE must not exceed 4294967296."); @@ -75,6 +77,7 @@ namespace randomx { constexpr uint32_t ArgonBlockSize = 1024; constexpr int ArgonSaltSize = sizeof("" RANDOMX_ARGON_SALT) - 1; + static_assert(ArgonSaltSize >= 8, "RANDOMX_ARGON_SALT must be at least 8 characters long"); constexpr int SuperscalarMaxSize = 3 * RANDOMX_SUPERSCALAR_LATENCY + 2; constexpr size_t CacheLineSize = RANDOMX_DATASET_ITEM_SIZE; constexpr int ScratchpadSize = RANDOMX_SCRATCHPAD_L3; diff --git a/src/dataset.cpp b/src/dataset.cpp index e382fd0..bc0d0d1 100644 --- a/src/dataset.cpp +++ b/src/dataset.cpp @@ -38,6 +38,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include "common.hpp" #include "dataset.hpp" @@ -91,6 +92,9 @@ namespace randomx { context.flags = ARGON2_DEFAULT_FLAGS; context.version = ARGON2_VERSION_NUMBER; + int inputsValid = rxa2_validate_inputs(&context); + assert(inputsValid == ARGON2_OK); + /* 2. Align memory size */ /* Minimum memory_blocks = 8L blocks, where L is the number of lanes */ memory_blocks = context.m_cost;