Repository navigation
AArch64 divstep inversions: keep a, b signed across batches - #2764
Merged
Merged
Conversation
Each batch reduced the rows of a and b by one word of Montgomery reduction and then brought them into [0, p) with three masked passes of p (mredC). The inversion now keeps them signed in n + 1 words, in (-p, 2p), which one word of reduction keeps since |u| + |v| <= 2^59 (mredS); the passes run once, at the end (normC). The model is Proof/Divstep/TcS.lean's invRunS. The batches with a, b in [0, p) stay for the P-256 inversions built on them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
Kept out of modules of their own, which would bring Divstep/Tc.lean and Packed.lean more than 40 importers (ci/check_lean_speed.py). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #991. The AArch64 counterpart of #2746.
What
InvCfg.inv(Impl/Weierstrass/AArch64/Inv.lean), the divstep inversion of the generic AArch64 Weierstrass code, used to reduceaandbfully in every batch. Each batch did one word of Montgomery reduction, then brought the result into[0, p)with three masked passes ofp(mredC). Now:aandbstay signed inn + 1words, in(-p, 2p).|u| + |v| ≤ 2^59(mredS).normC, factored out ofmredC).The model is
Proof/Divstep/TcS.lean'sinvRunS, from #2746.The signed batches have slots of their own (
sBS,sNFS,sNGS,sTS):f,g,a,b,f'andg'ofn + 1words each, thent. That is7 n + 8of the table's9 nwords. The constant goes inf''s place.Old pieces kept.
batch,init,fgUpdate,abUpdateandfinishstay as they were, because the P-256 ECDH and verify inversions are built on them. Those areImpl/P256/EcdhInverse.leanandEcdsa/Verify/AArch64/Allocated.lean, register-allocated copies of the update certified against the generic one.fgUpdateandfinishare nowfgUpdateAtandfinishAtat the old slots, so their code is unchanged.ecdh_p256.rsand P-256 verify's code are byte-identical.Reach. This reaches every user of
inv:ec_p256);Dynamic instruction counts per inversion (straight-line batches, with
normConce at the end):abUpdateper batchP-256 ECDH and verify, measured and left as they are. I regenerated their allocated updates from the signed update with their generators (
GenerateP256Ecdh.lean,GenerateP256Verify.lean, which reproduce today's files byte for byte):inverseUpdate, per batchlinadds a word to each of its four rows.normCadds about 75 instructions.That is under 0.1% of ECDH or verify, against moving about 1,850 lines of their proofs to the signed invariant, so they keep the old batches.
No
TCB/orSpec/changes.Proof
InvBatch.lean:normC_ok:[t + 8]holdingr ∈ (-p, 2p)becomesnorm p r, byDivstep.norm_nat.mredS_ok:[dst] ≡ mredRaw p m T, byDivstep.mredRaw_nat. Both are split frommredC_ok's proof.IInvS, the signed batch state.abHalfS_ok,abUpdS_ok,batchS_ok: a batch asDivstep.batchS.fgUpd_okis generalized to any staging slots (fgUpdAt_ok); the old lemma is a corollary.InvBatchbecause modules of their own would bringDivstep/Tc.leanandPacked.leanmore than 40 importers.InvMain.lean:initS_ok.loopS_ok: the invariantinvRunS, witha,bin(-p, 2p)byinvRunS_range, andd,f,gthose ofinvRunbyinvRunS_rel.finishS_ok:normC, thenfinishAt_ok, the oldfinish_okgeneralized over the constant's slot.invPow_ok: the same statement, for the newinv. Itsaisnorm pofinvRunS's, which isinvRun's (norm_invRunS).InvSound, the contract every caller uses, is unchanged.Performance
Benchmarks run 39116706828: Neoverse N2, aarch64,
cpu_features='-', against the merge base (31531ad97), modulesecdsa_p256 ec_p256 ecdh_p384 ecdsa_p384 ec_p384 ecdh_p521 ecdsa_p521 ecdh_secp256k1.ec_p256_public_keyecdsa_p521_sha512_sign/64ecdsa_p521_sha512_sign/1024ecdsa_p521_sha512_sign/16384ec_p521_public_keyThe P-521 rows are not a regression of this change, in my reading:
p521_inverse.rs), and that runs 10.0% fewer instructions (58443 → 52627, about 5,800 fewer per call).FRESH_COPIESgroups (P-521's comb table): each side is the best of 8 fresh copies of its binary, and the copies of one side spread by 6–12%. That is page-placement noise ten times the size of these deltas.P-192, P-224 and the three brainpool curves run the same
invcode and were not benchmarked.Tests
lake build,Emit.lean --checkand theci/check_*.pyscripts pass.cargo test --release --target aarch64-unknown-linux-gnu, 61 tests.🤖 Generated with Claude Code
https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw