Re: [PATCH v2 1/2] lib/crypto: arm64: Fix lost Poly1305 carry when resuming NEON state

From: Jérémy Jean

Date: Fri Oct 09 2026 - 09:38:23 EST


On 2026-10-09 15:03, Eric Biggers wrote:
On Thu, Oct 08, 2026 at 08:19:50PM +0000, Jérémy Jean wrote:
These limbs in base 2^26 represent the value
4
+ (2^26 ) * 2^26
+ (2^26 - 1) * 2^52
+ (2^26 - 1) * 2^78
+ (2^24 - 1) * 2^104
= 2^128 + 4,
so converting back to base 2^64 must produce
h0 = 4, h1 = 0, h2 = 1,
so that h0 + h1 * 2^64 + h2 * 2^128 = 2^128 + 4.

The third limb starts at bit 52, so its low 12 bits belong in h0 and
its upper 14 bits belong in h1. The low-word ADDS starts from
4 + 2^26 * 2^26 = 2^52 + 4
and adds the low 64 bits of
(2^26 - 1) << 52 = 2^78 - 2^52,
namely 2^64 - 2^52. The sum is 2^64 + 4, so it leaves h0 = 4 and
carry = 1.

The middle word contains the upper 14 bits of the third limb, all of
the fourth limb, and the low 24 bits of the fifth limb. The next ADC
adds the carry from h0 to
((2^26 - 1) >> 12) + ((2^26 - 1) << 14),
giving
(2^14 - 1) + (2^40 - 2^14) + 1 = 2^40.
The following ADDS adds the low 64 bits of
(2^24 - 1) << 40 = 2^64 - 2^40,
so the sum is 2^64, h1 wraps to 0, and carry = 1.

The top word starts from the remaining bits of the fifth limb,
(2^24 - 1) >> 24 = 0.
The final ADC must add the carry from h1 and set h2 = 1. Writing the
carry into d2 instead leaves h2 = 0, so the reconstructed value is 4
instead of 2^128 + 4.

Thanks, but this LLM-generated "explanation" is way too verbose and
doesn't really say anything useful. The new test in patch 2 is also
unnecessarily specialized to this exact issue and implementation, isn't
properly explained, and it's apparently LLM-generated too. I'd normally
give a bit more time for submitters to fix things up, but since it will
likely just go back into the LLM, I don't think there's much point here.
So I went ahead and sent out a v3 that addresses these issues.

I did get help from LLM for the test, but I did write the explanation myself
to explain the carry propagation in the computations. I thought it explained
the carry bug nicely enough with an example, sorry that you disagree.
I also added a paragraph on the probability that this happens, because it's
very low and AFAICT, does not really impact current deployements.

Jérémy