Current state. #8543 deliverable 1 landed (#8670): the lattice-tier loop's .degenerate arm now reads the all-ones certificate off the same CLD lattice build the classifier already ran, byte-identical, 1.27×/1.62×/1.82× at SD4/SD5/SD6. This issue is deliverable 3 of #8543, scoped as its own work item: word-sized modulus arithmetic in the lattice tier's lift and CLD stages.
Where the time goes. Recovery-pipeline sub-stage profile at the first k ≥ floor (carica-class machine, hex_lattice_spike-style):
| input |
lift |
CLD build |
LLL+cut |
RREF |
| SD4 deg16 |
1.9ms |
0.39ms |
3.04ms (57%) |
0.05ms |
| SD5 deg32 |
15.4ms |
9.3ms |
75.8ms (75%) |
0.05ms |
| SD6 deg64 |
91ms |
98.9ms |
2161ms (92%) |
0.06ms |
The LLL reduction dominates and is integer Gram-Schmidt (not modular), so ZMod64/Montgomery does not apply to it — that is out of scope here (a separate word-sized/float LLL path would be its own issue). The word-sizable modular hot spots are the lift and CLD build, and they matter most at the SD4 / r=16 crossover, where the mod-pᵃ modulus fits 64 bits. At SD5/SD6 the modulus exceeds 2⁶⁴ and the big-integer path must stay; the win there is negligible (and those cases are already "won" versus the Isabelle comparator).
Deliverables.
- Word-sized poly-mod-
pᵃ layer. No polynomial type over a composite word-sized modulus exists yet (FpPoly is prime-only). Scalar Montgomery over an odd word-sized modulus does exist — HexArith.MontCtx needs only p % 2 = 1, and an odd prime power pᵃ < 2⁶⁴ qualifies. Build a small WordPolyMod-style layer (UInt64 residue arrays mod m, Montgomery multiply, monic division, reduce) with proven arithmetic. This is the landable first unit.
- Route
cldQuotientMod through it under a guard. cldQuotientMod f g p a = reduceModPow (f · g') p a → DensePoly.divMod _ g → reduce, all poly arithmetic mod pᵃ. Dispatch on Odd p ∧ pᵃ < 2⁶⁴; big-integer fallback otherwise. Prove cldQuotientMod = cldQuotientModWord under the guard so the CLD columns, indicators, and conformance stay byte-identical.
- Same pattern for the lift. Route
multifactorLiftQuadratic / quadraticHenselStep's mod-p^(2^i) poly arithmetic through the word-sized layer while p^(2^i) < 2⁶⁴, big-integer continuation past that. (Note the coupling: this touches HexHensel, which is more heavily proof-coupled than the CLD stage — land deliverable 2's data separately, and prefer the CLD stage first.)
Verification. Conformance byte-identical (hexbz_emit_fixtures, bz_flint.py, bz_trace_gate.py); hex_lattice_spike core ratios recorded before/after per deliverable, with special attention to SD4 (r=16); runFactorLatticeAdvSwinnertonDyerSD{3,4}Checksum stay inside the verify budget; no change to factorFast semantics; no sorry/axiom; the CI-gated HexBerlekampZassenhausMathlib layer stays green.
Context. Descends from #8543 deliverable 3 (that umbrella issue is closed; deliverable 1 landed as #8670, deliverable 2 was deprioritized after measurement showed SD5/SD6 do a single lift+recover step, and deliverable 4 — re-measuring the classical/lattice crossover and revisiting the dispatch threshold — should follow once this lands, since it is what actually moves the r=16 seam). The scalar Montgomery infrastructure is in HexArith/Montgomery/Context.lean and HexModArith/HotLoop.lean.
🤖 Prepared with Claude Code
Current state. #8543 deliverable 1 landed (#8670): the lattice-tier loop's
.degeneratearm now reads the all-ones certificate off the same CLD lattice build the classifier already ran, byte-identical, 1.27×/1.62×/1.82× at SD4/SD5/SD6. This issue is deliverable 3 of #8543, scoped as its own work item: word-sized modulus arithmetic in the lattice tier's lift and CLD stages.Where the time goes. Recovery-pipeline sub-stage profile at the first
k ≥ floor(carica-class machine,hex_lattice_spike-style):The LLL reduction dominates and is integer Gram-Schmidt (not modular), so ZMod64/Montgomery does not apply to it — that is out of scope here (a separate word-sized/float LLL path would be its own issue). The word-sizable modular hot spots are the lift and CLD build, and they matter most at the SD4 / r=16 crossover, where the mod-
pᵃmodulus fits 64 bits. At SD5/SD6 the modulus exceeds 2⁶⁴ and the big-integer path must stay; the win there is negligible (and those cases are already "won" versus the Isabelle comparator).Deliverables.
pᵃlayer. No polynomial type over a composite word-sized modulus exists yet (FpPolyis prime-only). Scalar Montgomery over an odd word-sized modulus does exist —HexArith.MontCtxneeds onlyp % 2 = 1, and an odd prime powerpᵃ < 2⁶⁴qualifies. Build a smallWordPolyMod-style layer (UInt64 residue arrays modm, Montgomery multiply, monic division, reduce) with proven arithmetic. This is the landable first unit.cldQuotientModthrough it under a guard.cldQuotientMod f g p a=reduceModPow (f · g') p a→DensePoly.divMod _ g→ reduce, all poly arithmetic modpᵃ. Dispatch onOdd p ∧ pᵃ < 2⁶⁴; big-integer fallback otherwise. ProvecldQuotientMod = cldQuotientModWordunder the guard so the CLD columns, indicators, and conformance stay byte-identical.multifactorLiftQuadratic/quadraticHenselStep's mod-p^(2^i)poly arithmetic through the word-sized layer whilep^(2^i) < 2⁶⁴, big-integer continuation past that. (Note the coupling: this touches HexHensel, which is more heavily proof-coupled than the CLD stage — land deliverable 2's data separately, and prefer the CLD stage first.)Verification. Conformance byte-identical (
hexbz_emit_fixtures,bz_flint.py,bz_trace_gate.py);hex_lattice_spike coreratios recorded before/after per deliverable, with special attention to SD4 (r=16);runFactorLatticeAdvSwinnertonDyerSD{3,4}Checksumstay inside the verify budget; no change tofactorFastsemantics; nosorry/axiom; the CI-gatedHexBerlekampZassenhausMathliblayer stays green.Context. Descends from #8543 deliverable 3 (that umbrella issue is closed; deliverable 1 landed as #8670, deliverable 2 was deprioritized after measurement showed SD5/SD6 do a single lift+recover step, and deliverable 4 — re-measuring the classical/lattice crossover and revisiting the dispatch threshold — should follow once this lands, since it is what actually moves the r=16 seam). The scalar Montgomery infrastructure is in
HexArith/Montgomery/Context.leanandHexModArith/HotLoop.lean.🤖 Prepared with Claude Code