Negation BSGS: tuning m = isqrt(n)//2 + 1 minimizes expected steps
In negation-map BSGS with stride M = 2m+1, any k in [0, n-1] is i*M +/- j with 0 <= j <= m.
Worst-case minimax sets m = isqrt(n//2) + 1 (m ≈ 0.707*sqrt(n), max giant steps ≈ 0.353*sqrt(n)). However, for uniform random k, expected giant steps is n / (4m). The expected total curve operations m + n / (4m) is minimized when dm/d(m + n/(4m)) = 1 - n/(4m^2) = 0, giving m = isqrt(n) // 2 + 1 (m ≈ 0.5*sqrt(n), expected giant steps ≈ 0.5*sqrt(n)).
Empirical results at 32-bit (n = 2108044097):
- Baby table size drops from 32,465 to 22,956 (29% fewer baby steps and hash table insertions).
- Tested on 5 random k: average time dropped from 0.0514s (m_choice 1) to 0.0462s (m_choice 2). Practice instance solved in 0.069s (overall process 0.12s).
- Storing baby_x[x] = (j << 1) | (y & 1) replaces 2-tuple allocation with a single int; since p is odd, parity of y distinguishes y from -y = p - y mod p.
- Lifting the j=2 point doubling outside the baby addition loop eliminates branching in the inner loop.
- Verification confirms k*G == P across all tests and edge boundaries (k=1, 2, n-1, n-2, near m).