Repository navigation
x86-64 Ed25519: negate the comb's cached point with SSE2 swaps and 2p - x - #1358
Merged
Merged
Conversation
… - x The fixed-base comb negates the selected cached point [Y - X, Y + X, 2dT] for a negative digit, 52 times per multiplication. It computed 0 - 2dT with the field subtraction (two borrow corrections) and swapped two 32-byte slot pairs through the general registers: 116 instructions. Exchange Y - X and Y + X sixteen bytes at a time in xmm0-xmm2 (SSE2), and negate 2dT as 2p - [x], whose borrow needs one correction for any four words, keeping the original with cmove for a positive digit: 58 instructions. combNeg_ok keeps its statement; the new lemmas are in Proof/Ed25519/X86_64/CombNeg.lean. 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 comb negates the selected cached point
[Y - X, Y + X, 2dT]for a negative digit, 52 times per fixed-base multiplication. It did that with a field subtraction0 - 2dT, whose borrow needs two corrections (sub's secondsbb/and/subround), and two 32-byte conditional swaps through the general registers (cswap: eight loads, five instructions per word, eight stores each) — 116 instructions.This computes the same thing in 58:
xmm0–xmm2(swapPieceX), with the mask in both quadwords ofxmm15as the selection already builds it. Only SSE2, which every target of this code has, so the baseline and the ADX variants share it. Four loads and four stores replace sixteen, and the exchange no longer walks a chain of five instructions per word before the multiplications that read these slots can start.2dTis negated as2p - [x]rather than0 - [x]. The borrow of2²⁵⁶ - 38 - [x]means2²⁵⁶ ≡ 38too many, subtracted once — and that subtraction cannot borrow again whatever the four words are, since a borrow means[x] > 2²⁵⁶ - 38and the difference is then above2²⁵⁶ - 76.0 - [x]has no such slack: its borrow leaves a difference below 38, so it needs a second correction.cmove, for whichtestsetsZFexactly for a zero mask, keeps the unnegated value for a positive digit.combNeg_okkeeps its statement (the specification'snegCachedunder the sign's mask), so nothing above it changed. The new lemmas are inProof/Ed25519/X86_64/CombNeg.lean:swapFieldX_ok, which concludes exactly whatswapFieldWide_okconcludes forcswap, andnegWords_ok/negField_okfor the negation, withfe_of_read128relating a slot's two sixteen-byte halves to its four words. No change toSpec/orTCB/.Measurements
On a Sapphire Rapids Xeon restricted to
VG_CPU_FEATURES=avx,avx2,bmi1,bmi2,adx(the_adxvariants, as on a CPU without AVX512_IFMA), fastest of five interleaved runs of each side (ci/bench_compare.py):ed25519_keygen/32ed25519_sign/64ed25519_sign/1024x25519_generate/32x25519_public_key/32Ed25519 verification, the X25519 ladder and signing long messages, which this does not change or where SHA-512 dominates, moved by under 2.1% either way.
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 the fixed-base multiplication is nearly all of a signature's time outside SHA-512. With #1351 and this change, the sign handling and the addition that follows it no longer stall on each other; measured against s2n-bignum's
edwards25519_scalarmulbaseon the same machine, ourvg_ed25519_scalar_base_adxwent from 10.1 µs to 9.4 µs against its 8.5 µs. What remains of that difference is mostly the field inversion at the end (2.2 µs againstbignum_inv_p25519's 1.6 µs).🤖 Generated with Claude Code
https://claude.ai/code/session_01RLVbycsRXKPfaW1swVZejG
Generated by Claude Code