diff options
author | Niels Möller <nisse@lysator.liu.se> | 2022-10-24 21:10:32 +0200 |
---|---|---|
committer | Niels Möller <nisse@lysator.liu.se> | 2022-10-24 21:10:32 +0200 |
commit | 672b76f6a36440cb8a8417db56bdf2cc3f2c5d4f (patch) | |
tree | ca2c3c6651f5ebb5504e964886528fc4083b5495 | |
parent | 79dd4dbae6419872f581d67a212fb8c612320330 (diff) | |
download | nettle-672b76f6a36440cb8a8417db56bdf2cc3f2c5d4f.tar.gz |
x86_64 implementation of _nettle_poly1305_blocks.
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | poly1305-update.c | 57 | ||||
-rw-r--r-- | x86_64/poly1305-internal.asm | 106 |
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') |