2
0
Fork 0
mirror of https://git.sr.ht/~sircmpwn/mkproof synced 2024-06-08 16:36:07 +02:00
mkproof/src/core.h

233 lines
7.5 KiB
C
Raw Normal View History

2015-10-16 10:52:09 +02:00
/*
* Argon2 source code package
2015-10-16 19:05:50 +02:00
*
2015-10-16 10:52:09 +02:00
* Written by Daniel Dinu and Dmitry Khovratovich, 2015
2015-10-16 19:05:50 +02:00
*
2015-10-16 10:52:09 +02:00
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
2015-10-16 19:05:50 +02:00
*
2015-10-20 22:46:17 +02:00
* 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/>.
2015-10-16 10:52:09 +02:00
*/
#pragma once
2015-10-21 01:59:09 +02:00
#ifndef ARGON2_CORE_H
#define ARGON2_CORE_H
2015-10-16 10:52:09 +02:00
2015-10-20 22:46:17 +02:00
/*************************Argon2 internal
* constants**************************************************/
2015-10-16 10:52:09 +02:00
2015-10-19 18:51:21 +02:00
enum Argon2_core_constants {
/* Version of the algorithm */
ARGON2_VERSION_NUMBER = 0x10,
/* Memory block size in bytes */
ARGON2_BLOCK_SIZE = 1024,
ARGON2_WORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8,
ARGON2_QWORDS_IN_BLOCK = 64,
/* Number of pseudo-random values generated by one call to Blake in Argon2i
to
generate reference block positions */
ARGON2_ADDRESSES_IN_BLOCK = 128,
/* Pre-hashing digest length and its extension*/
ARGON2_PREHASH_DIGEST_LENGTH = 64,
ARGON2_PREHASH_SEED_LENGTH = 72
2015-10-19 18:40:58 +02:00
};
2015-10-16 10:52:09 +02:00
/* Argon2 primitive type */
2015-10-20 22:46:17 +02:00
typedef enum _Argon2_type {
Argon2_d = 0,
Argon2_i = 1,
2015-10-16 10:52:09 +02:00
} Argon2_type;
2015-10-20 22:46:17 +02:00
/*************************Argon2 internal data
* types**************************************************/
2015-10-16 10:52:09 +02:00
/*
* Structure for the (1KB) memory block implemented as 128 64-bit words.
2015-10-20 22:46:17 +02:00
* Memory blocks can be copied, XORed. Internal words can be accessed by [] (no
* bounds checking).
2015-10-16 10:52:09 +02:00
*/
2015-10-16 22:09:31 +02:00
#ifndef _MSC_VER
2015-10-20 22:46:17 +02:00
typedef struct _block {
uint64_t v[ARGON2_WORDS_IN_BLOCK];
2015-10-20 22:46:17 +02:00
} __attribute__((aligned(16))) block;
2015-10-16 22:09:31 +02:00
#else
2015-10-20 22:46:17 +02:00
typedef struct _block {
uint64_t v[ARGON2_WORDS_IN_BLOCK];
2015-10-20 22:46:17 +02:00
} __declspec(align(16)) block;
2015-10-16 22:09:31 +02:00
#endif
2015-10-16 10:52:09 +02:00
/*****************Functions that work with the block******************/
2015-10-20 22:46:17 +02:00
// Initialize each byte of the block with @in
extern void init_block_value(block *b, uint8_t in);
2015-10-16 10:52:09 +02:00
2015-10-20 22:46:17 +02:00
// Copy block @src to block @dst
extern void copy_block(block *dst, const block *src);
2015-10-16 10:52:09 +02:00
2015-10-20 22:46:17 +02:00
// XOR @src onto @dst bytewise
extern void xor_block(block *dst, const block *src);
2015-10-16 10:52:09 +02:00
/*
2015-10-20 22:46:17 +02:00
* 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
2015-10-16 19:05:50 +02:00
} Argon2_instance_t;
2015-10-16 10:52:09 +02:00
/*
2015-10-20 22:46:17 +02:00
* 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;
2015-10-16 19:05:50 +02:00
} Argon2_position_t;
2015-10-16 10:52:09 +02:00
/*Struct that holds the inputs for thread handling FillSegment*/
2015-10-20 22:46:17 +02:00
typedef struct _Argon2_thread_data {
Argon2_instance_t *instance_ptr;
Argon2_position_t pos;
2015-10-16 19:05:50 +02:00
} Argon2_thread_data;
2015-10-16 10:52:09 +02:00
/*Macro for endianness conversion*/
2015-10-16 19:05:50 +02:00
#if defined(_MSC_VER)
2015-10-16 10:52:09 +02:00
#define BSWAP32(x) _byteswap_ulong(x)
#else
#define BSWAP32(x) __builtin_bswap32(x)
#endif
2015-10-20 22:46:17 +02:00
/*************************Argon2 core
* functions**************************************************/
2015-10-16 10:52:09 +02:00
/* 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
*/
2015-10-20 22:46:17 +02:00
int allocate_memory(block **memory, uint32_t m_cost);
2015-10-16 10:52:09 +02:00
/* Clears memory
* @param instance pointer to the current instance
* @param clear_memory indicates if we clear the memory with zeros.
*/
2015-10-20 22:46:17 +02:00
void clear_memory(Argon2_instance_t *instance, bool clear);
2015-10-16 10:52:09 +02:00
/* Deallocates memory
* @param memory pointer to the blocks
*/
2015-10-20 22:46:17 +02:00
void free_memory(block *memory);
2015-10-16 10:52:09 +02:00
/*
2015-10-20 22:46:17 +02:00
* Computes absolute position of reference block in the lane following a skewed
* distribution and using a pseudo-random value as input
2015-10-16 10:52:09 +02:00
* @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
2015-10-20 22:46:17 +02:00
* @param same_lane Indicates if the block will be taken from the current lane.
* If so we can reference the current segment
2015-10-16 10:52:09 +02:00
* @pre All pointers must be valid
*/
2015-10-20 22:46:17 +02:00
uint32_t index_alpha(const Argon2_instance_t *instance,
const Argon2_position_t *position, uint32_t pseudo_rand,
bool same_lane);
2015-10-16 10:52:09 +02:00
/*
2015-10-20 22:46:17 +02:00
* Function that validates all inputs against predefined restrictions and return
* an error code
2015-10-16 10:52:09 +02:00
* @param context Pointer to current Argon2 context
2015-10-20 22:46:17 +02:00
* @return ARGON2_OK if everything is all right, otherwise one of error codes
* (all defined in <argon2.h>
2015-10-16 10:52:09 +02:00
*/
2015-10-20 22:46:17 +02:00
int validate_inputs(const Argon2_Context *context);
2015-10-16 10:52:09 +02:00
/*
2015-10-20 22:46:17 +02:00
* 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.
2015-10-16 10:52:09 +02:00
* @param blockhash Buffer for pre-hashing digest
* @param type Argon2 type
2015-10-20 22:46:17 +02:00
* @pre @a blockhash must have at least @a PREHASH_DIGEST_LENGTH bytes
* allocated
2015-10-16 10:52:09 +02:00
*/
2015-10-20 22:46:17 +02:00
void initial_hash(uint8_t *blockhash, Argon2_Context *context,
Argon2_type type);
2015-10-16 10:52:09 +02:00
/*
* Function creates first 2 blocks per lane
* @param instance Pointer to the current instance
* @param blockhash Pointer to the pre-hashing digest
* @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values
*/
2015-10-20 22:46:17 +02:00
void fill_firsts_blocks(uint8_t *blockhash, const Argon2_instance_t *instance);
2015-10-16 10:52:09 +02:00
/*
2015-10-20 22:46:17 +02:00
* 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
2015-10-16 10:52:09 +02:00
* initialized
2015-10-20 22:46:17 +02:00
* @param context Pointer to the Argon2 internal structure containing memory
* pointer, and parameters for time and space requirements.
2015-10-16 10:52:09 +02:00
* @param instance Current Argon2 instance
2015-10-20 22:46:17 +02:00
* @return Zero if successful, -1 if memory failed to allocate. @context->state
* will be modified if successful.
2015-10-16 10:52:09 +02:00
*/
2015-10-20 22:46:17 +02:00
int initialize(Argon2_instance_t *instance, Argon2_Context *context);
2015-10-16 10:52:09 +02:00
/*
2015-10-20 22:46:17 +02:00
* 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)
2015-10-16 10:52:09 +02:00
* @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
2015-10-20 22:46:17 +02:00
* @pre if context->free_cbk is not NULL, it should point to a function that
* deallocates memory
2015-10-16 10:52:09 +02:00
*/
2015-10-20 22:46:17 +02:00
void finalize(const Argon2_Context *context, Argon2_instance_t *instance);
2015-10-16 10:52:09 +02:00
/*
2015-10-20 22:46:17 +02:00
* Function that fills the segment using previous segments also from other
* threads
2015-10-16 10:52:09 +02:00
* @param instance Pointer to the current instance
* @param position Current position
* @pre all block pointers must be valid
*/
2015-10-20 22:46:17 +02:00
extern void fill_segment(const Argon2_instance_t *instance,
Argon2_position_t position);
2015-10-16 10:52:09 +02:00
/*
2015-10-20 22:46:17 +02:00
* Function that fills the entire memory t_cost times based on the first two
* blocks in each lane
2015-10-16 10:52:09 +02:00
* @param instance Pointer to the current instance
*/
2015-10-20 22:46:17 +02:00
void fill_memory_blocks(Argon2_instance_t *instance);
2015-10-16 10:52:09 +02:00
/*
* 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
*/
2015-10-20 22:46:17 +02:00
int argon2_core(Argon2_Context *context, Argon2_type type);
2015-10-16 10:52:09 +02:00
#endif