From: Loup Vaillant Date: Thu, 12 Jan 2023 13:55:10 +0000 (+0100) Subject: Simplified Blake2b API X-Git-Url: https://git.codecow.com/?a=commitdiff_plain;h=7d38a1ae38bf6904ac768e83fa39463cd3835730;p=Monocypher.git Simplified Blake2b API Removed the non-general functions, added a default configuration. Documentation is not updated yet (I don't know how to document structs in mandoc) --- diff --git a/doc/man/man3/crypto_argon2i_general.3monocypher b/doc/man/man3/crypto_argon2i_general.3monocypher deleted file mode 120000 index 6aaa189..0000000 --- a/doc/man/man3/crypto_argon2i_general.3monocypher +++ /dev/null @@ -1 +0,0 @@ -crypto_argon2i.3monocypher \ No newline at end of file diff --git a/doc/man/man3/crypto_blake2b_general_init.3monocypher b/doc/man/man3/crypto_blake2b_general_init.3monocypher deleted file mode 120000 index 63f57c0..0000000 --- a/doc/man/man3/crypto_blake2b_general_init.3monocypher +++ /dev/null @@ -1 +0,0 @@ -crypto_blake2b.3monocypher \ No newline at end of file diff --git a/src/monocypher.c b/src/monocypher.c index 0960574..33ab4bb 100644 --- a/src/monocypher.c +++ b/src/monocypher.c @@ -523,33 +523,30 @@ static void blake2b_set_input(crypto_blake2b_ctx *ctx, u8 input, size_t index) ctx->input[word] |= (u64)input << (byte << 3); } -void crypto_blake2b_general_init(crypto_blake2b_ctx *ctx, size_t hash_size, - const u8 *key, size_t key_size) +// Defaults are no key, 64 byte hash +crypto_blake2b_config crypto_blake2b_defaults = { 0, 0, 64 }; + +void crypto_blake2b_init(crypto_blake2b_ctx *ctx, crypto_blake2b_config config) { // initial hash COPY(ctx->hash, iv, 8); - ctx->hash[0] ^= 0x01010000 ^ (key_size << 8) ^ hash_size; + ctx->hash[0] ^= 0x01010000 ^ (config.key_size << 8) ^ config.hash_size; - ctx->input_offset[0] = 0; // beginning of the input, no offset - ctx->input_offset[1] = 0; // beginning of the input, no offset - ctx->hash_size = hash_size; // remember the hash size we want + ctx->input_offset[0] = 0; // beginning of the input, no offset + ctx->input_offset[1] = 0; // beginning of the input, no offset + ctx->hash_size = config.hash_size; ctx->input_idx = 0; // if there is a key, the first block is that key (padded with zeroes) - if (key_size > 0) { + if (config.key_size > 0) { u8 key_block[128] = {0}; - COPY(key_block, key, key_size); + COPY(key_block, config.key, config.key_size); // same as calling crypto_blake2b_update(ctx, key_block , 128) load64_le_buf(ctx->input, key_block, 16); ctx->input_idx = 128; } } -void crypto_blake2b_init(crypto_blake2b_ctx *ctx) -{ - crypto_blake2b_general_init(ctx, 64, 0, 0); -} - void crypto_blake2b_update(crypto_blake2b_ctx *ctx, const u8 *message, size_t message_size) { @@ -603,19 +600,13 @@ void crypto_blake2b_final(crypto_blake2b_ctx *ctx, u8 *hash) WIPE_CTX(ctx); } -void crypto_blake2b_general(u8 *hash , size_t hash_size, - const u8 *key , size_t key_size, - const u8 *message, size_t message_size) +void crypto_blake2b(u8 *hash, crypto_blake2b_config config, + const u8 *message, size_t message_size) { crypto_blake2b_ctx ctx; - crypto_blake2b_general_init(&ctx, hash_size, key, key_size); + crypto_blake2b_init (&ctx, config); crypto_blake2b_update(&ctx, message, message_size); - crypto_blake2b_final(&ctx, hash); -} - -void crypto_blake2b(u8 hash[64], const u8 *message, size_t message_size) -{ - crypto_blake2b_general(hash, 64, 0, 0, message, message_size); + crypto_blake2b_final (&ctx, hash); } ////////////// @@ -654,11 +645,12 @@ static void xor_block(blk *o,const blk*in){FOR(i, 0, 128) o->a[i] ^= in->a[i];} static void extended_hash(u8 *digest, u32 digest_size, const u8 *input , u32 input_size) { + crypto_blake2b_config config = { 0, 0, MIN(digest_size, 64) }; crypto_blake2b_ctx ctx; - crypto_blake2b_general_init(&ctx, MIN(digest_size, 64), 0, 0); - blake_update_32 (&ctx, digest_size); - crypto_blake2b_update (&ctx, input, input_size); - crypto_blake2b_final (&ctx, digest); + crypto_blake2b_init (&ctx, config); + blake_update_32 (&ctx, digest_size); + crypto_blake2b_update(&ctx, input, input_size); + crypto_blake2b_final (&ctx, digest); if (digest_size > 64) { // the conversion to u64 avoids integer overflow on @@ -669,14 +661,14 @@ static void extended_hash(u8 *digest, u32 digest_size, u32 out = 32; while (i < r) { // Input and output overlap. This is intentional - crypto_blake2b(digest + out, digest + in, 64); + crypto_blake2b(digest + out, crypto_blake2b_defaults, + digest + in, 64); i += 1; in += 32; out += 32; } - crypto_blake2b_general(digest + out, digest_size - (32 * r), - 0, 0, // no key - digest + in , 64); + config.hash_size = digest_size - (32 * r); + crypto_blake2b(digest + out, config, digest + in , 64); } } @@ -728,7 +720,7 @@ void crypto_argon2(u8 *hash, u32 hash_size, void *work_area, { u8 initial_hash[72]; // 64 bytes plus 2 words for future hashes crypto_blake2b_ctx ctx; - crypto_blake2b_init (&ctx); + crypto_blake2b_init (&ctx, crypto_blake2b_defaults); blake_update_32 (&ctx, config.nb_lanes ); // p: number of "threads" blake_update_32 (&ctx, hash_size); blake_update_32 (&ctx, config.nb_blocks); @@ -2175,16 +2167,34 @@ void crypto_eddsa_scalarbase(u8 point[32], const u8 scalar[32]) WIPE_CTX(&P); } +// Input: +// - seed. +// Outputs: +// - secret_key[ 0..31] = seed +// - secret_key[32..63] = [trim(hash(seed)[0..31])]B +// - public_key = [trim(hash(seed)[0..31])]B +// - seed = zeroes +// +// Writes happen in the following order: +// 1. seed +// 2. secret_key[0..31] +// 3. public_key +// 4. secret_key[32..63] +// +// The point of it all is to be robust to overly clever users who +// overlap input arguments: +// - We don' care if the seed is overwritten. +// - Everything still works when public_key == secret_key + 32. void crypto_eddsa_key_pair(u8 secret_key[64], u8 public_key[32], u8 seed[32]) { u8 a[64]; - COPY(a, seed, 32); // a[ 0..31] = seed + COPY(a, seed, 32); crypto_wipe(seed, 32); - COPY(secret_key, a, 32); // secret key = seed - crypto_blake2b(a, a, 32); // a[ 0..31] = scalar - crypto_eddsa_trim_scalar(a, a); // a[ 0..31] = trimmed scalar - crypto_eddsa_scalarbase(public_key, a); // public key = [trimmed scalar]B - COPY(secret_key + 32, public_key, 32); // secret key includes public half + COPY(secret_key, a, 32); + crypto_blake2b(a, crypto_blake2b_defaults, a, 32); + crypto_eddsa_trim_scalar(a, a); + crypto_eddsa_scalarbase(public_key, a); + COPY(secret_key + 32, public_key, 32); WIPE_BUFFER(a); } @@ -2195,7 +2205,7 @@ static void hash_reduce(u8 h[32], { u8 hash[64]; crypto_blake2b_ctx ctx; - crypto_blake2b_init (&ctx); + crypto_blake2b_init (&ctx, crypto_blake2b_defaults); crypto_blake2b_update(&ctx, a, a_size); crypto_blake2b_update(&ctx, b, b_size); crypto_blake2b_update(&ctx, c, c_size); @@ -2266,7 +2276,7 @@ void crypto_eddsa_sign(u8 signature [64], const u8 secret_key[32], u8 h[32]; // publically verifiable hash of the message (not wiped) u8 R[32]; // first half of the signature (allows overlapping inputs) - crypto_blake2b(a, secret_key, 32); + crypto_blake2b(a, crypto_blake2b_defaults, secret_key, 32); crypto_eddsa_trim_scalar(a, a); hash_reduce(r, a + 32, 32, message, message_size, 0, 0); crypto_eddsa_scalarbase(R, r); diff --git a/src/monocypher.h b/src/monocypher.h index 0aa4f1a..308a547 100644 --- a/src/monocypher.h +++ b/src/monocypher.h @@ -138,14 +138,18 @@ int crypto_aead_read(crypto_aead_ctx *ctx, // General purpose hash (BLAKE2b) // ------------------------------ +typedef struct { + const uint8_t *key; + size_t key_size; + size_t hash_size; +} crypto_blake2b_config; + +extern crypto_blake2b_config crypto_blake2b_defaults; + // Direct interface -void crypto_blake2b(uint8_t hash[64], +void crypto_blake2b(uint8_t *hash, crypto_blake2b_config config, const uint8_t *message, size_t message_size); -void crypto_blake2b_general(uint8_t *hash , size_t hash_size, - const uint8_t *key , size_t key_size, // optional - const uint8_t *message, size_t message_size); - // Incremental interface typedef struct { // Do not rely on the size or contents of this type, @@ -157,13 +161,10 @@ typedef struct { size_t hash_size; } crypto_blake2b_ctx; -void crypto_blake2b_init (crypto_blake2b_ctx *ctx); +void crypto_blake2b_init(crypto_blake2b_ctx *ctx, crypto_blake2b_config config); void crypto_blake2b_update(crypto_blake2b_ctx *ctx, const uint8_t *message, size_t message_size); -void crypto_blake2b_final (crypto_blake2b_ctx *ctx, uint8_t *hash); - -void crypto_blake2b_general_init(crypto_blake2b_ctx *ctx, size_t hash_size, - const uint8_t *key, size_t key_size); +void crypto_blake2b_final(crypto_blake2b_ctx *ctx, uint8_t *hash); // Password key derivation (Argon2) diff --git a/tests/speed/speed.c b/tests/speed/speed.c index 359bba8..9544b59 100644 --- a/tests/speed/speed.c +++ b/tests/speed/speed.c @@ -100,7 +100,8 @@ static u64 blake2b(void) RANDOM_INPUT(key, 32); TIMING_START { - crypto_blake2b_general(hash, 64, key, 32, in, SIZE); + crypto_blake2b_config config = {key, 32, 64}; + crypto_blake2b(hash, config, in, SIZE); } TIMING_END; } diff --git a/tests/test.c b/tests/test.c index 70f4607..abe15e8 100644 --- a/tests/test.c +++ b/tests/test.c @@ -415,9 +415,8 @@ static void blake2b(vector_reader *reader) vector msg = next_input(reader); vector key = next_input(reader); vector out = next_output(reader); - crypto_blake2b_general(out.buf, out.size, - key.buf, key.size, - msg.buf, msg.size); + crypto_blake2b_config config = { key.buf, key.size, out.size, }; + crypto_blake2b(out.buf, config, msg.buf, msg.size); } static void test_blake2b() @@ -439,13 +438,13 @@ static void test_blake2b() // Authenticate bit by bit crypto_blake2b_ctx ctx; - crypto_blake2b_init(&ctx); + crypto_blake2b_init(&ctx, crypto_blake2b_defaults); crypto_blake2b_update(&ctx, input , i); crypto_blake2b_update(&ctx, input + i, INPUT_SIZE - i); crypto_blake2b_final(&ctx, hash_chunk); // Authenticate all at once - crypto_blake2b(hash_whole, input, INPUT_SIZE); + crypto_blake2b(hash_whole, crypto_blake2b_defaults, input, INPUT_SIZE); // Compare the results (must be the same) ASSERT_EQUAL(hash_chunk, hash_whole, 64); @@ -457,8 +456,9 @@ static void test_blake2b() FOR (i, 0, BLAKE2B_BLOCK_SIZE + 64) { u8 hash [64]; RANDOM_INPUT(input, INPUT_SIZE); - crypto_blake2b(hash , input + 64, BLAKE2B_BLOCK_SIZE); - crypto_blake2b(input+i, input + 64, BLAKE2B_BLOCK_SIZE); + crypto_blake2b_config config = crypto_blake2b_defaults; + crypto_blake2b(hash , config, input + 64, BLAKE2B_BLOCK_SIZE); + crypto_blake2b(input+i, config, input + 64, BLAKE2B_BLOCK_SIZE); ASSERT_EQUAL(hash, input + i, 64); } } @@ -1084,10 +1084,11 @@ static void test_conversions() { printf("\tX25519 <-> EdDSA\n"); FOR (i, 0, 32) { + crypto_blake2b_config config = crypto_blake2b_defaults; RANDOM_INPUT(e_seed, 32); - u8 secret [64]; + u8 secret [64]; u8 e_public1[32]; crypto_eddsa_key_pair(secret, e_public1, e_seed); - u8 x_private[64]; crypto_blake2b (x_private, secret, 32); + u8 x_private[64]; crypto_blake2b(x_private, config, secret, 32); u8 x_public1[32]; crypto_eddsa_to_x25519 (x_public1, e_public1); u8 x_public2[32]; crypto_x25519_public_key(x_public2, x_private); ASSERT_EQUAL(x_public1, x_public2, 32); diff --git a/tests/tis-ci.c b/tests/tis-ci.c index 435d904..9bc1a7a 100644 --- a/tests/tis-ci.c +++ b/tests/tis-ci.c @@ -138,9 +138,8 @@ static void blake2b(vector_reader *reader) vector msg = next_input(reader); vector key = next_input(reader); vector out = next_output(reader); - crypto_blake2b_general(out.buf, out.size, - key.buf, key.size, - msg.buf, msg.size); + crypto_blake2b_config config = { key.buf, key.size, out.size, }; + crypto_blake2b(out.buf, config, msg.buf, msg.size); } static void sha512(vector_reader *reader) @@ -255,9 +254,10 @@ static void elligator_inv(vector_reader *reader) static int p_eddsa_x25519() { RANDOM_INPUT(e_seed, 32); + crypto_blake2b_config config = crypto_blake2b_defaults; u8 secret [64]; u8 e_public1[32]; crypto_eddsa_key_pair(secret, e_public1, e_seed); - u8 x_private[64]; crypto_blake2b (x_private, secret, 32); + u8 x_private[64]; crypto_blake2b(x_private, config, secret, 32); u8 x_public1[32]; crypto_eddsa_to_x25519 (x_public1, e_public1); u8 x_public2[32]; crypto_x25519_public_key(x_public2, x_private); ASSERT_EQUAL(x_public1, x_public2, 32);