Repository navigation
ML-KEM AArch64: 16-bit paired key generation, encapsulation and decapsulation - #2849
Merged
Merged
Conversation
Two TBLs look up the low and high bytes of (f - 2) mod q for each nibble f <= 4, and ZIP1/ZIP2 interleave them into halfwords: 14 vector instructions per 32 coefficients after the nibble arithmetic, against 46 for the u32 version's widening and reduction. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
…p2_arith) pass1Body and pass2Body name their arithmetic (pass1Arith, pass2Arith) and pass 2's loads, so that a pass with other loads or stores can share them; the instructions are the same, and so is the emitted code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
…by vg_mlkem16_cbd2 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
…wdW) Each row of pass 1 is one load (no uzp1 from u32s), and each vector of pass 2 one store (no widening zips): 160 fewer instructions per transform. The arithmetic is pass1Arith/pass2Arith, shared with the u32 version; wp_stores takes the region's length (wp_storesN), and pass 2's loads come from where they are in memory (p2_loadsOf). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
…1_arith, ip2_arith) invPass1Body and invPass2Body name their arithmetic (invPass1Arith, invPass2Arith); the instructions, and the emitted code, are the same. invPass1BodyW and invPass2BodyW load and store 16-bit coefficients. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
… bits (invW) Each vector of pass 1 is one load and each row of pass 2 one store (no uzp1 from u32s, no widening zips). CoeffsInW, coeffAtW16_write: 16-bit coefficients written eight at a time at any offset. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
…d its lane lemmas Each iteration takes 8 pairs of each term: UZP1/UZP2 of halfwords and UMLAL/UMLAL2 into word accumulators. The proof of the loop follows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
…module (Mem16Bytes) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
…accumulateW_ok) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
… any registers 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
…ients (dotW_ok) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
…W_ok) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
…W_ok) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
…nd of the terms Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
…ts (addW_ok, subW_ok) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
… apart (default off, same code) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
…al_writeW) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
…6 or 32 bits) The 32-bit names are the w16 = false instances; the code is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
…ces over a coefficient width The 16-bit batch stores the compacted halfwords themselves; the 32-bit names are the w16 = false instances, and the code is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
… a coefficient width Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
…iming over a coefficient width Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
…a coefficient width Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
… over a coefficient width 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
…with x86-64 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
…kem16_cbd2 and the 16-bit-stored transforms inlined) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
…it coefficients Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
…ilding blocks in the KEM context 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
…and verified Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
… and verified Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
…ion and decapsulation Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma2fA9rUTPXEEQjYyCMCRw
The 16-bit key generation, encapsulation and decapsulation replace the u32 paired compositions, so their implementations and proofs, and the lemmas only they used, are deleted. 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.
On AArch64, ML-KEM-768 and ML-KEM-1024 key generation, encapsulation and decapsulation now keep polynomials as u16 coefficients all the way through. Each polynomial sits in the first 512 bytes of its 1024-byte slot. The old paired whole-KEM compositions kept u32 coefficients, and these replace them.
Changes
Impl/MlKem/AArch64/Kem16.lean, plus the remaining 16-bit pieces it uses (widen, a 16-bit CBD call in the shared noise sampler). The new pieces:addWdotWnttInvAtWithWdecW/encWcodecsProof/MlKem/AArch64/Kem16/*proves all six artifactsVerified(correct, constant time, stack depth).KBinvariants are generalized over width (BInv := BInvW false, …).half_subcarries frames over the 512-byte halves to the 1024-byte slots.Generic/KeccakX2/Keccak/AArch64/MlKem.leannow binds the 16-bitkeyGen/encaps/decaps.src/asm/aarch64/is regenerated, and the new modulemlkem16.rsholdsvg_mlkem16_cbd2.Kem*,KeyGen*,DecapsTiming, …KeyGenFinal/Verified/Using,DecapsVerified/Correct, …vRest/encryptRest/encapscompositions and their abbreviationsnarrowApiis still registered, so no follow-up Spec PR is needed.No changes to
TCB/orSpec/.Speed
Benchmarks run 39186145283, Neoverse N2, fastest of 8 copies, all features:
neonandnoneare 0.0%: that code is unchanged. No row is slower.Checks
These pass locally:
lake buildEmit.lean --checkcheck_lean_imports,check_lean_modules,check_registrations,check_lean_speed,check_vectors,check_arch_gates,check_variants,check_mcdtalgorithms_table.py(table unchanged)cargo fmt --checkandclippy -D warningsFollow-ups
w16parameters on the shared noise sampler are now alwaystrue, so they can be removed.subW/hsubOpwere already there before this PR and are left as they are.Generated by Claude Code