summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiels Möller <nisse@lysator.liu.se>2022-10-24 21:10:32 +0200
committerNiels Möller <nisse@lysator.liu.se>2022-10-24 21:10:32 +0200
commit672b76f6a36440cb8a8417db56bdf2cc3f2c5d4f (patch)
treeca2c3c6651f5ebb5504e964886528fc4083b5495
parent79dd4dbae6419872f581d67a212fb8c612320330 (diff)
downloadnettle-672b76f6a36440cb8a8417db56bdf2cc3f2c5d4f.tar.gz
x86_64 implementation of _nettle_poly1305_blocks.
-rw-r--r--configure.ac1
-rw-r--r--poly1305-update.c57
-rw-r--r--x86_64/poly1305-internal.asm106
3 files changed, 163 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index 59f68b00..040b772f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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
index 00000000..aa391859
--- /dev/null
+++ b/poly1305-update.c
@@ -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;
+}
diff --git a/x86_64/poly1305-internal.asm b/x86_64/poly1305-internal.asm
index ef2f38e4..95c39a91 100644
--- a/x86_64/poly1305-internal.asm
+++ b/x86_64/poly1305-internal.asm
@@ -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')