Repository navigation
x86-64 X25519/Ed25519: packed divsteps in the field inversion - #1377
Merged
Merged
Conversation
The inversion ran each batch's 59 divsteps one at a time, 44 instructions per step. Run them in the short Weierstrass curves' packed chunks (15, 15, 15, 14 steps, two rows of the chunk's matrix in one word each, 15 instructions per step), repeated under the names pk... since that module imports this one. The code proofs show the code computes pkBatchV (Divstep/Packed.lean, Loop.lean); Divstep/Sound.lean shows pkBatchV is 59 divsteps for an odd f and a small d (pkChunkV_rel, pkBatchV_rel), where it used wsteps_rel. From the analysis of the rustls provider's handshake signing in #991. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RLVbycsRXKPfaW1swVZejG
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.
The x86-64 field inversion of X25519 and Ed25519 (
invertDS, Bernstein–Yang divsteps in ten batches of 59) ran each batch's divsteps one at a time on the low words offandgand the four matrix entries: 44 instructions per step, tencmovs among them, about 13 cycles per step, for 590 steps. That was about a fifth ofvg_ed25519_scalar_base_adx, and the largest single difference left between our fixed-base multiplication and s2n-bignum's (which aws-lc-rs uses): 2.2 µs againstbignum_inv_p25519's 1.6 µs.This runs each batch's 59 divsteps in the packed chunks of the short Weierstrass curves' inversion (
Impl/Weierstrass/X86_64/Inv.lean): four chunks of15, 15, 15, 14steps, each on two rowsu P + v Qandq P + r Qof the chunk's matrix in one word each, so that a step is 15 instructions and updatesfandu,v(organdq,r) at once; the chunk's matrix is read from the rows' fields, updates the low words, and multiplies the batch's. The rows (fRow,aRow) and everything else are unchanged.Code
That module imports this one (through
Impl/Mont/X86_64.lean), soImpl/X25519/X86_64.leanrepeats its 60 lines of chunk code under the namespk…(pkStep,pkSteps,pkSet,pkExt,pkLow,pkComp,pkChunk), the low words and a temporary atdsT = 744(the end of the inversion's working area, unused until now). The batch count moves tor14during the chunks, which userbp.dstepand its loop are gone.Proof
The structure of the proof is unchanged: the code proofs show the code computes a word-level function for any words, and
Divstep/Sound.lean(imported only by the registration files) shows that function inverts.Divstep/Spec.lean: a batch's divsteps are nowpkBatchV, fourpkChunkVs on words (Divstep.psteps,pextLo/pextHi, the low words' update, the matrix product) in place ofDivstep.wsteps 59.Divstep/Packed.lean(new): the code computespkChunkV(pkChunk_ok), the proofs ofProof/Weierstrass/X86_64/InvPacked.leanwithout their integers, on this file'sScr,Keepsanddrun.Divstep/Loop.lean:dsteps_okcomposes the start, the four chunks and the stores;Batch.leantakes it as before.Divstep/Sound.lean:pkChunkV_relandpkBatchV_relshow the chunks are 59 divsteps (msteps 59) for an oddfand a smalld, withProof/Divstep/Packed.lean'spsteps_rel,pext_rel,low_updandmsteps_gen(the integer half ofInvPacked'spchunk_ok);run_stepuses it where it usedwsteps_rel.Divstep/Step.leankeeps onlydrun.No change to
Spec/orTCB/.Measurements
On a Sapphire Rapids Xeon, fastest of seven interleaved runs of each side (
ci/bench_compare.py), restricted toVG_CPU_FEATURES=avx,avx2,bmi1,bmi2,adx(the_adxvariants, as on a CPU without AVX512_IFMA):ed25519_keygen/32ed25519_sign/64ed25519_sign/1024x25519_generate/32x25519_public_key/32x25519_raw/32and with all of its features (the
_ifmavariants):ed25519_keygen/32ed25519_sign/64x25519_generate/32x25519_public_key/32x25519_raw/32Ed25519 verification, which compares points without encoding one, moved by under 0.5%. On the same machine (ADX only), aws-lc-rs's
ed25519_sign/64was 10.41 µs and itsed25519_keygen/329.09 µs.Why
From the analysis of the rustls provider's handshake signing in #991: on a CPU without AVX512_IFMA, Ed25519 signing was the gap against aws-lc-rs, and after #1351, #1358 and #1360 the field inversion was most of what remained between our fixed-base multiplication and s2n-bignum's. Every x86-64 X25519 and Ed25519 function that encodes a point inverts once, so X25519 (key generation and the ladder), Ed25519 key generation and signing all gain about 0.4 µs, with or without IFMA.
🤖 Generated with Claude Code
https://claude.ai/code/session_01RLVbycsRXKPfaW1swVZejG
Generated by Claude Code