On the web a shift truncates to 32 bits, so the carries of Poly1305 are
taken with a division. A fault injected in the carry of limb 0 passed every
test, on the VM, where the shift is exact, and on Node, because no vector
took that sum past 2^32. The generator now simulates the 13-bit limbs with
the largest r that clamping allows and finds two messages that do; Go's
poly1305 gives their tags, and the fault fails on Node. The sums of the
other limbs stay below 2^32 (at most 4.14e9 with that r).
The strict Ed25519 verification is also checked against
testdata/vectors/ed25519_strict.json directly.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The generator checks its copy of the strict profile against the
testdata/ of datekeys-dart, the copy synced at spec-v0.11, rather than
the working tree of datekeys-go. The vectors do not change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SHA-256 with its own compression, and on it HMAC-SHA256 with the inner and
outer states of the key computed once, HKDF-SHA256 and PBKDF2-HMAC-SHA256,
whose iterations are two compressions over words; scrypt with Salsa20/8;
ChaCha20, Poly1305 in 13-bit limbs and ChaCha20-Poly1305 with the tag
compared in constant time; X25519 on the field of TweetNaCl in doubles,
with the all-zero secret refused; the strict Ed25519 verification of
internal/ed25519strict; Go's Base64 with the offsets of its errors, and
age's Bech32.
tool/gen_primitive_vectors.go computes every expected value with Go and
x/crypto, from the inputs of RFC 5869, 7748, 7914, 8032 and 8439, edge
cases and seeded random ones. The tests also run compiled to JavaScript,
from a Dart copy of the JSON, without the cases that would take too long.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>