Expand description
POLYVAL, the universal hash underneath AES-GCM-SIV (RFC 8452 section 3).
POLYVAL and GHASH are the same field with the bits written down in opposite
orders. GHASH reads a 16-byte block as a polynomial with the most
significant coefficient first; POLYVAL reads it least-significant first, and
reduces modulo x^128 + x^127 + x^126 + x^121 + 1 instead of GHASH’s
x^128 + x^7 + x^2 + x + 1. The two polynomials are each other’s reverse,
which is why the same hardware instruction serves both.
§Two implementations, on purpose
RFC 8452 Appendix A states the relationship exactly:
POLYVAL(H, X_1, ..., X_n) =
ByteReverse(GHASH(mulX_GHASH(ByteReverse(H)),
ByteReverse(X_1), ..., ByteReverse(X_n)))So POLYVAL can be computed two entirely different ways: directly in its own
field, or by reversing bytes and borrowing GHASH. This module implements the
first; the tests implement the second over crate::gcm’s GHASH, which is
validated against published GCM vectors. Agreement between them is real
evidence rather than a round trip, and it is the one part of AES-GCM-SIV
that gets such evidence — see the gcm_siv module documentation for what
does not.
§Constant time
The multiplication is bit-by-bit with a mask, never a table lookup and never
a branch on data, for the same reason crate::gcm’s GHASH is: a
table-driven implementation leaks the key through the cache.
Structs§
- Polyval
- A POLYVAL accumulator.
Constants§
- BLOCK_
LEN - Block size, which is also the field element width.