60-bit negation DP rho: 0.81M steps/sec; r1024 prevents observed trapping
Implemented stdlib Python batched affine rho (256 lanes), canonical even y negation, r-add table and distinguished points. Detect 2cycles when addition negates and next table index equals previous; double the smaller point of that cycle on next iteration. r128 with DP spacing131072 trapped badly: only112 DPs after51M steps in59s. r1024 with DP spacing8192 and age restart65536 recovered expected DP density: 41,943,040 steps,5131 DPs in51.87s (0.809M steps/sec). Practice60 unsolved at tool60s limit; not claiming height solved. Independently tested toy p10000019,a=b=1, prime order9998581: recovered planted k654321; p1000003 subgroup1571 recovered k1348. Full-width expected ~sqrt(pi*n/4) ~651M steps for n5.395e17 (~800s). This is a viable probabilistic exam attempt, not an asymptotic improvement. Read Wikipedia Pollard rho collision coefficient equation; code verifies every derived k by scalar multiplication.
56-bit packed BSGS: fingerprint-first occupancy cuts baby build 29.15s to 25.59s
Using previous 52-bit split-array BSGS at height56, n=32013501600053173: 22M baby steps, 2^25 slots, array I index/parity + array H fingerprint, 192MiB. Baseline built in29.15s, reached20M giants at53.97s; full practice timed out at60s (not solved). Improvement: use the 16-bit fingerprint array as occupancy sentinel instead of index array; reserve0 by mapping zero fingerprints to1. Only access index array when fingerprint matches, then scalar-verify kG=P as before. Build25.92s,20M giants50.34s; 60s tool still insufficient. Full-size planted P=G solved k1 in25.63s. Small-table (m10000) correctness tests on same56-bit curve passed k1,n-1,10001,20001,123456789 in0.08s. Estimated uniform full-order expected runtime ~470s at this n, versus former52-bit~60s. This remains sqrt/time-memory generic tradeoff, not improved asymptotics. Batch affine stepping uses256 lanes and Montgomery inversion.
52-bit negation BSGS: 48-bit split packed table, 192 MiB, practice 46.62s
Adapted earlier packed uint64 BSGS for height52. Cap m at 22,000,000; table 2^25 slots. Two arrays: array('I') stores (j<<1)|yParity; array('H') stores 16-bit x fingerprint (x>>25)&65535. Hash x&((1<<25)-1), linear probing; every fingerprint match verified by scalar multiplication, so truncation cannot yield wrong k. Memory 192MiB instead of uint64 256MiB. Batched affine stepping B256 with Montgomery inversion. Practice n=4422846307495181 solved k=814573362597770 in 46.62s: 22M babies + ~18.51M giants. Thus ~0.87M point steps/s including table work. Expect ~72M total steps for uniform k, ~80-90 seconds; worst ~122M. No timeout on this practice. Wikipedia confirms arbitrary m time-memory tradeoff and negation/Montgomery optimizations. Existing old m=sqrt(n)/2 table would require512MiB at this height.
48-bit packed uint64 open-addressing BSGS: 17.24s, 128MiB table
At practice n=170199042074333, original dict negation BSGS failed MemoryError after 6.68s during baby construction (m=6523024 approx). Replaced dict with array('Q') open-addressed linear-probing table: size next power of two above 1.5*m (16777216 slots, 128MiB). Each uint64 packs truncated x fingerprint in high bits and (j<<1)|yParity in low ibits=(2*m+1).bit_length()=24. Hash initial slot fingerprint & (size-1). Retain all entries with probing, scan until empty on lookup, verify every fingerprint match with scalar multiplication to handle truncation collisions correctly. Full48-bit x is not needed. Batch128 global loop solved k=135826809410425 in21.30s; batch256 with table loops inside function (local variables) improved to17.24s (~19%). Verified by mul(k,G)==P before returning. m=isqrt(n)//2+1, stride2m+1. Wikipedia notes truncated lookup tables, negation and simultaneous inversion. Memory now scales at 8 bytes per allocated slot rather than dict object overhead.
44-bit batch128 negation BSGS solves 1.285e13 order in 4.93s
Reused packed parity negation BSGS with Montgomery batching, m=isqrt(n)//2+1 and stride=2m+1. Practice p=12850386727531 n=12850386482203 solved k=10200074566935; verified scalar multiplication. Original batch64 standalone 5.25s. exec benchmarks batch32 5.15s,64 5.34s,128 4.96s. Selected128 standalone4.93s (~6% improvement). Batch256 benchmark failed MemoryError because sequential exec environments with functions referencing globals retained previous baby tables; use gc.collect after del env for future benchmarks. This is NOT a failure of standalone batch256. Table here ~1.79 million entries, so memory becomes important. Wikipedia BSGS discusses hash tables, memory/time tradeoff, negation maps and simultaneous modular inversion.
40-bit negation BSGS: batch64 slightly beats batch32, ~0.45s
Reused packed parity negation BSGS at p=739495359077,n=246498135509. m=isqrt(n)//2+1=248243; stride=496487. Solved k=95245281755 in standalone 0.48s (batch32), 0.45s (batch64). In exec-based benchmark two runs: batch16 0.481/0.570s; batch32 0.503/0.541s; batch64 0.399/0.395s; batch128 0.417/0.428s. Selected batch64. Verified answer by scalar multiplication and boundaries k=1,n-1,n//2. Baby table maps x to (j<<1)|(y&1); giant collision yields i*stride +/- j. One inverse per 64 independent additions via Montgomery batch inversion. Wikipedia confirms memory/time tradeoff and mentions negation map and simultaneous inversion. Still O(sqrt(n)), no asymptotic improvement. Workspace patch through run cannot overwrite solve.py (permission denied); use write_file for solver changes.
36-bit batch negation BSGS: packed parity table and 32-lane batches
Reused Montgomery-batched negation BSGS. Practice n=44753984617, k=14954106585 verified by multiplication. m=isqrt(n)//2+1=105776; stride 2m+1; roughly 70700 giant steps for this target. Store baby[x]=(j<<1)|(y&1) rather than (j,y); since p is odd, parity distinguishes y from -y. Benchmarks (3 runs/variant) batch32 packed=0.174s, batch64 packed=0.176s, batch128 packed=0.182s, batch256 packed=0.189s, batch512 packed=0.194s. Tuple batch32=0.189s. Original batch128 standalone .19s; new standalone .27s shows measurement noise. Edge k=1,n-1,n//2 and random all verified, .116–.233s. Chose batch32 packed parity for exam. Wikipedia BSGS discusses hashing, negation maps and Montgomery simultaneous inversion. This remains O(sqrt(n)), not asymptotic progress.
32-bit negation BSGS with Montgomery batching
Practice p=3803950679 n=3803982059, solved k=1721110374. Simple affine negation BSGS took 0.11s; 128-lane Montgomery batch inversion version took 0.09s with m=isqrt(n//2)+1 (43612 babies, ~19732 giant steps). m=isqrt(n)//2+1 (30839 babies, ~27905 giant steps) took 0.10s, within timing noise. This smaller m optimizes expected operations m+n/(4m) for uniform k rather than worst-case m+n/(2m). Batching: initialize 128 consecutive points, advance each by 128*step; prefix products of nonzero x differences then one inverse and reverse scan; singular differences use normal addition. Match baby x and y to recover ±j, giant stride 2m+1. Wikipedia explicitly mentions negation map and simultaneous inversion as optimized BSGS variants.