]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
x86_64 implementation of _nettle_poly1305_blocks.
authorNiels Möller <nisse@lysator.liu.se>
Mon, 24 Oct 2022 19:10:32 +0000 (21:10 +0200)
committerNiels Möller <nisse@lysator.liu.se>
Mon, 24 Oct 2022 19:10:32 +0000 (21:10 +0200)
configure.ac
poly1305-update.c [new file with mode: 0644]
x86_64/poly1305-internal.asm

index 59f68b007d5191c6fcedca46e386e6801d17e387..040b772f5467270c874f8e55bf796da1712846de 100644 (file)
@@ -761,6 +761,7 @@ AH_VERBATIM([HAVE_NATIVE],
 #undef HAVE_NATIVE_ecc_secp521r1_redc
 #undef HAVE_NATIVE_poly1305_set_key
 #undef HAVE_NATIVE_poly1305_block
+#undef HAVE_NATIVE_poly1305_blocks
 #undef HAVE_NATIVE_poly1305_digest
 #undef HAVE_NATIVE_ghash_set_key
 #undef HAVE_NATIVE_ghash_update
diff --git a/poly1305-update.c b/poly1305-update.c
new file mode 100644 (file)
index 0000000..aa39185
--- /dev/null
@@ -0,0 +1,57 @@
+/* poly1305-update.c
+
+   Copyright (C) 2022 Niels Möller
+
+   This file is part of GNU Nettle.
+
+   GNU Nettle is free software: you can redistribute it and/or
+   modify it under the terms of either:
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at your
+       option) any later version.
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at your
+       option) any later version.
+
+   or both in parallel, as here.
+
+   GNU Nettle is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see http://www.gnu.org/licenses/.
+*/
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "poly1305.h"
+#include "poly1305-internal.h"
+#include "md-internal.h"
+
+unsigned
+_nettle_poly1305_update (struct poly1305_ctx *ctx,
+                        uint8_t *block, unsigned index,
+                        size_t length, const uint8_t *m)
+{
+  if (index > 0)
+    {
+      /* Try to fill partial block */
+      MD_FILL_OR_RETURN_INDEX (POLY1305_BLOCK_SIZE, block, index,
+                              length, m);
+      _nettle_poly1305_block(ctx, block, 1);
+    }
+  m = _nettle_poly1305_blocks (ctx, length >> 4, m);
+  length &= 15;
+
+  memcpy (block, m, length);
+  return length;
+}
index ef2f38e4fde1c3df24147eaace19f96816dceaa2..95c39a91734d30f2cec7ab15f7b544c2e000a472 100644 (file)
@@ -106,7 +106,7 @@ PROLOGUE(_nettle_poly1305_block)
        adc     P1305_H2 (CTX), T2
 
        mov     P1305_R1 (CTX), %rax
-       mul     T0                      C R1 T0
+       mul     T0                      C R1*T0
        mov     %rax, F0
        mov     %rdx, F1
 
@@ -160,6 +160,110 @@ undefine(`H1')
 undefine(`F0')
 undefine(`F1')
 
+C const uint8_t *
+C _nettle_poly1305_blocks (struct poly1305_ctx *ctx, size_t blocks, const uint8_t *m)
+
+define(`BLOCKS', `%rsi')
+define(`MP_PARAM', `%rdx')     C Moved to MP, to not collide with mul instruction.
+
+define(`MP', `%r8')            C May clobber, both with unix and windows conventions.
+define(`T0', `%rbx')
+define(`T1', `%rcx')
+define(`H0', `%rbp')
+define(`H1', `%r9')
+define(`H2', `%r10')
+define(`F0', `%r11')
+define(`F1', `%r12')
+PROLOGUE(_nettle_poly1305_blocks)
+       W64_ENTRY(3, 0)
+       mov     MP_PARAM, MP
+       test    BLOCKS, BLOCKS
+       jz      .Lend
+
+       push    %rbx
+       push    %rbp
+       push    %r12
+       mov     P1305_H0 (CTX), H0
+       mov     P1305_H1 (CTX), H1
+       mov     P1305_H2 (CTX), H2
+       ALIGN(16)
+.Loop:
+       mov     (MP), T0
+       mov     8(MP), T1
+       add     $16, MP
+
+       add     H0, T0
+       adc     H1, T1
+       adc     $1, H2
+
+       mov     P1305_R1 (CTX), %rax
+       mul     T0                      C R1*T0
+       mov     %rax, F0
+       mov     %rdx, F1
+
+       mov     T0, %rax                C Last use of T0 input
+       mov     P1305_R0 (CTX), T0
+       mul     T0                      C R0*T0
+       mov     %rax, H0
+       mov     %rdx, H1
+
+       mov     T1, %rax
+       mul     T0                      C R0*T1
+       add     %rax, F0
+       adc     %rdx, F1
+
+       mov     P1305_S1 (CTX), T0
+       mov     T1, %rax                C Last use of T1 input
+       mul     T0                      C S1*T1
+       add     %rax, H0
+       adc     %rdx, H1
+
+       mov     H2, %rax
+       mul     T0                      C S1*H2
+       add     %rax, F0
+       adc     %rdx, F1
+
+       mov     H2, T0
+       and     $3, H2
+
+       shr     $2, T0
+       mov     P1305_S0 (CTX), %rax
+       mul     T0                      C S0*(H2 >> 2)
+       add     %rax, H0
+       adc     %rdx, H1
+
+       imul    P1305_R0 (CTX), H2      C R0*(H2 & 3)
+       add     F0, H1
+       adc     F1, H2
+
+       dec     BLOCKS
+       jnz     .Loop
+
+       mov     H0, P1305_H0 (CTX)
+       mov     H1, P1305_H1 (CTX)
+       mov     H2, P1305_H2 (CTX)
+
+       pop     %r12
+       pop     %rbp
+       pop     %rbx
+
+.Lend:
+       mov     MP, %rax
+       W64_EXIT(3, 0)
+       ret
+EPILOGUE(_nettle_poly1305_blocks)
+undefine(`BLOCKS')
+undefine(`MP_PARAM')
+undefine(`MP')
+undefine(`T0', `%rbx')
+undefine(`T1', `%rcx')
+undefine(`H0', `%r8')
+undefine(`H1', `%r9')
+undefine(`H2', `%r10')
+undefine(`F0', `%r11')
+undefine(`F1', `%r12')
+
+
        C _poly1305_digest (struct poly1305_ctx *ctx, uint8_t *s)
 define(`S', `%rsi')