Pippenger's window method (banderwagon.MultiExp) branches on scalar
digits, leaking secret prover-side scalars to a Flush+Reload attacker.
Wrap MultiExp with multiplicative blinding (k_i -> k_i*r, post-multiply
by r^-1 via Fermat) so the cache trace depends on a fresh per-call r
instead of the underlying witness/blinding scalars.
Five prover-side call sites switched to the blinded path:
- prover.go:109,113,118,122 (a_R/a_L witness halves and z_L/z_R)
- config.go:64 IPAConfig.Commit (full witness polynomial; trades the
PrecompMSM precomputed-table speedup for protection of secret coeffs)
Verifier-side callers (verifier.go:50,70 and multiproof.go:241) keep
using the unblinded MultiScalar since they only consume public scalars.
r is sampled via crypto/rand and converted to Montgomery form so the
downstream Mul/Exp operate consistently with ScalarsMont:true.
r^-1 uses Fermat (r^(q-2)) for a constant-iteration inversion ladder
rather than the variable-time extended-Euclidean Inverse.
A post-MSM normalization restores the canonical (0,1,1) projective
form for the identity element, since gnark's scalarMulGLV produces
a non-canonical representation that confuses Element.Equal.
Tests in ipa/ipa/prover_blinding_test.go: 600 random correctness
checks across 6 input sizes (n=2,4,8,64,128,256), input-mutation
guard, length-mismatch error, and a timing-variance smoke test
(cv ~34%, indicates fresh r per call exercises the masking path).
The Banderwagon prime-order group used by Verkle / IPA had been vendored
internally under lux/crypto/ipa/banderwagon. Extract it to
lux/crypto/banderwagon as the canonical Lux public surface; rewrite all
internal ipa callers (prover, verifier, config, multiproof, common,
transcript, test_helper, tests) to import from the canonical home.
- Provenance comment on every file: github.com/crate-crypto/go-ipa
(Apache-2.0 / MIT dual). Adds LICENSE-GO-IPA-APACHE2 and
LICENSE-GO-IPA-MIT alongside the package.
- Element / Generator / Identity / Fr / MSMPrecomp / PrecompPoint /
CompressedSize / UncompressedSize / SetBytes / SetBytesUncompressed /
ElementsToBytes / BatchToBytesUncompressed / BatchNormalize /
MapToScalarField / BatchMapToScalarField / Add / Sub / Double / Neg /
ScalarMul / MultiExp now have one and only one home: lux/crypto/banderwagon.
- Verkle (parallel branch) will switch its banderwagon import to this
canonical surface.
- KAT vectors from the upstream go-ipa Verkle reference suite preserved
(TestEncodingFixedVectors, TestPointAtInfinityComponent) plus all
precomp MSM-vs-gnark random-round tests (1000 * NumCPU rounds).
Tests: go test ./banderwagon/... ./ipa/... — all PASS (banderwagon 27s,
ipa 16s, ipa/bandersnatch 24s, fp/fr 4s+2s, common 3s).