Repository navigation
AArch64 25519: a register-resident divstep inversion, structured as s2n-bignum's bignum_inv_p25519 - #2606
Merged
Conversation
…oofs 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
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
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
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
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
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
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.
Divstep.invert, the inversion modulo p = 2²⁵⁵ − 19 thatvg_x25519,vg_x25519_baseand Ed25519's key generation, signing and verification share on AArch64, now follows the structure of s2n-bignum'sbignum_inv_p25519. It replaces the generic memory-residentInvCfg.invthat it used before; the short Weierstrass curves' inversion is untouched.invert_okkeeps its statement, so no caller changes.There are no TCB or Spec changes. No contract or Rust API changes.
Benchmarks
The Benchmarks workflow compares this branch (7df2a50) with
main(4e93b6c) on thex25519anded25519modules. Below are three N2 runs (one run of each side) and the two clean Apple runs (the fastest of five).x25519/32x25519_raw/32x25519_public_key/32x25519_generate/32ed25519_keygen/32ed25519_sign/64ed25519_sign/1024ed25519_sign/16384ed25519_verify/64ed25519_verify/1024ed25519_verify/16384Runs:
Every inversion is about 0.44 µs faster on N2. On N2,
x25519is now 26.97 µs, against s2n-bignum's own 26.6 µs.Which Apple runs count:
x25519andx25519_rawrun the same ladder and inversion, so an Apple run counts only when the two agree within 3%.x25519was 22.84 µs againstx25519_raw's 25.70 µs.Impl
Impl/Ed25519/AArch64/Divstep.leanreplaces the code in place.Weierstrass.AArch64.pwords).mat).q = ⌊W/2²⁵⁵⌋ − [W < 0], a fold of 19q.eor/andselect rather than a branch.All of it is in registers except the numbers f, g, u and v, the staging rows, and d. The batch counter is in
x20and the output pointer inx19: the taint analysis treats memory as secret, so a counter or pointer reloaded from memory would fail callers'taint_decide. To freex19, the matrix's second carry is computed intox11. The registers written are still withinx19 :: clob 4 ++ [x2, x20], whichinvert_okpromises.Proofs
Proof/Ed25519/AArch64/Inv/:Half,Row: a row: (W + 2²⁵⁶ (k_a + k_b)) mod 2³²⁰ = (c + X' a + Y' b) mod 2³²⁰ (row_ok).Mat: the matrix's magnitudes, masks and carries (mat_ok).Conn: the rows as integers, signed for f and g, unsigned for u and v.Out: the shift and the reduction (shift_ok,reduce_ok).Math.redV_congshows the reduction is W mod p for W ≡ R (mod 2³²⁰) with |R| < 2³¹⁷.Step: the batches' invariantRInvandstep_inv, mirroring x86-64'sProof/X25519/X86_64/Divstep/Sound.lean.Batch,Ends: the tail of a batch (outs_ok), andinit_okandfinish_ok.The two ends reduce with the same word lemmas as
Freeze.lean(fold_top,add19_top), in this code's registers.Divstep.leanstates the result as the classSound, whose field isinvert_okitself. Its proof is inDivstepSound.lean, which only the registration files import, as before:batch_okand the loop;divsteps_590, p prime);Keeping the proof behind the class keeps callers free of the algebra, and
Divstep/Packedundercheck_lean_speed's 40-importer limit. Constant time is unchanged: the callers'taint_decidecovers the new code.Speed:
row_ok(3.0 s),batch_ok(2.3 s) andred_arith(2.2 s).red_arithcallsomega_usingwith the facts each step needs; the whole-contextomegatook 11 s.2 ^ 256 * 2 ^ 64, so that unifying core's and Mathlib'sNatpowers never evaluates 2³²⁰.Checks
lake buildpasses, andEmit.leanregeneratedsrc/asm/aarch64/x25519.rsanded25519.rs.check_lean_imports,check_lean_modules,check_registrations,check_lean_speed,check_vectors,check_arch_gates,check_variants,check_mcdtandcpu_tests.py lintpass, as doescargo fmt --check.x25519anded25519unit tests, the RFC 7748 and RFC 8032 vectors, and Wycheproof'sx25519anded25519tests pass.ci/algorithms_table.pyleaves the README unchanged: the docs don't describe the inversion.🤖 Generated with Claude Code
https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw