7c9db9ca9c
Implements the secp256k1 GLV (Gallant-Lambert-Vanstone) endomorphism to halve the number of point doublings during signature verification. How it works: secp256k1 has an efficiently computable endomorphism φ(x,y) = (β·x, y) where β is a cube root of unity in the field. The corresponding scalar λ satisfies λ·P = φ(P). Any 256-bit scalar k can be decomposed into k = k₁ + k₂·λ (mod n) where k₁, k₂ are ~128 bits. This means k·P = k₁·P + k₂·(β·P.x, P.y), requiring only ~130 doublings instead of 256. For verification (s·G - e·P), both scalars are split into halves, giving 4 streams processed in a single pass: s₁·G, s₂·λ(G), e₁·P, e₂·λ(P). Key fixes from earlier debugging: - MINUS_LAMBDA constant was wrong (byte-level transcription error) - G1/G2 Babai rounding constants were truncated to ~142 bits instead of the full 256-bit values from libsecp256k1 - wNAF overflow fix: extended working array with maxOf(totalBits, scalar.size) to handle scalars larger than maxBits (IntArray(8) > IntArray(5) for 129-bit) - GLV sign handling: XOR the negation flag with each wNAF digit sign instead of pre-baking into tables (avoids double-negation on negative digits) - P-side uses Jacobian tables (avoids 8 expensive field inversions that would negate the GLV speedup) Tests: 4 new GLV-specific tests (scalar split reconstruction, endomorphism correctness, wNAF+GLV k1*G, mulDoubleG with zero scalar) Benchmark improvement for verifySchnorr: Before (wNAF only): 2,626 ops/s (10.6x vs native) After (wNAF + GLV): 3,254 ops/s (8.7x vs native) https://claude.ai/code/session_01BhU63WUe9AhikZxRdw3Lpg