Repository navigation
ML-KEM AArch64: vg_mlkem16_ntt, mlkem-native's scheduled forward NTT, called by the KEM tops - #3046
Conversation
|
N2 benchmarks (run 39664565308,
This meets the gate: keygen at least 2% faster, encaps and decaps faster, and nothing slower. Next on this PR: delete the forward NTT code this leaves unused ( Generated by Claude Code |
… called by the KEM tops The schedule is ported from mlkem-native's mlkem_ntt_aarch64_asm.S (dev/aarch64_opt, scheduled by SLOTHY), as vendored in aws-lc-sys 0.45.0 (aws-lc/crypto/fipsmodule/ml_kem/mlkem/native/aarch64/src/mlkem_ntt_aarch64_asm.S), Copyright (c) 2022 Arm Limited, (c) 2022 Hanno Becker, (c) 2023 Amin Abdulrahman and Matthias Kannwischer, (c) the mlkem-native project authors; Apache-2.0 OR ISC OR MIT. Its instructions are transcribed into Lean and proven by the NTT machine (NttR). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FoYWDDEDFq1DFev5X7n2aq
…lls now Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FoYWDDEDFq1DFev5X7n2aq
|
Run 39685056275 on N2 (
The gate still holds on this head: keygen is at least 2% faster, encaps and decaps are faster, and nothing is slower. CI is green. Generated by Claude Code |
Provenance. The forward NTT's schedule is ported from mlkem-native's
mlkem_ntt_aarch64_asm.S, itsdev/aarch64_optversion scheduled by SLOTHY. The source is the copy vendored in AWS-LC:aws-lc-sys0.45.0,aws-lc/crypto/fipsmodule/ml_kem/mlkem/native/aarch64/src/mlkem_ntt_aarch64_asm.S.Apache-2.0 OR ISC OR MIT. The header ofImpl/MlKem/AArch64/Ntt16/Fast.leankeeps the notice.Instrlists, then proven like every other function here. Nothing is trusted because it came from mlkem-native.It builds on #3020 (TCB: the by-element multiplies), #3042 (Spec:
vg_mlkem16_ntt'sApi) and #3041 (the NTT machine), all merged.What changes
vg_mlkem16_nttis a new out-of-line function on AArch64:Impl/MlKem/AArch64/Ntt16/Fast.lean.MUL/SQRDMULH/MLSby element).[0, q), so that the bounds ofSpec's transform hold. Each is stored with itstw = round(ζ·2¹⁵/q), as mlkem-native's are.VG_MLKEM16_NTT_ZETAS(928 bytes); the second starts 160 bytes in.[0, q), whichntt16Contractrequires.v8–v15are kept inx7–x14(umov/ins) rather than on the stack, so the function needs no stack.nttAtWithWnow callsvg_mlkem16_ntt, where it used to inlineReadonly.fwdW.Readonly.fwdW, which nothing calls now, with its row bodies (pass1BodyW,pass2BodyW), its literal and its proofs (W.fwdW_ok,fwdContractW,NttR.fwdW_run,checkW_ok). WhatinvWshares with it stays (InW,ctxW,initW_rel,polyIsW_of_outW).uintou32s and transforms it with theu32NTT. Moving it to 16 bits is a follow-up.Proofs
All by the machine of
Proof/MlKem/AArch64/NttR/:RunF.checkF_ok: the kernel's run of the whole function (lit_decide, about 2.9 s), from the table as constants.LitFmaterializes the code and the table.Sym,Step:eval_mulHE),ins .d2andumov .x.FwdF.fwdF_run: the run leavesNTTof the input, reduced, in the polynomial.AbiF.fwdFast_abi: the ABI.savecopies the low halves ofv8–v15tox7–x14(umovOf_ok).x7–x14(core_keeps).restoreputs them back (insOf_ok).x19–x28,x30orsp(fwdFast_keeps).VerifiedF:taint_decide;Verifiedagainstntt16Contract (abi.withConsts tables), with a satisfying state.CallF.ntt16_call: the call, byWP.callV.W.Call.nttAtWithW_okkeeps its statement except for the table it needs (FastReady), so the noise proofs change only their table hypotheses.Optimized.TransformTablesandTablescarry the new table (FastTable).Benchmarks
Gate: keygen ≥2%; encaps and decaps any gain; nothing slower than 0.7%.
Run 39664565308 on N2 (
arches=aarch64,cpu_features=-,modules=mlkem768 mlkem1024), against4a71169, the branch's merge base withmainbefore the restack. Fastest of 8 copies per side; spread ≤ 0.2%. The restack ontomainchanged none of this PR's code.mlkem768_keygenmlkem768_encapsmlkem768_encaps_from_bytesmlkem768_decapsmlkem1024_keygenmlkem1024_encapsmlkem1024_encaps_from_bytesmlkem1024_decapsThe gate is met.
Checks
lake buildandEmit.lean --check.src/asm/aarch64/is regenerated:mlkem16.rsgainsvg_mlkem16_nttandconsts.rsgains the table.mlkem768.rsandmlkem1024.rscall the function where they used to inline the old NTT, about 13,000 fewer lines net.cargo testforaarch64-unknown-linux-gnuunderqemu-aarch64 -cpu max, with Wycheproof, both by default and withVG_CPU_FEATURES=none: all ML-KEM tests pass.check_lean_imports,check_lean_modulesandcheck_lean_public_imports;check_registrationsandcheck_lean_speed;check_vectorsandcheck_arch_gates;check_variantsandcheck_mcdt.🤖 Generated with Claude Code
https://claude.ai/code/session_01FoYWDDEDFq1DFev5X7n2aq