mirror of
https://git.sr.ht/~sircmpwn/mkproof
synced 2024-06-08 16:36:07 +02:00
code format and make format
This commit is contained in:
parent
e4a29780ff
commit
818608837d
5
Makefile
5
Makefile
|
@ -45,7 +45,7 @@ endif
|
|||
LIB_SH := lib$(LIB_NAME).$(LIB_EXT)
|
||||
LIB_ST := lib$(LIB_NAME).a
|
||||
|
||||
.PHONY: clean test
|
||||
.PHONY: clean dist format
|
||||
|
||||
all: clean $(BIN) $(LIB_SH) $(LIB_ST)
|
||||
bin: $(BIN)
|
||||
|
@ -69,3 +69,6 @@ clean:
|
|||
dist:
|
||||
cd ..; \
|
||||
tar cfvJ $(DIST)/$(DIST)-`date "+%Y%m%d%H%M00"`.txz $(DIST)/*
|
||||
|
||||
format:
|
||||
clang-format -i src/*.c src/*.h src/blake2/*.c src/blake2/*.h
|
||||
|
|
240
src/argon2.c
240
src/argon2.c
|
@ -5,11 +5,12 @@
|
|||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
* this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
@ -18,8 +19,8 @@
|
|||
#include "argon2.h"
|
||||
#include "core.h"
|
||||
|
||||
|
||||
/*************************Argon2 input parameter restrictions**************************************************/
|
||||
/*************************Argon2 input parameter
|
||||
* restrictions**************************************************/
|
||||
|
||||
/* Minimum and maximum number of lanes (degree of parallelism) */
|
||||
const uint32_t ARGON2_MIN_LANES = 1;
|
||||
|
@ -38,7 +39,8 @@ const uint32_t ARGON2_MIN_OUTLEN = 4;
|
|||
const uint32_t ARGON2_MAX_OUTLEN = 0xFFFFFFFF;
|
||||
|
||||
/* Minimum and maximum number of memory blocks (each of BLOCK_SIZE bytes) */
|
||||
const uint32_t ARGON2_MIN_MEMORY = 2 * __ARGON_SYNC_POINTS; // 2 blocks per slice
|
||||
const uint32_t ARGON2_MIN_MEMORY =
|
||||
2 * __ARGON_SYNC_POINTS; // 2 blocks per slice
|
||||
const uint32_t ARGON2_MAX_MEMORY = 0xFFFFFFFF; // 2^32-1 blocks
|
||||
|
||||
/* Minimum and maximum number of passes */
|
||||
|
@ -61,127 +63,159 @@ const uint32_t ARGON2_MAX_SALT_LENGTH = 0xFFFFFFFF;
|
|||
const uint32_t ARGON2_MIN_SECRET = 0;
|
||||
const uint32_t ARGON2_MAX_SECRET = 0xFFFFFFFF;
|
||||
|
||||
/************************* Error messages
|
||||
* *********************************************************************************/
|
||||
|
||||
/************************* Error messages *********************************************************************************/
|
||||
const char *Argon2_ErrorMessage[] = {
|
||||
/*{ARGON2_OK, */ "OK",
|
||||
/*},
|
||||
|
||||
const char *Argon2_ErrorMessage[] =
|
||||
{
|
||||
/*{ARGON2_OK, */"OK",/*},
|
||||
{ARGON2_OUTPUT_PTR_NULL, */ "Output pointer is NULL",
|
||||
/*},
|
||||
|
||||
{ARGON2_OUTPUT_PTR_NULL, */"Output pointer is NULL",/*},
|
||||
{ARGON2_OUTPUT_TOO_SHORT, */ "Output is too short",
|
||||
/*},
|
||||
{ARGON2_OUTPUT_TOO_LONG, */ "Output is too long",
|
||||
/*},
|
||||
|
||||
{ARGON2_OUTPUT_TOO_SHORT, */"Output is too short",/*},
|
||||
{ARGON2_OUTPUT_TOO_LONG, */"Output is too long",/*},
|
||||
{ARGON2_PWD_TOO_SHORT, */ "Password is too short",
|
||||
/*},
|
||||
{ARGON2_PWD_TOO_LONG, */ "Password is too long",
|
||||
/*},
|
||||
|
||||
{ARGON2_PWD_TOO_SHORT, */"Password is too short",/*},
|
||||
{ARGON2_PWD_TOO_LONG, */"Password is too long",/*},
|
||||
{ARGON2_SALT_TOO_SHORT, */ "Salt is too short",
|
||||
/*},
|
||||
{ARGON2_SALT_TOO_LONG, */ "Salt is too long",
|
||||
/*},
|
||||
|
||||
{ARGON2_SALT_TOO_SHORT, */"Salt is too short",/*},
|
||||
{ARGON2_SALT_TOO_LONG, */"Salt is too long",/*},
|
||||
{ARGON2_AD_TOO_SHORT, */ "Associated data is too short",
|
||||
/*},
|
||||
{ARGON2_AD_TOO_LONG, */ "Associated date is too long",
|
||||
/*},
|
||||
|
||||
{ARGON2_AD_TOO_SHORT, */"Associated data is too short",/*},
|
||||
{ARGON2_AD_TOO_LONG, */"Associated date is too long",/*},
|
||||
{ARGON2_SECRET_TOO_SHORT, */ "Secret is too short",
|
||||
/*},
|
||||
{ARGON2_SECRET_TOO_LONG, */ "Secret is too long",
|
||||
/*},
|
||||
|
||||
{ARGON2_SECRET_TOO_SHORT, */"Secret is too short",/*},
|
||||
{ARGON2_SECRET_TOO_LONG, */"Secret is too long",/*},
|
||||
{ARGON2_TIME_TOO_SMALL, */ "Time cost is too small",
|
||||
/*},
|
||||
{ARGON2_TIME_TOO_LARGE, */ "Time cost is too large",
|
||||
/*},
|
||||
|
||||
{ARGON2_TIME_TOO_SMALL, */"Time cost is too small",/*},
|
||||
{ARGON2_TIME_TOO_LARGE, */"Time cost is too large",/*},
|
||||
{ARGON2_MEMORY_TOO_LITTLE, */ "Memory cost is too small",
|
||||
/*},
|
||||
{ARGON2_MEMORY_TOO_MUCH, */ "Memory cost is too large",
|
||||
/*},
|
||||
|
||||
{ARGON2_MEMORY_TOO_LITTLE, */"Memory cost is too small",/*},
|
||||
{ARGON2_MEMORY_TOO_MUCH, */"Memory cost is too large",/*},
|
||||
{ARGON2_LANES_TOO_FEW, */ "Too few lanes",
|
||||
/*},
|
||||
{ARGON2_LANES_TOO_MANY, */ "Too many lanes",
|
||||
/*},
|
||||
|
||||
{ARGON2_LANES_TOO_FEW, */"Too few lanes",/*},
|
||||
{ARGON2_LANES_TOO_MANY, */"Too many lanes",/*},
|
||||
{ARGON2_PWD_PTR_MISMATCH, */ "Password pointer is NULL, but password length is not 0",
|
||||
/*},
|
||||
{ARGON2_SALT_PTR_MISMATCH, */ "Salt pointer is NULL, but salt length is not 0",
|
||||
/*},
|
||||
{ARGON2_SECRET_PTR_MISMATCH, */ "Secret pointer is NULL, but secret length is not 0",
|
||||
/*},
|
||||
{ARGON2_AD_PTR_MISMATCH, */ "Associated data pointer is NULL, but ad length is not 0",
|
||||
/*},
|
||||
|
||||
{ARGON2_PWD_PTR_MISMATCH, */"Password pointer is NULL, but password length is not 0",/*},
|
||||
{ARGON2_SALT_PTR_MISMATCH, */"Salt pointer is NULL, but salt length is not 0",/*},
|
||||
{ARGON2_SECRET_PTR_MISMATCH, */"Secret pointer is NULL, but secret length is not 0",/*},
|
||||
{ARGON2_AD_PTR_MISMATCH, */"Associated data pointer is NULL, but ad length is not 0",/*},
|
||||
{ARGON2_MEMORY_ALLOCATION_ERROR, */ "Memory allocation error",
|
||||
/*},
|
||||
|
||||
{ARGON2_MEMORY_ALLOCATION_ERROR, */"Memory allocation error",/*},
|
||||
{ARGON2_FREE_MEMORY_CBK_NULL, */ "The free memory callback is NULL",
|
||||
/*},
|
||||
{ARGON2_ALLOCATE_MEMORY_CBK_NULL, */ "The allocate memory callback is NULL",
|
||||
/*},
|
||||
|
||||
{ARGON2_FREE_MEMORY_CBK_NULL, */"The free memory callback is NULL",/*},
|
||||
{ARGON2_ALLOCATE_MEMORY_CBK_NULL, */"The allocate memory callback is NULL",/*},
|
||||
{ARGON2_INCORRECT_PARAMETER, */ "Argon2_Context context is NULL",
|
||||
/*},
|
||||
{ARGON2_INCORRECT_TYPE, */ "There is no such version of Argon2",
|
||||
/*},
|
||||
|
||||
{ARGON2_INCORRECT_PARAMETER, */"Argon2_Context context is NULL",/*},
|
||||
{ARGON2_INCORRECT_TYPE, */"There is no such version of Argon2",/*},
|
||||
|
||||
{ARGON2_OUT_PTR_MISMATCH, */"Output pointer mismatch"/*}*/
|
||||
{ARGON2_OUT_PTR_MISMATCH, */ "Output pointer mismatch" /*}*/
|
||||
};
|
||||
|
||||
int hashpwd( void *out, size_t outlen, const void *in, size_t inlen, const void *salt,
|
||||
size_t saltlen, unsigned int t_cost, unsigned int m_cost )
|
||||
{
|
||||
Argon2_Context context = {( uint8_t * ) out, ( uint32_t ) outlen,
|
||||
( uint8_t * ) in, ( uint32_t ) inlen,
|
||||
( uint8_t * ) salt, ( uint32_t ) saltlen,
|
||||
NULL, /*Pointer to the secret*/
|
||||
0, /*Secret length*/
|
||||
NULL, /*Pointer to the associated data*/
|
||||
0, /*Associated data length*/
|
||||
( uint32_t ) t_cost, ( uint32_t ) m_cost,
|
||||
1, /*Number of lanes*/
|
||||
1, /*Number of threads*/
|
||||
NULL, NULL, /*Pointers to external memory (de)allocators*/
|
||||
true, /*Clear the password after use*/
|
||||
false, /*Not use the secret so not clear it*/
|
||||
true, /*Clear the memory after use*/
|
||||
false /*Not printing the memory content to the file*/
|
||||
};
|
||||
int hashpwd(void *out, size_t outlen, const void *in, size_t inlen,
|
||||
const void *salt, size_t saltlen, unsigned int t_cost,
|
||||
unsigned int m_cost) {
|
||||
Argon2_Context context = {
|
||||
(uint8_t *)out,
|
||||
(uint32_t)outlen,
|
||||
(uint8_t *)in,
|
||||
(uint32_t)inlen,
|
||||
(uint8_t *)salt,
|
||||
(uint32_t)saltlen,
|
||||
NULL, /*Pointer to the secret*/
|
||||
0, /*Secret length*/
|
||||
NULL, /*Pointer to the associated data*/
|
||||
0, /*Associated data length*/
|
||||
(uint32_t)t_cost,
|
||||
(uint32_t)m_cost,
|
||||
1, /*Number of lanes*/
|
||||
1, /*Number of threads*/
|
||||
NULL,
|
||||
NULL, /*Pointers to external memory (de)allocators*/
|
||||
true, /*Clear the password after use*/
|
||||
false, /*Not use the secret so not clear it*/
|
||||
true, /*Clear the memory after use*/
|
||||
false /*Not printing the memory content to the file*/
|
||||
};
|
||||
|
||||
return argon2_core( &context, Argon2_i );
|
||||
return argon2_core(&context, Argon2_i);
|
||||
}
|
||||
|
||||
int hashpwd2( void *out, size_t outlen, const void *in, size_t inlen, const void *salt,
|
||||
size_t saltlen, unsigned int t_cost, unsigned int m_cost )
|
||||
{
|
||||
Argon2_Context context = {( uint8_t * ) out, ( uint32_t ) outlen,
|
||||
( uint8_t * ) in, ( uint32_t ) inlen,
|
||||
( uint8_t * ) salt, ( uint32_t ) saltlen,
|
||||
NULL, 0, NULL, 0,
|
||||
( uint32_t ) t_cost, ( uint32_t ) m_cost,
|
||||
1, 1, NULL, NULL,
|
||||
true, true, true, false
|
||||
};
|
||||
int hashpwd2(void *out, size_t outlen, const void *in, size_t inlen,
|
||||
const void *salt, size_t saltlen, unsigned int t_cost,
|
||||
unsigned int m_cost) {
|
||||
Argon2_Context context = {(uint8_t *)out,
|
||||
(uint32_t)outlen,
|
||||
(uint8_t *)in,
|
||||
(uint32_t)inlen,
|
||||
(uint8_t *)salt,
|
||||
(uint32_t)saltlen,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
(uint32_t)t_cost,
|
||||
(uint32_t)m_cost,
|
||||
1,
|
||||
1,
|
||||
NULL,
|
||||
NULL,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false};
|
||||
|
||||
return argon2_core( &context, Argon2_d );
|
||||
return argon2_core(&context, Argon2_d);
|
||||
}
|
||||
|
||||
int argon2d(Argon2_Context *context) { return argon2_core(context, Argon2_d); }
|
||||
|
||||
int argon2d( Argon2_Context *context )
|
||||
{
|
||||
return argon2_core( context, Argon2_d );
|
||||
int argon2i(Argon2_Context *context) { return argon2_core(context, Argon2_i); }
|
||||
|
||||
int verify_d(Argon2_Context *context, const char *hash) {
|
||||
if (0 == context->outlen || NULL == hash) {
|
||||
return ARGON2_OUT_PTR_MISMATCH;
|
||||
}
|
||||
|
||||
int result = argon2_core(context, Argon2_d);
|
||||
|
||||
if (ARGON2_OK != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return 0 == memcmp(hash, context->out, context->outlen);
|
||||
}
|
||||
|
||||
int argon2i( Argon2_Context *context )
|
||||
{
|
||||
return argon2_core( context, Argon2_i );
|
||||
}
|
||||
|
||||
int verify_d( Argon2_Context *context, const char *hash )
|
||||
{
|
||||
if ( 0 == context->outlen || NULL == hash )
|
||||
{
|
||||
return ARGON2_OUT_PTR_MISMATCH;
|
||||
}
|
||||
|
||||
int result = argon2_core( context, Argon2_d );
|
||||
|
||||
if ( ARGON2_OK != result )
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return 0 == memcmp( hash, context->out, context->outlen );
|
||||
}
|
||||
|
||||
const char *error_message( int error_code )
|
||||
{
|
||||
if ( error_code < ARGON2_ERROR_CODES_LENGTH )
|
||||
{
|
||||
return Argon2_ErrorMessage[( Argon2_ErrorCodes ) error_code];
|
||||
}
|
||||
|
||||
return "Unknown error code.";
|
||||
const char *error_message(int error_code) {
|
||||
if (error_code < ARGON2_ERROR_CODES_LENGTH) {
|
||||
return Argon2_ErrorMessage[(Argon2_ErrorCodes)error_code];
|
||||
}
|
||||
|
||||
return "Unknown error code.";
|
||||
}
|
||||
|
|
221
src/argon2.h
221
src/argon2.h
|
@ -5,8 +5,10 @@
|
|||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
* this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
@ -17,17 +19,17 @@
|
|||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/************************* Constants to enable Known Answer Tests (KAT) **************************************************/
|
||||
/************************* Constants to enable Known Answer Tests (KAT)
|
||||
* **************************************************/
|
||||
/* Enable ARGON2_KAT */
|
||||
//#define ARGON2_KAT
|
||||
//#define ARGON2_KAT_INTERNAL
|
||||
|
||||
|
||||
/* The KAT file name */
|
||||
const char *ARGON2_KAT_FILENAME;
|
||||
|
||||
|
||||
/*************************Argon2 input parameter restrictions**************************************************/
|
||||
/*************************Argon2 input parameter
|
||||
* restrictions**************************************************/
|
||||
|
||||
/* Minimum and maximum number of lanes (degree of parallelism) */
|
||||
const uint32_t ARGON2_MIN_LANES;
|
||||
|
@ -41,92 +43,95 @@ const uint32_t ARGON2_MAX_THREADS;
|
|||
const uint32_t ARGON2_SYNC_POINTS;
|
||||
|
||||
/* Minimum and maximum digest size in bytes */
|
||||
const uint32_t ARGON2_MIN_OUTLEN ;
|
||||
const uint32_t ARGON2_MAX_OUTLEN ;
|
||||
const uint32_t ARGON2_MIN_OUTLEN;
|
||||
const uint32_t ARGON2_MAX_OUTLEN;
|
||||
|
||||
/* Minimum and maximum number of memory blocks (each of BLOCK_SIZE bytes) */
|
||||
const uint32_t ARGON2_MIN_MEMORY ; // 2 blocks per slice
|
||||
const uint32_t ARGON2_MIN_MEMORY; // 2 blocks per slice
|
||||
const uint32_t ARGON2_MAX_MEMORY; // 2^32-1 blocks
|
||||
|
||||
/* Minimum and maximum number of passes */
|
||||
const uint32_t ARGON2_MIN_TIME ;
|
||||
const uint32_t ARGON2_MIN_TIME;
|
||||
const uint32_t ARGON2_MAX_TIME;
|
||||
|
||||
/* Minimum and maximum password length in bytes */
|
||||
const uint32_t ARGON2_MIN_PWD_LENGTH ;
|
||||
const uint32_t ARGON2_MAX_PWD_LENGTH ;
|
||||
const uint32_t ARGON2_MIN_PWD_LENGTH;
|
||||
const uint32_t ARGON2_MAX_PWD_LENGTH;
|
||||
|
||||
/* Minimum and maximum associated data length in bytes */
|
||||
const uint32_t ARGON2_MIN_AD_LENGTH ;
|
||||
const uint32_t ARGON2_MAX_AD_LENGTH ;
|
||||
const uint32_t ARGON2_MIN_AD_LENGTH;
|
||||
const uint32_t ARGON2_MAX_AD_LENGTH;
|
||||
|
||||
/* Minimum and maximum salt length in bytes */
|
||||
const uint32_t ARGON2_MIN_SALT_LENGTH ;
|
||||
const uint32_t ARGON2_MIN_SALT_LENGTH;
|
||||
const uint32_t ARGON2_MAX_SALT_LENGTH;
|
||||
|
||||
/* Minimum and maximum key length in bytes */
|
||||
const uint32_t ARGON2_MIN_SECRET ;
|
||||
const uint32_t ARGON2_MAX_SECRET ;
|
||||
const uint32_t ARGON2_MIN_SECRET;
|
||||
const uint32_t ARGON2_MAX_SECRET;
|
||||
|
||||
/************************* Error codes *********************************************************************************/
|
||||
typedef enum _Argon2_ErrorCodes
|
||||
{
|
||||
ARGON2_OK = 0,
|
||||
/************************* Error codes
|
||||
* *********************************************************************************/
|
||||
typedef enum _Argon2_ErrorCodes {
|
||||
ARGON2_OK = 0,
|
||||
|
||||
ARGON2_OUTPUT_PTR_NULL = 1,
|
||||
ARGON2_OUTPUT_PTR_NULL = 1,
|
||||
|
||||
ARGON2_OUTPUT_TOO_SHORT = 2,
|
||||
ARGON2_OUTPUT_TOO_LONG = 3,
|
||||
ARGON2_OUTPUT_TOO_SHORT = 2,
|
||||
ARGON2_OUTPUT_TOO_LONG = 3,
|
||||
|
||||
ARGON2_PWD_TOO_SHORT = 4,
|
||||
ARGON2_PWD_TOO_LONG = 5,
|
||||
ARGON2_PWD_TOO_SHORT = 4,
|
||||
ARGON2_PWD_TOO_LONG = 5,
|
||||
|
||||
ARGON2_SALT_TOO_SHORT = 6,
|
||||
ARGON2_SALT_TOO_LONG = 7,
|
||||
ARGON2_SALT_TOO_SHORT = 6,
|
||||
ARGON2_SALT_TOO_LONG = 7,
|
||||
|
||||
ARGON2_AD_TOO_SHORT = 8,
|
||||
ARGON2_AD_TOO_LONG = 9,
|
||||
ARGON2_AD_TOO_SHORT = 8,
|
||||
ARGON2_AD_TOO_LONG = 9,
|
||||
|
||||
ARGON2_SECRET_TOO_SHORT = 10,
|
||||
ARGON2_SECRET_TOO_LONG = 11,
|
||||
ARGON2_SECRET_TOO_SHORT = 10,
|
||||
ARGON2_SECRET_TOO_LONG = 11,
|
||||
|
||||
ARGON2_TIME_TOO_SMALL = 12,
|
||||
ARGON2_TIME_TOO_LARGE = 13,
|
||||
ARGON2_TIME_TOO_SMALL = 12,
|
||||
ARGON2_TIME_TOO_LARGE = 13,
|
||||
|
||||
ARGON2_MEMORY_TOO_LITTLE = 14,
|
||||
ARGON2_MEMORY_TOO_MUCH = 15,
|
||||
ARGON2_MEMORY_TOO_LITTLE = 14,
|
||||
ARGON2_MEMORY_TOO_MUCH = 15,
|
||||
|
||||
ARGON2_LANES_TOO_FEW = 16,
|
||||
ARGON2_LANES_TOO_MANY = 17,
|
||||
ARGON2_LANES_TOO_FEW = 16,
|
||||
ARGON2_LANES_TOO_MANY = 17,
|
||||
|
||||
ARGON2_PWD_PTR_MISMATCH = 18, //NULL ptr with non-zero length
|
||||
ARGON2_SALT_PTR_MISMATCH = 19, //NULL ptr with non-zero length
|
||||
ARGON2_SECRET_PTR_MISMATCH = 20, //NULL ptr with non-zero length
|
||||
ARGON2_AD_PTR_MISMATCH = 21, //NULL ptr with non-zero length
|
||||
ARGON2_PWD_PTR_MISMATCH = 18, // NULL ptr with non-zero length
|
||||
ARGON2_SALT_PTR_MISMATCH = 19, // NULL ptr with non-zero length
|
||||
ARGON2_SECRET_PTR_MISMATCH = 20, // NULL ptr with non-zero length
|
||||
ARGON2_AD_PTR_MISMATCH = 21, // NULL ptr with non-zero length
|
||||
|
||||
ARGON2_MEMORY_ALLOCATION_ERROR = 22,
|
||||
ARGON2_MEMORY_ALLOCATION_ERROR = 22,
|
||||
|
||||
ARGON2_FREE_MEMORY_CBK_NULL = 23,
|
||||
ARGON2_ALLOCATE_MEMORY_CBK_NULL = 24,
|
||||
ARGON2_FREE_MEMORY_CBK_NULL = 23,
|
||||
ARGON2_ALLOCATE_MEMORY_CBK_NULL = 24,
|
||||
|
||||
ARGON2_INCORRECT_PARAMETER = 25,
|
||||
ARGON2_INCORRECT_TYPE = 26,
|
||||
ARGON2_INCORRECT_PARAMETER = 25,
|
||||
ARGON2_INCORRECT_TYPE = 26,
|
||||
|
||||
ARGON2_OUT_PTR_MISMATCH = 27,
|
||||
ARGON2_OUT_PTR_MISMATCH = 27,
|
||||
|
||||
ARGON2_THREADS_TOO_FEW = 28,
|
||||
ARGON2_THREADS_TOO_MANY = 29,
|
||||
ARGON2_THREADS_TOO_FEW = 28,
|
||||
ARGON2_THREADS_TOO_MANY = 29,
|
||||
|
||||
ARGON2_ERROR_CODES_LENGTH /* Do NOT remove; Do NOT add error codes after this error code */
|
||||
ARGON2_ERROR_CODES_LENGTH /* Do NOT remove; Do NOT add error codes after this
|
||||
error code */
|
||||
} Argon2_ErrorCodes;
|
||||
|
||||
/********************************************* Memory allocator types --- for
|
||||
* external allocation
|
||||
* *************************************************************/
|
||||
typedef int (*AllocateMemoryCallback)(uint8_t **memory,
|
||||
size_t bytes_to_allocate);
|
||||
typedef void (*FreeMemoryCallback)(uint8_t *memory, size_t bytes_to_allocate);
|
||||
|
||||
|
||||
/********************************************* Memory allocator types --- for external allocation *************************************************************/
|
||||
typedef int ( *AllocateMemoryCallback )( uint8_t **memory, size_t bytes_to_allocate );
|
||||
typedef void( *FreeMemoryCallback )( uint8_t *memory, size_t bytes_to_allocate );
|
||||
|
||||
/********************************************* Argon2 external data structures*************************************************************/
|
||||
/********************************************* Argon2 external data
|
||||
* structures*************************************************************/
|
||||
|
||||
/*
|
||||
*****Context: structure to hold Argon2 inputs:
|
||||
|
@ -138,51 +143,53 @@ typedef void( *FreeMemoryCallback )( uint8_t *memory, size_t bytes_to_allocate )
|
|||
* number of passes, amount of used memory (in KBytes, can be rounded up a bit)
|
||||
* number of parallel threads that will be run.
|
||||
* All the parameters above affect the output hash value.
|
||||
* Additionally, two function pointers can be provided to allocate and deallocate the memory (if NULL, memory will be allocated internally).
|
||||
* Also, three flags indicate whether to erase password, secret as soon as they are pre-hashed (and thus not needed anymore), and the entire memory
|
||||
* Additionally, two function pointers can be provided to allocate and
|
||||
deallocate the memory (if NULL, memory will be allocated internally).
|
||||
* Also, three flags indicate whether to erase password, secret as soon as they
|
||||
are pre-hashed (and thus not needed anymore), and the entire memory
|
||||
****************************
|
||||
Simplest situation: you have output array out[8], password is stored in pwd[32], salt is stored in salt[16], you do not have keys nor associated data.
|
||||
You need to spend 1 GB of RAM and you run 5 passes of Argon2d with 4 parallel lanes.
|
||||
Simplest situation: you have output array out[8], password is stored in
|
||||
pwd[32], salt is stored in salt[16], you do not have keys nor associated data.
|
||||
You need to spend 1 GB of RAM and you run 5 passes of Argon2d with 4 parallel
|
||||
lanes.
|
||||
You want to erase the password, but you're OK with last pass not being erased.
|
||||
You want to use the default memory allocator.
|
||||
Then you initialize
|
||||
Argon2_Context(out,8,pwd,32,salt,16,NULL,0,NULL,0,5,1<<20,4,4,NULL,NULL,true,false,false,false).
|
||||
*/
|
||||
typedef struct _Argon2_Context
|
||||
{
|
||||
uint8_t *out; //output array
|
||||
uint32_t outlen; //digest length
|
||||
typedef struct _Argon2_Context {
|
||||
uint8_t *out; // output array
|
||||
uint32_t outlen; // digest length
|
||||
|
||||
uint8_t *pwd; //password array
|
||||
uint32_t pwdlen; //password length
|
||||
uint8_t *pwd; // password array
|
||||
uint32_t pwdlen; // password length
|
||||
|
||||
uint8_t *salt; //salt array
|
||||
uint32_t saltlen; //salt length
|
||||
uint8_t *salt; // salt array
|
||||
uint32_t saltlen; // salt length
|
||||
|
||||
uint8_t *secret; //key array
|
||||
uint32_t secretlen; //key length
|
||||
uint8_t *secret; // key array
|
||||
uint32_t secretlen; // key length
|
||||
|
||||
uint8_t *ad; //associated data array
|
||||
uint32_t adlen; //associated data length
|
||||
uint8_t *ad; // associated data array
|
||||
uint32_t adlen; // associated data length
|
||||
|
||||
uint32_t t_cost; //number of passes
|
||||
uint32_t m_cost; //amount of memory requested (KB)
|
||||
uint32_t lanes; //number of lanes
|
||||
uint32_t threads; //maximum number of threads
|
||||
uint32_t t_cost; // number of passes
|
||||
uint32_t m_cost; // amount of memory requested (KB)
|
||||
uint32_t lanes; // number of lanes
|
||||
uint32_t threads; // maximum number of threads
|
||||
|
||||
AllocateMemoryCallback allocate_cbk; //pointer to memory allocator
|
||||
FreeMemoryCallback free_cbk; //pointer to memory deallocator
|
||||
AllocateMemoryCallback allocate_cbk; // pointer to memory allocator
|
||||
FreeMemoryCallback free_cbk; // pointer to memory deallocator
|
||||
|
||||
bool clear_password; //whether to clear the password array
|
||||
bool clear_secret; //whether to clear the secret array
|
||||
bool clear_memory; //whether to clear the memory after the run
|
||||
bool clear_password; // whether to clear the password array
|
||||
bool clear_secret; // whether to clear the secret array
|
||||
bool clear_memory; // whether to clear the memory after the run
|
||||
|
||||
bool print; //whether to print starting variables, memory blocks, and the tag to the file -- Test vectors only!
|
||||
bool print; // whether to print starting variables, memory blocks, and the tag
|
||||
// to the file -- Test vectors only!
|
||||
|
||||
} Argon2_Context;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Function to hash the inputs in the memory-hard fashion (uses Argon2i)
|
||||
* @param out Pointer to the memory where the hash digest will be written
|
||||
|
@ -196,64 +203,72 @@ typedef struct _Argon2_Context
|
|||
* @pre @a saltlen must be at least @saltlen bytes long
|
||||
* @return Zero if successful, 1 otherwise.
|
||||
*/
|
||||
int hashpwd( void *out, size_t outlen, const void *in, size_t inlen, const void *salt, size_t saltlen,
|
||||
unsigned int t_cost, unsigned int m_cost );
|
||||
int hashpwd(void *out, size_t outlen, const void *in, size_t inlen,
|
||||
const void *salt, size_t saltlen, unsigned int t_cost,
|
||||
unsigned int m_cost);
|
||||
|
||||
/* same for argon2d */
|
||||
int hashpwd2( void *out, size_t outlen, const void *in, size_t inlen, const void *salt, size_t saltlen,
|
||||
unsigned int t_cost, unsigned int m_cost );
|
||||
int hashpwd2(void *out, size_t outlen, const void *in, size_t inlen,
|
||||
const void *salt, size_t saltlen, unsigned int t_cost,
|
||||
unsigned int m_cost);
|
||||
|
||||
/*
|
||||
* **************Argon2d: Version of Argon2 that picks memory blocks depending on the password and salt. Only for side-channel-free environment!!***************
|
||||
* **************Argon2d: Version of Argon2 that picks memory blocks depending
|
||||
* on the password and salt. Only for side-channel-free
|
||||
* environment!!***************
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @return Zero if successful, a non zero error code otherwise
|
||||
*/
|
||||
int argon2d( Argon2_Context *context );
|
||||
int argon2d(Argon2_Context *context);
|
||||
|
||||
/*
|
||||
* * **************Argon2i: Version of Argon2 that picks memory blocks independent on the password and salt. Good for side-channels,
|
||||
* * **************Argon2i: Version of Argon2 that picks memory blocks
|
||||
*independent on the password and salt. Good for side-channels,
|
||||
******************* but worse w.r.t. tradeoff attacks if
|
||||
*******************only one pass is used***************
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @return Zero if successful, a non zero error code otherwise
|
||||
*/
|
||||
int argon2i( Argon2_Context *context );
|
||||
int argon2i(Argon2_Context *context);
|
||||
|
||||
/*
|
||||
* * **************Argon2di: Reserved name***************
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @return Zero if successful, a non zero error code otherwise
|
||||
*/
|
||||
int argon2di( Argon2_Context *context );
|
||||
int argon2di(Argon2_Context *context);
|
||||
|
||||
/*
|
||||
* * **************Argon2ds: Argon2d hardened against GPU attacks, 20% slower***************
|
||||
* * **************Argon2ds: Argon2d hardened against GPU attacks, 20%
|
||||
* slower***************
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @return Zero if successful, a non zero error code otherwise
|
||||
*/
|
||||
int argon2ds( Argon2_Context *context );
|
||||
|
||||
int argon2ds(Argon2_Context *context);
|
||||
|
||||
/*
|
||||
* * **************Argon2id: First half-pass over memory is password-independent, the rest are password-dependent
|
||||
********************OK against side channels: they reduce to 1/2-pass Argon2i***************
|
||||
* * **************Argon2id: First half-pass over memory is
|
||||
*password-independent, the rest are password-dependent
|
||||
********************OK against side channels: they reduce to 1/2-pass
|
||||
*Argon2i***************
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @return Zero if successful, a non zero error code otherwise
|
||||
*/
|
||||
int argon2id( Argon2_Context *context );
|
||||
int argon2id(Argon2_Context *context);
|
||||
|
||||
/*
|
||||
* Verify if a given password is correct for Argon2d hashing
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @param hash The password hash to verify. The length of the hash is specified by the context outlen member
|
||||
* @param hash The password hash to verify. The length of the hash is
|
||||
* specified by the context outlen member
|
||||
* @return Zero if successful, a non zero error code otherwise
|
||||
*/
|
||||
int verify_d( Argon2_Context *context, const char *hash );
|
||||
int verify_d(Argon2_Context *context, const char *hash);
|
||||
|
||||
/*
|
||||
* Get the associated error message for given error code
|
||||
* @return The error message associated with the given error code
|
||||
*/
|
||||
const char *error_message( int error_code );
|
||||
const char *error_message(int error_code);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
You should have received a copy of the CC0 Public Domain Dedication along
|
||||
with
|
||||
this software. If not, see
|
||||
<http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef __BLAKE2_CONFIG_H__
|
||||
|
@ -35,7 +37,6 @@
|
|||
#define HAVE_XOP
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_AVX2
|
||||
#ifndef HAVE_AVX
|
||||
#define HAVE_AVX
|
||||
|
@ -69,4 +70,3 @@
|
|||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
You should have received a copy of the CC0 Public Domain Dedication along
|
||||
with
|
||||
this software. If not, see
|
||||
<http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef __BLAKE2_IMPL_H__
|
||||
|
@ -19,128 +21,133 @@
|
|||
/* Argon2 Team - Begin Code */
|
||||
#include "brg-endian.h"
|
||||
|
||||
#if defined(PLATFORM_BYTE_ORDER) && (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) && !defined(NATIVE_LITTLE_ENDIAN)
|
||||
#if defined(PLATFORM_BYTE_ORDER) && \
|
||||
(PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) && \
|
||||
!defined(NATIVE_LITTLE_ENDIAN)
|
||||
#define NATIVE_LITTLE_ENDIAN
|
||||
#endif
|
||||
/* Argon2 Team - End Code */
|
||||
|
||||
|
||||
static __inline uint32_t load32( const void *src )
|
||||
{
|
||||
static __inline uint32_t load32(const void *src) {
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
uint32_t w;
|
||||
memcpy( &w, src, sizeof w );
|
||||
return w;
|
||||
uint32_t w;
|
||||
memcpy(&w, src, sizeof w);
|
||||
return w;
|
||||
#else
|
||||
const uint8_t *p = ( const uint8_t * )src;
|
||||
uint32_t w = *p++;
|
||||
w |= ( uint32_t )( *p++ ) << 8;
|
||||
w |= ( uint32_t )( *p++ ) << 16;
|
||||
w |= ( uint32_t )( *p++ ) << 24;
|
||||
return w;
|
||||
const uint8_t *p = (const uint8_t *)src;
|
||||
uint32_t w = *p++;
|
||||
w |= (uint32_t)(*p++) << 8;
|
||||
w |= (uint32_t)(*p++) << 16;
|
||||
w |= (uint32_t)(*p++) << 24;
|
||||
return w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static __inline uint64_t load64( const void *src )
|
||||
{
|
||||
static __inline uint64_t load64(const void *src) {
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
uint64_t w;
|
||||
memcpy( &w, src, sizeof w );
|
||||
return w;
|
||||
uint64_t w;
|
||||
memcpy(&w, src, sizeof w);
|
||||
return w;
|
||||
#else
|
||||
const uint8_t *p = ( const uint8_t * )src;
|
||||
uint64_t w = *p++;
|
||||
w |= ( uint64_t )( *p++ ) << 8;
|
||||
w |= ( uint64_t )( *p++ ) << 16;
|
||||
w |= ( uint64_t )( *p++ ) << 24;
|
||||
w |= ( uint64_t )( *p++ ) << 32;
|
||||
w |= ( uint64_t )( *p++ ) << 40;
|
||||
w |= ( uint64_t )( *p++ ) << 48;
|
||||
w |= ( uint64_t )( *p++ ) << 56;
|
||||
return w;
|
||||
const uint8_t *p = (const uint8_t *)src;
|
||||
uint64_t w = *p++;
|
||||
w |= (uint64_t)(*p++) << 8;
|
||||
w |= (uint64_t)(*p++) << 16;
|
||||
w |= (uint64_t)(*p++) << 24;
|
||||
w |= (uint64_t)(*p++) << 32;
|
||||
w |= (uint64_t)(*p++) << 40;
|
||||
w |= (uint64_t)(*p++) << 48;
|
||||
w |= (uint64_t)(*p++) << 56;
|
||||
return w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static __inline void store32( void *dst, uint32_t w )
|
||||
{
|
||||
static __inline void store32(void *dst, uint32_t w) {
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
memcpy( dst, &w, sizeof w );
|
||||
memcpy(dst, &w, sizeof w);
|
||||
#else
|
||||
uint8_t *p = ( uint8_t * )dst;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w;
|
||||
uint8_t *p = (uint8_t *)dst;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static __inline void store64( void *dst, uint64_t w )
|
||||
{
|
||||
static __inline void store64(void *dst, uint64_t w) {
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
memcpy( dst, &w, sizeof w );
|
||||
memcpy(dst, &w, sizeof w);
|
||||
#else
|
||||
uint8_t *p = ( uint8_t * )dst;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w;
|
||||
uint8_t *p = (uint8_t *)dst;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static __inline uint64_t load48( const void *src )
|
||||
{
|
||||
const uint8_t *p = ( const uint8_t * )src;
|
||||
uint64_t w = *p++;
|
||||
w |= ( uint64_t )( *p++ ) << 8;
|
||||
w |= ( uint64_t )( *p++ ) << 16;
|
||||
w |= ( uint64_t )( *p++ ) << 24;
|
||||
w |= ( uint64_t )( *p++ ) << 32;
|
||||
w |= ( uint64_t )( *p++ ) << 40;
|
||||
return w;
|
||||
static __inline uint64_t load48(const void *src) {
|
||||
const uint8_t *p = (const uint8_t *)src;
|
||||
uint64_t w = *p++;
|
||||
w |= (uint64_t)(*p++) << 8;
|
||||
w |= (uint64_t)(*p++) << 16;
|
||||
w |= (uint64_t)(*p++) << 24;
|
||||
w |= (uint64_t)(*p++) << 32;
|
||||
w |= (uint64_t)(*p++) << 40;
|
||||
return w;
|
||||
}
|
||||
|
||||
static __inline void store48( void *dst, uint64_t w )
|
||||
{
|
||||
uint8_t *p = ( uint8_t * )dst;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w;
|
||||
static __inline void store48(void *dst, uint64_t w) {
|
||||
uint8_t *p = (uint8_t *)dst;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
}
|
||||
|
||||
static __inline uint32_t rotl32( const uint32_t w, const unsigned c )
|
||||
{
|
||||
return ( w << c ) | ( w >> ( 32 - c ) );
|
||||
static __inline uint32_t rotl32(const uint32_t w, const unsigned c) {
|
||||
return (w << c) | (w >> (32 - c));
|
||||
}
|
||||
|
||||
static __inline uint64_t rotl64( const uint64_t w, const unsigned c )
|
||||
{
|
||||
return ( w << c ) | ( w >> ( 64 - c ) );
|
||||
static __inline uint64_t rotl64(const uint64_t w, const unsigned c) {
|
||||
return (w << c) | (w >> (64 - c));
|
||||
}
|
||||
|
||||
static __inline uint32_t rotr32( const uint32_t w, const unsigned c )
|
||||
{
|
||||
return ( w >> c ) | ( w << ( 32 - c ) );
|
||||
static __inline uint32_t rotr32(const uint32_t w, const unsigned c) {
|
||||
return (w >> c) | (w << (32 - c));
|
||||
}
|
||||
|
||||
static __inline uint64_t rotr64( const uint64_t w, const unsigned c )
|
||||
{
|
||||
return ( w >> c ) | ( w << ( 64 - c ) );
|
||||
static __inline uint64_t rotr64(const uint64_t w, const unsigned c) {
|
||||
return (w >> c) | (w << (64 - c));
|
||||
}
|
||||
|
||||
/* prevents compiler optimizing out memset() */
|
||||
static __inline void secure_zero_memory( void *v, size_t n )
|
||||
{
|
||||
volatile uint8_t *p = ( volatile uint8_t * )v;
|
||||
static __inline void secure_zero_memory(void *v, size_t n) {
|
||||
volatile uint8_t *p = (volatile uint8_t *)v;
|
||||
|
||||
while( n-- ) *p++ = 0;
|
||||
while (n--)
|
||||
*p++ = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,85 +1,91 @@
|
|||
#define _mm_roti_epi64(x, c) \
|
||||
(-(c) == 32) ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2,3,0,1)) \
|
||||
: (-(c) == 24) ? _mm_shuffle_epi8((x), r24) \
|
||||
: (-(c) == 16) ? _mm_shuffle_epi8((x), r16) \
|
||||
: (-(c) == 63) ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_add_epi64((x), (x))) \
|
||||
: _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_slli_epi64((x), 64-(-(c))))
|
||||
#define _mm_roti_epi64(x, c) \
|
||||
(-(c) == 32) \
|
||||
? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \
|
||||
: (-(c) == 24) \
|
||||
? _mm_shuffle_epi8((x), r24) \
|
||||
: (-(c) == 16) \
|
||||
? _mm_shuffle_epi8((x), r16) \
|
||||
: (-(c) == 63) \
|
||||
? _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
|
||||
_mm_add_epi64((x), (x))) \
|
||||
: _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
|
||||
_mm_slli_epi64((x), 64 - (-(c))))
|
||||
|
||||
#define G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
|
||||
row1l = _mm_add_epi64(row1l, row2l); \
|
||||
row1h = _mm_add_epi64(row1h, row2h); \
|
||||
\
|
||||
row4l = _mm_xor_si128(row4l, row1l); \
|
||||
row4h = _mm_xor_si128(row4h, row1h); \
|
||||
\
|
||||
row4l = _mm_roti_epi64(row4l, -32); \
|
||||
row4h = _mm_roti_epi64(row4h, -32); \
|
||||
\
|
||||
row3l = _mm_add_epi64(row3l, row4l); \
|
||||
row3h = _mm_add_epi64(row3h, row4h); \
|
||||
\
|
||||
row2l = _mm_xor_si128(row2l, row3l); \
|
||||
row2h = _mm_xor_si128(row2h, row3h); \
|
||||
\
|
||||
row2l = _mm_roti_epi64(row2l, -24); \
|
||||
row2h = _mm_roti_epi64(row2h, -24); \
|
||||
#define G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \
|
||||
row1l = _mm_add_epi64(row1l, row2l); \
|
||||
row1h = _mm_add_epi64(row1h, row2h); \
|
||||
\
|
||||
row4l = _mm_xor_si128(row4l, row1l); \
|
||||
row4h = _mm_xor_si128(row4h, row1h); \
|
||||
\
|
||||
row4l = _mm_roti_epi64(row4l, -32); \
|
||||
row4h = _mm_roti_epi64(row4h, -32); \
|
||||
\
|
||||
row3l = _mm_add_epi64(row3l, row4l); \
|
||||
row3h = _mm_add_epi64(row3h, row4h); \
|
||||
\
|
||||
row2l = _mm_xor_si128(row2l, row3l); \
|
||||
row2h = _mm_xor_si128(row2h, row3h); \
|
||||
\
|
||||
row2l = _mm_roti_epi64(row2l, -24); \
|
||||
row2h = _mm_roti_epi64(row2h, -24);
|
||||
|
||||
#define G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
|
||||
row1l = _mm_add_epi64(row1l, row2l); \
|
||||
row1h = _mm_add_epi64(row1h, row2h); \
|
||||
\
|
||||
row4l = _mm_xor_si128(row4l, row1l); \
|
||||
row4h = _mm_xor_si128(row4h, row1h); \
|
||||
\
|
||||
row4l = _mm_roti_epi64(row4l, -16); \
|
||||
row4h = _mm_roti_epi64(row4h, -16); \
|
||||
\
|
||||
row3l = _mm_add_epi64(row3l, row4l); \
|
||||
row3h = _mm_add_epi64(row3h, row4h); \
|
||||
\
|
||||
row2l = _mm_xor_si128(row2l, row3l); \
|
||||
row2h = _mm_xor_si128(row2h, row3h); \
|
||||
\
|
||||
row2l = _mm_roti_epi64(row2l, -63); \
|
||||
row2h = _mm_roti_epi64(row2h, -63); \
|
||||
#define G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \
|
||||
row1l = _mm_add_epi64(row1l, row2l); \
|
||||
row1h = _mm_add_epi64(row1h, row2h); \
|
||||
\
|
||||
row4l = _mm_xor_si128(row4l, row1l); \
|
||||
row4h = _mm_xor_si128(row4h, row1h); \
|
||||
\
|
||||
row4l = _mm_roti_epi64(row4l, -16); \
|
||||
row4h = _mm_roti_epi64(row4h, -16); \
|
||||
\
|
||||
row3l = _mm_add_epi64(row3l, row4l); \
|
||||
row3h = _mm_add_epi64(row3h, row4h); \
|
||||
\
|
||||
row2l = _mm_xor_si128(row2l, row3l); \
|
||||
row2h = _mm_xor_si128(row2h, row3h); \
|
||||
\
|
||||
row2l = _mm_roti_epi64(row2l, -63); \
|
||||
row2h = _mm_roti_epi64(row2h, -63);
|
||||
|
||||
#define DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
|
||||
t0 = _mm_alignr_epi8(row2h, row2l, 8); \
|
||||
t1 = _mm_alignr_epi8(row2l, row2h, 8); \
|
||||
row2l = t0; \
|
||||
row2h = t1; \
|
||||
\
|
||||
t0 = row3l; \
|
||||
row3l = row3h; \
|
||||
row3h = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(row4h, row4l, 8); \
|
||||
t1 = _mm_alignr_epi8(row4l, row4h, 8); \
|
||||
row4l = t1; \
|
||||
row4h = t0;
|
||||
#define DIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \
|
||||
t0 = _mm_alignr_epi8(row2h, row2l, 8); \
|
||||
t1 = _mm_alignr_epi8(row2l, row2h, 8); \
|
||||
row2l = t0; \
|
||||
row2h = t1; \
|
||||
\
|
||||
t0 = row3l; \
|
||||
row3l = row3h; \
|
||||
row3h = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(row4h, row4l, 8); \
|
||||
t1 = _mm_alignr_epi8(row4l, row4h, 8); \
|
||||
row4l = t1; \
|
||||
row4h = t0;
|
||||
|
||||
#define UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
|
||||
t0 = _mm_alignr_epi8(row2l, row2h, 8); \
|
||||
t1 = _mm_alignr_epi8(row2h, row2l, 8); \
|
||||
row2l = t0; \
|
||||
row2h = t1; \
|
||||
\
|
||||
t0 = row3l; \
|
||||
row3l = row3h; \
|
||||
row3h = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(row4l, row4h, 8); \
|
||||
t1 = _mm_alignr_epi8(row4h, row4l, 8); \
|
||||
row4l = t1; \
|
||||
row4h = t0;
|
||||
#define UNDIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \
|
||||
t0 = _mm_alignr_epi8(row2l, row2h, 8); \
|
||||
t1 = _mm_alignr_epi8(row2h, row2l, 8); \
|
||||
row2l = t0; \
|
||||
row2h = t1; \
|
||||
\
|
||||
t0 = row3l; \
|
||||
row3l = row3h; \
|
||||
row3h = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(row4l, row4h, 8); \
|
||||
t1 = _mm_alignr_epi8(row4h, row4l, 8); \
|
||||
row4l = t1; \
|
||||
row4h = t0;
|
||||
|
||||
#define BLAKE2_ROUND(row1l,row1h,row2l,row2h,row3l,row3h,row4l,row4h) \
|
||||
G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \
|
||||
G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \
|
||||
\
|
||||
DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \
|
||||
\
|
||||
G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \
|
||||
G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \
|
||||
\
|
||||
UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h);
|
||||
#define BLAKE2_ROUND(row1l, row1h, row2l, row2h, row3l, row3h, row4l, row4h) \
|
||||
G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
\
|
||||
DIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
\
|
||||
G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
\
|
||||
UNDIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h);
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
You should have received a copy of the CC0 Public Domain Dedication along
|
||||
with
|
||||
this software. If not, see
|
||||
<http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef __BLAKE2_H__
|
||||
|
@ -21,7 +23,7 @@
|
|||
#if defined(_MSC_VER)
|
||||
#define ALIGN(x) __declspec(align(x))
|
||||
#else
|
||||
#define ALIGN(x) __attribute__ ((__aligned__(x)))
|
||||
#define ALIGN(x) __attribute__((__aligned__(x)))
|
||||
#endif
|
||||
/* Argon2 Team - End Code */
|
||||
|
||||
|
@ -29,59 +31,56 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum blake2b_constant
|
||||
{
|
||||
BLAKE2B_BLOCKBYTES = 128,
|
||||
BLAKE2B_OUTBYTES = 64,
|
||||
BLAKE2B_KEYBYTES = 64,
|
||||
BLAKE2B_SALTBYTES = 16,
|
||||
BLAKE2B_PERSONALBYTES = 16
|
||||
enum blake2b_constant {
|
||||
BLAKE2B_BLOCKBYTES = 128,
|
||||
BLAKE2B_OUTBYTES = 64,
|
||||
BLAKE2B_KEYBYTES = 64,
|
||||
BLAKE2B_SALTBYTES = 16,
|
||||
BLAKE2B_PERSONALBYTES = 16
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct __blake2b_param
|
||||
{
|
||||
uint8_t digest_length; // 1
|
||||
uint8_t key_length; // 2
|
||||
uint8_t fanout; // 3
|
||||
uint8_t depth; // 4
|
||||
uint32_t leaf_length; // 8
|
||||
uint64_t node_offset; // 16
|
||||
uint8_t node_depth; // 17
|
||||
uint8_t inner_length; // 18
|
||||
uint8_t reserved[14]; // 32
|
||||
uint8_t salt[BLAKE2B_SALTBYTES]; // 48
|
||||
uint8_t personal[BLAKE2B_PERSONALBYTES]; // 64
|
||||
typedef struct __blake2b_param {
|
||||
uint8_t digest_length; // 1
|
||||
uint8_t key_length; // 2
|
||||
uint8_t fanout; // 3
|
||||
uint8_t depth; // 4
|
||||
uint32_t leaf_length; // 8
|
||||
uint64_t node_offset; // 16
|
||||
uint8_t node_depth; // 17
|
||||
uint8_t inner_length; // 18
|
||||
uint8_t reserved[14]; // 32
|
||||
uint8_t salt[BLAKE2B_SALTBYTES]; // 48
|
||||
uint8_t personal[BLAKE2B_PERSONALBYTES]; // 64
|
||||
} blake2b_param;
|
||||
|
||||
ALIGN( 64 ) typedef struct __blake2b_state
|
||||
{
|
||||
uint64_t h[8];
|
||||
uint64_t t[2];
|
||||
uint64_t f[2];
|
||||
uint8_t buf[2 * BLAKE2B_BLOCKBYTES];
|
||||
size_t buflen;
|
||||
uint8_t last_node;
|
||||
ALIGN(64) typedef struct __blake2b_state {
|
||||
uint64_t h[8];
|
||||
uint64_t t[2];
|
||||
uint64_t f[2];
|
||||
uint8_t buf[2 * BLAKE2B_BLOCKBYTES];
|
||||
size_t buflen;
|
||||
uint8_t last_node;
|
||||
} blake2b_state;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
int blake2b_init( blake2b_state *S, const uint8_t outlen );
|
||||
int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );
|
||||
int blake2b_init_param( blake2b_state *S, const blake2b_param *P );
|
||||
int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen );
|
||||
int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen );
|
||||
int blake2b_init(blake2b_state *S, const uint8_t outlen);
|
||||
int blake2b_init_key(blake2b_state *S, const uint8_t outlen, const void *key,
|
||||
const uint8_t keylen);
|
||||
int blake2b_init_param(blake2b_state *S, const blake2b_param *P);
|
||||
int blake2b_update(blake2b_state *S, const uint8_t *in, uint64_t inlen);
|
||||
int blake2b_final(blake2b_state *S, uint8_t *out, uint8_t outlen);
|
||||
|
||||
|
||||
int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );
|
||||
int blake2b(uint8_t *out, const void *in, const void *key, const uint8_t outlen,
|
||||
const uint64_t inlen, uint8_t keylen);
|
||||
/* Argon2 Team - Begin Code */
|
||||
int blake2b_long( uint8_t *out, const void *in, const uint32_t outlen, const uint64_t inlen );
|
||||
int blake2b_long(uint8_t *out, const void *in, const uint32_t outlen,
|
||||
const uint64_t inlen);
|
||||
/* Argon2 Team - End Code */
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
You should have received a copy of the CC0 Public Domain Dedication along
|
||||
with
|
||||
this software. If not, see
|
||||
<http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
@ -18,324 +20,310 @@
|
|||
#include "blake2.h"
|
||||
#include "blake2-impl.h"
|
||||
|
||||
static const uint64_t blake2b_IV[8] =
|
||||
{
|
||||
0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
|
||||
0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
|
||||
0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
|
||||
0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
|
||||
};
|
||||
static const uint64_t blake2b_IV[8] = {
|
||||
0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
|
||||
0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
|
||||
0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL};
|
||||
|
||||
static const uint8_t blake2b_sigma[12][16] =
|
||||
{
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
|
||||
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
|
||||
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
|
||||
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
|
||||
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
|
||||
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
|
||||
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
|
||||
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
|
||||
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
|
||||
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
|
||||
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
|
||||
};
|
||||
static const uint8_t blake2b_sigma[12][16] = {
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
|
||||
{14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
|
||||
{11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4},
|
||||
{7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8},
|
||||
{9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
|
||||
{2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9},
|
||||
{12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11},
|
||||
{13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10},
|
||||
{6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5},
|
||||
{10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0},
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
|
||||
{14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}};
|
||||
|
||||
|
||||
static __inline int blake2b_set_lastnode( blake2b_state *S )
|
||||
{
|
||||
S->f[1] = ~0ULL;
|
||||
return 0;
|
||||
static __inline int blake2b_set_lastnode(blake2b_state *S) {
|
||||
S->f[1] = ~0ULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Some helper functions, not necessarily useful */
|
||||
static __inline int blake2b_set_lastblock( blake2b_state *S )
|
||||
{
|
||||
if( S->last_node ) blake2b_set_lastnode( S );
|
||||
static __inline int blake2b_set_lastblock(blake2b_state *S) {
|
||||
if (S->last_node)
|
||||
blake2b_set_lastnode(S);
|
||||
|
||||
S->f[0] = ~0ULL;
|
||||
return 0;
|
||||
S->f[0] = ~0ULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __inline int blake2b_increment_counter( blake2b_state *S, const uint64_t inc )
|
||||
{
|
||||
S->t[0] += inc;
|
||||
S->t[1] += ( S->t[0] < inc );
|
||||
return 0;
|
||||
static __inline int blake2b_increment_counter(blake2b_state *S,
|
||||
const uint64_t inc) {
|
||||
S->t[0] += inc;
|
||||
S->t[1] += (S->t[0] < inc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __inline int blake2b_init0(blake2b_state *S) {
|
||||
memset(S, 0, sizeof(blake2b_state));
|
||||
|
||||
static __inline int blake2b_init0( blake2b_state *S )
|
||||
{
|
||||
memset( S, 0, sizeof( blake2b_state ) );
|
||||
for (int i = 0; i < 8; ++i)
|
||||
S->h[i] = blake2b_IV[i];
|
||||
|
||||
for( int i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* init xors IV with input parameter block */
|
||||
int blake2b_init_param( blake2b_state *S, const blake2b_param *P )
|
||||
{
|
||||
blake2b_init0( S );
|
||||
const uint8_t *p = ( const uint8_t * )( P );
|
||||
int blake2b_init_param(blake2b_state *S, const blake2b_param *P) {
|
||||
blake2b_init0(S);
|
||||
const uint8_t *p = (const uint8_t *)(P);
|
||||
|
||||
/* IV XOR ParamBlock */
|
||||
for( size_t i = 0; i < 8; ++i )
|
||||
S->h[i] ^= load64( p + sizeof( S->h[i] ) * i );
|
||||
/* IV XOR ParamBlock */
|
||||
for (size_t i = 0; i < 8; ++i)
|
||||
S->h[i] ^= load64(p + sizeof(S->h[i]) * i);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2b_init(blake2b_state *S, const uint8_t outlen) {
|
||||
blake2b_param P[1];
|
||||
|
||||
if ((!outlen) || (outlen > BLAKE2B_OUTBYTES))
|
||||
return -1;
|
||||
|
||||
int blake2b_init( blake2b_state *S, const uint8_t outlen )
|
||||
{
|
||||
blake2b_param P[1];
|
||||
|
||||
if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
|
||||
|
||||
P->digest_length = outlen;
|
||||
P->key_length = 0;
|
||||
P->fanout = 1;
|
||||
P->depth = 1;
|
||||
store32( &P->leaf_length, 0 );
|
||||
store64( &P->node_offset, 0 );
|
||||
P->node_depth = 0;
|
||||
P->inner_length = 0;
|
||||
memset( P->reserved, 0, sizeof( P->reserved ) );
|
||||
memset( P->salt, 0, sizeof( P->salt ) );
|
||||
memset( P->personal, 0, sizeof( P->personal ) );
|
||||
return blake2b_init_param( S, P );
|
||||
P->digest_length = outlen;
|
||||
P->key_length = 0;
|
||||
P->fanout = 1;
|
||||
P->depth = 1;
|
||||
store32(&P->leaf_length, 0);
|
||||
store64(&P->node_offset, 0);
|
||||
P->node_depth = 0;
|
||||
P->inner_length = 0;
|
||||
memset(P->reserved, 0, sizeof(P->reserved));
|
||||
memset(P->salt, 0, sizeof(P->salt));
|
||||
memset(P->personal, 0, sizeof(P->personal));
|
||||
return blake2b_init_param(S, P);
|
||||
}
|
||||
|
||||
int blake2b_init_key(blake2b_state *S, const uint8_t outlen, const void *key,
|
||||
const uint8_t keylen) {
|
||||
blake2b_param P[1];
|
||||
|
||||
int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen )
|
||||
{
|
||||
blake2b_param P[1];
|
||||
if ((!outlen) || (outlen > BLAKE2B_OUTBYTES))
|
||||
return -1;
|
||||
|
||||
if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
|
||||
if (!key || !keylen || keylen > BLAKE2B_KEYBYTES)
|
||||
return -1;
|
||||
|
||||
if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;
|
||||
P->digest_length = outlen;
|
||||
P->key_length = keylen;
|
||||
P->fanout = 1;
|
||||
P->depth = 1;
|
||||
store32(&P->leaf_length, 0);
|
||||
store64(&P->node_offset, 0);
|
||||
P->node_depth = 0;
|
||||
P->inner_length = 0;
|
||||
memset(P->reserved, 0, sizeof(P->reserved));
|
||||
memset(P->salt, 0, sizeof(P->salt));
|
||||
memset(P->personal, 0, sizeof(P->personal));
|
||||
|
||||
P->digest_length = outlen;
|
||||
P->key_length = keylen;
|
||||
P->fanout = 1;
|
||||
P->depth = 1;
|
||||
store32( &P->leaf_length, 0 );
|
||||
store64( &P->node_offset, 0 );
|
||||
P->node_depth = 0;
|
||||
P->inner_length = 0;
|
||||
memset( P->reserved, 0, sizeof( P->reserved ) );
|
||||
memset( P->salt, 0, sizeof( P->salt ) );
|
||||
memset( P->personal, 0, sizeof( P->personal ) );
|
||||
if (blake2b_init_param(S, P) < 0)
|
||||
return -1;
|
||||
|
||||
if( blake2b_init_param( S, P ) < 0 ) return -1;
|
||||
|
||||
{
|
||||
uint8_t block[BLAKE2B_BLOCKBYTES];
|
||||
memset( block, 0, BLAKE2B_BLOCKBYTES );
|
||||
memcpy( block, key, keylen );
|
||||
blake2b_update( S, block, BLAKE2B_BLOCKBYTES );
|
||||
secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */
|
||||
}
|
||||
return 0;
|
||||
{
|
||||
uint8_t block[BLAKE2B_BLOCKBYTES];
|
||||
memset(block, 0, BLAKE2B_BLOCKBYTES);
|
||||
memcpy(block, key, keylen);
|
||||
blake2b_update(S, block, BLAKE2B_BLOCKBYTES);
|
||||
secure_zero_memory(block, BLAKE2B_BLOCKBYTES); /* Burn the key from stack */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] )
|
||||
{
|
||||
uint64_t m[16];
|
||||
uint64_t v[16];
|
||||
int i;
|
||||
static int blake2b_compress(blake2b_state *S,
|
||||
const uint8_t block[BLAKE2B_BLOCKBYTES]) {
|
||||
uint64_t m[16];
|
||||
uint64_t v[16];
|
||||
int i;
|
||||
|
||||
for( i = 0; i < 16; ++i )
|
||||
m[i] = load64( block + i * sizeof( m[i] ) );
|
||||
for (i = 0; i < 16; ++i)
|
||||
m[i] = load64(block + i * sizeof(m[i]));
|
||||
|
||||
for( i = 0; i < 8; ++i )
|
||||
v[i] = S->h[i];
|
||||
for (i = 0; i < 8; ++i)
|
||||
v[i] = S->h[i];
|
||||
|
||||
v[ 8] = blake2b_IV[0];
|
||||
v[ 9] = blake2b_IV[1];
|
||||
v[10] = blake2b_IV[2];
|
||||
v[11] = blake2b_IV[3];
|
||||
v[12] = S->t[0] ^ blake2b_IV[4];
|
||||
v[13] = S->t[1] ^ blake2b_IV[5];
|
||||
v[14] = S->f[0] ^ blake2b_IV[6];
|
||||
v[15] = S->f[1] ^ blake2b_IV[7];
|
||||
#define G(r,i,a,b,c,d) \
|
||||
do { \
|
||||
a = a + b + m[blake2b_sigma[r][2*i+0]]; \
|
||||
d = rotr64(d ^ a, 32); \
|
||||
c = c + d; \
|
||||
b = rotr64(b ^ c, 24); \
|
||||
a = a + b + m[blake2b_sigma[r][2*i+1]]; \
|
||||
d = rotr64(d ^ a, 16); \
|
||||
c = c + d; \
|
||||
b = rotr64(b ^ c, 63); \
|
||||
} while(0)
|
||||
#define ROUND(r) \
|
||||
do { \
|
||||
G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
|
||||
G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
|
||||
G(r,2,v[ 2],v[ 6],v[10],v[14]); \
|
||||
G(r,3,v[ 3],v[ 7],v[11],v[15]); \
|
||||
G(r,4,v[ 0],v[ 5],v[10],v[15]); \
|
||||
G(r,5,v[ 1],v[ 6],v[11],v[12]); \
|
||||
G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
|
||||
G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
|
||||
} while(0)
|
||||
ROUND( 0 );
|
||||
ROUND( 1 );
|
||||
ROUND( 2 );
|
||||
ROUND( 3 );
|
||||
ROUND( 4 );
|
||||
ROUND( 5 );
|
||||
ROUND( 6 );
|
||||
ROUND( 7 );
|
||||
ROUND( 8 );
|
||||
ROUND( 9 );
|
||||
ROUND( 10 );
|
||||
ROUND( 11 );
|
||||
v[8] = blake2b_IV[0];
|
||||
v[9] = blake2b_IV[1];
|
||||
v[10] = blake2b_IV[2];
|
||||
v[11] = blake2b_IV[3];
|
||||
v[12] = S->t[0] ^ blake2b_IV[4];
|
||||
v[13] = S->t[1] ^ blake2b_IV[5];
|
||||
v[14] = S->f[0] ^ blake2b_IV[6];
|
||||
v[15] = S->f[1] ^ blake2b_IV[7];
|
||||
#define G(r, i, a, b, c, d) \
|
||||
do { \
|
||||
a = a + b + m[blake2b_sigma[r][2 * i + 0]]; \
|
||||
d = rotr64(d ^ a, 32); \
|
||||
c = c + d; \
|
||||
b = rotr64(b ^ c, 24); \
|
||||
a = a + b + m[blake2b_sigma[r][2 * i + 1]]; \
|
||||
d = rotr64(d ^ a, 16); \
|
||||
c = c + d; \
|
||||
b = rotr64(b ^ c, 63); \
|
||||
} while (0)
|
||||
#define ROUND(r) \
|
||||
do { \
|
||||
G(r, 0, v[0], v[4], v[8], v[12]); \
|
||||
G(r, 1, v[1], v[5], v[9], v[13]); \
|
||||
G(r, 2, v[2], v[6], v[10], v[14]); \
|
||||
G(r, 3, v[3], v[7], v[11], v[15]); \
|
||||
G(r, 4, v[0], v[5], v[10], v[15]); \
|
||||
G(r, 5, v[1], v[6], v[11], v[12]); \
|
||||
G(r, 6, v[2], v[7], v[8], v[13]); \
|
||||
G(r, 7, v[3], v[4], v[9], v[14]); \
|
||||
} while (0)
|
||||
ROUND(0);
|
||||
ROUND(1);
|
||||
ROUND(2);
|
||||
ROUND(3);
|
||||
ROUND(4);
|
||||
ROUND(5);
|
||||
ROUND(6);
|
||||
ROUND(7);
|
||||
ROUND(8);
|
||||
ROUND(9);
|
||||
ROUND(10);
|
||||
ROUND(11);
|
||||
|
||||
for( i = 0; i < 8; ++i )
|
||||
S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
|
||||
for (i = 0; i < 8; ++i)
|
||||
S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
|
||||
|
||||
#undef G
|
||||
#undef ROUND
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* inlen now in bytes */
|
||||
int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen )
|
||||
{
|
||||
while( inlen > 0 )
|
||||
int blake2b_update(blake2b_state *S, const uint8_t *in, uint64_t inlen) {
|
||||
while (inlen > 0) {
|
||||
size_t left = S->buflen;
|
||||
size_t fill = 2 * BLAKE2B_BLOCKBYTES - left;
|
||||
|
||||
if (inlen > fill) {
|
||||
memcpy(S->buf + left, in, fill); // Fill buffer
|
||||
S->buflen += fill;
|
||||
blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
|
||||
blake2b_compress(S, S->buf); // Compress
|
||||
memcpy(S->buf, S->buf + BLAKE2B_BLOCKBYTES,
|
||||
BLAKE2B_BLOCKBYTES); // Shift buffer left
|
||||
S->buflen -= BLAKE2B_BLOCKBYTES;
|
||||
in += fill;
|
||||
inlen -= fill;
|
||||
} else // inlen <= fill
|
||||
{
|
||||
size_t left = S->buflen;
|
||||
size_t fill = 2 * BLAKE2B_BLOCKBYTES - left;
|
||||
|
||||
if( inlen > fill )
|
||||
{
|
||||
memcpy( S->buf + left, in, fill ); // Fill buffer
|
||||
S->buflen += fill;
|
||||
blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
|
||||
blake2b_compress( S, S->buf ); // Compress
|
||||
memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); // Shift buffer left
|
||||
S->buflen -= BLAKE2B_BLOCKBYTES;
|
||||
in += fill;
|
||||
inlen -= fill;
|
||||
}
|
||||
else // inlen <= fill
|
||||
{
|
||||
memcpy( S->buf + left, in, inlen );
|
||||
S->buflen += inlen; // Be lazy, do not compress
|
||||
in += inlen;
|
||||
inlen -= inlen;
|
||||
}
|
||||
memcpy(S->buf + left, in, inlen);
|
||||
S->buflen += inlen; // Be lazy, do not compress
|
||||
in += inlen;
|
||||
inlen -= inlen;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Is this correct? */
|
||||
int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen )
|
||||
{
|
||||
uint8_t buffer[BLAKE2B_OUTBYTES] = {0};
|
||||
int blake2b_final(blake2b_state *S, uint8_t *out, uint8_t outlen) {
|
||||
uint8_t buffer[BLAKE2B_OUTBYTES] = {0};
|
||||
|
||||
if( outlen > BLAKE2B_OUTBYTES )
|
||||
return -1;
|
||||
if (outlen > BLAKE2B_OUTBYTES)
|
||||
return -1;
|
||||
|
||||
if( S->buflen > BLAKE2B_BLOCKBYTES )
|
||||
{
|
||||
blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
|
||||
blake2b_compress( S, S->buf );
|
||||
S->buflen -= BLAKE2B_BLOCKBYTES;
|
||||
memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen );
|
||||
}
|
||||
if (S->buflen > BLAKE2B_BLOCKBYTES) {
|
||||
blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
|
||||
blake2b_compress(S, S->buf);
|
||||
S->buflen -= BLAKE2B_BLOCKBYTES;
|
||||
memcpy(S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen);
|
||||
}
|
||||
|
||||
blake2b_increment_counter( S, S->buflen );
|
||||
blake2b_set_lastblock( S );
|
||||
memset( S->buf + S->buflen, 0, 2 * BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */
|
||||
blake2b_compress( S, S->buf );
|
||||
blake2b_increment_counter(S, S->buflen);
|
||||
blake2b_set_lastblock(S);
|
||||
memset(S->buf + S->buflen, 0,
|
||||
2 * BLAKE2B_BLOCKBYTES - S->buflen); /* Padding */
|
||||
blake2b_compress(S, S->buf);
|
||||
|
||||
for( int i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
|
||||
store64( buffer + sizeof( S->h[i] ) * i, S->h[i] );
|
||||
for (int i = 0; i < 8; ++i) /* Output full hash to temp buffer */
|
||||
store64(buffer + sizeof(S->h[i]) * i, S->h[i]);
|
||||
|
||||
memcpy( out, buffer, outlen );
|
||||
return 0;
|
||||
memcpy(out, buffer, outlen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* inlen, at least, should be uint64_t. Others can be size_t. */
|
||||
int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen )
|
||||
{
|
||||
blake2b_state S[1];
|
||||
int blake2b(uint8_t *out, const void *in, const void *key, const uint8_t outlen,
|
||||
const uint64_t inlen, uint8_t keylen) {
|
||||
blake2b_state S[1];
|
||||
|
||||
/* Verify parameters */
|
||||
if ( NULL == in && inlen > 0 ) return -1;
|
||||
/* Verify parameters */
|
||||
if (NULL == in && inlen > 0)
|
||||
return -1;
|
||||
|
||||
if ( NULL == out ) return -1;
|
||||
if (NULL == out)
|
||||
return -1;
|
||||
|
||||
if( NULL == key && keylen > 0 ) return -1;
|
||||
if (NULL == key && keylen > 0)
|
||||
return -1;
|
||||
|
||||
if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;
|
||||
if (!outlen || outlen > BLAKE2B_OUTBYTES)
|
||||
return -1;
|
||||
|
||||
if( keylen > BLAKE2B_KEYBYTES ) return -1;
|
||||
if (keylen > BLAKE2B_KEYBYTES)
|
||||
return -1;
|
||||
|
||||
if( keylen > 0 )
|
||||
{
|
||||
if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( blake2b_init( S, outlen ) < 0 ) return -1;
|
||||
}
|
||||
if (keylen > 0) {
|
||||
if (blake2b_init_key(S, outlen, key, keylen) < 0)
|
||||
return -1;
|
||||
} else {
|
||||
if (blake2b_init(S, outlen) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
blake2b_update( S, ( const uint8_t * )in, inlen );
|
||||
blake2b_final( S, out, outlen );
|
||||
return 0;
|
||||
blake2b_update(S, (const uint8_t *)in, inlen);
|
||||
blake2b_final(S, out, outlen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Argon2 Team - Begin Code */
|
||||
int blake2b_long( uint8_t *out, const void *in, const uint32_t outlen, const uint64_t inlen )
|
||||
{
|
||||
blake2b_state blake_state;
|
||||
memset( &blake_state, 0, sizeof blake_state );
|
||||
int blake2b_long(uint8_t *out, const void *in, const uint32_t outlen,
|
||||
const uint64_t inlen) {
|
||||
blake2b_state blake_state;
|
||||
memset(&blake_state, 0, sizeof blake_state);
|
||||
|
||||
if ( outlen <= BLAKE2B_OUTBYTES )
|
||||
{
|
||||
blake2b_init( &blake_state, outlen );
|
||||
blake2b_update( &blake_state, ( const uint8_t * )&outlen, sizeof( uint32_t ) );
|
||||
blake2b_update( &blake_state, ( const uint8_t * )in, inlen );
|
||||
blake2b_final( &blake_state, out, outlen );
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t out_buffer[BLAKE2B_OUTBYTES];
|
||||
uint8_t in_buffer[BLAKE2B_OUTBYTES];
|
||||
blake2b_init( &blake_state, BLAKE2B_OUTBYTES );
|
||||
blake2b_update( &blake_state, ( const uint8_t * )&outlen, sizeof( uint32_t ) );
|
||||
blake2b_update( &blake_state, ( const uint8_t * )in, inlen );
|
||||
blake2b_final( &blake_state, out_buffer, BLAKE2B_OUTBYTES );
|
||||
memcpy( out, out_buffer, BLAKE2B_OUTBYTES / 2 );
|
||||
out += BLAKE2B_OUTBYTES / 2;
|
||||
uint32_t toproduce = outlen - BLAKE2B_OUTBYTES / 2;
|
||||
|
||||
while ( toproduce > BLAKE2B_OUTBYTES )
|
||||
{
|
||||
memcpy( in_buffer, out_buffer, BLAKE2B_OUTBYTES );
|
||||
blake2b( out_buffer, in_buffer, NULL, BLAKE2B_OUTBYTES, BLAKE2B_OUTBYTES, 0 );
|
||||
memcpy( out, out_buffer, BLAKE2B_OUTBYTES / 2 );
|
||||
out += BLAKE2B_OUTBYTES / 2;
|
||||
toproduce -= BLAKE2B_OUTBYTES / 2;
|
||||
}
|
||||
|
||||
memcpy( in_buffer, out_buffer, BLAKE2B_OUTBYTES );
|
||||
blake2b( out_buffer, in_buffer, NULL, toproduce, BLAKE2B_OUTBYTES, 0 );
|
||||
memcpy( out, out_buffer, toproduce );
|
||||
if (outlen <= BLAKE2B_OUTBYTES) {
|
||||
blake2b_init(&blake_state, outlen);
|
||||
blake2b_update(&blake_state, (const uint8_t *)&outlen, sizeof(uint32_t));
|
||||
blake2b_update(&blake_state, (const uint8_t *)in, inlen);
|
||||
blake2b_final(&blake_state, out, outlen);
|
||||
} else {
|
||||
uint8_t out_buffer[BLAKE2B_OUTBYTES];
|
||||
uint8_t in_buffer[BLAKE2B_OUTBYTES];
|
||||
blake2b_init(&blake_state, BLAKE2B_OUTBYTES);
|
||||
blake2b_update(&blake_state, (const uint8_t *)&outlen, sizeof(uint32_t));
|
||||
blake2b_update(&blake_state, (const uint8_t *)in, inlen);
|
||||
blake2b_final(&blake_state, out_buffer, BLAKE2B_OUTBYTES);
|
||||
memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2);
|
||||
out += BLAKE2B_OUTBYTES / 2;
|
||||
uint32_t toproduce = outlen - BLAKE2B_OUTBYTES / 2;
|
||||
|
||||
while (toproduce > BLAKE2B_OUTBYTES) {
|
||||
memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES);
|
||||
blake2b(out_buffer, in_buffer, NULL, BLAKE2B_OUTBYTES, BLAKE2B_OUTBYTES,
|
||||
0);
|
||||
memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2);
|
||||
out += BLAKE2B_OUTBYTES / 2;
|
||||
toproduce -= BLAKE2B_OUTBYTES / 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES);
|
||||
blake2b(out_buffer, in_buffer, NULL, toproduce, BLAKE2B_OUTBYTES, 0);
|
||||
memcpy(out, out_buffer, toproduce);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* Argon2 Team - End Code */
|
||||
|
|
|
@ -7,135 +7,141 @@
|
|||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
You should have received a copy of the CC0 Public Domain Dedication along
|
||||
with
|
||||
this software. If not, see
|
||||
<http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef __BLAKE2B_ROUND_H__
|
||||
#define __BLAKE2B_ROUND_H__
|
||||
|
||||
/* Argon2 Team - Begin Code */
|
||||
#define LOAD(p) _mm_load_si128( (const __m128i *)(p) )
|
||||
#define STORE(p,r) _mm_store_si128((__m128i *)(p), r)
|
||||
#define LOAD(p) _mm_load_si128((const __m128i *)(p))
|
||||
#define STORE(p, r) _mm_store_si128((__m128i *)(p), r)
|
||||
/* Argon2 Team - End Code */
|
||||
|
||||
#define LOADU(p) _mm_loadu_si128( (const __m128i *)(p) )
|
||||
#define STOREU(p,r) _mm_storeu_si128((__m128i *)(p), r)
|
||||
#define LOADU(p) _mm_loadu_si128((const __m128i *)(p))
|
||||
#define STOREU(p, r) _mm_storeu_si128((__m128i *)(p), r)
|
||||
|
||||
#define TOF(reg) _mm_castsi128_ps((reg))
|
||||
#define TOI(reg) _mm_castps_si128((reg))
|
||||
|
||||
#define LIKELY(x) __builtin_expect((x),1)
|
||||
|
||||
#define LIKELY(x) __builtin_expect((x), 1)
|
||||
|
||||
/* Microarchitecture-specific macros */
|
||||
#ifndef HAVE_XOP
|
||||
#ifdef HAVE_SSSE3
|
||||
#define _mm_roti_epi64(x, c) \
|
||||
(-(c) == 32) ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2,3,0,1)) \
|
||||
: (-(c) == 24) ? _mm_shuffle_epi8((x), r24) \
|
||||
: (-(c) == 16) ? _mm_shuffle_epi8((x), r16) \
|
||||
: (-(c) == 63) ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_add_epi64((x), (x))) \
|
||||
: _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_slli_epi64((x), 64-(-(c))))
|
||||
#define _mm_roti_epi64(x, c) \
|
||||
(-(c) == 32) \
|
||||
? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \
|
||||
: (-(c) == 24) \
|
||||
? _mm_shuffle_epi8((x), r24) \
|
||||
: (-(c) == 16) \
|
||||
? _mm_shuffle_epi8((x), r16) \
|
||||
: (-(c) == 63) \
|
||||
? _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
|
||||
_mm_add_epi64((x), (x))) \
|
||||
: _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
|
||||
_mm_slli_epi64((x), 64 - (-(c))))
|
||||
#else
|
||||
#define _mm_roti_epi64(r, c) _mm_xor_si128(_mm_srli_epi64( (r), -(c) ),_mm_slli_epi64( (r), 64-(-c) ))
|
||||
#define _mm_roti_epi64(r, c) \
|
||||
_mm_xor_si128(_mm_srli_epi64((r), -(c)), _mm_slli_epi64((r), 64 - (-c)))
|
||||
#endif
|
||||
#else
|
||||
/* ... */
|
||||
#endif
|
||||
|
||||
#define G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1) \
|
||||
row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \
|
||||
row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \
|
||||
\
|
||||
row4l = _mm_xor_si128(row4l, row1l); \
|
||||
row4h = _mm_xor_si128(row4h, row1h); \
|
||||
\
|
||||
row4l = _mm_roti_epi64(row4l, -32); \
|
||||
row4h = _mm_roti_epi64(row4h, -32); \
|
||||
\
|
||||
row3l = _mm_add_epi64(row3l, row4l); \
|
||||
row3h = _mm_add_epi64(row3h, row4h); \
|
||||
\
|
||||
row2l = _mm_xor_si128(row2l, row3l); \
|
||||
row2h = _mm_xor_si128(row2h, row3h); \
|
||||
\
|
||||
row2l = _mm_roti_epi64(row2l, -24); \
|
||||
row2h = _mm_roti_epi64(row2h, -24);
|
||||
|
||||
|
||||
#define G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \
|
||||
row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \
|
||||
row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \
|
||||
\
|
||||
row4l = _mm_xor_si128(row4l, row1l); \
|
||||
row4h = _mm_xor_si128(row4h, row1h); \
|
||||
\
|
||||
row4l = _mm_roti_epi64(row4l, -32); \
|
||||
row4h = _mm_roti_epi64(row4h, -32); \
|
||||
\
|
||||
row3l = _mm_add_epi64(row3l, row4l); \
|
||||
row3h = _mm_add_epi64(row3h, row4h); \
|
||||
\
|
||||
row2l = _mm_xor_si128(row2l, row3l); \
|
||||
row2h = _mm_xor_si128(row2h, row3h); \
|
||||
\
|
||||
row2l = _mm_roti_epi64(row2l, -24); \
|
||||
row2h = _mm_roti_epi64(row2h, -24); \
|
||||
|
||||
#define G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \
|
||||
row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \
|
||||
row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \
|
||||
\
|
||||
row4l = _mm_xor_si128(row4l, row1l); \
|
||||
row4h = _mm_xor_si128(row4h, row1h); \
|
||||
\
|
||||
row4l = _mm_roti_epi64(row4l, -16); \
|
||||
row4h = _mm_roti_epi64(row4h, -16); \
|
||||
\
|
||||
row3l = _mm_add_epi64(row3l, row4l); \
|
||||
row3h = _mm_add_epi64(row3h, row4h); \
|
||||
\
|
||||
row2l = _mm_xor_si128(row2l, row3l); \
|
||||
row2h = _mm_xor_si128(row2h, row3h); \
|
||||
\
|
||||
row2l = _mm_roti_epi64(row2l, -63); \
|
||||
row2h = _mm_roti_epi64(row2h, -63); \
|
||||
#define G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1) \
|
||||
row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \
|
||||
row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \
|
||||
\
|
||||
row4l = _mm_xor_si128(row4l, row1l); \
|
||||
row4h = _mm_xor_si128(row4h, row1h); \
|
||||
\
|
||||
row4l = _mm_roti_epi64(row4l, -16); \
|
||||
row4h = _mm_roti_epi64(row4h, -16); \
|
||||
\
|
||||
row3l = _mm_add_epi64(row3l, row4l); \
|
||||
row3h = _mm_add_epi64(row3h, row4h); \
|
||||
\
|
||||
row2l = _mm_xor_si128(row2l, row3l); \
|
||||
row2h = _mm_xor_si128(row2h, row3h); \
|
||||
\
|
||||
row2l = _mm_roti_epi64(row2l, -63); \
|
||||
row2h = _mm_roti_epi64(row2h, -63);
|
||||
|
||||
#if defined(HAVE_SSSE3)
|
||||
#define DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
|
||||
t0 = _mm_alignr_epi8(row2h, row2l, 8); \
|
||||
t1 = _mm_alignr_epi8(row2l, row2h, 8); \
|
||||
row2l = t0; \
|
||||
row2h = t1; \
|
||||
\
|
||||
t0 = row3l; \
|
||||
row3l = row3h; \
|
||||
row3h = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(row4h, row4l, 8); \
|
||||
t1 = _mm_alignr_epi8(row4l, row4h, 8); \
|
||||
row4l = t1; \
|
||||
#define DIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \
|
||||
t0 = _mm_alignr_epi8(row2h, row2l, 8); \
|
||||
t1 = _mm_alignr_epi8(row2l, row2h, 8); \
|
||||
row2l = t0; \
|
||||
row2h = t1; \
|
||||
\
|
||||
t0 = row3l; \
|
||||
row3l = row3h; \
|
||||
row3h = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(row4h, row4l, 8); \
|
||||
t1 = _mm_alignr_epi8(row4l, row4h, 8); \
|
||||
row4l = t1; \
|
||||
row4h = t0;
|
||||
|
||||
#define UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
|
||||
t0 = _mm_alignr_epi8(row2l, row2h, 8); \
|
||||
t1 = _mm_alignr_epi8(row2h, row2l, 8); \
|
||||
row2l = t0; \
|
||||
row2h = t1; \
|
||||
\
|
||||
t0 = row3l; \
|
||||
row3l = row3h; \
|
||||
row3h = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(row4l, row4h, 8); \
|
||||
t1 = _mm_alignr_epi8(row4h, row4l, 8); \
|
||||
row4l = t1; \
|
||||
#define UNDIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \
|
||||
t0 = _mm_alignr_epi8(row2l, row2h, 8); \
|
||||
t1 = _mm_alignr_epi8(row2h, row2l, 8); \
|
||||
row2l = t0; \
|
||||
row2h = t1; \
|
||||
\
|
||||
t0 = row3l; \
|
||||
row3l = row3h; \
|
||||
row3h = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(row4l, row4h, 8); \
|
||||
t1 = _mm_alignr_epi8(row4h, row4l, 8); \
|
||||
row4l = t1; \
|
||||
row4h = t0;
|
||||
#else
|
||||
|
||||
#define DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
|
||||
t0 = row4l;\
|
||||
t1 = row2l;\
|
||||
row4l = row3l;\
|
||||
row3l = row3h;\
|
||||
row3h = row4l;\
|
||||
row4l = _mm_unpackhi_epi64(row4h, _mm_unpacklo_epi64(t0, t0)); \
|
||||
row4h = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(row4h, row4h)); \
|
||||
row2l = _mm_unpackhi_epi64(row2l, _mm_unpacklo_epi64(row2h, row2h)); \
|
||||
#define DIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \
|
||||
t0 = row4l; \
|
||||
t1 = row2l; \
|
||||
row4l = row3l; \
|
||||
row3l = row3h; \
|
||||
row3h = row4l; \
|
||||
row4l = _mm_unpackhi_epi64(row4h, _mm_unpacklo_epi64(t0, t0)); \
|
||||
row4h = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(row4h, row4h)); \
|
||||
row2l = _mm_unpackhi_epi64(row2l, _mm_unpacklo_epi64(row2h, row2h)); \
|
||||
row2h = _mm_unpackhi_epi64(row2h, _mm_unpacklo_epi64(t1, t1))
|
||||
|
||||
#define UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
|
||||
t0 = row3l;\
|
||||
row3l = row3h;\
|
||||
row3h = t0;\
|
||||
t0 = row2l;\
|
||||
t1 = row4l;\
|
||||
row2l = _mm_unpackhi_epi64(row2h, _mm_unpacklo_epi64(row2l, row2l)); \
|
||||
row2h = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(row2h, row2h)); \
|
||||
row4l = _mm_unpackhi_epi64(row4l, _mm_unpacklo_epi64(row4h, row4h)); \
|
||||
#define UNDIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \
|
||||
t0 = row3l; \
|
||||
row3l = row3h; \
|
||||
row3h = t0; \
|
||||
t0 = row2l; \
|
||||
t1 = row4l; \
|
||||
row2l = _mm_unpackhi_epi64(row2h, _mm_unpacklo_epi64(row2l, row2l)); \
|
||||
row2h = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(row2h, row2h)); \
|
||||
row4l = _mm_unpackhi_epi64(row4l, _mm_unpacklo_epi64(row4h, row4h)); \
|
||||
row4h = _mm_unpackhi_epi64(row4h, _mm_unpacklo_epi64(t1, t1))
|
||||
|
||||
#endif
|
||||
|
@ -146,27 +152,27 @@
|
|||
#include "blake2b-load-sse2.h"
|
||||
#endif
|
||||
|
||||
#define ROUND(r) \
|
||||
LOAD_MSG_ ##r ##_1(b0, b1); \
|
||||
G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \
|
||||
LOAD_MSG_ ##r ##_2(b0, b1); \
|
||||
G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \
|
||||
DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \
|
||||
LOAD_MSG_ ##r ##_3(b0, b1); \
|
||||
G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \
|
||||
LOAD_MSG_ ##r ##_4(b0, b1); \
|
||||
G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \
|
||||
UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h);
|
||||
#define ROUND(r) \
|
||||
LOAD_MSG_##r##_1(b0, b1); \
|
||||
G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \
|
||||
LOAD_MSG_##r##_2(b0, b1); \
|
||||
G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \
|
||||
DIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
LOAD_MSG_##r##_3(b0, b1); \
|
||||
G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \
|
||||
LOAD_MSG_##r##_4(b0, b1); \
|
||||
G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \
|
||||
UNDIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h);
|
||||
|
||||
#endif
|
||||
|
||||
#define BLAKE2_ROUND(row1l,row1h,row2l,row2h,row3l,row3h,row4l,row4h) \
|
||||
G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
\
|
||||
DIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
\
|
||||
G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
\
|
||||
UNDIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h);
|
||||
#define BLAKE2_ROUND(row1l, row1h, row2l, row2h, row3l, row3h, row4l, row4h) \
|
||||
G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
\
|
||||
DIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
\
|
||||
G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
\
|
||||
UNDIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h);
|
||||
|
|
|
@ -1,92 +1,96 @@
|
|||
#define _mm_roti_epi64(x, c) \
|
||||
(-(c) == 32) ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2,3,0,1)) \
|
||||
: (-(c) == 24) ? _mm_shuffle_epi8((x), r24) \
|
||||
: (-(c) == 16) ? _mm_shuffle_epi8((x), r16) \
|
||||
: (-(c) == 63) ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_add_epi64((x), (x))) \
|
||||
: _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_slli_epi64((x), 64-(-(c))))
|
||||
#define _mm_roti_epi64(x, c) \
|
||||
(-(c) == 32) \
|
||||
? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \
|
||||
: (-(c) == 24) \
|
||||
? _mm_shuffle_epi8((x), r24) \
|
||||
: (-(c) == 16) \
|
||||
? _mm_shuffle_epi8((x), r16) \
|
||||
: (-(c) == 63) \
|
||||
? _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
|
||||
_mm_add_epi64((x), (x))) \
|
||||
: _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
|
||||
_mm_slli_epi64((x), 64 - (-(c))))
|
||||
|
||||
static inline __m128i fBlaMka( __m128i x, __m128i y )
|
||||
{
|
||||
const __m128i z = _mm_mul_epu32 ( x, y );
|
||||
return _mm_add_epi64(_mm_add_epi64(x, y), _mm_add_epi64(z, z));
|
||||
static inline __m128i fBlaMka(__m128i x, __m128i y) {
|
||||
const __m128i z = _mm_mul_epu32(x, y);
|
||||
return _mm_add_epi64(_mm_add_epi64(x, y), _mm_add_epi64(z, z));
|
||||
}
|
||||
|
||||
#define G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
|
||||
row1l = fBlaMka(row1l, row2l); \
|
||||
row1h = fBlaMka(row1h, row2h); \
|
||||
\
|
||||
row4l = _mm_xor_si128(row4l, row1l); \
|
||||
row4h = _mm_xor_si128(row4h, row1h); \
|
||||
\
|
||||
row4l = _mm_roti_epi64(row4l, -32); \
|
||||
row4h = _mm_roti_epi64(row4h, -32); \
|
||||
\
|
||||
row3l = fBlaMka(row3l, row4l); \
|
||||
row3h = fBlaMka(row3h, row4h); \
|
||||
\
|
||||
row2l = _mm_xor_si128(row2l, row3l); \
|
||||
row2h = _mm_xor_si128(row2h, row3h); \
|
||||
\
|
||||
row2l = _mm_roti_epi64(row2l, -24); \
|
||||
row2h = _mm_roti_epi64(row2h, -24); \
|
||||
#define G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \
|
||||
row1l = fBlaMka(row1l, row2l); \
|
||||
row1h = fBlaMka(row1h, row2h); \
|
||||
\
|
||||
row4l = _mm_xor_si128(row4l, row1l); \
|
||||
row4h = _mm_xor_si128(row4h, row1h); \
|
||||
\
|
||||
row4l = _mm_roti_epi64(row4l, -32); \
|
||||
row4h = _mm_roti_epi64(row4h, -32); \
|
||||
\
|
||||
row3l = fBlaMka(row3l, row4l); \
|
||||
row3h = fBlaMka(row3h, row4h); \
|
||||
\
|
||||
row2l = _mm_xor_si128(row2l, row3l); \
|
||||
row2h = _mm_xor_si128(row2h, row3h); \
|
||||
\
|
||||
row2l = _mm_roti_epi64(row2l, -24); \
|
||||
row2h = _mm_roti_epi64(row2h, -24);
|
||||
|
||||
#define G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
|
||||
row1l = fBlaMka(row1l, row2l); \
|
||||
row1h = fBlaMka(row1h, row2h); \
|
||||
\
|
||||
row4l = _mm_xor_si128(row4l, row1l); \
|
||||
row4h = _mm_xor_si128(row4h, row1h); \
|
||||
\
|
||||
row4l = _mm_roti_epi64(row4l, -16); \
|
||||
row4h = _mm_roti_epi64(row4h, -16); \
|
||||
\
|
||||
row3l = fBlaMka(row3l, row4l); \
|
||||
row3h = fBlaMka(row3h, row4h); \
|
||||
\
|
||||
row2l = _mm_xor_si128(row2l, row3l); \
|
||||
row2h = _mm_xor_si128(row2h, row3h); \
|
||||
\
|
||||
row2l = _mm_roti_epi64(row2l, -63); \
|
||||
row2h = _mm_roti_epi64(row2h, -63); \
|
||||
#define G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \
|
||||
row1l = fBlaMka(row1l, row2l); \
|
||||
row1h = fBlaMka(row1h, row2h); \
|
||||
\
|
||||
row4l = _mm_xor_si128(row4l, row1l); \
|
||||
row4h = _mm_xor_si128(row4h, row1h); \
|
||||
\
|
||||
row4l = _mm_roti_epi64(row4l, -16); \
|
||||
row4h = _mm_roti_epi64(row4h, -16); \
|
||||
\
|
||||
row3l = fBlaMka(row3l, row4l); \
|
||||
row3h = fBlaMka(row3h, row4h); \
|
||||
\
|
||||
row2l = _mm_xor_si128(row2l, row3l); \
|
||||
row2h = _mm_xor_si128(row2h, row3h); \
|
||||
\
|
||||
row2l = _mm_roti_epi64(row2l, -63); \
|
||||
row2h = _mm_roti_epi64(row2h, -63);
|
||||
|
||||
#define DIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \
|
||||
t0 = _mm_alignr_epi8(row2h, row2l, 8); \
|
||||
t1 = _mm_alignr_epi8(row2l, row2h, 8); \
|
||||
row2l = t0; \
|
||||
row2h = t1; \
|
||||
\
|
||||
t0 = row3l; \
|
||||
row3l = row3h; \
|
||||
row3h = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(row4h, row4l, 8); \
|
||||
t1 = _mm_alignr_epi8(row4l, row4h, 8); \
|
||||
row4l = t1; \
|
||||
row4h = t0;
|
||||
|
||||
#define DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
|
||||
t0 = _mm_alignr_epi8(row2h, row2l, 8); \
|
||||
t1 = _mm_alignr_epi8(row2l, row2h, 8); \
|
||||
row2l = t0; \
|
||||
row2h = t1; \
|
||||
\
|
||||
t0 = row3l; \
|
||||
row3l = row3h; \
|
||||
row3h = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(row4h, row4l, 8); \
|
||||
t1 = _mm_alignr_epi8(row4l, row4h, 8); \
|
||||
row4l = t1; \
|
||||
row4h = t0;
|
||||
#define UNDIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \
|
||||
t0 = _mm_alignr_epi8(row2l, row2h, 8); \
|
||||
t1 = _mm_alignr_epi8(row2h, row2l, 8); \
|
||||
row2l = t0; \
|
||||
row2h = t1; \
|
||||
\
|
||||
t0 = row3l; \
|
||||
row3l = row3h; \
|
||||
row3h = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(row4l, row4h, 8); \
|
||||
t1 = _mm_alignr_epi8(row4h, row4l, 8); \
|
||||
row4l = t1; \
|
||||
row4h = t0;
|
||||
|
||||
#define UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
|
||||
t0 = _mm_alignr_epi8(row2l, row2h, 8); \
|
||||
t1 = _mm_alignr_epi8(row2h, row2l, 8); \
|
||||
row2l = t0; \
|
||||
row2h = t1; \
|
||||
\
|
||||
t0 = row3l; \
|
||||
row3l = row3h; \
|
||||
row3h = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(row4l, row4h, 8); \
|
||||
t1 = _mm_alignr_epi8(row4h, row4l, 8); \
|
||||
row4l = t1; \
|
||||
row4h = t0;
|
||||
|
||||
#define BLAKE2_ROUND(row1l,row1h,row2l,row2h,row3l,row3h,row4l,row4h) \
|
||||
G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \
|
||||
G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \
|
||||
\
|
||||
DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \
|
||||
\
|
||||
G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \
|
||||
G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \
|
||||
\
|
||||
UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h);
|
||||
#define BLAKE2_ROUND(row1l, row1h, row2l, row2h, row3l, row3h, row4l, row4h) \
|
||||
G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
\
|
||||
DIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
\
|
||||
G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
\
|
||||
UNDIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h);
|
||||
|
|
|
@ -3,42 +3,39 @@
|
|||
#ifndef __BLAKE_ROUND_MKA_H__
|
||||
#define __BLAKE_ROUND_MKA_H__
|
||||
|
||||
#define G(a, b, c, d) \
|
||||
a = fBlaMka(a, b); \
|
||||
d = rotr64(d ^ a, 32); \
|
||||
c = fBlaMka(c, d); \
|
||||
b = rotr64(b ^ c, 24); \
|
||||
a = fBlaMka(a, b); \
|
||||
d = rotr64(d ^ a, 16); \
|
||||
c = fBlaMka(c, d); \
|
||||
b = rotr64(b ^ c, 63);
|
||||
|
||||
#define G(a,b,c,d) \
|
||||
a = fBlaMka(a, b) ; \
|
||||
d = rotr64(d ^ a, 32); \
|
||||
c = fBlaMka(c, d); \
|
||||
b = rotr64(b ^ c, 24); \
|
||||
a = fBlaMka(a, b) ; \
|
||||
d = rotr64(d ^ a, 16); \
|
||||
c = fBlaMka(c, d); \
|
||||
b = rotr64(b ^ c, 63);
|
||||
|
||||
#define BLAKE2_ROUND_NOMSG(v0,v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15) \
|
||||
G(v0, v4, v8, v12); \
|
||||
G(v1, v5, v9, v13); \
|
||||
G(v2, v6, v10, v14); \
|
||||
G(v3, v7, v11, v15); \
|
||||
G(v0, v5, v10, v15); \
|
||||
G(v1, v6, v11, v12); \
|
||||
G(v2, v7, v8, v13); \
|
||||
G(v3, v4, v9, v14);
|
||||
|
||||
#define BLAKE2_ROUND_NOMSG(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, \
|
||||
v12, v13, v14, v15) \
|
||||
G(v0, v4, v8, v12); \
|
||||
G(v1, v5, v9, v13); \
|
||||
G(v2, v6, v10, v14); \
|
||||
G(v3, v7, v11, v15); \
|
||||
G(v0, v5, v10, v15); \
|
||||
G(v1, v6, v11, v12); \
|
||||
G(v2, v7, v8, v13); \
|
||||
G(v3, v4, v9, v14);
|
||||
|
||||
/*designed by the Lyra PHC team */
|
||||
static __inline uint64_t fBlaMka( uint64_t x, uint64_t y )
|
||||
{
|
||||
uint32_t lessX = ( uint32_t )x;
|
||||
uint32_t lessY = ( uint32_t )y;
|
||||
static __inline uint64_t fBlaMka(uint64_t x, uint64_t y) {
|
||||
uint32_t lessX = (uint32_t)x;
|
||||
uint32_t lessY = (uint32_t)y;
|
||||
|
||||
uint64_t lessZ = ( uint64_t )lessX;
|
||||
lessZ = lessZ * lessY;
|
||||
lessZ = lessZ << 1;
|
||||
uint64_t lessZ = (uint64_t)lessX;
|
||||
lessZ = lessZ * lessY;
|
||||
lessZ = lessZ << 1;
|
||||
|
||||
uint64_t z = lessZ + x + y;
|
||||
uint64_t z = lessZ + x + y;
|
||||
|
||||
return z;
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -29,25 +29,25 @@
|
|||
#ifndef _BRG_ENDIAN_H
|
||||
#define _BRG_ENDIAN_H
|
||||
|
||||
#define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
|
||||
#define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
|
||||
#define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
|
||||
#define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
|
||||
|
||||
#if 0
|
||||
/* Include files where endian defines and byteswap functions may reside */
|
||||
#if defined( __sun )
|
||||
# include <sys/isa_defs.h>
|
||||
#elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ )
|
||||
# include <sys/endian.h>
|
||||
#elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \
|
||||
defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ )
|
||||
# include <machine/endian.h>
|
||||
#elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ )
|
||||
# if !defined( __MINGW32__ ) && !defined( _AIX )
|
||||
# include <endian.h>
|
||||
# if !defined( __BEOS__ )
|
||||
# include <byteswap.h>
|
||||
# endif
|
||||
# endif
|
||||
#if defined(__sun)
|
||||
#include <sys/isa_defs.h>
|
||||
#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
#include <sys/endian.h>
|
||||
#elif defined(BSD) && (BSD >= 199103) || defined(__APPLE__) || \
|
||||
defined(__CYGWIN32__) || defined(__DJGPP__) || defined(__osf__)
|
||||
#include <machine/endian.h>
|
||||
#elif defined(__linux__) || defined(__GNUC__) || defined(__GNU_LIBRARY__)
|
||||
#if !defined(__MINGW32__) && !defined(_AIX)
|
||||
#include <endian.h>
|
||||
#if !defined(__BEOS__)
|
||||
#include <byteswap.h>
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -55,89 +55,88 @@
|
|||
/* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, which */
|
||||
/* seem to encompass most endian symbol definitions */
|
||||
|
||||
#if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN )
|
||||
# if defined( BYTE_ORDER ) && BYTE_ORDER == BIG_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
# elif defined( BYTE_ORDER ) && BYTE_ORDER == LITTLE_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
# endif
|
||||
#elif defined( BIG_ENDIAN )
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined( LITTLE_ENDIAN )
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#if defined(BIG_ENDIAN) && defined(LITTLE_ENDIAN)
|
||||
#if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN
|
||||
#define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN
|
||||
#define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
#elif defined(BIG_ENDIAN)
|
||||
#define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined(LITTLE_ENDIAN)
|
||||
#define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#if defined( _BIG_ENDIAN ) && defined( _LITTLE_ENDIAN )
|
||||
# if defined( _BYTE_ORDER ) && _BYTE_ORDER == _BIG_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
# elif defined( _BYTE_ORDER ) && _BYTE_ORDER == _LITTLE_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
# endif
|
||||
#elif defined( _BIG_ENDIAN )
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined( _LITTLE_ENDIAN )
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#if defined(_BIG_ENDIAN) && defined(_LITTLE_ENDIAN)
|
||||
#if defined(_BYTE_ORDER) && _BYTE_ORDER == _BIG_ENDIAN
|
||||
#define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined(_BYTE_ORDER) && _BYTE_ORDER == _LITTLE_ENDIAN
|
||||
#define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
#elif defined(_BIG_ENDIAN)
|
||||
#define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined(_LITTLE_ENDIAN)
|
||||
#define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#if defined( __BIG_ENDIAN ) && defined( __LITTLE_ENDIAN )
|
||||
# if defined( __BYTE_ORDER ) && __BYTE_ORDER == __BIG_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
# elif defined( __BYTE_ORDER ) && __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
# endif
|
||||
#elif defined( __BIG_ENDIAN )
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined( __LITTLE_ENDIAN )
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#if defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN)
|
||||
#if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
#elif defined(__BIG_ENDIAN)
|
||||
#define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined(__LITTLE_ENDIAN)
|
||||
#define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#if defined( __BIG_ENDIAN__ ) && defined( __LITTLE_ENDIAN__ )
|
||||
# if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __BIG_ENDIAN__
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
# elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __LITTLE_ENDIAN__
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
# endif
|
||||
#elif defined( __BIG_ENDIAN__ )
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined( __LITTLE_ENDIAN__ )
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#if defined(__BIG_ENDIAN__) && defined(__LITTLE_ENDIAN__)
|
||||
#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __BIG_ENDIAN__
|
||||
#define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __LITTLE_ENDIAN__
|
||||
#define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
#elif defined(__BIG_ENDIAN__)
|
||||
#define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined(__LITTLE_ENDIAN__)
|
||||
#define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
/* if the platform byte order could not be determined, then try to */
|
||||
/* set this define using common machine defines */
|
||||
#if !defined(PLATFORM_BYTE_ORDER)
|
||||
|
||||
#if defined( __alpha__ ) || defined( __alpha ) || defined( i386 ) || \
|
||||
defined( __i386__ ) || defined( _M_I86 ) || defined( _M_IX86 ) || \
|
||||
defined( __OS2__ ) || defined( sun386 ) || defined( __TURBOC__ ) || \
|
||||
defined( vax ) || defined( vms ) || defined( VMS ) || \
|
||||
defined( __VMS ) || defined( _M_X64 )
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#if defined(__alpha__) || defined(__alpha) || defined(i386) || \
|
||||
defined(__i386__) || defined(_M_I86) || defined(_M_IX86) || \
|
||||
defined(__OS2__) || defined(sun386) || defined(__TURBOC__) || \
|
||||
defined(vax) || defined(vms) || defined(VMS) || defined(__VMS) || \
|
||||
defined(_M_X64)
|
||||
#define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
|
||||
#elif defined( AMIGA ) || defined( applec ) || defined( __AS400__ ) || \
|
||||
defined( _CRAY ) || defined( __hppa ) || defined( __hp9000 ) || \
|
||||
defined( ibm370 ) || defined( mc68000 ) || defined( m68k ) || \
|
||||
defined( __MRC__ ) || defined( __MVS__ ) || defined( __MWERKS__ ) || \
|
||||
defined( sparc ) || defined( __sparc) || defined( SYMANTEC_C ) || \
|
||||
defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM ) || \
|
||||
defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX )
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined(AMIGA) || defined(applec) || defined(__AS400__) || \
|
||||
defined(_CRAY) || defined(__hppa) || defined(__hp9000) || \
|
||||
defined(ibm370) || defined(mc68000) || defined(m68k) || \
|
||||
defined(__MRC__) || defined(__MVS__) || defined(__MWERKS__) || \
|
||||
defined(sparc) || defined(__sparc) || defined(SYMANTEC_C) || \
|
||||
defined(__VOS__) || defined(__TIGCC__) || defined(__TANDEM) || \
|
||||
defined(THINK_C) || defined(__VMCMS__) || defined(_AIX)
|
||||
#define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
|
||||
#elif defined(__arm__)
|
||||
# ifdef __BIG_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
# else
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
# endif
|
||||
#elif 1 /* **** EDIT HERE IF NECESSARY **** */
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#elif 0 /* **** EDIT HERE IF NECESSARY **** */
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#ifdef __BIG_ENDIAN
|
||||
#define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#else
|
||||
# error Please edit lines 132 or 134 in brg_endian.h to set the platform byte order
|
||||
#define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
#elif 1 /* **** EDIT HERE IF NECESSARY **** */
|
||||
#define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#elif 0 /* **** EDIT HERE IF NECESSARY **** */
|
||||
#define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#else
|
||||
#error Please edit lines 132 or 134 in brg_endian.h to set the platform byte order
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
964
src/core.c
964
src/core.c
|
@ -5,11 +5,12 @@
|
|||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
* this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
|
||||
/*For memory wiping*/
|
||||
#ifdef _MSC_VER
|
||||
#include "windows.h"
|
||||
|
@ -18,8 +19,7 @@
|
|||
#if defined __STDC_LIB_EXT1__
|
||||
#define __STDC_WANT_LIB_EXT1__ 1
|
||||
#endif
|
||||
#define VC_GE_2005( version ) ( version >= 1400 )
|
||||
|
||||
#define VC_GE_2005(version) (version >= 1400)
|
||||
|
||||
#include <inttypes.h>
|
||||
#ifndef _MSC_VER
|
||||
|
@ -33,7 +33,6 @@
|
|||
#include "core.h"
|
||||
#include "kat.h"
|
||||
|
||||
|
||||
#include "blake2/blake2.h"
|
||||
#include "blake2/blake2-impl.h"
|
||||
|
||||
|
@ -42,9 +41,8 @@
|
|||
#define NOT_OPTIMIZED __attribute__((optnone))
|
||||
#endif
|
||||
#elif defined(__GNUC__)
|
||||
#define GCC_VERSION (__GNUC__ * 10000 \
|
||||
+ __GNUC_MINOR__ * 100 \
|
||||
+ __GNUC_PATCHLEVEL__)
|
||||
#define GCC_VERSION \
|
||||
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
||||
#if GCC_VERSION >= 40400
|
||||
#define NOT_OPTIMIZED __attribute__((optimize("O0")))
|
||||
#endif
|
||||
|
@ -54,48 +52,37 @@
|
|||
#endif
|
||||
|
||||
/***************Instance and Position constructors**********/
|
||||
void init_block_value( block *b, uint8_t in )
|
||||
{
|
||||
memset( b->v,in,sizeof( b->v ) );
|
||||
void init_block_value(block *b, uint8_t in) { memset(b->v, in, sizeof(b->v)); }
|
||||
|
||||
void copy_block(block *dst, const block *src) {
|
||||
memcpy(dst->v, src->v, sizeof(uint64_t) * ARGON2_WORDS_IN_BLOCK);
|
||||
}
|
||||
|
||||
void copy_block( block *dst, const block *src )
|
||||
{
|
||||
memcpy( dst->v,src->v,sizeof( uint64_t )*ARGON2_WORDS_IN_BLOCK );
|
||||
void xor_block(block *dst, const block *src) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARGON2_WORDS_IN_BLOCK; ++i) {
|
||||
dst->v[i] ^= src->v[i];
|
||||
}
|
||||
}
|
||||
|
||||
void xor_block( block *dst, const block *src )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i=0; i<ARGON2_WORDS_IN_BLOCK; ++i )
|
||||
{
|
||||
dst->v[i] ^= src->v[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************Memory allocators*****************/
|
||||
int allocate_memory( block **memory, uint32_t m_cost )
|
||||
{
|
||||
if ( memory != NULL )
|
||||
{
|
||||
size_t memory_size = sizeof( block )*m_cost;
|
||||
if(m_cost != 0 && memory_size / m_cost != sizeof(block))
|
||||
{
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
|
||||
*memory = ( block * )malloc( memory_size );
|
||||
|
||||
if ( !*memory )
|
||||
{
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
|
||||
return ARGON2_OK;
|
||||
int allocate_memory(block **memory, uint32_t m_cost) {
|
||||
if (memory != NULL) {
|
||||
size_t memory_size = sizeof(block) * m_cost;
|
||||
if (m_cost != 0 && memory_size / m_cost != sizeof(block)) {
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
else return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
|
||||
*memory = (block *)malloc(memory_size);
|
||||
|
||||
if (!*memory) {
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
|
||||
return ARGON2_OK;
|
||||
} else
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
|
||||
/* Function that securely cleans the memory
|
||||
|
@ -103,587 +90,522 @@ int allocate_memory( block **memory, uint32_t m_cost )
|
|||
* @param s Memory size in bytes
|
||||
*/
|
||||
|
||||
static __inline void NOT_OPTIMIZED secure_wipe_memory( void *v, size_t n )
|
||||
{
|
||||
#if defined (_MSC_VER ) && VC_GE_2005( _MSC_VER )
|
||||
SecureZeroMemory( v, n );
|
||||
static __inline void NOT_OPTIMIZED secure_wipe_memory(void *v, size_t n) {
|
||||
#if defined(_MSC_VER) && VC_GE_2005(_MSC_VER)
|
||||
SecureZeroMemory(v, n);
|
||||
#elif defined memset_s
|
||||
memset_s( v, n );
|
||||
#elif defined( __OpenBSD__ )
|
||||
explicit_bzero( memory, size );
|
||||
memset_s(v, n);
|
||||
#elif defined(__OpenBSD__)
|
||||
explicit_bzero(memory, size);
|
||||
#else
|
||||
static void *( *const volatile memset_sec )( void *, int, size_t ) = &memset;
|
||||
memset_sec( v, 0, n );
|
||||
static void *(*const volatile memset_sec)(void *, int, size_t) = &memset;
|
||||
memset_sec(v, 0, n);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*************************Argon2 internal constants**************************************************/
|
||||
/*************************Argon2 internal
|
||||
* constants**************************************************/
|
||||
|
||||
/* Version of the algorithm */
|
||||
const uint32_t ARGON2_VERSION_NUMBER = 0x10;
|
||||
|
||||
/* Memory block size in bytes */
|
||||
#define ARGON2_BLOCK_SIZE 1024
|
||||
#define ARGON2_WORDS_IN_BLOCK (ARGON2_BLOCK_SIZE/8)
|
||||
#define ARGON2_BLOCK_SIZE 1024
|
||||
#define ARGON2_WORDS_IN_BLOCK (ARGON2_BLOCK_SIZE / 8)
|
||||
const uint32_t ARGON2_QWORDS_IN_BLOCK = 64; /*Dependent values!*/
|
||||
|
||||
/* Number of pseudo-random values generated by one call to Blake in Argon2i to generate reference block positions*/
|
||||
/* Number of pseudo-random values generated by one call to Blake in Argon2i to
|
||||
* generate reference block positions*/
|
||||
const uint32_t ARGON2_ADDRESSES_IN_BLOCK = 128;
|
||||
|
||||
|
||||
|
||||
/*********Memory functions*/
|
||||
|
||||
void clear_memory( Argon2_instance_t *instance, bool clear )
|
||||
{
|
||||
if ( instance->memory != NULL && clear )
|
||||
{
|
||||
secure_wipe_memory( instance->memory, sizeof ( block ) * instance->memory_blocks );
|
||||
}
|
||||
void clear_memory(Argon2_instance_t *instance, bool clear) {
|
||||
if (instance->memory != NULL && clear) {
|
||||
secure_wipe_memory(instance->memory,
|
||||
sizeof(block) * instance->memory_blocks);
|
||||
}
|
||||
}
|
||||
|
||||
void free_memory( block *memory )
|
||||
{
|
||||
if ( memory != NULL )
|
||||
{
|
||||
free( memory );
|
||||
}
|
||||
void free_memory(block *memory) {
|
||||
if (memory != NULL) {
|
||||
free(memory);
|
||||
}
|
||||
}
|
||||
|
||||
void finalize( const Argon2_Context *context, Argon2_instance_t *instance )
|
||||
{
|
||||
if ( context != NULL && instance != NULL )
|
||||
{
|
||||
block blockhash;
|
||||
copy_block( &blockhash, instance->memory+ instance->lane_length - 1 );
|
||||
|
||||
// XOR the last blocks
|
||||
for ( uint32_t l = 1; l < instance->lanes; ++l )
|
||||
{
|
||||
uint32_t last_block_in_lane = l * instance->lane_length + ( instance->lane_length - 1 );
|
||||
xor_block( &blockhash,instance->memory + last_block_in_lane );
|
||||
|
||||
}
|
||||
|
||||
// Hash the result
|
||||
blake2b_long( context->out, ( uint8_t * ) blockhash.v, context->outlen, ARGON2_BLOCK_SIZE );
|
||||
secure_wipe_memory( blockhash.v, ARGON2_BLOCK_SIZE ); //clear the blockhash
|
||||
|
||||
if( context->print ) //Shall we print the output tag?
|
||||
{
|
||||
print_tag( context->out, context->outlen );
|
||||
}
|
||||
|
||||
// Clear memory
|
||||
clear_memory( instance, context->clear_memory );
|
||||
|
||||
// Deallocate the memory
|
||||
if ( NULL != context->free_cbk )
|
||||
{
|
||||
context->free_cbk( ( uint8_t * ) instance->memory, instance->memory_blocks * sizeof ( block ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
free_memory( instance->memory );
|
||||
}
|
||||
void finalize(const Argon2_Context *context, Argon2_instance_t *instance) {
|
||||
if (context != NULL && instance != NULL) {
|
||||
block blockhash;
|
||||
copy_block(&blockhash, instance->memory + instance->lane_length - 1);
|
||||
|
||||
// XOR the last blocks
|
||||
for (uint32_t l = 1; l < instance->lanes; ++l) {
|
||||
uint32_t last_block_in_lane =
|
||||
l * instance->lane_length + (instance->lane_length - 1);
|
||||
xor_block(&blockhash, instance->memory + last_block_in_lane);
|
||||
}
|
||||
|
||||
// Hash the result
|
||||
blake2b_long(context->out, (uint8_t *)blockhash.v, context->outlen,
|
||||
ARGON2_BLOCK_SIZE);
|
||||
secure_wipe_memory(blockhash.v, ARGON2_BLOCK_SIZE); // clear the blockhash
|
||||
|
||||
if (context->print) // Shall we print the output tag?
|
||||
{
|
||||
print_tag(context->out, context->outlen);
|
||||
}
|
||||
|
||||
// Clear memory
|
||||
clear_memory(instance, context->clear_memory);
|
||||
|
||||
// Deallocate the memory
|
||||
if (NULL != context->free_cbk) {
|
||||
context->free_cbk((uint8_t *)instance->memory,
|
||||
instance->memory_blocks * sizeof(block));
|
||||
} else {
|
||||
free_memory(instance->memory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t index_alpha( const Argon2_instance_t *instance, const Argon2_position_t *position, uint32_t pseudo_rand, bool same_lane )
|
||||
{
|
||||
/*
|
||||
* Pass 0:
|
||||
* This lane : all already finished segments plus already constructed blocks in this segment
|
||||
* Other lanes : all already finished segments
|
||||
* Pass 1+:
|
||||
* This lane : (SYNC_POINTS - 1) last segments plus already constructed blocks in this segment
|
||||
* Other lanes : (SYNC_POINTS - 1) last segments
|
||||
*/
|
||||
uint32_t reference_area_size;
|
||||
uint32_t index_alpha(const Argon2_instance_t *instance,
|
||||
const Argon2_position_t *position, uint32_t pseudo_rand,
|
||||
bool same_lane) {
|
||||
/*
|
||||
* Pass 0:
|
||||
* This lane : all already finished segments plus already constructed
|
||||
* blocks in this segment
|
||||
* Other lanes : all already finished segments
|
||||
* Pass 1+:
|
||||
* This lane : (SYNC_POINTS - 1) last segments plus already constructed
|
||||
* blocks in this segment
|
||||
* Other lanes : (SYNC_POINTS - 1) last segments
|
||||
*/
|
||||
uint32_t reference_area_size;
|
||||
|
||||
if ( 0 == position->pass )
|
||||
{
|
||||
// First pass
|
||||
if ( 0 == position->slice )
|
||||
{
|
||||
// First slice
|
||||
reference_area_size = position->index - 1; // all but the previous
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( same_lane )
|
||||
{
|
||||
// The same lane => add current segment
|
||||
reference_area_size = position->slice * instance->segment_length + position->index - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
reference_area_size = position->slice * instance->segment_length + ( ( position->index == 0 ) ? ( -1 ) : 0 );
|
||||
}
|
||||
}
|
||||
if (0 == position->pass) {
|
||||
// First pass
|
||||
if (0 == position->slice) {
|
||||
// First slice
|
||||
reference_area_size = position->index - 1; // all but the previous
|
||||
} else {
|
||||
if (same_lane) {
|
||||
// The same lane => add current segment
|
||||
reference_area_size =
|
||||
position->slice * instance->segment_length + position->index - 1;
|
||||
} else {
|
||||
reference_area_size = position->slice * instance->segment_length +
|
||||
((position->index == 0) ? (-1) : 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Second pass
|
||||
if ( same_lane )
|
||||
{
|
||||
reference_area_size = instance->lane_length - instance->segment_length + position->index - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
reference_area_size = instance->lane_length - instance->segment_length + ( ( position->index == 0 ) ? ( -1 ) : 0 );
|
||||
}
|
||||
} else {
|
||||
// Second pass
|
||||
if (same_lane) {
|
||||
reference_area_size = instance->lane_length - instance->segment_length +
|
||||
position->index - 1;
|
||||
} else {
|
||||
reference_area_size = instance->lane_length - instance->segment_length +
|
||||
((position->index == 0) ? (-1) : 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* 1.2.4. Mapping pseudo_rand to 0..<reference_area_size-1> and produce relative position */
|
||||
uint64_t relative_position = pseudo_rand;
|
||||
relative_position = relative_position * relative_position >> 32;
|
||||
relative_position = reference_area_size - 1 - ( reference_area_size * relative_position >> 32 );
|
||||
/* 1.2.4. Mapping pseudo_rand to 0..<reference_area_size-1> and produce
|
||||
* relative position */
|
||||
uint64_t relative_position = pseudo_rand;
|
||||
relative_position = relative_position * relative_position >> 32;
|
||||
relative_position =
|
||||
reference_area_size - 1 - (reference_area_size * relative_position >> 32);
|
||||
|
||||
/* 1.2.5 Computing starting position */
|
||||
uint32_t start_position = 0;
|
||||
/* 1.2.5 Computing starting position */
|
||||
uint32_t start_position = 0;
|
||||
|
||||
if ( 0 != position->pass )
|
||||
{
|
||||
start_position = ( position->slice == ARGON2_SYNC_POINTS - 1 ) ? 0 : ( position->slice + 1 ) * instance->segment_length;
|
||||
}
|
||||
if (0 != position->pass) {
|
||||
start_position = (position->slice == ARGON2_SYNC_POINTS - 1)
|
||||
? 0
|
||||
: (position->slice + 1) * instance->segment_length;
|
||||
}
|
||||
|
||||
/* 1.2.6. Computing absolute position */
|
||||
uint32_t absolute_position = ( start_position + relative_position ) % instance->lane_length; // absolute position
|
||||
return absolute_position;
|
||||
/* 1.2.6. Computing absolute position */
|
||||
uint32_t absolute_position = (start_position + relative_position) %
|
||||
instance->lane_length; // absolute position
|
||||
return absolute_position;
|
||||
}
|
||||
|
||||
void fill_memory_blocks( Argon2_instance_t *instance )
|
||||
{
|
||||
if ( instance == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
void fill_memory_blocks(Argon2_instance_t *instance) {
|
||||
if (instance == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( uint32_t r = 0; r < instance->passes; ++r )
|
||||
{
|
||||
for ( uint8_t s = 0; s < ARGON2_SYNC_POINTS; ++s )
|
||||
{
|
||||
for (uint32_t r = 0; r < instance->passes; ++r) {
|
||||
for (uint8_t s = 0; s < ARGON2_SYNC_POINTS; ++s) {
|
||||
#ifndef _MSC_VER
|
||||
//1. Allocating space for threads
|
||||
pthread_t *thread = malloc( sizeof( pthread_t )*( instance->lanes ) );
|
||||
Argon2_thread_data *thr_data = malloc( sizeof( Argon2_thread_data )*( instance->lanes ) );
|
||||
pthread_attr_t attr;
|
||||
int rc;
|
||||
void *status;
|
||||
pthread_attr_init( &attr );
|
||||
pthread_attr_setdetachstate( &attr,PTHREAD_CREATE_JOINABLE );
|
||||
// 1. Allocating space for threads
|
||||
pthread_t *thread = malloc(sizeof(pthread_t) * (instance->lanes));
|
||||
Argon2_thread_data *thr_data =
|
||||
malloc(sizeof(Argon2_thread_data) * (instance->lanes));
|
||||
pthread_attr_t attr;
|
||||
int rc;
|
||||
void *status;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
|
||||
|
||||
//2. Calling threads
|
||||
for ( uint32_t l = 0; l < instance->lanes; ++l )
|
||||
{
|
||||
//2.1 Join a thread if limit is exceeded
|
||||
if( l>=instance->threads )
|
||||
{
|
||||
rc = pthread_join( thread[l-instance->threads],&status );
|
||||
// 2. Calling threads
|
||||
for (uint32_t l = 0; l < instance->lanes; ++l) {
|
||||
// 2.1 Join a thread if limit is exceeded
|
||||
if (l >= instance->threads) {
|
||||
rc = pthread_join(thread[l - instance->threads], &status);
|
||||
|
||||
if ( rc )
|
||||
{
|
||||
printf( "ERROR; return code from pthread_join() is %d\n", rc );
|
||||
exit( -1 );
|
||||
}
|
||||
}
|
||||
if (rc) {
|
||||
printf("ERROR; return code from pthread_join() is %d\n", rc);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
//2.2 Create thread
|
||||
Argon2_position_t position = {r,l,s,0};
|
||||
thr_data[l].instance_ptr = instance;//preparing the thread input
|
||||
memcpy( &( thr_data[l].pos ), &position, sizeof( Argon2_position_t ) );
|
||||
rc = pthread_create( &thread[l],&attr,fill_segment_thr,( void * )&thr_data[l] );
|
||||
// 2.2 Create thread
|
||||
Argon2_position_t position = {r, l, s, 0};
|
||||
thr_data[l].instance_ptr = instance; // preparing the thread input
|
||||
memcpy(&(thr_data[l].pos), &position, sizeof(Argon2_position_t));
|
||||
rc = pthread_create(&thread[l], &attr, fill_segment_thr,
|
||||
(void *)&thr_data[l]);
|
||||
|
||||
//FillSegment(instance, position); //Non-thread equivalent of the lines above
|
||||
}
|
||||
// FillSegment(instance, position); //Non-thread equivalent of the
|
||||
// lines above
|
||||
}
|
||||
|
||||
//3. Joining remaining threads
|
||||
for ( uint32_t l = instance->lanes - instance->threads; l < instance->lanes; ++l )
|
||||
{
|
||||
rc = pthread_join( thread[l],&status );
|
||||
// 3. Joining remaining threads
|
||||
for (uint32_t l = instance->lanes - instance->threads;
|
||||
l < instance->lanes; ++l) {
|
||||
rc = pthread_join(thread[l], &status);
|
||||
|
||||
if ( rc )
|
||||
{
|
||||
printf( "ERROR; return code from pthread_join() is %d\n", rc );
|
||||
exit( -1 );
|
||||
}
|
||||
}
|
||||
if (rc) {
|
||||
printf("ERROR; return code from pthread_join() is %d\n", rc);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
free( thread );
|
||||
pthread_attr_destroy( &attr );
|
||||
free( thr_data );
|
||||
#else //No threads for Windows
|
||||
for (uint32_t l = 0; l < instance->lanes; ++l)
|
||||
{
|
||||
Argon2_position_t position = { r, l, s, 0 };
|
||||
fill_segment(instance, position);
|
||||
}
|
||||
free(thread);
|
||||
pthread_attr_destroy(&attr);
|
||||
free(thr_data);
|
||||
#else // No threads for Windows
|
||||
for (uint32_t l = 0; l < instance->lanes; ++l) {
|
||||
Argon2_position_t position = {r, l, s, 0};
|
||||
fill_segment(instance, position);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if( instance->print_internals )
|
||||
{
|
||||
internal_kat( instance, r ); // Print all memory blocks
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (instance->print_internals) {
|
||||
internal_kat(instance, r); // Print all memory blocks
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int validate_inputs( const Argon2_Context *context )
|
||||
{
|
||||
if ( NULL == context )
|
||||
{
|
||||
return ARGON2_INCORRECT_PARAMETER;
|
||||
int validate_inputs(const Argon2_Context *context) {
|
||||
if (NULL == 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 length */
|
||||
if (NULL == context->pwd) {
|
||||
if (0 != context->pwdlen) {
|
||||
return ARGON2_PWD_PTR_MISMATCH;
|
||||
}
|
||||
} else {
|
||||
if (ARGON2_MIN_PWD_LENGTH != 0 && ARGON2_MIN_PWD_LENGTH > context->pwdlen) {
|
||||
return ARGON2_PWD_TOO_SHORT;
|
||||
}
|
||||
|
||||
if ( NULL == context->out )
|
||||
{
|
||||
return ARGON2_OUTPUT_PTR_NULL;
|
||||
if (ARGON2_MAX_PWD_LENGTH < context->pwdlen) {
|
||||
return ARGON2_PWD_TOO_LONG;
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate salt length */
|
||||
if (NULL == context->salt) {
|
||||
if (0 != context->saltlen) {
|
||||
return ARGON2_SALT_PTR_MISMATCH;
|
||||
}
|
||||
} else {
|
||||
if (ARGON2_MIN_SALT_LENGTH > context->saltlen) {
|
||||
return ARGON2_SALT_TOO_SHORT;
|
||||
}
|
||||
|
||||
/* Validate output length */
|
||||
if ( ARGON2_MIN_OUTLEN > context->outlen )
|
||||
{
|
||||
return ARGON2_OUTPUT_TOO_SHORT;
|
||||
if (ARGON2_MAX_SALT_LENGTH < context->saltlen) {
|
||||
return ARGON2_SALT_TOO_LONG;
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate secret length */
|
||||
if (NULL == context->secret) {
|
||||
if (0 != context->secretlen) {
|
||||
return ARGON2_SECRET_PTR_MISMATCH;
|
||||
}
|
||||
} else {
|
||||
if (ARGON2_MIN_SECRET > context->secretlen) {
|
||||
return ARGON2_SECRET_TOO_SHORT;
|
||||
}
|
||||
|
||||
if ( ARGON2_MAX_OUTLEN < context->outlen )
|
||||
{
|
||||
return ARGON2_OUTPUT_TOO_LONG;
|
||||
if (ARGON2_MAX_SECRET < context->secretlen) {
|
||||
return ARGON2_SECRET_TOO_LONG;
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate associated data */
|
||||
if (NULL == context->ad) {
|
||||
if (0 != context->adlen) {
|
||||
return ARGON2_AD_PTR_MISMATCH;
|
||||
}
|
||||
} else {
|
||||
if (ARGON2_MIN_AD_LENGTH > context->adlen) {
|
||||
return ARGON2_AD_TOO_SHORT;
|
||||
}
|
||||
|
||||
/* Validate password length */
|
||||
if ( NULL == context->pwd )
|
||||
{
|
||||
if ( 0 != context->pwdlen )
|
||||
{
|
||||
return ARGON2_PWD_PTR_MISMATCH;
|
||||
}
|
||||
if (ARGON2_MAX_AD_LENGTH < context->adlen) {
|
||||
return ARGON2_AD_TOO_LONG;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ARGON2_MIN_PWD_LENGTH != 0 && ARGON2_MIN_PWD_LENGTH > context->pwdlen )
|
||||
{
|
||||
return ARGON2_PWD_TOO_SHORT;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ARGON2_MAX_PWD_LENGTH < context->pwdlen )
|
||||
{
|
||||
return ARGON2_PWD_TOO_LONG;
|
||||
}
|
||||
}
|
||||
/* Validate memory cost */
|
||||
if (ARGON2_MIN_MEMORY > context->m_cost) {
|
||||
return ARGON2_MEMORY_TOO_LITTLE;
|
||||
}
|
||||
|
||||
/* Validate salt length */
|
||||
if ( NULL == context->salt )
|
||||
{
|
||||
if ( 0 != context->saltlen )
|
||||
{
|
||||
return ARGON2_SALT_PTR_MISMATCH;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ARGON2_MIN_SALT_LENGTH > context->saltlen )
|
||||
{
|
||||
return ARGON2_SALT_TOO_SHORT;
|
||||
}
|
||||
if (ARGON2_MAX_MEMORY < context->m_cost) {
|
||||
return ARGON2_MEMORY_TOO_MUCH;
|
||||
}
|
||||
|
||||
if ( ARGON2_MAX_SALT_LENGTH < context->saltlen )
|
||||
{
|
||||
return ARGON2_SALT_TOO_LONG;
|
||||
}
|
||||
}
|
||||
/* Validate time cost */
|
||||
if (ARGON2_MIN_TIME > context->t_cost) {
|
||||
return ARGON2_TIME_TOO_SMALL;
|
||||
}
|
||||
|
||||
/* Validate secret length */
|
||||
if ( NULL == context->secret )
|
||||
{
|
||||
if ( 0 != context->secretlen )
|
||||
{
|
||||
return ARGON2_SECRET_PTR_MISMATCH;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ARGON2_MIN_SECRET > context->secretlen )
|
||||
{
|
||||
return ARGON2_SECRET_TOO_SHORT;
|
||||
}
|
||||
if (ARGON2_MAX_TIME < context->t_cost) {
|
||||
return ARGON2_TIME_TOO_LARGE;
|
||||
}
|
||||
|
||||
if ( ARGON2_MAX_SECRET < context->secretlen )
|
||||
{
|
||||
return ARGON2_SECRET_TOO_LONG;
|
||||
}
|
||||
}
|
||||
/* Validate lanes */
|
||||
if (ARGON2_MIN_LANES > context->lanes) {
|
||||
return ARGON2_LANES_TOO_FEW;
|
||||
}
|
||||
|
||||
/* Validate associated data */
|
||||
if ( NULL == context->ad )
|
||||
{
|
||||
if ( 0 != context->adlen )
|
||||
{
|
||||
return ARGON2_AD_PTR_MISMATCH;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ARGON2_MIN_AD_LENGTH > context->adlen )
|
||||
{
|
||||
return ARGON2_AD_TOO_SHORT;
|
||||
}
|
||||
if (ARGON2_MAX_LANES < context->lanes) {
|
||||
return ARGON2_LANES_TOO_MANY;
|
||||
}
|
||||
|
||||
if ( ARGON2_MAX_AD_LENGTH < context->adlen )
|
||||
{
|
||||
return ARGON2_AD_TOO_LONG;
|
||||
}
|
||||
}
|
||||
/* Validate threads */
|
||||
if (ARGON2_MIN_THREADS > context->threads) {
|
||||
return ARGON2_THREADS_TOO_FEW;
|
||||
}
|
||||
|
||||
/* Validate memory cost */
|
||||
if ( ARGON2_MIN_MEMORY > context->m_cost )
|
||||
{
|
||||
return ARGON2_MEMORY_TOO_LITTLE;
|
||||
}
|
||||
if (ARGON2_MAX_THREADS < context->threads) {
|
||||
return ARGON2_THREADS_TOO_MANY;
|
||||
}
|
||||
|
||||
if ( ARGON2_MAX_MEMORY < context->m_cost )
|
||||
{
|
||||
return ARGON2_MEMORY_TOO_MUCH;
|
||||
}
|
||||
if (NULL != context->allocate_cbk && NULL == context->free_cbk) {
|
||||
return ARGON2_FREE_MEMORY_CBK_NULL;
|
||||
}
|
||||
|
||||
/* Validate time cost */
|
||||
if ( ARGON2_MIN_TIME > context->t_cost )
|
||||
{
|
||||
return ARGON2_TIME_TOO_SMALL;
|
||||
}
|
||||
if (NULL == context->allocate_cbk && NULL != context->free_cbk) {
|
||||
return ARGON2_ALLOCATE_MEMORY_CBK_NULL;
|
||||
}
|
||||
|
||||
if ( ARGON2_MAX_TIME < context->t_cost )
|
||||
{
|
||||
return ARGON2_TIME_TOO_LARGE;
|
||||
}
|
||||
|
||||
/* Validate lanes */
|
||||
if ( ARGON2_MIN_LANES > context->lanes )
|
||||
{
|
||||
return ARGON2_LANES_TOO_FEW;
|
||||
}
|
||||
|
||||
if ( ARGON2_MAX_LANES < context->lanes )
|
||||
{
|
||||
return ARGON2_LANES_TOO_MANY;
|
||||
}
|
||||
|
||||
/* Validate threads */
|
||||
if ( ARGON2_MIN_THREADS > context->threads )
|
||||
{
|
||||
return ARGON2_THREADS_TOO_FEW;
|
||||
}
|
||||
|
||||
if ( ARGON2_MAX_THREADS < context->threads )
|
||||
{
|
||||
return ARGON2_THREADS_TOO_MANY;
|
||||
}
|
||||
|
||||
if ( NULL != context->allocate_cbk && NULL == context->free_cbk )
|
||||
{
|
||||
return ARGON2_FREE_MEMORY_CBK_NULL;
|
||||
}
|
||||
|
||||
if ( NULL == context->allocate_cbk && NULL != context->free_cbk )
|
||||
{
|
||||
return ARGON2_ALLOCATE_MEMORY_CBK_NULL;
|
||||
}
|
||||
|
||||
return ARGON2_OK;
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
void fill_first_blocks( uint8_t *blockhash, const Argon2_instance_t *instance )
|
||||
{
|
||||
// Make the first and second block in each lane as G(H0||i||0) or G(H0||i||1)
|
||||
for ( uint32_t l = 0; l < instance->lanes; ++l )
|
||||
{
|
||||
store32( blockhash+ARGON2_PREHASH_DIGEST_LENGTH,0 );
|
||||
store32( blockhash+ARGON2_PREHASH_DIGEST_LENGTH + 4,l );
|
||||
blake2b_long( ( uint8_t * ) ( instance->memory[l * instance->lane_length].v ), blockhash, ARGON2_BLOCK_SIZE, ARGON2_PREHASH_SEED_LENGTH );
|
||||
void fill_first_blocks(uint8_t *blockhash, const Argon2_instance_t *instance) {
|
||||
// Make the first and second block in each lane as G(H0||i||0) or G(H0||i||1)
|
||||
for (uint32_t l = 0; l < instance->lanes; ++l) {
|
||||
store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0);
|
||||
store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4, l);
|
||||
blake2b_long((uint8_t *)(instance->memory[l * instance->lane_length].v),
|
||||
blockhash, ARGON2_BLOCK_SIZE, ARGON2_PREHASH_SEED_LENGTH);
|
||||
|
||||
store32( blockhash+ARGON2_PREHASH_DIGEST_LENGTH,1 );
|
||||
blake2b_long( ( uint8_t * ) ( instance->memory[l * instance->lane_length + 1].v ), blockhash, ARGON2_BLOCK_SIZE, ARGON2_PREHASH_SEED_LENGTH );
|
||||
}
|
||||
store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 1);
|
||||
blake2b_long((uint8_t *)(instance->memory[l * instance->lane_length + 1].v),
|
||||
blockhash, ARGON2_BLOCK_SIZE, ARGON2_PREHASH_SEED_LENGTH);
|
||||
}
|
||||
}
|
||||
|
||||
void initial_hash( uint8_t *blockhash, Argon2_Context *context, Argon2_type type )
|
||||
{
|
||||
blake2b_state BlakeHash;
|
||||
uint8_t value[sizeof ( uint32_t )];
|
||||
void initial_hash(uint8_t *blockhash, Argon2_Context *context,
|
||||
Argon2_type type) {
|
||||
blake2b_state BlakeHash;
|
||||
uint8_t value[sizeof(uint32_t)];
|
||||
|
||||
if ( NULL == context || NULL == blockhash )
|
||||
{
|
||||
return;
|
||||
if (NULL == context || NULL == blockhash) {
|
||||
return;
|
||||
}
|
||||
|
||||
blake2b_init(&BlakeHash, ARGON2_PREHASH_DIGEST_LENGTH);
|
||||
|
||||
store32(&value, context->lanes);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32(&value, context->outlen);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32(&value, context->m_cost);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32(&value, context->t_cost);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32(&value, ARGON2_VERSION_NUMBER);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32(&value, (uint32_t)type);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32(&value, context->pwdlen);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
if (context->pwd != NULL) {
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)context->pwd, context->pwdlen);
|
||||
|
||||
if (context->clear_password) {
|
||||
secure_wipe_memory(context->pwd, context->pwdlen);
|
||||
context->pwdlen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
blake2b_init( &BlakeHash, ARGON2_PREHASH_DIGEST_LENGTH );
|
||||
store32(&value, context->saltlen);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32( &value, context->lanes );
|
||||
blake2b_update( &BlakeHash, ( const uint8_t * ) &value, sizeof ( value ) );
|
||||
if (context->salt != NULL) {
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)context->salt,
|
||||
context->saltlen);
|
||||
}
|
||||
|
||||
store32( &value, context->outlen );
|
||||
blake2b_update( &BlakeHash, ( const uint8_t * ) &value, sizeof ( value ) );
|
||||
store32(&value, context->secretlen);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32( &value, context->m_cost );
|
||||
blake2b_update( &BlakeHash, ( const uint8_t * ) &value, sizeof ( value ) );
|
||||
if (context->secret != NULL) {
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)context->secret,
|
||||
context->secretlen);
|
||||
|
||||
store32( &value, context->t_cost );
|
||||
blake2b_update( &BlakeHash, ( const uint8_t * ) &value, sizeof ( value ) );
|
||||
|
||||
store32( &value, ARGON2_VERSION_NUMBER );
|
||||
blake2b_update( &BlakeHash, ( const uint8_t * ) &value, sizeof ( value ) );
|
||||
|
||||
store32( &value, ( uint32_t ) type );
|
||||
blake2b_update( &BlakeHash, ( const uint8_t * ) &value, sizeof ( value ) );
|
||||
|
||||
store32( &value, context->pwdlen );
|
||||
blake2b_update( &BlakeHash, ( const uint8_t * ) &value, sizeof ( value ) );
|
||||
|
||||
if ( context->pwd != NULL )
|
||||
{
|
||||
blake2b_update( &BlakeHash, ( const uint8_t * ) context->pwd, context->pwdlen );
|
||||
|
||||
if ( context->clear_password )
|
||||
{
|
||||
secure_wipe_memory( context->pwd, context->pwdlen );
|
||||
context->pwdlen = 0;
|
||||
}
|
||||
if (context->clear_secret) {
|
||||
secure_wipe_memory(context->secret, context->secretlen);
|
||||
context->secretlen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
store32( &value, context->saltlen );
|
||||
blake2b_update( &BlakeHash, ( const uint8_t * ) &value, sizeof ( value ) );
|
||||
store32(&value, context->adlen);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
if ( context->salt != NULL )
|
||||
{
|
||||
blake2b_update( &BlakeHash, ( const uint8_t * ) context->salt, context->saltlen );
|
||||
}
|
||||
if (context->ad != NULL) {
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)context->ad, context->adlen);
|
||||
}
|
||||
|
||||
store32( &value, context->secretlen );
|
||||
blake2b_update( &BlakeHash, ( const uint8_t * ) &value, sizeof ( value ) );
|
||||
|
||||
if ( context->secret != NULL )
|
||||
{
|
||||
blake2b_update( &BlakeHash, ( const uint8_t * ) context->secret, context->secretlen );
|
||||
|
||||
if ( context->clear_secret )
|
||||
{
|
||||
secure_wipe_memory( context->secret, context->secretlen );
|
||||
context->secretlen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
store32( &value, context->adlen );
|
||||
blake2b_update( &BlakeHash, ( const uint8_t * ) &value, sizeof ( value ) );
|
||||
|
||||
if ( context->ad != NULL )
|
||||
{
|
||||
blake2b_update( &BlakeHash, ( const uint8_t * ) context->ad, context->adlen );
|
||||
}
|
||||
|
||||
blake2b_final( &BlakeHash, blockhash, ARGON2_PREHASH_DIGEST_LENGTH );
|
||||
blake2b_final(&BlakeHash, blockhash, ARGON2_PREHASH_DIGEST_LENGTH);
|
||||
}
|
||||
|
||||
int initialize( Argon2_instance_t *instance, Argon2_Context *context )
|
||||
{
|
||||
if ( instance == NULL || context == NULL )
|
||||
return ARGON2_INCORRECT_PARAMETER;
|
||||
int initialize(Argon2_instance_t *instance, Argon2_Context *context) {
|
||||
if (instance == NULL || context == NULL)
|
||||
return ARGON2_INCORRECT_PARAMETER;
|
||||
|
||||
// 1. Memory allocation
|
||||
int result = ARGON2_OK;
|
||||
// 1. Memory allocation
|
||||
int result = ARGON2_OK;
|
||||
|
||||
if ( NULL != context->allocate_cbk )
|
||||
{
|
||||
result = context->allocate_cbk( ( uint8_t ** )&( instance->memory ), instance->memory_blocks * ARGON2_BLOCK_SIZE );
|
||||
}
|
||||
else
|
||||
{
|
||||
result = allocate_memory( &( instance->memory ), instance->memory_blocks );
|
||||
}
|
||||
if (NULL != context->allocate_cbk) {
|
||||
result = context->allocate_cbk((uint8_t **)&(instance->memory),
|
||||
instance->memory_blocks * ARGON2_BLOCK_SIZE);
|
||||
} else {
|
||||
result = allocate_memory(&(instance->memory), instance->memory_blocks);
|
||||
}
|
||||
|
||||
if ( ARGON2_OK != result )
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (ARGON2_OK != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. Initial hashing
|
||||
// H_0 + 8 extra bytes to produce the first blocks
|
||||
uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH];
|
||||
// Hashing all inputs
|
||||
initial_hash( blockhash, context, instance->type );
|
||||
// Zeroing 8 extra bytes
|
||||
secure_wipe_memory( blockhash + ARGON2_PREHASH_DIGEST_LENGTH, ARGON2_PREHASH_SEED_LENGTH - ARGON2_PREHASH_DIGEST_LENGTH );
|
||||
// 2. Initial hashing
|
||||
// H_0 + 8 extra bytes to produce the first blocks
|
||||
uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH];
|
||||
// Hashing all inputs
|
||||
initial_hash(blockhash, context, instance->type);
|
||||
// Zeroing 8 extra bytes
|
||||
secure_wipe_memory(blockhash + ARGON2_PREHASH_DIGEST_LENGTH,
|
||||
ARGON2_PREHASH_SEED_LENGTH - ARGON2_PREHASH_DIGEST_LENGTH);
|
||||
|
||||
if( context->print )
|
||||
{
|
||||
initial_kat( blockhash, context, instance->type );
|
||||
}
|
||||
if (context->print) {
|
||||
initial_kat(blockhash, context, instance->type);
|
||||
}
|
||||
|
||||
// 3. Creating first blocks, we always have at least two blocks in a slice
|
||||
fill_first_blocks( blockhash, instance );
|
||||
// Clearing the hash
|
||||
secure_wipe_memory( blockhash, ARGON2_PREHASH_SEED_LENGTH );
|
||||
// 3. Creating first blocks, we always have at least two blocks in a slice
|
||||
fill_first_blocks(blockhash, instance);
|
||||
// Clearing the hash
|
||||
secure_wipe_memory(blockhash, ARGON2_PREHASH_SEED_LENGTH);
|
||||
|
||||
return ARGON2_OK;
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
int argon2_core( Argon2_Context *context, Argon2_type type )
|
||||
{
|
||||
/* 1. Validate all inputs */
|
||||
int result = validate_inputs( context );
|
||||
int argon2_core(Argon2_Context *context, Argon2_type type) {
|
||||
/* 1. Validate all inputs */
|
||||
int result = validate_inputs(context);
|
||||
|
||||
if ( ARGON2_OK != result )
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (ARGON2_OK != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if ( Argon2_d != type && Argon2_i != type )
|
||||
{
|
||||
return ARGON2_INCORRECT_TYPE;
|
||||
}
|
||||
if (Argon2_d != type && Argon2_i != type) {
|
||||
return ARGON2_INCORRECT_TYPE;
|
||||
}
|
||||
|
||||
/* 2. Align memory size */
|
||||
// Minimum memory_blocks = 8L blocks, where L is the number of lanes
|
||||
uint32_t memory_blocks = context->m_cost;
|
||||
/* 2. Align memory size */
|
||||
// Minimum memory_blocks = 8L blocks, where L is the number of lanes
|
||||
uint32_t memory_blocks = context->m_cost;
|
||||
|
||||
if ( memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes )
|
||||
{
|
||||
memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes;
|
||||
}
|
||||
if (memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes) {
|
||||
memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes;
|
||||
}
|
||||
|
||||
uint32_t segment_length = memory_blocks / ( context->lanes * ARGON2_SYNC_POINTS );
|
||||
bool print_internals = context->print;
|
||||
// Ensure that all segments have equal length
|
||||
memory_blocks = segment_length * ( context->lanes * ARGON2_SYNC_POINTS );
|
||||
Argon2_instance_t instance = { NULL, context->t_cost, memory_blocks, segment_length,
|
||||
segment_length * ARGON2_SYNC_POINTS, context->lanes, context->threads, type, print_internals
|
||||
};
|
||||
uint32_t segment_length =
|
||||
memory_blocks / (context->lanes * ARGON2_SYNC_POINTS);
|
||||
bool print_internals = context->print;
|
||||
// Ensure that all segments have equal length
|
||||
memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS);
|
||||
Argon2_instance_t instance = {NULL,
|
||||
context->t_cost,
|
||||
memory_blocks,
|
||||
segment_length,
|
||||
segment_length * ARGON2_SYNC_POINTS,
|
||||
context->lanes,
|
||||
context->threads,
|
||||
type,
|
||||
print_internals};
|
||||
|
||||
/* 3. Initialization: Hashing inputs, allocating memory, filling first blocks */
|
||||
result = initialize( &instance, context );
|
||||
/* 3. Initialization: Hashing inputs, allocating memory, filling first blocks
|
||||
*/
|
||||
result = initialize(&instance, context);
|
||||
|
||||
if ( ARGON2_OK != result )
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (ARGON2_OK != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/* 4. Filling memory */
|
||||
fill_memory_blocks( &instance );
|
||||
/* 4. Filling memory */
|
||||
fill_memory_blocks(&instance);
|
||||
|
||||
/* 5. Finalization */
|
||||
finalize( context, &instance );
|
||||
/* 5. Finalization */
|
||||
finalize(context, &instance);
|
||||
|
||||
return ARGON2_OK;
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
#ifndef _MSC_VER /* No threads for Windows*/
|
||||
void *fill_segment_thr( void *thread_data )
|
||||
{
|
||||
Argon2_thread_data *my_data = ( Argon2_thread_data * )thread_data;
|
||||
fill_segment( my_data->instance_ptr, my_data->pos );
|
||||
pthread_exit( thread_data );
|
||||
#ifndef _MSC_VER /* No threads for Windows*/
|
||||
void *fill_segment_thr(void *thread_data) {
|
||||
Argon2_thread_data *my_data = (Argon2_thread_data *)thread_data;
|
||||
fill_segment(my_data->instance_ptr, my_data->pos);
|
||||
pthread_exit(thread_data);
|
||||
}
|
||||
#endif
|
||||
|
|
198
src/core.h
198
src/core.h
|
@ -5,104 +5,104 @@
|
|||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
* this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARGON2_CORE_H__
|
||||
#define __ARGON2_CORE_H__
|
||||
|
||||
/*************************Argon2 internal constants**************************************************/
|
||||
/*************************Argon2 internal
|
||||
* constants**************************************************/
|
||||
|
||||
/* Version of the algorithm */
|
||||
extern const uint32_t ARGON2_VERSION_NUMBER;
|
||||
|
||||
/* Memory block size in bytes */
|
||||
#define ARGON2_BLOCK_SIZE 1024
|
||||
#define ARGON2_WORDS_IN_BLOCK (ARGON2_BLOCK_SIZE/8)
|
||||
extern const uint32_t ARGON2_QWORDS_IN_BLOCK ; /*Dependent values!*/
|
||||
#define ARGON2_BLOCK_SIZE 1024
|
||||
#define ARGON2_WORDS_IN_BLOCK (ARGON2_BLOCK_SIZE / 8)
|
||||
extern const uint32_t ARGON2_QWORDS_IN_BLOCK; /*Dependent values!*/
|
||||
|
||||
/* Number of pseudo-random values generated by one call to Blake in Argon2i to generate reference block positions*/
|
||||
/* Number of pseudo-random values generated by one call to Blake in Argon2i to
|
||||
* generate reference block positions*/
|
||||
extern const uint32_t ARGON2_ADDRESSES_IN_BLOCK;
|
||||
|
||||
/* Pre-hashing digest length and its extension*/
|
||||
#define ARGON2_PREHASH_DIGEST_LENGTH 64
|
||||
#define ARGON2_PREHASH_SEED_LENGTH 72 /*Dependent values!*/
|
||||
#define ARGON2_PREHASH_DIGEST_LENGTH 64
|
||||
#define ARGON2_PREHASH_SEED_LENGTH 72 /*Dependent values!*/
|
||||
|
||||
/* Argon2 primitive type */
|
||||
typedef enum _Argon2_type
|
||||
{
|
||||
Argon2_d=0,
|
||||
Argon2_i=1,
|
||||
typedef enum _Argon2_type {
|
||||
Argon2_d = 0,
|
||||
Argon2_i = 1,
|
||||
} Argon2_type;
|
||||
|
||||
/*************************Argon2 internal data types**************************************************/
|
||||
/*************************Argon2 internal data
|
||||
* types**************************************************/
|
||||
|
||||
/*
|
||||
* Structure for the (1KB) memory block implemented as 128 64-bit words.
|
||||
* Memory blocks can be copied, XORed. Internal words can be accessed by [] (no bounds checking).
|
||||
* Memory blocks can be copied, XORed. Internal words can be accessed by [] (no
|
||||
* bounds checking).
|
||||
*/
|
||||
#ifndef _MSC_VER
|
||||
typedef struct _block
|
||||
{
|
||||
uint64_t v[ARGON2_WORDS_IN_BLOCK];
|
||||
} __attribute__ ( ( aligned ( 16 ) ) ) block;
|
||||
typedef struct _block {
|
||||
uint64_t v[ARGON2_WORDS_IN_BLOCK];
|
||||
} __attribute__((aligned(16))) block;
|
||||
#else
|
||||
typedef struct _block
|
||||
{
|
||||
uint64_t v[ARGON2_WORDS_IN_BLOCK];
|
||||
} __declspec( align( 16 ) ) block;
|
||||
typedef struct _block {
|
||||
uint64_t v[ARGON2_WORDS_IN_BLOCK];
|
||||
} __declspec(align(16)) block;
|
||||
#endif
|
||||
|
||||
/*****************Functions that work with the block******************/
|
||||
|
||||
//Initialize each byte of the block with @in
|
||||
extern void init_block_value( block *b, uint8_t in );
|
||||
// Initialize each byte of the block with @in
|
||||
extern void init_block_value(block *b, uint8_t in);
|
||||
|
||||
//Copy block @src to block @dst
|
||||
extern void copy_block( block *dst, const block *src );
|
||||
|
||||
//XOR @src onto @dst bytewise
|
||||
extern void xor_block( block *dst, const block *src );
|
||||
// Copy block @src to block @dst
|
||||
extern void copy_block(block *dst, const block *src);
|
||||
|
||||
// XOR @src onto @dst bytewise
|
||||
extern void xor_block(block *dst, const block *src);
|
||||
|
||||
/*
|
||||
* Argon2 instance: memory pointer, number of passes, amount of memory, type, and derived values.
|
||||
* Used to evaluate the number and location of blocks to construct in each thread
|
||||
* Argon2 instance: memory pointer, number of passes, amount of memory, type,
|
||||
* and derived values.
|
||||
* Used to evaluate the number and location of blocks to construct in each
|
||||
* thread
|
||||
*/
|
||||
typedef struct _Argon2_instance_t
|
||||
{
|
||||
block *memory; //Memory pointer
|
||||
const uint32_t passes; //Number of passes
|
||||
const uint32_t memory_blocks; //Number of blocks in memory
|
||||
const uint32_t segment_length;
|
||||
const uint32_t lane_length;
|
||||
const uint32_t lanes;
|
||||
const uint32_t threads;
|
||||
const Argon2_type type;
|
||||
const bool print_internals; //whether to print the memory blocks
|
||||
typedef struct _Argon2_instance_t {
|
||||
block *memory; // Memory pointer
|
||||
const uint32_t passes; // Number of passes
|
||||
const uint32_t memory_blocks; // Number of blocks in memory
|
||||
const uint32_t segment_length;
|
||||
const uint32_t lane_length;
|
||||
const uint32_t lanes;
|
||||
const uint32_t threads;
|
||||
const Argon2_type type;
|
||||
const bool print_internals; // whether to print the memory blocks
|
||||
} Argon2_instance_t;
|
||||
|
||||
|
||||
/*
|
||||
* Argon2 position: where we construct the block right now. Used to distribute work between threads.
|
||||
* Argon2 position: where we construct the block right now. Used to distribute
|
||||
* work between threads.
|
||||
*/
|
||||
typedef struct _Argon2_position_t
|
||||
{
|
||||
const uint32_t pass;
|
||||
const uint32_t lane;
|
||||
const uint8_t slice;
|
||||
uint32_t index;
|
||||
typedef struct _Argon2_position_t {
|
||||
const uint32_t pass;
|
||||
const uint32_t lane;
|
||||
const uint8_t slice;
|
||||
uint32_t index;
|
||||
} Argon2_position_t;
|
||||
|
||||
/*Struct that holds the inputs for thread handling FillSegment*/
|
||||
typedef struct _Argon2_thread_data
|
||||
{
|
||||
Argon2_instance_t *instance_ptr;
|
||||
Argon2_position_t pos;
|
||||
typedef struct _Argon2_thread_data {
|
||||
Argon2_instance_t *instance_ptr;
|
||||
Argon2_position_t pos;
|
||||
} Argon2_thread_data;
|
||||
|
||||
/*Macro for endianness conversion*/
|
||||
|
@ -113,54 +113,62 @@ typedef struct _Argon2_thread_data
|
|||
#define BSWAP32(x) __builtin_bswap32(x)
|
||||
#endif
|
||||
|
||||
/*************************Argon2 core functions**************************************************/
|
||||
/*************************Argon2 core
|
||||
* functions**************************************************/
|
||||
|
||||
/* Allocates memory to the given pointer
|
||||
* @param memory pointer to the pointer to the memory
|
||||
* @param m_cost number of blocks to allocate in the memory
|
||||
* @return ARGON2_OK if @memory is a valid pointer and memory is allocated
|
||||
*/
|
||||
int allocate_memory( block **memory, uint32_t m_cost );
|
||||
int allocate_memory(block **memory, uint32_t m_cost);
|
||||
|
||||
/* Clears memory
|
||||
* @param instance pointer to the current instance
|
||||
* @param clear_memory indicates if we clear the memory with zeros.
|
||||
*/
|
||||
void clear_memory( Argon2_instance_t *instance, bool clear );
|
||||
void clear_memory(Argon2_instance_t *instance, bool clear);
|
||||
|
||||
/* Deallocates memory
|
||||
* @param memory pointer to the blocks
|
||||
*/
|
||||
void free_memory( block *memory );
|
||||
|
||||
|
||||
|
||||
void free_memory(block *memory);
|
||||
|
||||
/*
|
||||
* Computes absolute position of reference block in the lane following a skewed distribution and using a pseudo-random value as input
|
||||
* Computes absolute position of reference block in the lane following a skewed
|
||||
* distribution and using a pseudo-random value as input
|
||||
* @param instance Pointer to the current instance
|
||||
* @param position Pointer to the current position
|
||||
* @param pseudo_rand 32-bit pseudo-random value used to determine the position
|
||||
* @param same_lane Indicates if the block will be taken from the current lane. If so we can reference the current segment
|
||||
* @param same_lane Indicates if the block will be taken from the current lane.
|
||||
* If so we can reference the current segment
|
||||
* @pre All pointers must be valid
|
||||
*/
|
||||
uint32_t index_alpha( const Argon2_instance_t *instance, const Argon2_position_t *position, uint32_t pseudo_rand, bool same_lane );
|
||||
uint32_t index_alpha(const Argon2_instance_t *instance,
|
||||
const Argon2_position_t *position, uint32_t pseudo_rand,
|
||||
bool same_lane);
|
||||
|
||||
/*
|
||||
* Function that validates all inputs against predefined restrictions and return an error code
|
||||
* Function that validates all inputs against predefined restrictions and return
|
||||
* an error code
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @return ARGON2_OK if everything is all right, otherwise one of error codes (all defined in <argon2.h>
|
||||
* @return ARGON2_OK if everything is all right, otherwise one of error codes
|
||||
* (all defined in <argon2.h>
|
||||
*/
|
||||
int validate_inputs( const Argon2_Context *context );
|
||||
int validate_inputs(const Argon2_Context *context);
|
||||
|
||||
/*
|
||||
* Hashes all the inputs into @a blockhash[PREHASH_DIGEST_LENGTH], clears password and secret if needed
|
||||
* @param context Pointer to the Argon2 internal structure containing memory pointer, and parameters for time and space requirements.
|
||||
* Hashes all the inputs into @a blockhash[PREHASH_DIGEST_LENGTH], clears
|
||||
* password and secret if needed
|
||||
* @param context Pointer to the Argon2 internal structure containing memory
|
||||
* pointer, and parameters for time and space requirements.
|
||||
* @param blockhash Buffer for pre-hashing digest
|
||||
* @param type Argon2 type
|
||||
* @pre @a blockhash must have at least @a PREHASH_DIGEST_LENGTH bytes allocated
|
||||
* @pre @a blockhash must have at least @a PREHASH_DIGEST_LENGTH bytes
|
||||
* allocated
|
||||
*/
|
||||
void initial_hash( uint8_t *blockhash, Argon2_Context *context, Argon2_type type );
|
||||
void initial_hash(uint8_t *blockhash, Argon2_Context *context,
|
||||
Argon2_type type);
|
||||
|
||||
/*
|
||||
* Function creates first 2 blocks per lane
|
||||
|
@ -168,58 +176,62 @@ void initial_hash( uint8_t *blockhash, Argon2_Context *context, Argon2_type typ
|
|||
* @param blockhash Pointer to the pre-hashing digest
|
||||
* @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values
|
||||
*/
|
||||
void fill_firsts_blocks( uint8_t *blockhash, const Argon2_instance_t *instance );
|
||||
|
||||
void fill_firsts_blocks(uint8_t *blockhash, const Argon2_instance_t *instance);
|
||||
|
||||
/*
|
||||
* Function allocates memory, hashes the inputs with Blake, and creates first two blocks. Returns the pointer to the main memory with 2 blocks per lane
|
||||
* Function allocates memory, hashes the inputs with Blake, and creates first
|
||||
* two blocks. Returns the pointer to the main memory with 2 blocks per lane
|
||||
* initialized
|
||||
* @param context Pointer to the Argon2 internal structure containing memory pointer, and parameters for time and space requirements.
|
||||
* @param context Pointer to the Argon2 internal structure containing memory
|
||||
* pointer, and parameters for time and space requirements.
|
||||
* @param instance Current Argon2 instance
|
||||
* @return Zero if successful, -1 if memory failed to allocate. @context->state will be modified if successful.
|
||||
* @return Zero if successful, -1 if memory failed to allocate. @context->state
|
||||
* will be modified if successful.
|
||||
*/
|
||||
int initialize( Argon2_instance_t *instance, Argon2_Context *context );
|
||||
int initialize(Argon2_instance_t *instance, Argon2_Context *context);
|
||||
|
||||
/*
|
||||
* XORing the last block of each lane, hashing it, making the tag. Deallocates the memory.
|
||||
* @param context Pointer to current Argon2 context (use only the out parameters from it)
|
||||
* XORing the last block of each lane, hashing it, making the tag. Deallocates
|
||||
* the memory.
|
||||
* @param context Pointer to current Argon2 context (use only the out parameters
|
||||
* from it)
|
||||
* @param instance Pointer to current instance of Argon2
|
||||
* @pre instance->state must point to necessary amount of memory
|
||||
* @pre context->out must point to outlen bytes of memory
|
||||
* @pre if context->free_cbk is not NULL, it should point to a function that deallocates memory
|
||||
* @pre if context->free_cbk is not NULL, it should point to a function that
|
||||
* deallocates memory
|
||||
*/
|
||||
void finalize( const Argon2_Context *context, Argon2_instance_t *instance );
|
||||
|
||||
|
||||
void finalize(const Argon2_Context *context, Argon2_instance_t *instance);
|
||||
|
||||
/*
|
||||
* Function that fills the segment using previous segments also from other threads
|
||||
* Function that fills the segment using previous segments also from other
|
||||
* threads
|
||||
* @param instance Pointer to the current instance
|
||||
* @param position Current position
|
||||
* @pre all block pointers must be valid
|
||||
*/
|
||||
extern void fill_segment( const Argon2_instance_t *instance, Argon2_position_t position );
|
||||
extern void fill_segment(const Argon2_instance_t *instance,
|
||||
Argon2_position_t position);
|
||||
|
||||
/*
|
||||
* Wrapper for FillSegment for <pthread> library
|
||||
* @param thread_data Pointer to the structure that holds inputs for FillSegment
|
||||
* @pre all block pointers must be valid
|
||||
*/
|
||||
void *fill_segment_thr( void *Argon2_thread_data );
|
||||
void *fill_segment_thr(void *Argon2_thread_data);
|
||||
|
||||
/*
|
||||
* Function that fills the entire memory t_cost times based on the first two blocks in each lane
|
||||
* Function that fills the entire memory t_cost times based on the first two
|
||||
* blocks in each lane
|
||||
* @param instance Pointer to the current instance
|
||||
*/
|
||||
void fill_memory_blocks( Argon2_instance_t *instance );
|
||||
|
||||
void fill_memory_blocks(Argon2_instance_t *instance);
|
||||
|
||||
/*
|
||||
* Function that performs memory-hard hashing with certain degree of parallelism
|
||||
* @param context Pointer to the Argon2 internal structure
|
||||
* @return Error code if smth is wrong, ARGON2_OK otherwise
|
||||
*/
|
||||
int argon2_core( Argon2_Context *context, Argon2_type type );
|
||||
|
||||
int argon2_core(Argon2_Context *context, Argon2_type type);
|
||||
|
||||
#endif
|
||||
|
|
190
src/encoding.h
190
src/encoding.h
|
@ -7,8 +7,10 @@
|
|||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
* this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#include "argon2.h"
|
||||
|
@ -22,25 +24,21 @@
|
|||
* Some macros for constant-time comparisons. These work over values in
|
||||
* the 0..255 range. Returned value is 0x00 on "false", 0xFF on "true".
|
||||
*/
|
||||
#define EQ(x, y) ((((-((unsigned)(x) ^ (unsigned)(y))) >> 8) & 0xFF) ^ 0xFF)
|
||||
#define GT(x, y) ((((unsigned)(y) - (unsigned)(x)) >> 8) & 0xFF)
|
||||
#define GE(x, y) (GT(y, x) ^ 0xFF)
|
||||
#define LT(x, y) GT(y, x)
|
||||
#define LE(x, y) GE(y, x)
|
||||
#define EQ(x, y) ((((-((unsigned)(x) ^ (unsigned)(y))) >> 8) & 0xFF) ^ 0xFF)
|
||||
#define GT(x, y) ((((unsigned)(y) - (unsigned)(x)) >> 8) & 0xFF)
|
||||
#define GE(x, y) (GT(y, x) ^ 0xFF)
|
||||
#define LT(x, y) GT(y, x)
|
||||
#define LE(x, y) GE(y, x)
|
||||
|
||||
/*
|
||||
* Convert value x (0..63) to corresponding Base64 character.
|
||||
*/
|
||||
static int
|
||||
b64_byte_to_char(unsigned x)
|
||||
{
|
||||
return (LT(x, 26) & (x + 'A'))
|
||||
| (GE(x, 26) & LT(x, 52) & (x + ('a' - 26)))
|
||||
| (GE(x, 52) & LT(x, 62) & (x + ('0' - 52)))
|
||||
| (EQ(x, 62) & '+') | (EQ(x, 63) & '/');
|
||||
static int b64_byte_to_char(unsigned x) {
|
||||
return (LT(x, 26) & (x + 'A')) | (GE(x, 26) & LT(x, 52) & (x + ('a' - 26))) |
|
||||
(GE(x, 52) & LT(x, 62) & (x + ('0' - 52))) | (EQ(x, 62) & '+') |
|
||||
(EQ(x, 63) & '/');
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert some bytes to Base64. 'dst_len' is the length (in characters)
|
||||
* of the output buffer 'dst'; if that buffer is not large enough to
|
||||
|
@ -49,45 +47,42 @@ b64_byte_to_char(unsigned x)
|
|||
* in the buffer, and the output length (counted WITHOUT the terminating
|
||||
* zero) is returned.
|
||||
*/
|
||||
static size_t
|
||||
to_base64(char *dst, size_t dst_len, const void *src, size_t src_len)
|
||||
{
|
||||
size_t olen;
|
||||
const unsigned char *buf;
|
||||
unsigned acc, acc_len;
|
||||
static size_t to_base64(char *dst, size_t dst_len, const void *src,
|
||||
size_t src_len) {
|
||||
size_t olen;
|
||||
const unsigned char *buf;
|
||||
unsigned acc, acc_len;
|
||||
|
||||
olen = (src_len / 3) << 2;
|
||||
switch (src_len % 3) {
|
||||
case 2:
|
||||
olen ++;
|
||||
/* fall through */
|
||||
case 1:
|
||||
olen += 2;
|
||||
break;
|
||||
}
|
||||
if (dst_len <= olen) {
|
||||
return (size_t)-1;
|
||||
}
|
||||
acc = 0;
|
||||
acc_len = 0;
|
||||
buf = (const unsigned char *)src;
|
||||
while (src_len -- > 0) {
|
||||
acc = (acc << 8) + (*buf ++);
|
||||
acc_len += 8;
|
||||
while (acc_len >= 6) {
|
||||
acc_len -= 6;
|
||||
*dst ++ = b64_byte_to_char((acc >> acc_len) & 0x3F);
|
||||
}
|
||||
}
|
||||
if (acc_len > 0) {
|
||||
*dst ++ = b64_byte_to_char((acc << (6 - acc_len)) & 0x3F);
|
||||
}
|
||||
*dst ++ = 0;
|
||||
return olen;
|
||||
olen = (src_len / 3) << 2;
|
||||
switch (src_len % 3) {
|
||||
case 2:
|
||||
olen++;
|
||||
/* fall through */
|
||||
case 1:
|
||||
olen += 2;
|
||||
break;
|
||||
}
|
||||
if (dst_len <= olen) {
|
||||
return (size_t)-1;
|
||||
}
|
||||
acc = 0;
|
||||
acc_len = 0;
|
||||
buf = (const unsigned char *)src;
|
||||
while (src_len-- > 0) {
|
||||
acc = (acc << 8) + (*buf++);
|
||||
acc_len += 8;
|
||||
while (acc_len >= 6) {
|
||||
acc_len -= 6;
|
||||
*dst++ = b64_byte_to_char((acc >> acc_len) & 0x3F);
|
||||
}
|
||||
}
|
||||
if (acc_len > 0) {
|
||||
*dst++ = b64_byte_to_char((acc << (6 - acc_len)) & 0x3F);
|
||||
}
|
||||
*dst++ = 0;
|
||||
return olen;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ==================================================================== */
|
||||
/*
|
||||
* Code specific to Argon2i.
|
||||
|
@ -108,59 +103,60 @@ to_base64(char *dst, size_t dst_len, const void *src, size_t src_len)
|
|||
* The output length is always exactly 32 bytes.
|
||||
*/
|
||||
|
||||
int encode_string(char *dst, size_t dst_len, Argon2_Context *ctx) {
|
||||
#define SS(str) \
|
||||
do { \
|
||||
size_t pp_len = strlen(str); \
|
||||
if (pp_len >= dst_len) { \
|
||||
return 0; \
|
||||
} \
|
||||
memcpy(dst, str, pp_len + 1); \
|
||||
dst += pp_len; \
|
||||
dst_len -= pp_len; \
|
||||
} while (0)
|
||||
|
||||
int
|
||||
encode_string( char *dst, size_t dst_len, Argon2_Context *ctx )
|
||||
{
|
||||
#define SS(str) do { \
|
||||
size_t pp_len = strlen(str); \
|
||||
if (pp_len >= dst_len) { \
|
||||
return 0; \
|
||||
} \
|
||||
memcpy(dst, str, pp_len + 1); \
|
||||
dst += pp_len; \
|
||||
dst_len -= pp_len; \
|
||||
} while (0)
|
||||
#define SX(x) \
|
||||
do { \
|
||||
char tmp[30]; \
|
||||
sprintf(tmp, "%lu", (unsigned long)(x)); \
|
||||
SS(tmp); \
|
||||
} while (0);
|
||||
|
||||
#define SX(x) do { \
|
||||
char tmp[30]; \
|
||||
sprintf(tmp, "%lu", (unsigned long)(x)); \
|
||||
SS(tmp); \
|
||||
} while (0); \
|
||||
#define SB(buf, len) \
|
||||
do { \
|
||||
size_t sb_len = to_base64(dst, dst_len, buf, len); \
|
||||
if (sb_len == (size_t)-1) { \
|
||||
return 0; \
|
||||
} \
|
||||
dst += sb_len; \
|
||||
dst_len -= sb_len; \
|
||||
} while (0);
|
||||
|
||||
#define SB(buf, len) do { \
|
||||
size_t sb_len = to_base64(dst, dst_len, buf, len); \
|
||||
if (sb_len == (size_t)-1) { \
|
||||
return 0; \
|
||||
} \
|
||||
dst += sb_len; \
|
||||
dst_len -= sb_len; \
|
||||
} while (0); \
|
||||
SS("$argon2i$m=");
|
||||
SX(ctx->m_cost);
|
||||
SS(",t=");
|
||||
SX(ctx->t_cost);
|
||||
SS(",p=");
|
||||
SX(ctx->lanes);
|
||||
|
||||
SS( "$argon2i$m=" );
|
||||
SX( ctx->m_cost );
|
||||
SS( ",t=" );
|
||||
SX( ctx->t_cost );
|
||||
SS( ",p=" );
|
||||
SX( ctx->lanes );
|
||||
if (ctx->adlen > 0) {
|
||||
SS(",data=");
|
||||
SB(ctx->ad, ctx->adlen);
|
||||
}
|
||||
|
||||
if ( ctx->adlen > 0 )
|
||||
{
|
||||
SS( ",data=" );
|
||||
SB( ctx->ad, ctx->adlen );
|
||||
}
|
||||
|
||||
if ( ctx->saltlen == 0 ) return 1;
|
||||
|
||||
SS( "$" );
|
||||
SB( ctx->salt, ctx->saltlen );
|
||||
|
||||
if ( ctx->outlen == 0 ) return 1;
|
||||
|
||||
SS( "$" );
|
||||
SB( ctx->out, ctx->outlen );
|
||||
if (ctx->saltlen == 0)
|
||||
return 1;
|
||||
|
||||
SS("$");
|
||||
SB(ctx->salt, ctx->saltlen);
|
||||
|
||||
if (ctx->outlen == 0)
|
||||
return 1;
|
||||
|
||||
SS("$");
|
||||
SB(ctx->out, ctx->outlen);
|
||||
return 1;
|
||||
|
||||
#undef SS
|
||||
#undef SX
|
||||
#undef SB
|
||||
|
|
217
src/kat.c
217
src/kat.c
|
@ -6,146 +6,127 @@
|
|||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
* this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "argon2.h"
|
||||
#include "core.h"
|
||||
|
||||
void initial_kat(const uint8_t *blockhash, const Argon2_Context *context,
|
||||
Argon2_type type) {
|
||||
FILE *fp = fopen(ARGON2_KAT_FILENAME, "a+");
|
||||
|
||||
if (fp && blockhash != NULL && context != NULL) {
|
||||
fprintf(fp, "=======================================");
|
||||
|
||||
void initial_kat( const uint8_t *blockhash, const Argon2_Context *context, Argon2_type type )
|
||||
{
|
||||
FILE *fp = fopen( ARGON2_KAT_FILENAME, "a+" );
|
||||
switch (type) {
|
||||
case Argon2_d:
|
||||
fprintf(fp, "Argon2d\n");
|
||||
break;
|
||||
|
||||
if ( fp && blockhash != NULL && context != NULL )
|
||||
{
|
||||
fprintf( fp, "=======================================" );
|
||||
case Argon2_i:
|
||||
fprintf(fp, "Argon2i\n");
|
||||
break;
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case Argon2_d:
|
||||
fprintf( fp, "Argon2d\n" );
|
||||
break;
|
||||
|
||||
case Argon2_i:
|
||||
fprintf( fp, "Argon2i\n" );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf( fp, "Iterations: %d, Memory: %d KBytes, Parallelism: %d lanes, Tag length: %d bytes\n",
|
||||
context->t_cost, context->m_cost, context->lanes, context->outlen );
|
||||
|
||||
|
||||
fprintf( fp, "Password[%d]: ", context->pwdlen );
|
||||
|
||||
if ( context->clear_password )
|
||||
{
|
||||
fprintf( fp, "CLEARED\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( unsigned i = 0; i < context->pwdlen; ++i )
|
||||
{
|
||||
fprintf( fp, "%2.2x ", ( ( unsigned char * ) context->pwd )[i] );
|
||||
}
|
||||
|
||||
fprintf( fp, "\n" );
|
||||
}
|
||||
|
||||
|
||||
fprintf( fp, "Salt[%d]: ", context->saltlen );
|
||||
|
||||
for ( unsigned i = 0; i < context->saltlen; ++i )
|
||||
{
|
||||
fprintf( fp, "%2.2x ", ( ( unsigned char * ) context->salt )[i] );
|
||||
}
|
||||
|
||||
fprintf( fp, "\n" );
|
||||
|
||||
fprintf( fp, "Secret[%d]: ", context->secretlen );
|
||||
|
||||
if ( context->clear_secret )
|
||||
{
|
||||
fprintf( fp, "CLEARED\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( unsigned i = 0; i < context->secretlen; ++i )
|
||||
{
|
||||
fprintf( fp, "%2.2x ", ( ( unsigned char * ) context->secret )[i] );
|
||||
}
|
||||
|
||||
fprintf( fp, "\n" );
|
||||
}
|
||||
|
||||
fprintf( fp, "Associated data[%d]: ", context->adlen );
|
||||
|
||||
for ( unsigned i = 0; i < context->adlen; ++i )
|
||||
{
|
||||
fprintf( fp, "%2.2x ", ( ( unsigned char * ) context->ad )[i] );
|
||||
}
|
||||
|
||||
fprintf( fp, "\n" );
|
||||
|
||||
|
||||
|
||||
fprintf( fp, "Pre-hashing digest: " );
|
||||
|
||||
for ( unsigned i = 0; i < ARGON2_PREHASH_DIGEST_LENGTH; ++i )
|
||||
{
|
||||
fprintf( fp, "%2.2x ", ( ( unsigned char * ) blockhash )[i] );
|
||||
}
|
||||
|
||||
fprintf( fp, "\n" );
|
||||
|
||||
fclose( fp );
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(fp, "Iterations: %d, Memory: %d KBytes, Parallelism: %d lanes, Tag "
|
||||
"length: %d bytes\n",
|
||||
context->t_cost, context->m_cost, context->lanes, context->outlen);
|
||||
|
||||
fprintf(fp, "Password[%d]: ", context->pwdlen);
|
||||
|
||||
if (context->clear_password) {
|
||||
fprintf(fp, "CLEARED\n");
|
||||
} else {
|
||||
for (unsigned i = 0; i < context->pwdlen; ++i) {
|
||||
fprintf(fp, "%2.2x ", ((unsigned char *)context->pwd)[i]);
|
||||
}
|
||||
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
|
||||
fprintf(fp, "Salt[%d]: ", context->saltlen);
|
||||
|
||||
for (unsigned i = 0; i < context->saltlen; ++i) {
|
||||
fprintf(fp, "%2.2x ", ((unsigned char *)context->salt)[i]);
|
||||
}
|
||||
|
||||
fprintf(fp, "\n");
|
||||
|
||||
fprintf(fp, "Secret[%d]: ", context->secretlen);
|
||||
|
||||
if (context->clear_secret) {
|
||||
fprintf(fp, "CLEARED\n");
|
||||
} else {
|
||||
for (unsigned i = 0; i < context->secretlen; ++i) {
|
||||
fprintf(fp, "%2.2x ", ((unsigned char *)context->secret)[i]);
|
||||
}
|
||||
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
|
||||
fprintf(fp, "Associated data[%d]: ", context->adlen);
|
||||
|
||||
for (unsigned i = 0; i < context->adlen; ++i) {
|
||||
fprintf(fp, "%2.2x ", ((unsigned char *)context->ad)[i]);
|
||||
}
|
||||
|
||||
fprintf(fp, "\n");
|
||||
|
||||
fprintf(fp, "Pre-hashing digest: ");
|
||||
|
||||
for (unsigned i = 0; i < ARGON2_PREHASH_DIGEST_LENGTH; ++i) {
|
||||
fprintf(fp, "%2.2x ", ((unsigned char *)blockhash)[i]);
|
||||
}
|
||||
|
||||
fprintf(fp, "\n");
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
void print_tag( const void *out, uint32_t outlen )
|
||||
{
|
||||
FILE *fp = fopen( ARGON2_KAT_FILENAME, "a+" );
|
||||
void print_tag(const void *out, uint32_t outlen) {
|
||||
FILE *fp = fopen(ARGON2_KAT_FILENAME, "a+");
|
||||
|
||||
if ( fp && out != NULL )
|
||||
{
|
||||
fprintf( fp, "Tag: " );
|
||||
if (fp && out != NULL) {
|
||||
fprintf(fp, "Tag: ");
|
||||
|
||||
for ( unsigned i = 0; i < outlen; ++i )
|
||||
{
|
||||
fprintf( fp, "%2.2x ", ( ( uint8_t * ) out )[i] );
|
||||
}
|
||||
|
||||
fprintf( fp, "\n" );
|
||||
|
||||
fclose( fp );
|
||||
for (unsigned i = 0; i < outlen; ++i) {
|
||||
fprintf(fp, "%2.2x ", ((uint8_t *)out)[i]);
|
||||
}
|
||||
|
||||
fprintf(fp, "\n");
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
void internal_kat( const Argon2_instance_t *instance, uint32_t pass )
|
||||
{
|
||||
FILE *fp = fopen( ARGON2_KAT_FILENAME, "a+" );
|
||||
void internal_kat(const Argon2_instance_t *instance, uint32_t pass) {
|
||||
FILE *fp = fopen(ARGON2_KAT_FILENAME, "a+");
|
||||
|
||||
if ( fp && instance != NULL )
|
||||
{
|
||||
fprintf( fp, "\n After pass %d:\n", pass );
|
||||
if (fp && instance != NULL) {
|
||||
fprintf(fp, "\n After pass %d:\n", pass);
|
||||
|
||||
for ( uint32_t i = 0; i < instance->memory_blocks; ++i )
|
||||
{
|
||||
uint32_t how_many_words = ( instance->memory_blocks > ARGON2_WORDS_IN_BLOCK ) ? 1 : ARGON2_WORDS_IN_BLOCK;
|
||||
for (uint32_t i = 0; i < instance->memory_blocks; ++i) {
|
||||
uint32_t how_many_words =
|
||||
(instance->memory_blocks > ARGON2_WORDS_IN_BLOCK)
|
||||
? 1
|
||||
: ARGON2_WORDS_IN_BLOCK;
|
||||
|
||||
for ( uint32_t j = 0; j < how_many_words; ++j )
|
||||
fprintf( fp, "Block %.4d [%3d]: %016" PRIx64 "\n", i, j, instance->memory[i].v[j] );
|
||||
}
|
||||
|
||||
fclose( fp );
|
||||
for (uint32_t j = 0; j < how_many_words; ++j)
|
||||
fprintf(fp, "Block %.4d [%3d]: %016" PRIx64 "\n", i, j,
|
||||
instance->memory[i].v[j]);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
|
19
src/kat.h
19
src/kat.h
|
@ -5,24 +5,26 @@
|
|||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
* this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __ARGON2_KAT_H__
|
||||
#define __ARGON2_KAT_H__
|
||||
|
||||
|
||||
/*
|
||||
* Initial KAT function that prints the inputs to the file
|
||||
* @param blockhash Array that contains pre-hashing digest
|
||||
* @param context Holds inputs
|
||||
* @param type Argon2 type
|
||||
* @pre blockhash must point to INPUT_INITIAL_HASH_LENGTH bytes
|
||||
* @pre context member pointers must point to allocated memory of size according to the length values
|
||||
* @pre context member pointers must point to allocated memory of size according
|
||||
* to the length values
|
||||
*/
|
||||
void initial_kat( const uint8_t *blockhash, const Argon2_Context *context, Argon2_type type );
|
||||
void initial_kat(const uint8_t *blockhash, const Argon2_Context *context,
|
||||
Argon2_type type);
|
||||
|
||||
/*
|
||||
* Function that prints the output tag
|
||||
|
@ -30,7 +32,7 @@ void initial_kat( const uint8_t *blockhash, const Argon2_Context *context, Argon
|
|||
* @param outlen digest length
|
||||
* @pre out must point to @a outlen bytes
|
||||
**/
|
||||
void print_tag( const void *out, uint32_t outlen );
|
||||
void print_tag(const void *out, uint32_t outlen);
|
||||
|
||||
/*
|
||||
* Function that prints the internal state at given moment
|
||||
|
@ -38,7 +40,6 @@ void print_tag( const void *out, uint32_t outlen );
|
|||
* @param pass current pass number
|
||||
* @pre instance must have necessary memory allocated
|
||||
**/
|
||||
void internal_kat( const Argon2_instance_t *instance, uint32_t pass );
|
||||
|
||||
void internal_kat(const Argon2_instance_t *instance, uint32_t pass);
|
||||
|
||||
#endif
|
||||
|
|
566
src/main.c
566
src/main.c
|
@ -5,11 +5,12 @@
|
|||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
* this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -25,382 +26,363 @@
|
|||
#define _MEASURE
|
||||
|
||||
#define T_COST_DEF 3
|
||||
#define LOG_M_COST_DEF 12 /*4 MB*/
|
||||
#define LOG_M_COST_DEF 12 /*4 MB*/
|
||||
#define LANES_DEF 4
|
||||
#define THREADS_DEF 4
|
||||
#define PWD_DEF "password"
|
||||
|
||||
#define UNUSED_PARAMETER(x) (void)(x)
|
||||
|
||||
|
||||
|
||||
static __inline uint64_t rdtsc( void )
|
||||
{
|
||||
static __inline uint64_t rdtsc(void) {
|
||||
#ifdef _MSC_VER
|
||||
return __rdtsc();
|
||||
return __rdtsc();
|
||||
#else
|
||||
#if defined(__amd64__) || defined(__x86_64__)
|
||||
uint64_t rax, rdx;
|
||||
__asm__ __volatile__ ( "rdtsc" : "=a" ( rax ), "=d"( rdx ) : : );
|
||||
return (rdx << 32) | rax;
|
||||
#elif defined(__i386__) || defined(__i386) || defined(__X86__)
|
||||
uint64_t rax;
|
||||
__asm__ __volatile__ ( "rdtsc" : "=A" ( rax ) : : );
|
||||
return rax;
|
||||
#else
|
||||
#error "Not implemented!"
|
||||
#endif
|
||||
#if defined(__amd64__) || defined(__x86_64__)
|
||||
uint64_t rax, rdx;
|
||||
__asm__ __volatile__("rdtsc" : "=a"(rax), "=d"(rdx) : :);
|
||||
return (rdx << 32) | rax;
|
||||
#elif defined(__i386__) || defined(__i386) || defined(__X86__)
|
||||
uint64_t rax;
|
||||
__asm__ __volatile__("rdtsc" : "=A"(rax) : :);
|
||||
return rax;
|
||||
#else
|
||||
#error "Not implemented!"
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Custom allocate memory
|
||||
*/
|
||||
int CustomAllocateMemory( uint8_t **memory, size_t length )
|
||||
{
|
||||
*memory = ( uint8_t * )malloc( length );
|
||||
int CustomAllocateMemory(uint8_t **memory, size_t length) {
|
||||
*memory = (uint8_t *)malloc(length);
|
||||
|
||||
if ( !*memory )
|
||||
{
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
if (!*memory) {
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
|
||||
return ARGON2_OK;
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Custom free memory
|
||||
*/
|
||||
void CustomFreeMemory( uint8_t *memory, size_t length )
|
||||
{
|
||||
UNUSED_PARAMETER( length );
|
||||
void CustomFreeMemory(uint8_t *memory, size_t length) {
|
||||
UNUSED_PARAMETER(length);
|
||||
|
||||
if ( memory )
|
||||
{
|
||||
free( memory );
|
||||
}
|
||||
if (memory) {
|
||||
free(memory);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void usage( const char *cmd )
|
||||
{
|
||||
printf( "usage: %s mode [parameters]\n", cmd );
|
||||
printf( "Mode:\n" );
|
||||
printf( "\tr\trun Argon2 with the selected parameters\n" );
|
||||
printf( "\tg\tgenerates test vectors for given Argon2 type\n" );
|
||||
printf( "\tb\tbenchmarks various Argon2 versions\n" );
|
||||
printf( "Parameters (for run mode):\n" );
|
||||
printf( "\t-y, --type [d or i, default i]\n" );
|
||||
printf( "\t-t, --tcost [time cost in 0..2^24, default %d]\n", T_COST_DEF );
|
||||
printf( "\t-m, --mcost [base 2 log of memory cost in 0..21, default %d]\n", LOG_M_COST_DEF );
|
||||
printf( "\t-l, --lanes [number of lanes in %u..%u, default %d]\n", ARGON2_MIN_LANES, ARGON2_MAX_LANES, LANES_DEF );
|
||||
printf( "\t-p, --threads [number of threads in %u..%u, default %d]\n", ARGON2_MIN_THREADS, ARGON2_MAX_THREADS, THREADS_DEF );
|
||||
printf( "\t-i, --password [password, default \"%s\"]\n", PWD_DEF );
|
||||
void usage(const char *cmd) {
|
||||
printf("usage: %s mode [parameters]\n", cmd);
|
||||
printf("Mode:\n");
|
||||
printf("\tr\trun Argon2 with the selected parameters\n");
|
||||
printf("\tg\tgenerates test vectors for given Argon2 type\n");
|
||||
printf("\tb\tbenchmarks various Argon2 versions\n");
|
||||
printf("Parameters (for run mode):\n");
|
||||
printf("\t-y, --type [d or i, default i]\n");
|
||||
printf("\t-t, --tcost [time cost in 0..2^24, default %d]\n", T_COST_DEF);
|
||||
printf("\t-m, --mcost [base 2 log of memory cost in 0..21, default %d]\n",
|
||||
LOG_M_COST_DEF);
|
||||
printf("\t-l, --lanes [number of lanes in %u..%u, default %d]\n",
|
||||
ARGON2_MIN_LANES, ARGON2_MAX_LANES, LANES_DEF);
|
||||
printf("\t-p, --threads [number of threads in %u..%u, default %d]\n",
|
||||
ARGON2_MIN_THREADS, ARGON2_MAX_THREADS, THREADS_DEF);
|
||||
printf("\t-i, --password [password, default \"%s\"]\n", PWD_DEF);
|
||||
}
|
||||
|
||||
|
||||
void fatal( const char *error )
|
||||
{
|
||||
fprintf( stderr, "error: %s\n", error );
|
||||
exit( 1 );
|
||||
void fatal(const char *error) {
|
||||
fprintf(stderr, "error: %s\n", error);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void print_bytes( const void *s, size_t len )
|
||||
{
|
||||
for( size_t i = 0; i < len; i++ )
|
||||
{
|
||||
printf( "%02x", ( ( const unsigned char * ) s )[i] & 0xff );
|
||||
}
|
||||
void print_bytes(const void *s, size_t len) {
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
printf("%02x", ((const unsigned char *)s)[i] & 0xff);
|
||||
}
|
||||
|
||||
printf( "\n" );
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Benchmarks Argon2 with salt length 16, password length 16, t_cost 1,
|
||||
and different m_cost and threads
|
||||
*/
|
||||
void benchmark()
|
||||
{
|
||||
void benchmark() {
|
||||
#define BENCH_OUTLEN 16
|
||||
#define BENCH_INLEN 16
|
||||
const uint32_t inlen = BENCH_INLEN;
|
||||
const unsigned outlen = BENCH_OUTLEN;
|
||||
unsigned char out[BENCH_OUTLEN];
|
||||
unsigned char pwd_array[BENCH_INLEN];
|
||||
unsigned char salt_array[BENCH_INLEN];
|
||||
const uint32_t inlen = BENCH_INLEN;
|
||||
const unsigned outlen = BENCH_OUTLEN;
|
||||
unsigned char out[BENCH_OUTLEN];
|
||||
unsigned char pwd_array[BENCH_INLEN];
|
||||
unsigned char salt_array[BENCH_INLEN];
|
||||
#undef BENCH_INLEN
|
||||
#undef BENCH_OUTLEN
|
||||
|
||||
uint32_t t_cost = 1;
|
||||
uint32_t t_cost = 1;
|
||||
|
||||
memset( pwd_array, 0, inlen );
|
||||
memset( salt_array, 1, inlen );
|
||||
uint32_t thread_test[6] = {1, 2, 4, 6, 8, 16};
|
||||
memset(pwd_array, 0, inlen);
|
||||
memset(salt_array, 1, inlen);
|
||||
uint32_t thread_test[6] = {1, 2, 4, 6, 8, 16};
|
||||
|
||||
uint32_t m_cost;
|
||||
uint32_t m_cost;
|
||||
|
||||
for ( m_cost = ( uint32_t ) 1 << 10; m_cost <= ( uint32_t ) 1 << 22; m_cost *= 2 )
|
||||
{
|
||||
uint32_t i;
|
||||
for (m_cost = (uint32_t)1 << 10; m_cost <= (uint32_t)1 << 22; m_cost *= 2) {
|
||||
uint32_t i;
|
||||
|
||||
for ( i=0; i <6; ++i )
|
||||
{
|
||||
uint32_t thread_n = thread_test[i];
|
||||
uint64_t start_cycles, stop_cycles, stop_cycles_i;
|
||||
for (i = 0; i < 6; ++i) {
|
||||
uint32_t thread_n = thread_test[i];
|
||||
uint64_t start_cycles, stop_cycles, stop_cycles_i;
|
||||
|
||||
clock_t start_time = clock();
|
||||
start_cycles = rdtsc();
|
||||
clock_t start_time = clock();
|
||||
start_cycles = rdtsc();
|
||||
|
||||
Argon2_Context context = {out, outlen, pwd_array, inlen, salt_array, inlen,
|
||||
NULL, 0, NULL, 0, t_cost, m_cost, thread_n, thread_n, NULL, NULL, false, false, false, false
|
||||
};
|
||||
argon2d( &context );
|
||||
stop_cycles = rdtsc();
|
||||
argon2i( &context );
|
||||
stop_cycles_i = rdtsc();
|
||||
clock_t stop_time = clock();
|
||||
Argon2_Context context = {out, outlen, pwd_array, inlen, salt_array,
|
||||
inlen, NULL, 0, NULL, 0,
|
||||
t_cost, m_cost, thread_n, thread_n, NULL,
|
||||
NULL, false, false, false, false};
|
||||
argon2d(&context);
|
||||
stop_cycles = rdtsc();
|
||||
argon2i(&context);
|
||||
stop_cycles_i = rdtsc();
|
||||
clock_t stop_time = clock();
|
||||
|
||||
uint64_t delta_d = ( stop_cycles - start_cycles ) / ( m_cost );
|
||||
uint64_t delta_i = ( stop_cycles_i - stop_cycles ) / ( m_cost );
|
||||
float mcycles_d = ( float ) ( stop_cycles - start_cycles ) / ( 1 << 20 );
|
||||
float mcycles_i = ( float ) ( stop_cycles_i - stop_cycles ) / ( 1 << 20 );
|
||||
printf( "Argon2d %d pass(es) %d Mbytes %d threads: %2.2f cpb %2.2f Mcycles \n", t_cost, m_cost >> 10, thread_n, ( float ) delta_d / 1024, mcycles_d );
|
||||
printf( "Argon2i %d pass(es) %d Mbytes %d threads: %2.2f cpb %2.2f Mcycles \n", t_cost, m_cost >> 10, thread_n, ( float ) delta_i / 1024, mcycles_i );
|
||||
uint64_t delta_d = (stop_cycles - start_cycles) / (m_cost);
|
||||
uint64_t delta_i = (stop_cycles_i - stop_cycles) / (m_cost);
|
||||
float mcycles_d = (float)(stop_cycles - start_cycles) / (1 << 20);
|
||||
float mcycles_i = (float)(stop_cycles_i - stop_cycles) / (1 << 20);
|
||||
printf("Argon2d %d pass(es) %d Mbytes %d threads: %2.2f cpb %2.2f "
|
||||
"Mcycles \n",
|
||||
t_cost, m_cost >> 10, thread_n, (float)delta_d / 1024, mcycles_d);
|
||||
printf("Argon2i %d pass(es) %d Mbytes %d threads: %2.2f cpb %2.2f "
|
||||
"Mcycles \n",
|
||||
t_cost, m_cost >> 10, thread_n, (float)delta_i / 1024, mcycles_i);
|
||||
|
||||
float run_time = ( ( float ) stop_time - start_time ) / ( CLOCKS_PER_SEC );
|
||||
printf( "%2.4f seconds\n\n", run_time );
|
||||
}
|
||||
float run_time = ((float)stop_time - start_time) / (CLOCKS_PER_SEC);
|
||||
printf("%2.4f seconds\n\n", run_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void run(uint8_t *out, char *pwd, uint32_t t_cost, uint32_t m_cost,
|
||||
uint32_t lanes, uint32_t threads, const char *type, bool print) {
|
||||
uint64_t start_cycles, stop_cycles;
|
||||
|
||||
void run( uint8_t *out, char *pwd, uint32_t t_cost, uint32_t m_cost, uint32_t lanes, uint32_t threads,const char *type, bool print )
|
||||
{
|
||||
uint64_t start_cycles, stop_cycles;
|
||||
|
||||
clock_t start_time = clock();
|
||||
start_cycles = rdtsc();
|
||||
clock_t start_time = clock();
|
||||
start_cycles = rdtsc();
|
||||
|
||||
#define SALT_LEN 16
|
||||
/*Fixed parameters*/
|
||||
const unsigned out_length = 32;
|
||||
const unsigned salt_length = SALT_LEN;
|
||||
bool clear_memory = false;
|
||||
bool clear_secret = false;
|
||||
bool clear_password = false;
|
||||
uint8_t salt[SALT_LEN];
|
||||
/*Fixed parameters*/
|
||||
const unsigned out_length = 32;
|
||||
const unsigned salt_length = SALT_LEN;
|
||||
bool clear_memory = false;
|
||||
bool clear_secret = false;
|
||||
bool clear_password = false;
|
||||
uint8_t salt[SALT_LEN];
|
||||
#undef SALT_LEN
|
||||
uint8_t *in = NULL;
|
||||
uint8_t *in = NULL;
|
||||
|
||||
if ( pwd )
|
||||
{
|
||||
in = malloc( strlen(pwd) + 1 );
|
||||
strcpy( (char *)in, pwd );
|
||||
}
|
||||
else
|
||||
{
|
||||
in = malloc( strlen(PWD_DEF) + 1 );
|
||||
strcpy( (char *)in, PWD_DEF );
|
||||
}
|
||||
if (pwd) {
|
||||
in = malloc(strlen(pwd) + 1);
|
||||
strcpy((char *)in, pwd);
|
||||
} else {
|
||||
in = malloc(strlen(PWD_DEF) + 1);
|
||||
strcpy((char *)in, PWD_DEF);
|
||||
}
|
||||
|
||||
const unsigned in_length = strlen( ( char * )in );
|
||||
const unsigned in_length = strlen((char *)in);
|
||||
|
||||
UNUSED_PARAMETER( threads );
|
||||
UNUSED_PARAMETER(threads);
|
||||
|
||||
memset( salt, 0x00, salt_length );
|
||||
memset(salt, 0x00, salt_length);
|
||||
|
||||
Argon2_Context context= {out, out_length, in, in_length, salt, salt_length,
|
||||
NULL, 0, NULL, 0, t_cost, m_cost, lanes, lanes,
|
||||
NULL, NULL,
|
||||
clear_password, clear_secret, clear_memory, print
|
||||
};
|
||||
printf( "Argon2%s with\n", type );
|
||||
printf( "\tt_cost = %d\n", t_cost );
|
||||
printf( "\tm_cost = %d\n", m_cost );
|
||||
printf( "\tpassword = %s\n", in );
|
||||
printf( "\tsalt = " ); print_bytes( salt, salt_length );
|
||||
Argon2_Context context = {
|
||||
out, out_length, in, in_length, salt, salt_length,
|
||||
NULL, 0, NULL, 0, t_cost, m_cost,
|
||||
lanes, lanes, NULL, NULL, clear_password, clear_secret,
|
||||
clear_memory, print};
|
||||
printf("Argon2%s with\n", type);
|
||||
printf("\tt_cost = %d\n", t_cost);
|
||||
printf("\tm_cost = %d\n", m_cost);
|
||||
printf("\tpassword = %s\n", in);
|
||||
printf("\tsalt = ");
|
||||
print_bytes(salt, salt_length);
|
||||
|
||||
if ( !strcmp( type,"d" ) ) argon2d( &context );
|
||||
else if ( !strcmp( type,"i" ) ) argon2i( &context );
|
||||
else fatal( "wrong Argon2 type" );
|
||||
if (!strcmp(type, "d"))
|
||||
argon2d(&context);
|
||||
else if (!strcmp(type, "i"))
|
||||
argon2i(&context);
|
||||
else
|
||||
fatal("wrong Argon2 type");
|
||||
|
||||
stop_cycles = rdtsc();
|
||||
clock_t finish_time = clock();
|
||||
stop_cycles = rdtsc();
|
||||
clock_t finish_time = clock();
|
||||
|
||||
float run_time = ((float)finish_time - start_time) / (CLOCKS_PER_SEC);
|
||||
printf("%2.3f seconds ", run_time);
|
||||
|
||||
float run_time = ( ( float ) finish_time - start_time ) / ( CLOCKS_PER_SEC );
|
||||
printf( "%2.3f seconds ", run_time );
|
||||
float mcycles = (float)(stop_cycles - start_cycles) / (1 << 20);
|
||||
printf("(%.3f mebicycles)\n", mcycles);
|
||||
|
||||
float mcycles = ( float ) ( stop_cycles - start_cycles ) / ( 1 << 20 );
|
||||
printf( "(%.3f mebicycles)\n", mcycles );
|
||||
print_bytes(out, out_length);
|
||||
|
||||
print_bytes( out, out_length );
|
||||
// show string encoding
|
||||
char string[300];
|
||||
encode_string(string, sizeof string, &context);
|
||||
printf("%s\n", string);
|
||||
|
||||
// show string encoding
|
||||
char string[300];
|
||||
encode_string( string, sizeof string, &context );
|
||||
printf( "%s\n", string );
|
||||
|
||||
free(in);
|
||||
free(in);
|
||||
}
|
||||
|
||||
void generate_testvectors( const char *type )
|
||||
{
|
||||
void generate_testvectors(const char *type) {
|
||||
#define TEST_OUTLEN 32
|
||||
#define TEST_PWDLEN 32
|
||||
#define TEST_SALTLEN 16
|
||||
#define TEST_SECRETLEN 8
|
||||
#define TEST_ADLEN 12
|
||||
bool clear_memory = false;
|
||||
bool clear_secret = false;
|
||||
bool clear_password = false;
|
||||
bool print_internals = true;
|
||||
bool clear_memory = false;
|
||||
bool clear_secret = false;
|
||||
bool clear_password = false;
|
||||
bool print_internals = true;
|
||||
|
||||
unsigned char out[TEST_OUTLEN];
|
||||
unsigned char pwd[TEST_PWDLEN];
|
||||
unsigned char salt[TEST_SALTLEN];
|
||||
unsigned char secret[TEST_SECRETLEN];
|
||||
unsigned char ad[TEST_ADLEN];
|
||||
const AllocateMemoryCallback myown_allocator = NULL;
|
||||
const FreeMemoryCallback myown_deallocator = NULL;
|
||||
unsigned char out[TEST_OUTLEN];
|
||||
unsigned char pwd[TEST_PWDLEN];
|
||||
unsigned char salt[TEST_SALTLEN];
|
||||
unsigned char secret[TEST_SECRETLEN];
|
||||
unsigned char ad[TEST_ADLEN];
|
||||
const AllocateMemoryCallback myown_allocator = NULL;
|
||||
const FreeMemoryCallback myown_deallocator = NULL;
|
||||
|
||||
unsigned t_cost = 3;
|
||||
unsigned m_cost = 16;
|
||||
unsigned lanes = 4;
|
||||
unsigned t_cost = 3;
|
||||
unsigned m_cost = 16;
|
||||
unsigned lanes = 4;
|
||||
|
||||
memset(pwd, 1, TEST_OUTLEN);
|
||||
memset(salt, 2, TEST_SALTLEN);
|
||||
memset(secret, 3, TEST_SECRETLEN);
|
||||
memset(ad, 4, TEST_ADLEN);
|
||||
memset(pwd, 1, TEST_OUTLEN);
|
||||
memset(salt, 2, TEST_SALTLEN);
|
||||
memset(secret, 3, TEST_SECRETLEN);
|
||||
memset(ad, 4, TEST_ADLEN);
|
||||
|
||||
printf( "Generating test vectors for Argon2%s in file \"%s\".\n", type, ARGON2_KAT_FILENAME );
|
||||
printf("Generating test vectors for Argon2%s in file \"%s\".\n", type,
|
||||
ARGON2_KAT_FILENAME);
|
||||
|
||||
Argon2_Context context = { out, TEST_OUTLEN, pwd, TEST_PWDLEN, salt, TEST_SALTLEN,
|
||||
secret, TEST_SECRETLEN, ad, TEST_ADLEN, t_cost, m_cost, lanes, lanes,
|
||||
myown_allocator, myown_deallocator,
|
||||
clear_password, clear_secret, clear_memory, print_internals
|
||||
};
|
||||
#undef TEST_OUTLEN
|
||||
#undef TEST_PWDLEN
|
||||
#undef TEST_SALTLEN
|
||||
#undef TEST_SECRETLEN
|
||||
#undef TEST_ADLEN
|
||||
Argon2_Context context = {out,
|
||||
TEST_OUTLEN,
|
||||
pwd,
|
||||
TEST_PWDLEN,
|
||||
salt,
|
||||
TEST_SALTLEN,
|
||||
secret,
|
||||
TEST_SECRETLEN,
|
||||
ad,
|
||||
TEST_ADLEN,
|
||||
t_cost,
|
||||
m_cost,
|
||||
lanes,
|
||||
lanes,
|
||||
myown_allocator,
|
||||
myown_deallocator,
|
||||
clear_password,
|
||||
clear_secret,
|
||||
clear_memory,
|
||||
print_internals};
|
||||
#undef TEST_OUTLEN
|
||||
#undef TEST_PWDLEN
|
||||
#undef TEST_SALTLEN
|
||||
#undef TEST_SECRETLEN
|
||||
#undef TEST_ADLEN
|
||||
|
||||
if ( !strcmp( type,"d" ) ) argon2d( &context );
|
||||
else if ( !strcmp( type,"i" ) ) argon2i( &context );
|
||||
else fatal( "wrong Argon2 type" );
|
||||
if (!strcmp(type, "d"))
|
||||
argon2d(&context);
|
||||
else if (!strcmp(type, "i"))
|
||||
argon2i(&context);
|
||||
else
|
||||
fatal("wrong Argon2 type");
|
||||
}
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
unsigned char out[32];
|
||||
uint32_t m_cost = 1<<LOG_M_COST_DEF;
|
||||
uint32_t t_cost = T_COST_DEF;
|
||||
uint32_t lanes = LANES_DEF;
|
||||
uint32_t threads = THREADS_DEF;
|
||||
char *pwd = NULL;
|
||||
int main(int argc, char *argv[]) {
|
||||
unsigned char out[32];
|
||||
uint32_t m_cost = 1 << LOG_M_COST_DEF;
|
||||
uint32_t t_cost = T_COST_DEF;
|
||||
uint32_t lanes = LANES_DEF;
|
||||
uint32_t threads = THREADS_DEF;
|
||||
char *pwd = NULL;
|
||||
|
||||
bool testvectors = false;
|
||||
const char *type= "i";
|
||||
bool testvectors = false;
|
||||
const char *type = "i";
|
||||
|
||||
remove( ARGON2_KAT_FILENAME );
|
||||
remove(ARGON2_KAT_FILENAME);
|
||||
|
||||
if ( argc == 1 )
|
||||
{
|
||||
usage( argv[0] );
|
||||
return 1;
|
||||
}
|
||||
if (argc == 1) {
|
||||
usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for ( int i = 1; i < argc; i++ )
|
||||
{
|
||||
char *a = argv[i];
|
||||
for (int i = 1; i < argc; i++) {
|
||||
char *a = argv[i];
|
||||
|
||||
if ( !strcmp( a, "-m" ) || !strcmp( a, "--mcost" ) )
|
||||
{
|
||||
if ( i < argc - 1 )
|
||||
{
|
||||
i++;
|
||||
m_cost = ( uint8_t ) 1 << ( ( uint8_t )atoi( argv[i] ) % 22 );
|
||||
continue;
|
||||
}
|
||||
else fatal( "missing memory cost argument" );
|
||||
}
|
||||
else if ( !strcmp( a, "-t" ) || !strcmp( a, "--tcost" ) )
|
||||
{
|
||||
if ( i < argc - 1 )
|
||||
{
|
||||
i++;
|
||||
t_cost = atoi( argv[i] ) & 0xffffff;
|
||||
continue;
|
||||
}
|
||||
else fatal( "missing time cost argument" );
|
||||
}
|
||||
else if ( !strcmp( a, "-p" ) || !strcmp( a, "--threads" ) )
|
||||
{
|
||||
if ( i < argc - 1 )
|
||||
{
|
||||
i++;
|
||||
threads = atoi( argv[i] ) % ARGON2_MAX_THREADS;
|
||||
continue;
|
||||
}
|
||||
else fatal( "missing threads argument" );
|
||||
}
|
||||
else if ( !strcmp( a, "-l" ) || !strcmp( a, "--lanes" ) )
|
||||
{
|
||||
if ( i < argc - 1 )
|
||||
{
|
||||
i++;
|
||||
lanes = atoi( argv[i] ) % ARGON2_MAX_LANES;
|
||||
continue;
|
||||
}
|
||||
else fatal( "missing lanes argument" );
|
||||
}
|
||||
else if ( !strcmp( a, "-y" ) || !strcmp( a, "--type" ) )
|
||||
{
|
||||
if ( i < argc - 1 )
|
||||
{
|
||||
i++;
|
||||
type = argv[i];
|
||||
continue;
|
||||
}
|
||||
else fatal( "missing type argument" );
|
||||
}
|
||||
else if ( !strcmp( a, "-i" ) || !strcmp( a, "--password" ) )
|
||||
{
|
||||
if ( i < argc - 1 )
|
||||
{
|
||||
i++;
|
||||
pwd = argv[i];
|
||||
continue;
|
||||
}
|
||||
else fatal( "missing threads argument" );
|
||||
}
|
||||
else if ( !strcmp( a, "r" ) )
|
||||
{
|
||||
testvectors = false;
|
||||
continue;
|
||||
}
|
||||
else if ( !strcmp( a, "g" ) )
|
||||
{
|
||||
testvectors = true;
|
||||
continue;
|
||||
}
|
||||
else if ( !strcmp( a, "b" ) )
|
||||
{
|
||||
benchmark();
|
||||
return 0;
|
||||
}
|
||||
else fatal( "unknown argument" );
|
||||
}
|
||||
|
||||
if ( testvectors )
|
||||
{
|
||||
generate_testvectors( type );
|
||||
return 0;
|
||||
}
|
||||
|
||||
run( out, pwd, t_cost, m_cost, lanes, threads, type, testvectors );
|
||||
if (!strcmp(a, "-m") || !strcmp(a, "--mcost")) {
|
||||
if (i < argc - 1) {
|
||||
i++;
|
||||
m_cost = (uint8_t)1 << ((uint8_t)atoi(argv[i]) % 22);
|
||||
continue;
|
||||
} else
|
||||
fatal("missing memory cost argument");
|
||||
} else if (!strcmp(a, "-t") || !strcmp(a, "--tcost")) {
|
||||
if (i < argc - 1) {
|
||||
i++;
|
||||
t_cost = atoi(argv[i]) & 0xffffff;
|
||||
continue;
|
||||
} else
|
||||
fatal("missing time cost argument");
|
||||
} else if (!strcmp(a, "-p") || !strcmp(a, "--threads")) {
|
||||
if (i < argc - 1) {
|
||||
i++;
|
||||
threads = atoi(argv[i]) % ARGON2_MAX_THREADS;
|
||||
continue;
|
||||
} else
|
||||
fatal("missing threads argument");
|
||||
} else if (!strcmp(a, "-l") || !strcmp(a, "--lanes")) {
|
||||
if (i < argc - 1) {
|
||||
i++;
|
||||
lanes = atoi(argv[i]) % ARGON2_MAX_LANES;
|
||||
continue;
|
||||
} else
|
||||
fatal("missing lanes argument");
|
||||
} else if (!strcmp(a, "-y") || !strcmp(a, "--type")) {
|
||||
if (i < argc - 1) {
|
||||
i++;
|
||||
type = argv[i];
|
||||
continue;
|
||||
} else
|
||||
fatal("missing type argument");
|
||||
} else if (!strcmp(a, "-i") || !strcmp(a, "--password")) {
|
||||
if (i < argc - 1) {
|
||||
i++;
|
||||
pwd = argv[i];
|
||||
continue;
|
||||
} else
|
||||
fatal("missing threads argument");
|
||||
} else if (!strcmp(a, "r")) {
|
||||
testvectors = false;
|
||||
continue;
|
||||
} else if (!strcmp(a, "g")) {
|
||||
testvectors = true;
|
||||
continue;
|
||||
} else if (!strcmp(a, "b")) {
|
||||
benchmark();
|
||||
return 0;
|
||||
} else
|
||||
fatal("unknown argument");
|
||||
}
|
||||
|
||||
if (testvectors) {
|
||||
generate_testvectors(type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
run(out, pwd, t_cost, m_cost, lanes, threads, type, testvectors);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
312
src/opt.c
312
src/opt.c
|
@ -5,11 +5,12 @@
|
|||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
* this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -22,216 +23,205 @@
|
|||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "argon2.h"
|
||||
#include "core.h"
|
||||
#include "opt.h"
|
||||
#include "kat.h"
|
||||
|
||||
|
||||
#include "blake2/blamka-round-opt.h"
|
||||
#include "blake2/blake2-impl.h"
|
||||
#include "blake2/blake2.h"
|
||||
|
||||
|
||||
/* The KAT file name */
|
||||
const char *ARGON2_KAT_FILENAME = "kat-argon2-opt.log";
|
||||
|
||||
#define r16 \
|
||||
(_mm_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9))
|
||||
#define r24 \
|
||||
(_mm_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10))
|
||||
|
||||
#define r16 (_mm_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9))
|
||||
#define r24 (_mm_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10))
|
||||
void fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_block) {
|
||||
__m128i t0, t1;
|
||||
__m128i block_XY[ARGON2_QWORDS_IN_BLOCK];
|
||||
|
||||
void fill_block( __m128i *state, const uint8_t *ref_block, uint8_t *next_block )
|
||||
{
|
||||
__m128i t0, t1;
|
||||
__m128i block_XY[ARGON2_QWORDS_IN_BLOCK];
|
||||
for (uint32_t i = 0; i < ARGON2_QWORDS_IN_BLOCK; i++) {
|
||||
block_XY[i] = _mm_loadu_si128((__m128i *)ref_block);
|
||||
ref_block += 16;
|
||||
}
|
||||
|
||||
for ( uint32_t i = 0; i < ARGON2_QWORDS_IN_BLOCK; i++ )
|
||||
{
|
||||
block_XY[i] = _mm_loadu_si128( ( __m128i * ) ref_block );
|
||||
ref_block += 16;
|
||||
}
|
||||
for (uint32_t i = 0; i < ARGON2_QWORDS_IN_BLOCK; i++) {
|
||||
block_XY[i] = state[i] = _mm_xor_si128(state[i], block_XY[i]);
|
||||
}
|
||||
|
||||
for ( uint32_t i = 0; i < ARGON2_QWORDS_IN_BLOCK; i++ )
|
||||
{
|
||||
block_XY[i] = state[i] = _mm_xor_si128( state[i], block_XY[i] );
|
||||
}
|
||||
BLAKE2_ROUND(state[0], state[1], state[2], state[3], state[4], state[5],
|
||||
state[6], state[7]);
|
||||
|
||||
BLAKE2_ROUND( state[0], state[1], state[2], state[3],
|
||||
state[4], state[5], state[6], state[7] );
|
||||
BLAKE2_ROUND(state[8], state[9], state[10], state[11], state[12], state[13],
|
||||
state[14], state[15]);
|
||||
|
||||
BLAKE2_ROUND( state[8], state[9], state[10], state[11],
|
||||
state[12], state[13], state[14], state[15] );
|
||||
BLAKE2_ROUND(state[16], state[17], state[18], state[19], state[20], state[21],
|
||||
state[22], state[23]);
|
||||
|
||||
BLAKE2_ROUND( state[16], state[17], state[18], state[19],
|
||||
state[20], state[21], state[22], state[23] );
|
||||
BLAKE2_ROUND(state[24], state[25], state[26], state[27], state[28], state[29],
|
||||
state[30], state[31]);
|
||||
|
||||
BLAKE2_ROUND( state[24], state[25], state[26], state[27],
|
||||
state[28], state[29], state[30], state[31] );
|
||||
BLAKE2_ROUND(state[32], state[33], state[34], state[35], state[36], state[37],
|
||||
state[38], state[39]);
|
||||
|
||||
BLAKE2_ROUND( state[32], state[33], state[34], state[35],
|
||||
state[36], state[37], state[38], state[39] );
|
||||
BLAKE2_ROUND(state[40], state[41], state[42], state[43], state[44], state[45],
|
||||
state[46], state[47]);
|
||||
|
||||
BLAKE2_ROUND( state[40], state[41], state[42], state[43],
|
||||
state[44], state[45], state[46], state[47] );
|
||||
BLAKE2_ROUND(state[48], state[49], state[50], state[51], state[52], state[53],
|
||||
state[54], state[55]);
|
||||
|
||||
BLAKE2_ROUND( state[48], state[49], state[50], state[51],
|
||||
state[52], state[53], state[54], state[55] );
|
||||
BLAKE2_ROUND(state[56], state[57], state[58], state[59], state[60], state[61],
|
||||
state[62], state[63]);
|
||||
|
||||
BLAKE2_ROUND( state[56], state[57], state[58], state[59],
|
||||
state[60], state[61], state[62], state[63] );
|
||||
BLAKE2_ROUND(state[0], state[8], state[16], state[24], state[32], state[40],
|
||||
state[48], state[56]);
|
||||
|
||||
BLAKE2_ROUND(state[1], state[9], state[17], state[25], state[33], state[41],
|
||||
state[49], state[57]);
|
||||
|
||||
BLAKE2_ROUND( state[0], state[8], state[16], state[24],
|
||||
state[32], state[40], state[48], state[56] );
|
||||
BLAKE2_ROUND(state[2], state[10], state[18], state[26], state[34], state[42],
|
||||
state[50], state[58])
|
||||
|
||||
BLAKE2_ROUND( state[1], state[9], state[17], state[25],
|
||||
state[33], state[41], state[49], state[57] );
|
||||
BLAKE2_ROUND(state[3], state[11], state[19], state[27], state[35], state[43],
|
||||
state[51], state[59]);
|
||||
|
||||
BLAKE2_ROUND( state[2], state[10], state[18], state[26],
|
||||
state[34], state[42], state[50], state[58] )
|
||||
BLAKE2_ROUND(state[4], state[12], state[20], state[28], state[36], state[44],
|
||||
state[52], state[60]);
|
||||
|
||||
BLAKE2_ROUND( state[3], state[11], state[19], state[27],
|
||||
state[35], state[43], state[51], state[59] );
|
||||
BLAKE2_ROUND(state[5], state[13], state[21], state[29], state[37], state[45],
|
||||
state[53], state[61]);
|
||||
|
||||
BLAKE2_ROUND( state[4], state[12], state[20], state[28],
|
||||
state[36], state[44], state[52], state[60] );
|
||||
BLAKE2_ROUND(state[6], state[14], state[22], state[30], state[38], state[46],
|
||||
state[54], state[62]);
|
||||
|
||||
BLAKE2_ROUND( state[5], state[13], state[21], state[29],
|
||||
state[37], state[45], state[53], state[61] );
|
||||
BLAKE2_ROUND(state[7], state[15], state[23], state[31], state[39], state[47],
|
||||
state[55], state[63]);
|
||||
|
||||
BLAKE2_ROUND( state[6], state[14], state[22], state[30],
|
||||
state[38], state[46], state[54], state[62] );
|
||||
for (uint32_t i = 0; i < ARGON2_QWORDS_IN_BLOCK; i++) {
|
||||
// Feedback
|
||||
state[i] = _mm_xor_si128(state[i], block_XY[i]);
|
||||
}
|
||||
|
||||
BLAKE2_ROUND( state[7], state[15], state[23], state[31],
|
||||
state[39], state[47], state[55], state[63] );
|
||||
|
||||
for ( uint32_t i = 0; i < ARGON2_QWORDS_IN_BLOCK; i++ )
|
||||
{
|
||||
// Feedback
|
||||
state[i] = _mm_xor_si128( state[i], block_XY[i] );
|
||||
}
|
||||
|
||||
for ( uint32_t i = 0; i < ARGON2_QWORDS_IN_BLOCK; i++ )
|
||||
{
|
||||
_mm_storeu_si128( ( __m128i * ) next_block, state[i] );
|
||||
next_block += 16;
|
||||
}
|
||||
for (uint32_t i = 0; i < ARGON2_QWORDS_IN_BLOCK; i++) {
|
||||
_mm_storeu_si128((__m128i *)next_block, state[i]);
|
||||
next_block += 16;
|
||||
}
|
||||
}
|
||||
|
||||
void generate_addresses( const Argon2_instance_t *instance, const Argon2_position_t *position, uint64_t *pseudo_rands )
|
||||
{
|
||||
block zero_block, address_block,input_block;
|
||||
init_block_value( &zero_block,0 );
|
||||
copy_block( &address_block,&zero_block );
|
||||
copy_block( &input_block,&zero_block );
|
||||
void generate_addresses(const Argon2_instance_t *instance,
|
||||
const Argon2_position_t *position,
|
||||
uint64_t *pseudo_rands) {
|
||||
block zero_block, address_block, input_block;
|
||||
init_block_value(&zero_block, 0);
|
||||
copy_block(&address_block, &zero_block);
|
||||
copy_block(&input_block, &zero_block);
|
||||
|
||||
if ( instance != NULL && position != NULL )
|
||||
{
|
||||
input_block.v[0] = position->pass;
|
||||
input_block.v[1] = position->lane;
|
||||
input_block.v[2] = position->slice;
|
||||
input_block.v[3] = instance->memory_blocks;
|
||||
input_block.v[4] = instance->passes;
|
||||
input_block.v[5] = instance->type;
|
||||
if (instance != NULL && position != NULL) {
|
||||
input_block.v[0] = position->pass;
|
||||
input_block.v[1] = position->lane;
|
||||
input_block.v[2] = position->slice;
|
||||
input_block.v[3] = instance->memory_blocks;
|
||||
input_block.v[4] = instance->passes;
|
||||
input_block.v[5] = instance->type;
|
||||
|
||||
for ( uint32_t i = 0; i < instance->segment_length; ++i )
|
||||
{
|
||||
if ( i % ARGON2_ADDRESSES_IN_BLOCK == 0 )
|
||||
{
|
||||
input_block.v[6]++;
|
||||
block zero_block, zero2_block;
|
||||
init_block_value( &zero_block,0 );
|
||||
init_block_value( &zero2_block,0 );
|
||||
fill_block( ( __m128i * ) & zero_block.v, ( uint8_t * ) & input_block.v, ( uint8_t * ) & address_block.v );
|
||||
fill_block( ( __m128i * ) & zero2_block.v, ( uint8_t * ) & address_block.v, ( uint8_t * ) & address_block.v );
|
||||
}
|
||||
for (uint32_t i = 0; i < instance->segment_length; ++i) {
|
||||
if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
|
||||
input_block.v[6]++;
|
||||
block zero_block, zero2_block;
|
||||
init_block_value(&zero_block, 0);
|
||||
init_block_value(&zero2_block, 0);
|
||||
fill_block((__m128i *)&zero_block.v, (uint8_t *)&input_block.v,
|
||||
(uint8_t *)&address_block.v);
|
||||
fill_block((__m128i *)&zero2_block.v, (uint8_t *)&address_block.v,
|
||||
(uint8_t *)&address_block.v);
|
||||
}
|
||||
|
||||
pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
|
||||
}
|
||||
pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fill_segment( const Argon2_instance_t *instance, Argon2_position_t position )
|
||||
{
|
||||
if ( instance == NULL ) return;
|
||||
void fill_segment(const Argon2_instance_t *instance,
|
||||
Argon2_position_t position) {
|
||||
if (instance == NULL)
|
||||
return;
|
||||
|
||||
uint64_t pseudo_rand, ref_index, ref_lane;
|
||||
uint32_t prev_offset, curr_offset;
|
||||
__m128i state[64];
|
||||
bool data_independent_addressing = ( instance->type == Argon2_i );
|
||||
uint64_t pseudo_rand, ref_index, ref_lane;
|
||||
uint32_t prev_offset, curr_offset;
|
||||
__m128i state[64];
|
||||
bool data_independent_addressing = (instance->type == Argon2_i);
|
||||
|
||||
// Pseudo-random values that determine the reference block position
|
||||
uint64_t *pseudo_rands = ( uint64_t * )malloc( sizeof( uint64_t )*instance->segment_length );
|
||||
// Pseudo-random values that determine the reference block position
|
||||
uint64_t *pseudo_rands =
|
||||
(uint64_t *)malloc(sizeof(uint64_t) * instance->segment_length);
|
||||
|
||||
if ( pseudo_rands == NULL ) return;
|
||||
if (pseudo_rands == NULL)
|
||||
return;
|
||||
|
||||
if ( data_independent_addressing )
|
||||
{
|
||||
generate_addresses( instance, &position, pseudo_rands );
|
||||
if (data_independent_addressing) {
|
||||
generate_addresses(instance, &position, pseudo_rands);
|
||||
}
|
||||
|
||||
uint32_t starting_index = 0;
|
||||
|
||||
if ((0 == position.pass) && (0 == position.slice)) {
|
||||
starting_index = 2; // we have already generated the first two blocks
|
||||
}
|
||||
|
||||
// Offset of the current block
|
||||
curr_offset = position.lane * instance->lane_length +
|
||||
position.slice * instance->segment_length + starting_index;
|
||||
|
||||
if (0 == curr_offset % instance->lane_length) {
|
||||
// Last block in this lane
|
||||
prev_offset = curr_offset + instance->lane_length - 1;
|
||||
} else {
|
||||
// Previous block
|
||||
prev_offset = curr_offset - 1;
|
||||
}
|
||||
|
||||
memcpy(state, (uint8_t *)((instance->memory + prev_offset)->v),
|
||||
ARGON2_BLOCK_SIZE);
|
||||
|
||||
for (uint32_t i = starting_index; i < instance->segment_length;
|
||||
++i, ++curr_offset, ++prev_offset) {
|
||||
/*1.1 Rotating prev_offset if needed */
|
||||
if (curr_offset % instance->lane_length == 1) {
|
||||
prev_offset = curr_offset - 1;
|
||||
}
|
||||
|
||||
uint32_t starting_index = 0;
|
||||
|
||||
if ( ( 0 == position.pass ) && ( 0 == position.slice ) )
|
||||
{
|
||||
starting_index = 2; // we have already generated the first two blocks
|
||||
/* 1.2 Computing the index of the reference block */
|
||||
/* 1.2.1 Taking pseudo-random value from the previous block */
|
||||
if (data_independent_addressing) {
|
||||
pseudo_rand = pseudo_rands[i];
|
||||
} else {
|
||||
pseudo_rand = instance->memory[prev_offset].v[0];
|
||||
}
|
||||
|
||||
// Offset of the current block
|
||||
curr_offset = position.lane * instance->lane_length + position.slice * instance->segment_length + starting_index;
|
||||
/* 1.2.2 Computing the lane of the reference block */
|
||||
ref_lane = ((pseudo_rand >> 32)) % instance->lanes;
|
||||
|
||||
if ( 0 == curr_offset % instance->lane_length )
|
||||
{
|
||||
// Last block in this lane
|
||||
prev_offset = curr_offset + instance->lane_length - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Previous block
|
||||
prev_offset = curr_offset - 1;
|
||||
if ((position.pass == 0) && (position.slice == 0)) {
|
||||
// Can not reference other lanes yet
|
||||
ref_lane = position.lane;
|
||||
}
|
||||
|
||||
memcpy( state, ( uint8_t * ) ( ( instance->memory + prev_offset )->v ), ARGON2_BLOCK_SIZE );
|
||||
/* 1.2.3 Computing the number of possible reference block within the lane.
|
||||
*/
|
||||
position.index = i;
|
||||
ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF,
|
||||
ref_lane == position.lane);
|
||||
|
||||
for ( uint32_t i = starting_index; i < instance->segment_length; ++i, ++curr_offset, ++prev_offset )
|
||||
{
|
||||
/*1.1 Rotating prev_offset if needed */
|
||||
if ( curr_offset % instance->lane_length == 1 )
|
||||
{
|
||||
prev_offset = curr_offset - 1;
|
||||
}
|
||||
|
||||
/* 1.2 Computing the index of the reference block */
|
||||
/* 1.2.1 Taking pseudo-random value from the previous block */
|
||||
if ( data_independent_addressing )
|
||||
{
|
||||
pseudo_rand = pseudo_rands[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
pseudo_rand = instance->memory[prev_offset].v[0];
|
||||
}
|
||||
|
||||
/* 1.2.2 Computing the lane of the reference block */
|
||||
ref_lane = ( ( pseudo_rand >> 32 ) ) % instance->lanes;
|
||||
|
||||
if ( ( position.pass == 0 ) && ( position.slice == 0 ) )
|
||||
{
|
||||
// Can not reference other lanes yet
|
||||
ref_lane = position.lane;
|
||||
}
|
||||
|
||||
/* 1.2.3 Computing the number of possible reference block within the lane. */
|
||||
position.index = i;
|
||||
ref_index = index_alpha( instance, &position, pseudo_rand & 0xFFFFFFFF, ref_lane == position.lane );
|
||||
|
||||
/* 2 Creating a new block */
|
||||
block *ref_block = instance->memory + instance->lane_length * ref_lane + ref_index;
|
||||
block *curr_block = instance->memory + curr_offset;
|
||||
fill_block( state, ( uint8_t * ) ref_block->v, ( uint8_t * ) curr_block->v );
|
||||
}
|
||||
|
||||
free( pseudo_rands );
|
||||
/* 2 Creating a new block */
|
||||
block *ref_block =
|
||||
instance->memory + instance->lane_length * ref_lane + ref_index;
|
||||
block *curr_block = instance->memory + curr_offset;
|
||||
fill_block(state, (uint8_t *)ref_block->v, (uint8_t *)curr_block->v);
|
||||
}
|
||||
|
||||
free(pseudo_rands);
|
||||
}
|
||||
|
|
25
src/opt.h
25
src/opt.h
|
@ -5,8 +5,10 @@
|
|||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
* this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#ifndef OPT_H
|
||||
|
@ -19,26 +21,29 @@
|
|||
* @param next_block Pointer to the block to be constructed
|
||||
* @pre all block pointers must be valid
|
||||
*/
|
||||
void fill_block( __m128i *state, const uint8_t *ref_block, uint8_t *next_block );
|
||||
|
||||
void fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_block);
|
||||
|
||||
/*
|
||||
* Generate pseudo-random values to reference blocks in the segment and puts them into the array
|
||||
* Generate pseudo-random values to reference blocks in the segment and puts
|
||||
* them into the array
|
||||
* @param instance Pointer to the current instance
|
||||
* @param position Pointer to the current position
|
||||
* @param pseudo_rands Pointer to the array of 64-bit values
|
||||
* @pre pseudo_rands must point to @a instance->segment_length allocated values
|
||||
*/
|
||||
void generate_addresses( const Argon2_instance_t *instance, const Argon2_position_t *position, uint64_t *pseudo_rands );
|
||||
void generate_addresses(const Argon2_instance_t *instance,
|
||||
const Argon2_position_t *position,
|
||||
uint64_t *pseudo_rands);
|
||||
|
||||
/*
|
||||
* Function that fills the segment using previous segments also from other threads.
|
||||
* Function that fills the segment using previous segments also from other
|
||||
* threads.
|
||||
* Identical to the reference code except that it calls optimized FillBlock()
|
||||
* @param instance Pointer to the current instance
|
||||
* @param position Current position
|
||||
* @pre all block pointers must be valid
|
||||
*/
|
||||
void fill_segment( const Argon2_instance_t *instance, Argon2_position_t position );
|
||||
|
||||
#endif /* ARGON2_OPT_CORE_H */
|
||||
void fill_segment(const Argon2_instance_t *instance,
|
||||
Argon2_position_t position);
|
||||
|
||||
#endif /* ARGON2_OPT_CORE_H */
|
||||
|
|
255
src/ref.c
255
src/ref.c
|
@ -5,11 +5,12 @@
|
|||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
* this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -19,157 +20,151 @@
|
|||
#include "ref.h"
|
||||
#include "kat.h"
|
||||
|
||||
|
||||
#include "blake2/blamka-round-ref.h"
|
||||
#include "blake2/blake2-impl.h"
|
||||
#include "blake2/blake2.h"
|
||||
|
||||
|
||||
/* The KAT file name */
|
||||
const char *ARGON2_KAT_FILENAME = "kat-argon2-ref.log";
|
||||
|
||||
void fill_block(const block *prev_block, const block *ref_block,
|
||||
block *next_block) {
|
||||
block blockR;
|
||||
copy_block(&blockR, ref_block);
|
||||
xor_block(&blockR, prev_block);
|
||||
block block_tmp;
|
||||
copy_block(&block_tmp, &blockR);
|
||||
|
||||
void fill_block( const block *prev_block, const block *ref_block, block *next_block )
|
||||
{
|
||||
block blockR;
|
||||
copy_block( &blockR,ref_block );
|
||||
xor_block( &blockR,prev_block );
|
||||
block block_tmp;
|
||||
copy_block( &block_tmp, &blockR );
|
||||
// Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then
|
||||
// (16,17,..31)... finally (112,113,...127)
|
||||
for (unsigned i = 0; i < 8; ++i) {
|
||||
BLAKE2_ROUND_NOMSG(
|
||||
blockR.v[16 * i], blockR.v[16 * i + 1], blockR.v[16 * i + 2],
|
||||
blockR.v[16 * i + 3], blockR.v[16 * i + 4], blockR.v[16 * i + 5],
|
||||
blockR.v[16 * i + 6], blockR.v[16 * i + 7], blockR.v[16 * i + 8],
|
||||
blockR.v[16 * i + 9], blockR.v[16 * i + 10], blockR.v[16 * i + 11],
|
||||
blockR.v[16 * i + 12], blockR.v[16 * i + 13], blockR.v[16 * i + 14],
|
||||
blockR.v[16 * i + 15]);
|
||||
}
|
||||
|
||||
// Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then (16,17,..31)... finally (112,113,...127)
|
||||
for ( unsigned i = 0; i < 8; ++i )
|
||||
{
|
||||
BLAKE2_ROUND_NOMSG( blockR.v[16 * i], blockR.v[16 * i + 1], blockR.v[16 * i + 2], blockR.v[16 * i + 3],
|
||||
blockR.v[16 * i + 4], blockR.v[16 * i + 5], blockR.v[16 * i + 6], blockR.v[16 * i + 7],
|
||||
blockR.v[16 * i + 8], blockR.v[16 * i + 9], blockR.v[16 * i + 10], blockR.v[16 * i + 11],
|
||||
blockR.v[16 * i + 12], blockR.v[16 * i + 13], blockR.v[16 * i + 14], blockR.v[16 * i + 15] );
|
||||
}
|
||||
// Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then
|
||||
// (2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127)
|
||||
for (unsigned i = 0; i < 8; i++) {
|
||||
BLAKE2_ROUND_NOMSG(
|
||||
blockR.v[2 * i], blockR.v[2 * i + 1], blockR.v[2 * i + 16],
|
||||
blockR.v[2 * i + 17], blockR.v[2 * i + 32], blockR.v[2 * i + 33],
|
||||
blockR.v[2 * i + 48], blockR.v[2 * i + 49], blockR.v[2 * i + 64],
|
||||
blockR.v[2 * i + 65], blockR.v[2 * i + 80], blockR.v[2 * i + 81],
|
||||
blockR.v[2 * i + 96], blockR.v[2 * i + 97], blockR.v[2 * i + 112],
|
||||
blockR.v[2 * i + 113]);
|
||||
}
|
||||
|
||||
// Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then (2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127)
|
||||
for ( unsigned i = 0; i < 8; i++ )
|
||||
{
|
||||
BLAKE2_ROUND_NOMSG( blockR.v[2 * i], blockR.v[2 * i + 1], blockR.v[2 * i + 16], blockR.v[2 * i + 17],
|
||||
blockR.v[2 * i + 32], blockR.v[2 * i + 33], blockR.v[2 * i + 48], blockR.v[2 * i + 49],
|
||||
blockR.v[2 * i + 64], blockR.v[2 * i + 65], blockR.v[2 * i + 80], blockR.v[2 * i + 81],
|
||||
blockR.v[2 * i + 96], blockR.v[2 * i + 97], blockR.v[2 * i + 112], blockR.v[2 * i + 113] );
|
||||
}
|
||||
|
||||
copy_block( next_block,&block_tmp );
|
||||
xor_block( next_block,&blockR );
|
||||
copy_block(next_block, &block_tmp);
|
||||
xor_block(next_block, &blockR);
|
||||
}
|
||||
|
||||
void generate_addresses( const Argon2_instance_t *instance, const Argon2_position_t *position, uint64_t *pseudo_rands )
|
||||
{
|
||||
block zero_block, input_block, address_block;
|
||||
init_block_value( &zero_block,0 );
|
||||
init_block_value( &input_block,0 );
|
||||
init_block_value( &address_block,0 );
|
||||
void generate_addresses(const Argon2_instance_t *instance,
|
||||
const Argon2_position_t *position,
|
||||
uint64_t *pseudo_rands) {
|
||||
block zero_block, input_block, address_block;
|
||||
init_block_value(&zero_block, 0);
|
||||
init_block_value(&input_block, 0);
|
||||
init_block_value(&address_block, 0);
|
||||
|
||||
if ( instance != NULL && position != NULL )
|
||||
{
|
||||
input_block.v[0] = position->pass;
|
||||
input_block.v[1] = position->lane;
|
||||
input_block.v[2] = position->slice;
|
||||
input_block.v[3] = instance->memory_blocks;
|
||||
input_block.v[4] = instance->passes;
|
||||
input_block.v[5] = instance->type;
|
||||
if (instance != NULL && position != NULL) {
|
||||
input_block.v[0] = position->pass;
|
||||
input_block.v[1] = position->lane;
|
||||
input_block.v[2] = position->slice;
|
||||
input_block.v[3] = instance->memory_blocks;
|
||||
input_block.v[4] = instance->passes;
|
||||
input_block.v[5] = instance->type;
|
||||
|
||||
for ( uint32_t i = 0; i < instance->segment_length; ++i )
|
||||
{
|
||||
if ( i % ARGON2_ADDRESSES_IN_BLOCK == 0 )
|
||||
{
|
||||
input_block.v[6]++;
|
||||
fill_block( &zero_block, &input_block, &address_block );
|
||||
fill_block( &zero_block, &address_block, &address_block );
|
||||
}
|
||||
for (uint32_t i = 0; i < instance->segment_length; ++i) {
|
||||
if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
|
||||
input_block.v[6]++;
|
||||
fill_block(&zero_block, &input_block, &address_block);
|
||||
fill_block(&zero_block, &address_block, &address_block);
|
||||
}
|
||||
|
||||
pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
|
||||
}
|
||||
pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fill_segment( const Argon2_instance_t *instance, Argon2_position_t position )
|
||||
{
|
||||
if ( instance == NULL )
|
||||
{
|
||||
return;
|
||||
void fill_segment(const Argon2_instance_t *instance,
|
||||
Argon2_position_t position) {
|
||||
if (instance == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t pseudo_rand, ref_index, ref_lane;
|
||||
uint32_t prev_offset, curr_offset;
|
||||
bool data_independent_addressing = (instance->type == Argon2_i);
|
||||
// Pseudo-random values that determine the reference block position
|
||||
uint64_t *pseudo_rands =
|
||||
(uint64_t *)malloc(sizeof(uint64_t) * (instance->segment_length));
|
||||
|
||||
if (pseudo_rands == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (data_independent_addressing) {
|
||||
generate_addresses(instance, &position, pseudo_rands);
|
||||
}
|
||||
|
||||
uint32_t starting_index = 0;
|
||||
|
||||
if ((0 == position.pass) && (0 == position.slice)) {
|
||||
starting_index = 2; // we have already generated the first two blocks
|
||||
}
|
||||
|
||||
// Offset of the current block
|
||||
curr_offset = position.lane * instance->lane_length +
|
||||
position.slice * instance->segment_length + starting_index;
|
||||
|
||||
if (0 == curr_offset % instance->lane_length) {
|
||||
// Last block in this lane
|
||||
prev_offset = curr_offset + instance->lane_length - 1;
|
||||
} else {
|
||||
// Previous block
|
||||
prev_offset = curr_offset - 1;
|
||||
}
|
||||
|
||||
for (uint32_t i = starting_index; i < instance->segment_length;
|
||||
++i, ++curr_offset, ++prev_offset) {
|
||||
/*1.1 Rotating prev_offset if needed */
|
||||
if (curr_offset % instance->lane_length == 1) {
|
||||
prev_offset = curr_offset - 1;
|
||||
}
|
||||
|
||||
uint64_t pseudo_rand, ref_index, ref_lane;
|
||||
uint32_t prev_offset, curr_offset;
|
||||
bool data_independent_addressing = ( instance->type == Argon2_i );
|
||||
// Pseudo-random values that determine the reference block position
|
||||
uint64_t *pseudo_rands = ( uint64_t * )malloc( sizeof( uint64_t )*( instance->segment_length ) );
|
||||
|
||||
if ( pseudo_rands == NULL )
|
||||
{
|
||||
return;
|
||||
/* 1.2 Computing the index of the reference block */
|
||||
/* 1.2.1 Taking pseudo-random value from the previous block */
|
||||
if (data_independent_addressing) {
|
||||
pseudo_rand = pseudo_rands[i];
|
||||
} else {
|
||||
pseudo_rand = instance->memory[prev_offset].v[0];
|
||||
}
|
||||
|
||||
if ( data_independent_addressing )
|
||||
{
|
||||
generate_addresses( instance, &position, pseudo_rands );
|
||||
/* 1.2.2 Computing the lane of the reference block */
|
||||
ref_lane = ((pseudo_rand >> 32)) % instance->lanes;
|
||||
|
||||
if ((position.pass == 0) && (position.slice == 0)) {
|
||||
// Can not reference other lanes yet
|
||||
ref_lane = position.lane;
|
||||
}
|
||||
|
||||
uint32_t starting_index = 0;
|
||||
/* 1.2.3 Computing the number of possible reference block within the lane.
|
||||
*/
|
||||
position.index = i;
|
||||
ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF,
|
||||
ref_lane == position.lane);
|
||||
|
||||
if ( ( 0 == position.pass ) && ( 0 == position.slice ) )
|
||||
{
|
||||
starting_index = 2; // we have already generated the first two blocks
|
||||
}
|
||||
/* 2 Creating a new block */
|
||||
block *ref_block =
|
||||
instance->memory + instance->lane_length * ref_lane + ref_index;
|
||||
block *curr_block = instance->memory + curr_offset;
|
||||
fill_block(instance->memory + prev_offset, ref_block, curr_block);
|
||||
}
|
||||
|
||||
// Offset of the current block
|
||||
curr_offset = position.lane * instance->lane_length + position.slice * instance->segment_length + starting_index;
|
||||
|
||||
if ( 0 == curr_offset % instance->lane_length )
|
||||
{
|
||||
// Last block in this lane
|
||||
prev_offset = curr_offset + instance->lane_length - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Previous block
|
||||
prev_offset = curr_offset - 1;
|
||||
}
|
||||
|
||||
for ( uint32_t i = starting_index; i < instance->segment_length; ++i, ++curr_offset, ++prev_offset )
|
||||
{
|
||||
/*1.1 Rotating prev_offset if needed */
|
||||
if ( curr_offset % instance->lane_length == 1 )
|
||||
{
|
||||
prev_offset = curr_offset - 1;
|
||||
}
|
||||
|
||||
/* 1.2 Computing the index of the reference block */
|
||||
/* 1.2.1 Taking pseudo-random value from the previous block */
|
||||
if ( data_independent_addressing )
|
||||
{
|
||||
pseudo_rand = pseudo_rands[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
pseudo_rand = instance->memory[prev_offset].v[0];
|
||||
}
|
||||
|
||||
/* 1.2.2 Computing the lane of the reference block */
|
||||
ref_lane = ( ( pseudo_rand >> 32 ) ) % instance->lanes;
|
||||
|
||||
if ( ( position.pass == 0 ) && ( position.slice == 0 ) )
|
||||
{
|
||||
// Can not reference other lanes yet
|
||||
ref_lane = position.lane;
|
||||
}
|
||||
|
||||
/* 1.2.3 Computing the number of possible reference block within the lane. */
|
||||
position.index = i;
|
||||
ref_index = index_alpha( instance, &position, pseudo_rand & 0xFFFFFFFF, ref_lane == position.lane );
|
||||
|
||||
/* 2 Creating a new block */
|
||||
block *ref_block = instance->memory + instance->lane_length * ref_lane + ref_index;
|
||||
block *curr_block = instance->memory + curr_offset;
|
||||
fill_block( instance->memory + prev_offset, ref_block, curr_block );
|
||||
}
|
||||
|
||||
free( pseudo_rands );
|
||||
free(pseudo_rands);
|
||||
}
|
||||
|
|
26
src/ref.h
26
src/ref.h
|
@ -5,14 +5,15 @@
|
|||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
* this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#ifndef REF_H
|
||||
#define REF_H
|
||||
|
||||
|
||||
/*
|
||||
* Function fills a new memory block
|
||||
* @param prev_block Pointer to the previous block
|
||||
|
@ -20,24 +21,29 @@
|
|||
* @param next_block Pointer to the block to be constructed
|
||||
* @pre all block pointers must be valid
|
||||
*/
|
||||
void fill_block( const block *prev_block, const block *ref_block, block *next_block );
|
||||
void fill_block(const block *prev_block, const block *ref_block,
|
||||
block *next_block);
|
||||
|
||||
/*
|
||||
* Generate pseudo-random values to reference blocks in the segment and puts them into the array
|
||||
* Generate pseudo-random values to reference blocks in the segment and puts
|
||||
* them into the array
|
||||
* @param instance Pointer to the current instance
|
||||
* @param position Pointer to the current position
|
||||
* @param pseudo_rands Pointer to the array of 64-bit values
|
||||
* @pre pseudo_rands must point to @a instance->segment_length allocated values
|
||||
*/
|
||||
void generate_addresses( const Argon2_instance_t *instance, const Argon2_position_t *position, uint64_t *pseudo_rands );
|
||||
void generate_addresses(const Argon2_instance_t *instance,
|
||||
const Argon2_position_t *position,
|
||||
uint64_t *pseudo_rands);
|
||||
|
||||
/*
|
||||
* Function that fills the segment using previous segments also from other threads
|
||||
* Function that fills the segment using previous segments also from other
|
||||
* threads
|
||||
* @param instance Pointer to the current instance
|
||||
* @param position Current position
|
||||
* @pre all block pointers must be valid
|
||||
*/
|
||||
void fill_segment( const Argon2_instance_t *instance, Argon2_position_t position );
|
||||
|
||||
#endif /* ARGON2_REF_CORE_H */
|
||||
void fill_segment(const Argon2_instance_t *instance,
|
||||
Argon2_position_t position);
|
||||
|
||||
#endif /* ARGON2_REF_CORE_H */
|
||||
|
|
Loading…
Reference in New Issue