2
0
Fork 0
mirror of https://git.sr.ht/~sircmpwn/mkproof synced 2024-06-03 11:36:12 +02:00
mkproof/src/argon2-test.c

442 lines
12 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-16 10:52:09 +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/>.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "time.h"
#include "argon2.h"
#ifdef _MSC_VER
#include "intrin.h"
2015-10-16 19:05:50 +02:00
#endif
2015-10-16 10:52:09 +02:00
/* Enable timing measurements */
#define _MEASURE
2015-10-16 16:07:06 +02:00
#define T_COST_DEF 3
#define M_COST_DEF (1<<18)
#define LANES_DEF 4
#define THREADS_DEF 4
2015-10-16 18:41:54 +02:00
#define UNUSED_PARAMETER(x) (void)(x)
2015-10-16 16:07:06 +02:00
2015-10-16 19:05:50 +02:00
static inline uint64_t rdtsc( void )
{
2015-10-16 10:52:09 +02:00
#ifdef _MSC_VER
2015-10-16 19:05:50 +02:00
return __rdtsc();
2015-10-16 10:52:09 +02:00
#else
uint64_t rax, rdx;
2015-10-16 19:05:50 +02:00
__asm__ __volatile__ ( "rdtsc" : "=a" ( rax ), "=d" ( rdx ) : : );
return ( rdx << 32 ) | rax;
2015-10-16 10:52:09 +02:00
#endif
}
/*
* Custom allocate memory
*/
2015-10-16 19:05:50 +02:00
int CustomAllocateMemory( uint8_t **memory, size_t length )
{
*memory = ( uint8_t * )malloc( length );
if ( !*memory )
{
2015-10-16 10:52:09 +02:00
return ARGON2_MEMORY_ALLOCATION_ERROR;
}
2015-10-16 19:05:50 +02:00
2015-10-16 10:52:09 +02:00
return ARGON2_OK;
}
/*
* Custom free memory
*/
2015-10-16 19:05:50 +02:00
void CustomFreeMemory( uint8_t *memory, size_t length )
{
UNUSED_PARAMETER( length );
if ( memory )
{
free( memory );
2015-10-16 10:52:09 +02:00
}
}
/*
* Benchmarks Argon2 with salt length 16, password length 32, t_cost 3, and different threads and m_cost
*/
2015-10-16 19:05:50 +02:00
void Benchmark()
{
2015-10-16 10:52:09 +02:00
const uint32_t inlen = 16;
const unsigned outlen=16;
unsigned char out[outlen];
unsigned char pwd_array[inlen];
unsigned char salt_array[inlen];
uint32_t t_cost = 1;
2015-10-16 19:05:50 +02:00
memset( pwd_array, 0, inlen );
memset( salt_array, 1, inlen );
2015-10-16 10:52:09 +02:00
uint32_t thread_test[6] = {1, 2, 4, 6, 8, 16};
uint32_t m_cost;
2015-10-16 19:05:50 +02:00
for ( m_cost = ( uint32_t ) 1 << 10; m_cost <= ( uint32_t ) 1 << 22; m_cost *= 2 )
{
2015-10-16 10:52:09 +02:00
uint32_t i;
2015-10-16 19:05:50 +02:00
for ( i=0; i <6; ++i )
{
uint32_t thread_n = thread_test[i];
2015-10-16 10:52:09 +02:00
#ifdef _MEASURE
uint64_t start_cycles, stop_cycles, stop_cycles_i, stop_cycles_di, stop_cycles_ds;
clock_t start_time = clock();
2015-10-16 18:41:54 +02:00
start_cycles = rdtsc();
2015-10-16 10:52:09 +02:00
#endif
2015-10-16 19:05:50 +02:00
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 );
2015-10-16 10:52:09 +02:00
#ifdef _MEASURE
2015-10-16 18:41:54 +02:00
stop_cycles = rdtsc();
2015-10-16 10:52:09 +02:00
#endif
2015-10-16 19:05:50 +02:00
Argon2i( &context );
2015-10-16 10:52:09 +02:00
#ifdef _MEASURE
2015-10-16 18:41:54 +02:00
stop_cycles_i = rdtsc();
2015-10-16 10:52:09 +02:00
#endif
2015-10-16 19:05:50 +02:00
Argon2id( &context );
2015-10-16 10:52:09 +02:00
#ifdef _MEASURE
2015-10-16 18:41:54 +02:00
stop_cycles_di = rdtsc();
2015-10-16 10:52:09 +02:00
#endif
2015-10-16 19:05:50 +02:00
Argon2ds( &context );
2015-10-16 10:52:09 +02:00
#ifdef _MEASURE
2015-10-16 18:41:54 +02:00
stop_cycles_ds = rdtsc();
2015-10-16 10:52:09 +02:00
clock_t stop_time = clock();
2015-10-16 19:05:50 +02:00
uint64_t delta_d = ( stop_cycles - start_cycles ) / ( m_cost );
uint64_t delta_i = ( stop_cycles_i - stop_cycles ) / ( m_cost );
uint64_t delta_id = ( stop_cycles_di - stop_cycles_i ) / m_cost;
uint64_t delta_ds = ( stop_cycles_ds - stop_cycles_di ) / m_cost;
float mcycles_d = ( float ) ( stop_cycles - start_cycles ) / ( 1 << 20 );
float mcycles_i = ( float ) ( stop_cycles_i - stop_cycles ) / ( 1 << 20 );
float mcycles_id = ( float ) ( stop_cycles_di - stop_cycles_i ) / ( 1 << 20 );
float mcycles_ds = ( float ) ( stop_cycles_ds - stop_cycles_di ) / ( 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 );
printf( "Argon2id %d pass(es) %d Mbytes %d threads: %2.2f cpb %2.2f Mcycles \n", t_cost, m_cost >> 10, thread_n, ( float ) delta_id / 1024, mcycles_id );
printf( "Argon2ds %d pass(es) %d Mbytes %d threads: %2.2f cpb %2.2f Mcycles \n", t_cost, m_cost >> 10, thread_n, ( float ) delta_ds / 1024, mcycles_ds );
float run_time = ( ( float ) stop_time - start_time ) / ( CLOCKS_PER_SEC );
printf( "%2.4f seconds\n\n", run_time );
2015-10-16 10:52:09 +02:00
#endif
}
}
}
/*Call Argon2 with default salt and password and user-defined parameter values.*/
2015-10-16 19:05:50 +02:00
void Run( uint8_t *out, uint32_t t_cost, uint32_t m_cost, uint32_t lanes, uint32_t threads,const char *type, bool print )
{
2015-10-16 10:52:09 +02:00
#ifdef _MEASURE
uint64_t start_cycles, stop_cycles, delta;
clock_t start_time = clock();
2015-10-16 18:41:54 +02:00
start_cycles = rdtsc();
2015-10-16 10:52:09 +02:00
#endif
/*Fixed parameters*/
const unsigned out_length = 32;
const unsigned pwd_length = 32;
const unsigned salt_length = 16;
const unsigned secret_length = 8;
const unsigned ad_length = 12;
bool clear_memory = false;
bool clear_secret = false;
bool clear_password = false;
uint8_t pwd[pwd_length];
uint8_t salt[salt_length];
uint8_t secret[secret_length];
uint8_t ad[ad_length];
2015-10-16 19:05:50 +02:00
UNUSED_PARAMETER( threads );
memset( pwd, 1, pwd_length );
memset( salt, 2, salt_length );
memset( secret, 3, secret_length );
memset( ad, 4, ad_length );
Argon2_Context context= {out, out_length, pwd, pwd_length, salt, salt_length,
secret, secret_length, ad, ad_length, t_cost, m_cost, lanes, lanes,
NULL, NULL,
clear_password, clear_secret, clear_memory, print
};
if ( !strcmp( type,"Argon2d" ) )
{
printf( "Test Argon2d\n" );
Argon2d( &context );
2015-10-16 10:52:09 +02:00
return;
}
2015-10-16 19:05:50 +02:00
if ( !strcmp( type,"Argon2i" ) )
{
printf( "Test Argon2i\n" );
Argon2i( &context );
2015-10-16 10:52:09 +02:00
return;
}
2015-10-16 19:05:50 +02:00
if ( !strcmp( type,"Argon2ds" ) )
{
printf( "Test Argon2ds\n" );
Argon2ds( &context );
2015-10-16 10:52:09 +02:00
return;
}
2015-10-16 19:05:50 +02:00
if ( !strcmp( type,"Argon2id" ) )
{
printf( "Test Argon2id\n" );
Argon2id( &context );
2015-10-16 10:52:09 +02:00
return;
}
2015-10-16 19:05:50 +02:00
printf( "Wrong Argon2 type!\n" );
2015-10-16 10:52:09 +02:00
#ifdef _MEASURE
2015-10-16 18:41:54 +02:00
stop_cycles = rdtsc();
2015-10-16 10:52:09 +02:00
clock_t finish_time = clock();
2015-10-16 19:05:50 +02:00
delta = ( stop_cycles - start_cycles ) / ( m_cost );
float mcycles = ( float ) ( stop_cycles - start_cycles ) / ( 1 << 20 );
printf( "Argon: %2.2f cpb %2.2f Mcycles ", ( float ) delta / 1024, mcycles );
2015-10-16 10:52:09 +02:00
2015-10-16 19:05:50 +02:00
float run_time = ( ( float ) finish_time - start_time ) / ( CLOCKS_PER_SEC );
printf( "%2.4f seconds\n", run_time );
2015-10-16 10:52:09 +02:00
#endif
}
2015-10-16 19:05:50 +02:00
void GenerateTestVectors( const char *type )
{
const unsigned out_length = 32;
2015-10-16 10:52:09 +02:00
const unsigned pwd_length = 32;
const unsigned salt_length = 16;
const unsigned secret_length = 8;
const unsigned ad_length = 12;
bool clear_memory = false;
bool clear_secret = false;
bool clear_password = false;
bool print_internals = true;
2015-10-16 10:52:09 +02:00
unsigned char out[out_length];
unsigned char pwd[pwd_length];
unsigned char salt[salt_length];
unsigned char secret[secret_length];
unsigned char ad[ad_length];
const AllocateMemoryCallback myown_allocator = NULL;
const FreeMemoryCallback myown_deallocator = NULL;
unsigned t_cost = 3;
unsigned m_cost = 16;
unsigned lanes = 4;
2015-10-16 19:05:50 +02:00
memset( pwd, 1, pwd_length );
memset( salt, 2, salt_length );
memset( secret, 3, secret_length );
memset( ad, 4, ad_length );
2015-10-16 10:52:09 +02:00
2015-10-16 19:05:50 +02:00
printf( "Generate test vectors in file: \"%s\".\n", ARGON2_KAT_FILENAME );
2015-10-16 10:52:09 +02:00
2015-10-16 19:05:50 +02:00
Argon2_Context context= {out, out_length, pwd, pwd_length, salt, salt_length,
secret, secret_length, ad, ad_length, t_cost, m_cost, lanes, lanes,
myown_allocator, myown_deallocator,
clear_password, clear_secret, clear_memory, print_internals
};
2015-10-16 10:52:09 +02:00
2015-10-16 19:05:50 +02:00
if ( !strcmp( type,"Argon2d" ) )
{
printf( "Test Argon2d\n" );
Argon2d( &context );
2015-10-16 10:52:09 +02:00
return;
}
2015-10-16 19:05:50 +02:00
if ( !strcmp( type,"Argon2i" ) )
{
printf( "Test Argon2i\n" );
Argon2i( &context );
2015-10-16 10:52:09 +02:00
return;
}
2015-10-16 19:05:50 +02:00
if ( !strcmp( type,"Argon2ds" ) )
{
printf( "Test Argon2ds\n" );
Argon2ds( &context );
2015-10-16 10:52:09 +02:00
return;
}
2015-10-16 19:05:50 +02:00
if ( !strcmp( type,"Argon2id" ) )
{
printf( "Test Argon2id\n" );
Argon2id( &context );
2015-10-16 10:52:09 +02:00
return;
}
2015-10-16 19:05:50 +02:00
printf( "Wrong Argon2 type!\n" );
2015-10-16 10:52:09 +02:00
}
2015-10-16 19:05:50 +02:00
void usage( const char *cmd )
{
printf( "usage: %s [options]\n", cmd );
printf( "Options:\n" );
printf( "\t-h, --help\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..23, default %d]\n", 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-y, --type [Argon2d | Argon2ds | Argon2i | Argon2id]\n" );
printf( "\t-g, --gentv\n" );
printf( "\t-b, --benchmark\n" );
2015-10-16 17:05:49 +02:00
}
2015-10-16 19:05:50 +02:00
void fatal( const char *error )
{
fprintf( stderr, "error: %s\n", error );
exit( 1 );
2015-10-16 16:07:06 +02:00
}
2015-10-16 10:52:09 +02:00
2015-10-16 19:05:50 +02:00
int main( int argc, char *argv[] )
{
2015-10-16 10:52:09 +02:00
unsigned char out[32];
2015-10-16 16:07:06 +02:00
uint32_t m_cost = M_COST_DEF;
uint32_t t_cost = T_COST_DEF;
uint32_t lanes = LANES_DEF;
uint32_t threads = THREADS_DEF;
2015-10-16 10:52:09 +02:00
bool generate_test_vectors = false;
//char type[argon2_type_length] = "Argon2d";
2015-10-16 19:05:50 +02:00
const char *type= "Argon2d";
2015-10-16 10:52:09 +02:00
#ifdef ARGON2_KAT
2015-10-16 19:05:50 +02:00
remove( ARGON2_KAT_FILENAME );
2015-10-16 10:52:09 +02:00
#endif
2015-10-16 19:05:50 +02:00
if ( argc == 1 )
{
usage( argv[0] );
2015-10-16 16:07:06 +02:00
return 1;
}
2015-10-16 19:05:50 +02:00
for ( int i = 1; i < argc; i++ )
{
char *a = argv[i];
if ( !strcmp( a, "-h" ) || !strcmp( a, "--help" ) )
{
usage( argv[0] );
2015-10-16 10:52:09 +02:00
return 0;
}
2015-10-16 19:05:50 +02:00
if ( !strcmp( a, "-m" ) || !strcmp( a, "--mcost" ) )
{
if ( i < argc - 1 )
{
2015-10-16 10:52:09 +02:00
i++;
2015-10-16 19:05:50 +02:00
m_cost = ( uint8_t ) 1 << ( ( uint8_t )atoi( argv[i] ) % 24 );
2015-10-16 10:52:09 +02:00
continue;
}
2015-10-16 19:05:50 +02:00
else
fatal( "missing memory cost argument" );
2015-10-16 10:52:09 +02:00
}
2015-10-16 19:05:50 +02:00
if ( !strcmp( a, "-t" ) || !strcmp( a, "--tcost" ) )
{
if ( i < argc - 1 )
{
2015-10-16 10:52:09 +02:00
i++;
2015-10-16 19:05:50 +02:00
t_cost = atoi( argv[i] ) & 0xffffff;
2015-10-16 10:52:09 +02:00
continue;
}
2015-10-16 19:05:50 +02:00
else
fatal( "missing time cost argument" );
2015-10-16 10:52:09 +02:00
}
2015-10-16 19:05:50 +02:00
if ( !strcmp( a, "-p" ) || !strcmp( a, "--threads" ) )
{
if ( i < argc - 1 )
{
2015-10-16 10:52:09 +02:00
i++;
2015-10-16 19:05:50 +02:00
threads = atoi( argv[i] ) % ARGON2_MAX_THREADS;
2015-10-16 10:52:09 +02:00
continue;
}
2015-10-16 19:05:50 +02:00
else
fatal( "missing threads argument" );
2015-10-16 10:52:09 +02:00
}
2015-10-16 19:05:50 +02:00
if ( !strcmp( a, "-l" ) || !strcmp( a, "--lanes" ) )
{
if ( i < argc - 1 )
{
2015-10-16 10:52:09 +02:00
i++;
2015-10-16 19:05:50 +02:00
lanes = atoi( argv[i] ) % ARGON2_MAX_LANES;
2015-10-16 10:52:09 +02:00
continue;
}
2015-10-16 19:05:50 +02:00
else
fatal( "missing lanes argument" );
2015-10-16 10:52:09 +02:00
}
2015-10-16 19:05:50 +02:00
if ( !strcmp( a, "-y" ) || !strcmp( a, "--type" ) )
{
if ( i < argc - 1 )
{
2015-10-16 10:52:09 +02:00
i++;
type = argv[i];
continue;
}
2015-10-16 17:05:49 +02:00
else
2015-10-16 19:05:50 +02:00
fatal( "missing type argument" );
2015-10-16 10:52:09 +02:00
}
2015-10-16 19:05:50 +02:00
if ( !strcmp( a, "-g" ) || !strcmp( a, "--gen-tv" ) )
{
2015-10-16 10:52:09 +02:00
generate_test_vectors = true;
continue;
}
2015-10-16 19:05:50 +02:00
if ( !strcmp( a, "-b" ) || !strcmp( a, "--benchmark" ) )
{
2015-10-16 10:52:09 +02:00
Benchmark();
return 0;
}
}
2015-10-16 19:05:50 +02:00
if ( generate_test_vectors )
{
GenerateTestVectors( type );
2015-10-16 10:52:09 +02:00
return 0;
}
2015-10-16 19:05:50 +02:00
2015-10-16 10:52:09 +02:00
/*No benchmark, no test vectors, just run*/
2015-10-16 19:05:50 +02:00
Run( out, t_cost, m_cost, lanes, threads, type, generate_test_vectors );
2015-10-16 10:52:09 +02:00
return 0;
}