.Fa "const uint32_t password_size"
.Fa "const uint8_t *salt"
.Fa "const uint32_t salt_size"
+.Fc
+.Ft void
+.Fo crypto_argon2i_general
+.Fa "uint8_t *hash"
+.Fa "uint32_t hash_size"
+.Fa "void *work_area"
+.Fa "uint32_t nb_blocks"
+.Fa "uint32_t nb_iterations"
+.Fa "const uint8_t *password"
+.Fa "const uint32_t password_size"
+.Fa "const uint8_t *salt"
+.Fa "const uint32_t salt_size"
.Fa "const uint8_t *key"
.Fa "const uint32_t key_size"
.Fa "const uint8_t *ad"
crypto_argon2i(hash, 32,
work_area, nb_blocks, nb_iterations,
password, password_size,
- salt, 16,
- 0, 0, /* no key */
- 0, 0); /* no additional data */
+ salt, 16);
/* Wipe secrets if they are no longer needed */
crypto_wipe(password, password_size);
.Ed
}
// Main algorithm
-void crypto_argon2i(u8 *hash, u32 hash_size,
- void *work_area, u32 nb_blocks, u32 nb_iterations,
- const u8 *password, u32 password_size,
- const u8 *salt, u32 salt_size,
- const u8 *key, u32 key_size,
- const u8 *ad, u32 ad_size)
+void crypto_argon2i_general(u8 *hash, u32 hash_size,
+ void *work_area, u32 nb_blocks,
+ u32 nb_iterations,
+ const u8 *password, u32 password_size,
+ const u8 *salt, u32 salt_size,
+ const u8 *key, u32 key_size,
+ const u8 *ad, u32 ad_size)
{
// work area seen as blocks (must be suitably aligned)
block *blocks = (block*)work_area;
}
}
+void crypto_argon2i(u8 *hash, u32 hash_size,
+ void *work_area, u32 nb_blocks,
+ u32 nb_iterations,
+ const u8 *password, u32 password_size,
+ const u8 *salt, u32 salt_size)
+{
+ crypto_argon2i_general(hash, hash_size,
+ work_area, nb_blocks, nb_iterations,
+ password, password_size,
+ salt , salt_size,
+ 0, 0, 0, 0);
+}
+
+
+
////////////////////////////////////
/// Arithmetic modulo 2^255 - 19 ///
////////////////////////////////////
////////////////
/// Argon2 i ///
////////////////
+void crypto_argon2i_general(uint8_t *hash, uint32_t hash_size, // >= 4
+ void *work_area, uint32_t nb_blocks, // >= 8
+ uint32_t nb_iterations, // >= 1
+ const uint8_t *password, uint32_t password_size,
+ const uint8_t *salt, uint32_t salt_size, // >= 8
+ const uint8_t *key, uint32_t key_size,
+ const uint8_t *ad, uint32_t ad_size);
+
void crypto_argon2i(uint8_t *hash, uint32_t hash_size, // >= 4
void *work_area, uint32_t nb_blocks, // >= 8
uint32_t nb_iterations, // >= 1
const uint8_t *password, uint32_t password_size,
- const uint8_t *salt, uint32_t salt_size, // >= 8
- const uint8_t *key, uint32_t key_size, // optional
- const uint8_t *ad, uint32_t ad_size); // optional
+ const uint8_t *salt, uint32_t salt_size);
///////////////
/// X-25519 ///
// TODO: provide a user defined buffer size
#define KILOBYTE 1024
#define MEGABYTE (1024 * KILOBYTE)
-#define SIZE MEGABYTE
-#define DIVIDER (MEGABYTE / SIZE)
+#define SIZE (50 * MEGABYTE)
+#define MULT (SIZE / MEGABYTE)
timespec diff(timespec start, timespec end)
{
u64 speed(timespec duration)
{
+#define DIV 1000 // avoid round errors
static const u64 giga = 1000000000;
- return giga / (duration.tv_nsec + duration.tv_sec * giga);
+ return DIV * giga / (duration.tv_nsec + duration.tv_sec * giga);
}
static void print(const char *name, u64 speed, const char *unit)
duration.tv_nsec = -1; \
duration.tv_sec = 3600 * 24; \
duration.tv_nsec = 0; \
- FOR (i, 0, 50) { \
+ FOR (i, 0, 10) { \
TIMESTAMP(start);
#define TIMING_END \
static u64 chacha20(void)
{
- static u8 in [SIZE]; p_random(in , SIZE);
- static u8 key [ 32]; p_random(key , 32);
- static u8 nonce [ 8]; p_random(nonce, 8);
+ static u8 in [SIZE]; p_random(in , SIZE);
+ static u8 key [ 32]; p_random(key , 32);
+ static u8 nonce[ 8]; p_random(nonce, 8);
static u8 out [SIZE];
TIMING_START {
static u64 poly1305(void)
{
- static u8 in [SIZE]; p_random(in , SIZE);
- static u8 key [ 32]; p_random(key , 32);
- static u8 out [ 16];
+ static u8 in [SIZE]; p_random(in , SIZE);
+ static u8 key[ 32]; p_random(key , 32);
+ static u8 out[ 16];
TIMING_START {
crypto_poly1305(out, in, SIZE, key);
static u64 authenticated(void)
{
- static u8 in [SIZE]; p_random(in , SIZE);
- static u8 key [ 32]; p_random(key , 32);
- static u8 nonce [ 8]; p_random(nonce, 8);
- static u8 out [SIZE];
- static u8 mac [ 16];
+ static u8 in [SIZE]; p_random(in , SIZE);
+ static u8 key [ 32]; p_random(key , 32);
+ static u8 nonce[ 8]; p_random(nonce, 8);
+ static u8 out [SIZE];
+ static u8 mac [ 16];
TIMING_START {
crypto_lock(mac, out, key, nonce, in, SIZE);
static u64 argon2i(void)
{
- size_t nb_blocks = 1024;
- static u8 work_area[MEGABYTE];
- static u8 password [ 16]; p_random(password, 16);
- static u8 salt [ 16]; p_random(salt , 16);
- static u8 hash [ 32];
+ size_t nb_blocks = SIZE / 1024;
+ static u8 work_area[SIZE];
+ static u8 password [ 16]; p_random(password, 16);
+ static u8 salt [ 16]; p_random(salt , 16);
+ static u8 hash [ 32];
TIMING_START {
crypto_argon2i(hash, 32, work_area, nb_blocks, 3,
- password, 16, salt, 16, 0, 0, 0, 0);
+ password, 16, salt, 16);
}
TIMING_END;
}
static u64 x25519(void)
{
- u8 in [32] = {9};
- u8 out [32] = {9};
+ u8 in [32] = {9};
+ u8 out[32] = {9};
TIMING_START {
if (crypto_x25519(out, out, in)) {
static u64 edDSA_sign(void)
{
- u8 sk [32]; p_random(sk, 32);
- u8 pk [32]; crypto_sign_public_key(pk, sk);
- u8 message [64]; p_random(message, 64);
- u8 signature [64];
+ u8 sk [32]; p_random(sk, 32);
+ u8 pk [32]; crypto_sign_public_key(pk, sk);
+ u8 message [64]; p_random(message, 64);
+ u8 signature[64];
TIMING_START {
crypto_sign(signature, sk, pk, message, 64);
static u64 edDSA_check(void)
{
- u8 sk [32]; p_random(sk, 32);
- u8 pk [32]; crypto_sign_public_key(pk, sk);
- u8 message [64]; p_random(message, 64);
- u8 signature [64];
+ u8 sk [32]; p_random(sk, 32);
+ u8 pk [32]; crypto_sign_public_key(pk, sk);
+ u8 message [64]; p_random(message, 64);
+ u8 signature[64];
crypto_sign(signature, sk, pk, message, 64);
int main()
{
- print("Chacha20 ", chacha20() / DIVIDER, "Mb/s" );
- print("Poly1305 ", poly1305() / DIVIDER, "Mb/s" );
- print("Auth'd encryption", authenticated() / DIVIDER, "Mb/s" );
- print("Blake2b ", blake2b() / DIVIDER, "Mb/s" );
- print("Argon2i ", argon2i() , "Mb/s (3 passes)" );
- print("x25519 ", x25519() , "exchanges per second");
- print("EdDSA(sign) ", edDSA_sign() , "signatures per second");
- print("EdDSA(check) ", edDSA_check() , "checks per second");
+ print("Chacha20 ", chacha20() * MULT/DIV, "Mb/s" );
+ print("Poly1305 ", poly1305() * MULT/DIV, "Mb/s" );
+ print("Auth'd encryption", authenticated() * MULT/DIV, "Mb/s" );
+ print("Blake2b ", blake2b() * MULT/DIV, "Mb/s" );
+ print("Argon2i ", argon2i() * MULT/DIV, "Mb/s (3 passes)" );
+ print("x25519 ", x25519() / DIV, "exchanges per second");
+ print("EdDSA(sign) ", edDSA_sign() / DIV, "signatures per second");
+ print("EdDSA(check) ", edDSA_check() / DIV, "checks per second");
printf("\n");
return 0;
}
crypto_argon2i(out->buf, out->size,
work_area, nb_blocks, nb_iterations,
password->buf, password->size,
- salt ->buf, salt ->size,
- 0, 0, 0, 0); // can't test key and ad with libsodium
+ salt ->buf, salt ->size);
free(work_area);
}
u8 key [32]; FOR (i, 0, 32) { key [i] = work_area[i + key_offset]; }
u8 ad [32]; FOR (i, 0, 32) { ad [i] = work_area[i + ad_offset]; }
- crypto_argon2i(hash1, 32, clean_work_area, 8, 1,
- pass, 16, salt, 16, key, 32, ad, 32);
- crypto_argon2i(hash2, 32, work_area, 8, 1,
- work_area + pass_offset, 16,
- work_area + salt_offset, 16,
- work_area + key_offset, 32,
- work_area + ad_offset, 32);
+ crypto_argon2i_general(hash1, 32, clean_work_area, 8, 1,
+ pass, 16, salt, 16, key, 32, ad, 32);
+ crypto_argon2i_general(hash2, 32, work_area, 8, 1,
+ work_area + pass_offset, 16,
+ work_area + salt_offset, 16,
+ work_area + key_offset, 32,
+ work_area + ad_offset, 32);
status |= memcmp(hash1, hash2, 32);
}
printf("%s: Argon2i (overlaping i/o)\n", status != 0 ? "FAILED" : "OK");