From 0257fb909b06aeef50af76260dab22eaba95ad0f Mon Sep 17 00:00:00 2001 From: Loup Vaillant Date: Sun, 14 Jan 2018 13:42:38 +0100 Subject: [PATCH] More concise Chacha20 Partially reverts the optimisation from d1be682. Hoisting the test out of the loop entirely was overkill. One level is sufficient, pushing it any further has negligible impact. --- src/monocypher.c | 80 ++++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 47 deletions(-) diff --git a/src/monocypher.c b/src/monocypher.c index 3f19476..9016f97 100644 --- a/src/monocypher.c +++ b/src/monocypher.c @@ -214,67 +214,53 @@ void crypto_chacha20_encrypt(crypto_chacha_ctx *ctx, const u8 *plain_text, size_t text_size) { - if (plain_text != 0) { - // Align ourselves with a block - while (ctx->pool_idx % 64 != 0 && text_size > 0) { - *cipher_text = chacha20_pool_byte(ctx) ^ *plain_text; + // Align ourselves with a block + while (ctx->pool_idx % 64 != 0 && text_size > 0) { + u8 stream = chacha20_pool_byte(ctx); + u8 plain = 0; + if (plain_text != 0) { + plain = *plain_text; plain_text++; - cipher_text++; - text_size--; } - // Main processing by 64 byte chunks - size_t nb_blocks = text_size / 64; - size_t remainder = text_size % 64; - FOR (i, 0, nb_blocks) { - chacha20_refill_pool(ctx); + *cipher_text = stream ^ plain; + text_size--; + cipher_text++; + } + + // Main processing by 64 byte chunks + size_t nb_blocks = text_size / 64; + size_t remainder = text_size % 64; + FOR (i, 0, nb_blocks) { + chacha20_refill_pool(ctx); + if (plain_text != 0) { FOR (j, 0, 16) { - store32_le(cipher_text + j * 4, - ctx->pool[j] ^ load32_le(plain_text)); + u32 plain = load32_le(plain_text); + store32_le(cipher_text + j * 4, ctx->pool[j] ^ plain); plain_text += 4; } - cipher_text += 64; - } - if (nb_blocks > 0) { - ctx->pool_idx = 64; - } - // Remaining input, byte by byte - FOR (i, 0, remainder) { - if (ctx->pool_idx == 64) { - chacha20_refill_pool(ctx); - } - *cipher_text = chacha20_pool_byte(ctx) ^ *plain_text; - plain_text++; - cipher_text++; - } - } - else { - // Align ourselves with a block - while (ctx->pool_idx % 64 != 0 && text_size > 0) { - *cipher_text = chacha20_pool_byte(ctx); - cipher_text++; - text_size--; } - // Main processing by 64 byte chunks - size_t nb_blocks = text_size / 64; - size_t remainder = text_size % 64; - FOR (i, 0, nb_blocks) { - chacha20_refill_pool(ctx); + else { FOR (j, 0, 16) { store32_le(cipher_text + j * 4, ctx->pool[j]); } - cipher_text += 64; } + cipher_text += 64; if (nb_blocks > 0) { ctx->pool_idx = 64; } - // Remaining input, byte by byte - FOR (i, 0, remainder) { - if (ctx->pool_idx == 64) { - chacha20_refill_pool(ctx); - } - *cipher_text = chacha20_pool_byte(ctx); - cipher_text++; + } + // Remaining input, byte by byte + FOR (i, 0, remainder) { + if (ctx->pool_idx == 64) { + chacha20_refill_pool(ctx); + } + u8 plain = 0; + if (plain_text != 0) { + plain = *plain_text; + plain_text++; } + *cipher_text = chacha20_pool_byte(ctx) ^ plain; + cipher_text++; } } -- 2.47.3