Changes recommended by Quarkslab (#111)

* Corrected bounds for some configuration parameters
* Clarifications in the specification
* Check validity of Argon2 parameters
This commit is contained in:
tevador 2019-08-25 13:47:21 +02:00 committed by GitHub
parent 91f3edb5eb
commit 971f10c9c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 30 additions and 21 deletions

View File

@ -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). This parameter determines the amount of memory needed in the light mode. Memory is specified in KiB (1 KiB = 1024 bytes).
#### Permitted values #### Permitted values
Integer powers of 2 in the range 1 - 2097152. Integer powers of 2 in the range 8 - 2097152.
#### Notes #### Notes
Lower sizes will reduce the memory-hardness of the algorithm. 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. Determines the number of passes of Argon2 that are used to generate the Cache.
#### Permitted values #### Permitted values
Any positive integer. Any positive 32-bit integer.
#### Notes #### Notes
The time needed to initialize the Cache is proportional to the value of this constant. 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. The number of parallel lanes for Cache initialization.
#### Permitted values #### Permitted values
Any positive integer. Integers in the range 1 - 16777215.
#### Notes #### Notes
This parameter determines how many threads can be used for Cache initialization. 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. Salt value for Cache initialization.
#### Permitted values #### Permitted values
Any string of byte values. A string of at least 8 characters.
#### Note #### Note
Every implementation should choose a unique salt value. Every implementation should choose a unique salt value.

View File

@ -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. 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. 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 #### 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 #### 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. 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* *Figure 7.1 - Dataset construction*

View File

@ -29,6 +29,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "soft_aes.h" #include "soft_aes.h"
#include <cassert> #include <cassert>
//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_STATE0 0xd7983aad, 0xcc82db47, 0x9fa856de, 0x92b52c0d
#define AES_HASH_1R_STATE1 0xace78057, 0xf59e125a, 0x15c7b798, 0x338d996e #define AES_HASH_1R_STATE1 0xace78057, 0xf59e125a, 0x15c7b798, 0x338d996e
#define AES_HASH_1R_STATE2 0xe8a07ce4, 0x5079506b, 0xae62c7d0, 0x6a770017 #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<false>(const void *input, size_t inputSize, void *hash); template void hashAes1Rx4<false>(const void *input, size_t inputSize, void *hash);
template void hashAes1Rx4<true>(const void *input, size_t inputSize, void *hash); template void hashAes1Rx4<true>(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_KEY0 0xb4f44917, 0xdbb5552b, 0x62716609, 0x6daca553
#define AES_GEN_1R_KEY1 0x0da1dc4e, 0x1725d378, 0x846a710d, 0x6d7caf07 #define AES_GEN_1R_KEY1 0x0da1dc4e, 0x1725d378, 0x846a710d, 0x6d7caf07
#define AES_GEN_1R_KEY2 0x3e20e345, 0xf4c0794f, 0x9f947ec6, 0x3f1262f1 #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<true>(void *state, size_t outputSize, void *buffer); template void fillAes1Rx4<true>(void *state, size_t outputSize, void *buffer);
template void fillAes1Rx4<false>(void *state, size_t outputSize, void *buffer); template void fillAes1Rx4<false>(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_KEY0 0x99e5d23f, 0x2f546d2b, 0xd1833ddb, 0x6421aadd
#define AES_GEN_4R_KEY1 0xa5dfcde5, 0x06f79d53, 0xb6913f55, 0xb20e3450 #define AES_GEN_4R_KEY1 0xa5dfcde5, 0x06f79d53, 0xb6913f55, 0xb20e3450
#define AES_GEN_4R_KEY2 0x171c02bf, 0x0aa4679f, 0x515e7baf, 0x5c3ed904 #define AES_GEN_4R_KEY2 0x171c02bf, 0x0aa4679f, 0x515e7baf, 0x5c3ed904

View File

@ -263,19 +263,6 @@ int rxa2_validate_inputs(const argon2_context *context) {
return ARGON2_INCORRECT_PARAMETER; 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) */ /* Validate password (required param) */
if (NULL == context->pwd) { if (NULL == context->pwd) {
if (0 != context->pwdlen) { if (0 != context->pwdlen) {

View File

@ -37,9 +37,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace randomx { 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 <= 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_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 >= 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 & (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."); 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 uint32_t ArgonBlockSize = 1024;
constexpr int ArgonSaltSize = sizeof("" RANDOMX_ARGON_SALT) - 1; 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 int SuperscalarMaxSize = 3 * RANDOMX_SUPERSCALAR_LATENCY + 2;
constexpr size_t CacheLineSize = RANDOMX_DATASET_ITEM_SIZE; constexpr size_t CacheLineSize = RANDOMX_DATASET_ITEM_SIZE;
constexpr int ScratchpadSize = RANDOMX_SCRATCHPAD_L3; constexpr int ScratchpadSize = RANDOMX_SCRATCHPAD_L3;

View File

@ -38,6 +38,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cstring> #include <cstring>
#include <limits> #include <limits>
#include <cstring> #include <cstring>
#include <cassert>
#include "common.hpp" #include "common.hpp"
#include "dataset.hpp" #include "dataset.hpp"
@ -91,6 +92,9 @@ namespace randomx {
context.flags = ARGON2_DEFAULT_FLAGS; context.flags = ARGON2_DEFAULT_FLAGS;
context.version = ARGON2_VERSION_NUMBER; context.version = ARGON2_VERSION_NUMBER;
int inputsValid = rxa2_validate_inputs(&context);
assert(inputsValid == ARGON2_OK);
/* 2. Align memory size */ /* 2. Align memory size */
/* Minimum memory_blocks = 8L blocks, where L is the number of lanes */ /* Minimum memory_blocks = 8L blocks, where L is the number of lanes */
memory_blocks = context.m_cost; memory_blocks = context.m_cost;