[PATCH] poly1305-avx512: fix lost carry in conversion from base 2^44

Jussi Kivilinna jussi.kivilinna at iki.fi
Sun Oct 11 17:44:07 CEST 2026


* cipher/poly1305-amd64-avx512.S (POLY1305_BLOCKS): Use add with
carry instead of OR for combining first and second limb.
* tests/basic.c (check_mac): Add crafted Poly1305 test vector.
--

After final partial reduction, first 44-bit limb of horizontally summed
hash may exceed 44 bits. Combining limbs with OR then loses carry and
gives wrong tag for some inputs.

GnuPG-bug-id: 8514
Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
 cipher/poly1305-amd64-avx512.S |  6 ++-
 tests/basic.c                  | 71 ++++++++++++++++++++++++++++++++++
 2 files changed, 76 insertions(+), 1 deletion(-)

diff --git a/cipher/poly1305-amd64-avx512.S b/cipher/poly1305-amd64-avx512.S
index 250db072..1f7bd736 100644
--- a/cipher/poly1305-amd64-avx512.S
+++ b/cipher/poly1305-amd64-avx512.S
@@ -1401,12 +1401,12 @@ ELF(.size _gcry_poly1305_avx512_consts,.-_gcry_poly1305_avx512_consts)
 	vpaddq  xmm13, xmm13, xmm0; \
 	\
 	/* ; Put together A */ \
+	/* ; First limb can exceed 44 bits after reduction, add with carry */ \
 	vmovq   A0, xmm13; \
 	\
 	vmovq   T0, xmm14; \
 	mov     T1, T0; \
 	shl     T1, 44; \
-	or      A0, T1; \
 	\
 	shr     T0, 20; \
 	vmovq   A2, xmm15; \
@@ -1415,6 +1415,10 @@ ELF(.size _gcry_poly1305_avx512_consts,.-_gcry_poly1305_avx512_consts)
 	or      A1, T0; \
 	shr     A2, 40; \
 	\
+	add     A0, T1; \
+	adc     A1, 0; \
+	adc     A2, 0; \
+	\
 	/* ; Clear powers of R */ \
 	vpxorq  zmm0, zmm0, zmm0; \
 	vmovdqa64 [rsp + STACK_r_save], zmm0; \
diff --git a/tests/basic.c b/tests/basic.c
index ab627786..d1793eea 100644
--- a/tests/basic.c
+++ b/tests/basic.c
@@ -17513,6 +17513,77 @@ check_mac (void)
         "\x12\x97\x6a\x08\xc4\x42\x6d\x0c\xe8\xa8\x24\x07\xc4\xf4\x82\x07"
         "\x80\xf8\xc2\x0a\xa7\x12\x02\xd1\xe2\x91\x79\xcb\xcb\x55\x5a\x57",
         "\x51\x54\xad\x0d\x2c\xb2\x6e\x01\x27\x4f\xc5\x11\x48\x49\x1f\x1b" },
