]> git.codecow.com Git - Monocypher.git/commitdiff
More concise Chacha20
authorLoup Vaillant <loup@loup-vaillant.fr>
Sun, 14 Jan 2018 12:42:38 +0000 (13:42 +0100)
committerLoup Vaillant <loup@loup-vaillant.fr>
Sun, 14 Jan 2018 12:42:38 +0000 (13:42 +0100)
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

index 3f194765ea3177e1fc2256d3879511bec1e737d3..9016f973994715292e5ebe6e9feb9387fcf4f5a1 100644 (file)
@@ -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++;
     }
 }