From 7e8cfb6b5e45c54213b7fd637fcda71e9ea9ab87 Mon Sep 17 00:00:00 2001 From: Loup Vaillant Date: Thu, 20 Jul 2017 15:55:12 +0200 Subject: [PATCH] optimised Poly1305 loading code --- src/monocypher.c | 55 ++++++++++++++++++++++++++++++++++++------------ src/monocypher.h | 2 +- 2 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/monocypher.c b/src/monocypher.c index a09ea47..aebb191 100644 --- a/src/monocypher.c +++ b/src/monocypher.c @@ -218,8 +218,7 @@ void crypto_chacha20_encrypt(crypto_chacha_ctx *ctx, plain_text += 4; } store32_le(cipher_text, ctx->pool[ctx->pool_idx / 4] ^ txt); - cipher_text += 4; - message_size -= 4; + cipher_text += 4; ctx->pool_idx += 4; } // Remaining input, byte by byte @@ -295,7 +294,20 @@ static void poly_block(crypto_poly1305_ctx *ctx) static void poly_clear_c(crypto_poly1305_ctx *ctx) { FOR (i, 0, 4) { ctx->c[i] = 0; } - ctx->c_index = 0; + ctx->c_idx = 0; +} + +static void poly_end_block(crypto_poly1305_ctx *ctx) +{ + if (ctx->c_idx == 16) { + poly_block(ctx); + poly_clear_c(ctx); + } +} + +static void poly_set_input(crypto_poly1305_ctx *ctx, u8 input) +{ + ctx->c[ctx->c_idx / 4] |= (u32)input << ((ctx->c_idx % 4) * 8); } void crypto_poly1305_init(crypto_poly1305_ctx *ctx, const u8 key[32]) @@ -314,25 +326,42 @@ void crypto_poly1305_init(crypto_poly1305_ctx *ctx, const u8 key[32]) void crypto_poly1305_update(crypto_poly1305_ctx *ctx, const u8 *msg, size_t msg_size) { - FOR (i, 0, msg_size) { - if (ctx->c_index == 16) { - poly_block(ctx); - poly_clear_c(ctx); - } - // feed the input buffer - ctx->c[ctx->c_index / 4] |= (u32)msg[i] << ((ctx->c_index % 4) * 8); - ctx->c_index++; + // Align ourselves with 4 byte words + while (ctx->c_idx % 4 != 0 && msg_size > 0) { + poly_set_input(ctx, *msg); + ctx->c_idx++; + msg++; + msg_size--; + } + + // Process the input 4 bytes at a time + size_t nb_words = msg_size / 4; + size_t remainder = msg_size % 4; + FOR (i, 0, nb_words) { + poly_end_block(ctx); + ctx->c[ctx->c_idx / 4] = load32_le(msg); + msg += 4; + ctx->c_idx += 4; + } + + // Input the remaining bytes + if (remainder != 0) { + poly_end_block(ctx); + } + FOR (i, 0, remainder) { + poly_set_input(ctx, msg[i]); + ctx->c_idx++; } } void crypto_poly1305_final(crypto_poly1305_ctx *ctx, u8 mac[16]) { // Process the last block (if any) - if (ctx->c_index != 0) { + if (ctx->c_idx != 0) { // move the final 1 according to remaining input length // (We may add less than 2^130 to the last input block) ctx->c[4] = 0; - ctx->c[ctx->c_index / 4] |= (u32)1 << ((ctx->c_index % 4) * 8); + poly_set_input(ctx, 1); // one last hash update poly_block(ctx); } diff --git a/src/monocypher.h b/src/monocypher.h index 9354669..7e80534 100644 --- a/src/monocypher.h +++ b/src/monocypher.h @@ -51,7 +51,7 @@ typedef struct { uint32_t h[5]; uint32_t c[5]; uint32_t pad[5]; - size_t c_index; + size_t c_idx; } crypto_poly1305_ctx; void crypto_poly1305_init(crypto_poly1305_ctx *ctx, const uint8_t key[32]); -- 2.47.3