From: Loup Vaillant Date: Thu, 16 Nov 2017 22:25:26 +0000 (+0100) Subject: Changed Argon2i API X-Git-Url: https://git.codecow.com/?a=commitdiff_plain;h=fe5b2c9939f8ca97f529d14c7efecdfe324cced3;p=Monocypher.git Changed Argon2i API - Removed the key and ad from crypto_argon2i() - Added crypto_argon2i_general(), which conform to the old API, to compensate. - Updated the manual. Related to #58 Rationale: the key and ad arguments are rarely used. Regular users shouldn't be burdened with them. --- diff --git a/doc/man/man3/crypto_argon2i.3monocypher b/doc/man/man3/crypto_argon2i.3monocypher index 109955d..bbfc699 100644 --- a/doc/man/man3/crypto_argon2i.3monocypher +++ b/doc/man/man3/crypto_argon2i.3monocypher @@ -17,6 +17,18 @@ .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" @@ -166,9 +178,7 @@ if (work_area == 0) { 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 diff --git a/src/monocypher.c b/src/monocypher.c index b6d001e..dd97a9c 100644 --- a/src/monocypher.c +++ b/src/monocypher.c @@ -876,12 +876,13 @@ static u32 gidx_next(gidx_ctx *ctx) } // 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; @@ -969,6 +970,21 @@ void crypto_argon2i(u8 *hash, u32 hash_size, } } +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 /// //////////////////////////////////// diff --git a/src/monocypher.h b/src/monocypher.h index 713d225..bacedb6 100644 --- a/src/monocypher.h +++ b/src/monocypher.h @@ -110,13 +110,19 @@ void crypto_blake2b(uint8_t hash[64], //////////////// /// 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 /// diff --git a/tests/speed.c b/tests/speed.c index a03818a..787f8e8 100644 --- a/tests/speed.c +++ b/tests/speed.c @@ -11,8 +11,8 @@ typedef struct timespec timespec; // 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) { @@ -37,8 +37,9 @@ timespec min(timespec a, timespec b) 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) @@ -57,7 +58,7 @@ 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 \ @@ -69,9 +70,9 @@ static void print(const char *name, u64 speed, const char *unit) 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 { @@ -84,9 +85,9 @@ static u64 chacha20(void) 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); @@ -96,11 +97,11 @@ static u64 poly1305(void) 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); @@ -122,23 +123,23 @@ static u64 blake2b(void) 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)) { @@ -150,10 +151,10 @@ static u64 x25519(void) 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); @@ -163,10 +164,10 @@ static u64 edDSA_sign(void) 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); @@ -180,14 +181,14 @@ static u64 edDSA_check(void) 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; } diff --git a/tests/test.c b/tests/test.c index ecaaad7..d9407bb 100644 --- a/tests/test.c +++ b/tests/test.c @@ -139,8 +139,7 @@ static void argon2i(const vector in[], vector *out) 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); } @@ -504,13 +503,13 @@ static int p_argon2i_overlap() 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");