Implement AES-CMAC on x86-64, with an AES-NI variant - #463
Merged
Merged
Conversation
The three AES-CMAC primitives specified in VG.Spec.Cmac (vg_cmac_aes_subkeys, vg_cmac_aes_update, vg_cmac_aes_finalize), proven against their contracts on x86-64: correct and constant time. Each encrypts a block by calling the verified vg_aes_ctr32 on a zero block with the block as the counter, so the CMAC code is generic over the implementations of ctr32 (a new AesCtr32 interface under Generic/ and Variants/): the emitter also emits the _aesni functions, calling vg_aes_ctr32_aesni. The Rust API is verified_garbage::cmac::aes::AesCmac (new, update, finalize, verify, mac), choosing the implementation by CPU feature. It is tested against Wycheproof's aes_cmac_test.json and every vector of the vendored NIST CAVP CMAC generation and verification files, and benchmarked against OpenSSL. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WkLN6tAYk76HACiEWLbAMD
Member
Author
|
The failures on the previous head ( Generated by Claude Code |
reaperhulk
enabled auto-merge
October 1, 2026 14:31
…ngth check The rust-cpu-features jobs run only the tests they name; without cmac, the scalar implementation (chosen under SDE's Pentium 4) never ran under coverage. The rejected key's assertion keeps its message on one line, which coverage counts as run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WkLN6tAYk76HACiEWLbAMD
This was referenced Oct 1, 2026
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.
Implements the AES-CMAC primitives specified in #447 (
VG.Spec.Cmac) on x86-64 and builds the public API on them. This PR is an implementation only: it changes noSpec/orTCB/files.Lean
Impl/CmacAes/X86_64.lean:vg_cmac_aes_subkeys,vg_cmac_aes_updateandvg_cmac_aes_finalize.vg_aes_ctr32with that block as the counter and a zero block as the data. The callee's output is thenCIPH_K(X)(ctr32_one).Lin two byte-swapped 64-bit words (Proof/CmacAes/X86_64/Dbl.lean).finalizehandles a full last block (XOR withK1) and a partial one (copy, pad with0x80, XOR withK2), then makes one more call.Proof/CmacAes/X86_64/) cover correctness against the shared contracts (Verified.of_correct, thensig_implies) and constant time.RelCT) from ctr32's own constant-time proof, because the callee's spills hide which saved registers stay public.AesCtr32interface:Generic/AesCtr32/X86_64/CmacAes.leanregisters the functions.Variants/AesCtr32/X86_64/{Scalar,AesNi}.leanadd the implementations.Proof/Aes/X86_64/Variant.leanpackages each ctr32 with its proofs.vg_cmac_aes_*_aesni(featuresaes,ssse3), which callvg_aes_ctr32_aesni.Proof/Cmac/(Spec,Mem,Dbl), ready for the other architectures.Rust
verified_garbage::cmac::aes::AesCmac(new,update,finalize,verify,mac), gated on x86-64 for now.finalize.match(Scalar/AesNi).cmac::{InvalidKeyLength, InvalidMac}are shared with the later 3DES-CMAC module.Tests and benchmark
aes_cmac_test.json: 63 valid, 243 modified tags and 5 bad key sizes. Each MAC is computed three ways: all at once, in oneupdate, and byte by byte.CMACGenfiles (336) andCMACVerfiles (480: 96 pass, 384 fail), with tags truncated toTlen.VG_CPU_FEATURES=none. Line coverage of the new files is 100% across the two configurations.bench/benches/primitives/cmac_aes.rsmeasuresaes-128-cmacandaes-128-cmac-verifyagainst OpenSSL'sPKey::cmac. A quick local run (AES-NI) gave about 230 MiB/s at 64 B and 560 MiB/s at 16 KiB, against OpenSSL's 13 and 335 MiB/s on the same machine.ci/algorithms_table.py): AES-CMAC is now ✅ AES-NI on x86-64.Checks run locally
lake build(full) andlake env lean --run Emit.lean --checkcheck_lean_imports,check_lean_speed,check_vectors,check_arch_gates,check_variantsandcheck_mcdtcargo fmt --checkandcargo clippy --all-targets -D warnings(crate and bench)cargo testwith Wycheproof, with and withoutVG_CPU_FEATURES=noneThe AArch64, ARMv7 and x86 implementations will follow in separate PRs.
🤖 Generated with Claude Code
https://claude.ai/code/session_01WkLN6tAYk76HACiEWLbAMD
Generated by Claude Code