+      /* Crafted to stress final reduction of vector implementations */
+      { GCRY_MAC_POLY1305,
+        "\xed\x2b\x47\x3b\x67\x72\x98\xd6\x9d\x70\xe7\x5b\x1e\x84\x00\x2d"
+        "\x3b\x63\x69\xcb\xaa\x33\x6c\xdf\xdf\x3f\xc5\x1b\x3b\x7f\x76\x59"
+        "\x78\xdd\x66\x4f\x81\x9f\xa1\x08\xa2\x1c\xe8\x00\x9b\x93\x7a\xbe"
+        "\x65\x9a\xce\x7f\x0d\x80\x52\x6d\x27\xe5\x68\x0f\x00\x07\x19\x6a"
+        "\xb7\x5c\x1e\x8b\x08\xfb\xcb\x35\x14\x74\x9a\x87\x25\x7a\x9a\x76"
+        "\x2c\xf1\x8f\x07\x36\x84\x0c\x05\x5d\x02\xae\xa8\x14\xa2\x08\x07"
+        "\x3a\xfc\x9b\xb0\x60\x0d\xff\x91\x16\xf4\x63\x9f\x72\x32\x56\x9a"
+        "\x3d\x09\x53\x5b\xa4\x77\x05\x1f\x74\x71\x37\x43\x8f\x56\xd6\xf2"
+        "\xea\x78\x12\x45\xf5\x82\x20\x46\x9d\x90\x7e\xb7\x43\x05\x46\xa4"
+        "\x5a\x59\xb8\xa2\x7c\x08\x8b\x6b\x17\x5b\x73\x1e\x57\x34\x7b\xa3"
+        "\x36\x43\xf4\xfb\x93\x48\x13\x52\xcb\x4c\x27\x50\xfa\x5d\x28\x97"
+        "\xb8\xd9\xbb\x98\x2b\x20\xbf\x02\x89\x6f\x27\x7a\x88\xd9\xa8\xce"
+        "\xe1\xe8\xf5\xb1\x9f\x63\x59\xa8\xd8\x62\xb5\xb9\x8a\x20\xe5\xb3"
+        "\x44\x30\x21\x7c\x40\x94\xce\x13\x9f\xc0\x20\x44\x81\x5f\x41\xf5"
+        "\xa5\xac\xeb\x4f\xc6\xa8\x80\xe9\xda\x37\xff\xaf\xb1\x15\x9f\xd1"
+        "\x08\x0f\xc3\xef\x84\x25\x99\x4d\x28\xdb\xe2\x1b\x03\x51\x52\xc5"
+        "\x8d\x83\x87\xb3\x47\xae\x30\x27\x06\x2b\x84\xde\xaf\xd8\x8c\x92"
+        "\xf1\xab\xa9\xb4\x19\x27\xc9\x24\x05\xff\x4b\x61\x4c\x8b\x1d\xde"
+        "\xbf\x4c\x2d\x25\x3a\x71\x63\xe2\x3c\xfc\x91\x94\xc8\x16\x78\xdc"
+        "\x6a\xa1\x99\x50\x26\x60\x8a\x74\x8b\x1f\x1e\x97\x96\x03\xd0\x79"
+        "\x99\x63\x9c\xd6\xe0\x9d\xc4\x3b\xb5\x3c\x72\x99\x74\x47\xdf\x1b"
+        "\xff\x07\x90\x16\xc5\x91\x0f\xcd\xb4\x66\x63\xc2\x13\x5e\x20\x70"
+        "\x01\x9e\x0e\x09\x6e\x48\x13\x7e\x93\xee\x6d\xb1\x35\x83\x61\x8b"
+        "\xb4\xfc\x2f\x4a\x14\x61\xd9\x53\x77\x3a\x82\xb8\xbc\x3b\x97\x3f"
+        "\x68\x61\x5d\xd4\xa0\x44\x8c\x0b\x0f\x60\xca\x5a\x9a\xbc\x29\xf1"
+        "\x68\x13\xa2\x27\xb0\x54\x40\x63\x62\x97\x75\xed\x18\x61\xf4\x8c"
+        "\x9a\xfe\xb6\xa6\x58\xe6\xd8\x60\xaa\x42\x75\x6d\x10\xb1\x77\xda"
+        "\x2f\x0b\xd2\x5d\xac\xde\x94\x50\x3c\xf1\x99\x71\x5e\xb2\x5b\x0c"
+        "\x1c\xb5\xd9\x59\x38\x7e\xaf\x4d\xc0\x24\x6e\x11\x44\x10\xb9\xe0"
+        "\x4d\x06\xc2\x6e\x72\x5e\x01\x33\x5a\x76\xe3\x0c\xec\x4c\x23\xf6"
+        "\xf9\x43\x93\xe9\xa5\x3c\x15\x10\xcb\x12\xcb\x1b\xc9\xe4\xce\x21"
+        "\x22\x9a\x94\x60\x27\x89\x0c\x05\x9e\xc9\x71\x1d\xce\x96\x06\x2b"
+        "\xbb\x9f\x68\xaf\xb3\xf2\x6d\xad\xab\xc4\x93\xda\x58\x7e\x45\xbd"
+        "\x18\x78\x17\x57\xee\x5b\x9a\xa0\xcf\x0e\x8f\x98\x24\x3e\xc1\xfb"
+        "\xed\x35\xd5\x6e\x26\x80\x0f\x73\x54\xfe\x2d\x72\x1e\x0b\x1b\x34"
+        "\x53\x77\x62\xf0\x1e\xe4\x03\x00\x86\xa9\xeb\x1a\xf4\xb6\x7e\xa2"
+        "\x88\x70\xe8\x4f\xf8\xa2\xc3\x7c\x9e\x01\xaa\x20\x7b\xb4\xc1\x8a"
+        "\x32\xa5\xab\xc4\x53\x5b\x59\x77\x8f\x38\x05\x42\x35\xc7\x0e\xd4"
+        "\x5c\xd8\x74\xe6\x6a\x52\xc8\xb9\x33\x34\x79\x17\xdd\xd7\x0c\xcb"
+        "\x65\xeb\x4a\xb8\x73\x24\xa4\x4d\xa4\x17\xf0\x4f\x8f\xe9\x3e\xf4"
+        "\x6c\x81\x1b\xd9\x49\x6f\xf8\x48\x40\x97\x92\xb6\x6a\x72\x5c\x1c"
+        "\x46\x97\xa6\xd8\x0b\x1c\x40\x0c\xca\x27\x1b\x5d\x7e\x48\xe9\xe5"
+        "\x72\xf1\xa2\xc1\x36\xe9\xdb\x9e\x51\x0b\xdf\xfd\xab\xd1\x20\xf9"
+        "\x27\xf7\x09\x60\xe8\xdd\xb9\xfe\x90\x35\xd1\xa0\xb5\x59\x99\x12"
+        "\xc3\x6f\x65\x58\xf4\xba\x30\xcf\x7a\x58\xec\x54\x57\x10\x38\xbc"
+        "\xf3\x7b\x3e\x1a\x51\x15\x9f\x29\x07\x43\x24\x1a\xfe\x74\xdb\x40"
+        "\x81\x1c\xfe\x2f\x7a\x79\xf0\x94\x35\xa0\xc3\x47\x1c\xc4\x5f\x0d"
+        "\x25\x2c\xd6\xd8\x6a\x45\xa2\xa2\x83\xde\xbe\xe8\x5b\x2a\x72\xdf"
+        "\xe9\x14\xb3\x99\x06\x22\xae\x56\x8c\x72\xb0\xa8\x62\x3d\xb2\x85"
+        "\x64\x87\xfe\x52\x85\x4e\x2a\xe6\x79\x5d\x0d\xef\x80\x77\x99\x36"
+        "\xfc\x00\xa6\x65\xb8\x66\x16\xa4\x0c\x0c\xf3\x9a\xa5\x4d\xa2\x51"
+        "\x4d\xda\x44\x5f\x73\x95\xca\x48\x34\x6b\x24\x49\xd2\xd9\x8f\x54"
+        "\x49\x27\x24\x3c\x9b\x36\x90\xfb\x29\x30\x36\xf4\xc7\x33\x81\xef"
+        "\x2f\x2b\xec\x18\x45\xa5\x6b\x3e\xf5\x53\x60\xce\x40\x38\x9c\xda"
+        "\xcb\x10\x47\x2e\xf9\xae\x19\x92\x4c\x5f\x92\xc7\x2b\x26\x16\x4e"
+        "\xeb\x9d\xab\x70\x0e\x48\xf0\x72\xb0\x03\xf9\x73\x8f\xff\xf3\xc4"
+        "\x18\xb1\x23\xf2\x35\x48\x61\x20\xe3\x9a\x85\xa3\xb5\x10\x5c\x9f"
+        "\x74\x45\xba\x36\x3c\x95\x4b\x26\x8f\xda\x4c\xb7\xa9\x35\xf7\x6e"
+        "\x55\x30\x3d\x80\xd2\x78\x5b\xcf\x56\xe9\x80\xe1\x97\x52\x62\x04"
+        "\xc0\x82\x0b\x2c\x37\x0c\xf2\xf1\xf3\x49\x43\x08\x14\xb6\xe6\x33"
+        "\x37\x22\x13\xf1\xa6\xe4\x64\xf7\x27\xd9\x8d\x5b\x79\x2c\x15\x30"
+        "\x27\x80\xbe\x5c\x2b\x5c\xb5\x2d\x72\x14\x56\x81\x68\x17\xd0\x41"
+        "\xa8\x42\x8d\xa2\xb2\x66\x2e\xb7\xeb\x84\x07\x08\x79\x7b\x68\x7a"
+        "\x53\x9b\xc5\xcd\x0a\x33\x09\x4a\x15\x42\x83\x14\x65\x72\x37\x4f",
+        "\x5b\x2c\x65\x07\x45\x87\xeb\xa1\x8e\x7d\x3f\x46\xe2\xf8\xf2\x18"
+        "\x6a\x65\x84\x82\x2b\xf7\x11\xdc\x39\x78\xb3\xf2\xfd\xdb\x0f\xc5",
+        "\x71\x65\x84\x82\x2b\xf7\x11\xdc\x39\x78\xb3\xf2\xfd\xdb\x0f\xc5",
+        NULL,
+        1024, 32 },
       { GCRY_MAC_POLY1305, "?", "????????????????????????????????",
         "\xc3\x88\xce\x8a\x52\xd6\xe7\x21\x86\xfa\xaa\x5d\x2d\x16\xf9\xa3" },
       /* from http://cr.yp.to/mac/poly1305-20050329.pdf */
-- 
2.53.0



More information about the Gcrypt-devel mailing list