Expand description
Poly1305 one-time message authentication code (RFC 8439 §2.5).
Poly1305 is a polynomial-evaluation MAC over GF(2^130 - 5). It
is keyed with a 32-byte one-time key (r, s) – the same key
must NEVER be reused for two different messages, otherwise the
authentication forgery becomes trivial. In ChaCha20-Poly1305 the
key is derived freshly per message from the ChaCha20 keystream
block 0, which is the standard way to satisfy this constraint.
§Construction
Acc = 0
for each 16-byte block m_i (last block possibly shorter):
n = m_i || 0x01 || zero-pad to 17 bytes (the 0x01 is appended
right after the message bytes; for a full 16-byte block it
lives at byte 16, for a short block of length L it lives
at byte L)
Acc = ((Acc + n) * r) mod p where p = 2^130 - 5
tag = (Acc + s) mod 2^128 (low 16 bytes only)r is “clamped” before use per the spec: certain bits of the 16
key bytes are cleared so that intermediate products fit in
130 + 26 bits and overflow can be handled by simple word-wise
reduction with no conditional branches.
§Internal representation
Field elements are stored in 5 limbs of 26 bits packed into
u32. This is the standard radix-2^26 representation: it gives
enough headroom that a 26-bit × 26-bit product fits in u64
(52 bits) and that the carry propagation between limbs after a
Poly1305 multiply-and-reduce stays comfortably under u64. It is
the same layout used by poly1305-donna, libsodium,
openssl/poly1305_64.c, and the reference implementation in
the RFC 8439 Appendix C.
§Tests
Pinned against the RFC 8439 §2.5.2 single test vector. A more
exhaustive set of vectors lives in §2.6 and Appendix A but the
§2.5.2 vector is sharp enough to catch every meaningful bug
(clamping, multiply-and-reduce, finalisation + s mod 2^128).
Structs§
- Poly1305
- Poly1305 MAC state.