Skip to content

HMAC init proofs: one shared lemma module for all four targets - #605

Merged
alex merged 1 commit into
mainfrom
claude/inspiring-pascal-labmxq-hmac-init-lemmas
Oct 2, 2026
Merged

alex merged 1 commit into
mainfrom
claude/inspiring-pascal-labmxq-hmac-init-lemmas

Conversation

@alex

@alex alex commented Oct 2, 2026

Copy link
Copy Markdown
Member

Summary

Two PRs gave HMAC's init the compression-level design: #586 (ARMv7 and x86) and #587 (x86-64 and AArch64). Each added its own target-independent lemma module, Proof/Pbkdf2/MdInit.lean and Proof/Pbkdf2/MdKeys.lean, and several facts ended up proven in both. This PR merges the two into MdKeys.lean, proves each fact once in its more general form, and points all four targets' HmacInit proofs at it. MdInit.lean is deleted.

This is a proof-only refactor. There are no changes to TCB/, Spec/, Impl/, Rust or the generated code.

Kept Replaces Note
Md.repr_block Md.repr_of_block The kept one is more general; the old one also needed stateAt m p = iv.
xorOpad_ipad xorPad_6a Same statement.
writeW_xorRep writeW_xorOpad Works for any repeated byte, not only 0x6a.
xor_byte the 32-bit one, and a 64-bit copy in AArch64's HmacInit.lean Now takes any width w ≥ 8.

The rest of MdInit's lemmas moved over unchanged, and MdKeys already imports everything they need. Some target-specific lemmas stay where they are, because they are stated over each target's own registers, state or parameters:

  • keep_st / keep_repr;
  • blockKey_eq;
  • AArch64's xor_word;
  • x86-64's double-setWidth xor_byte.

Proof cost

The table shows instructions, counted with valgrind's cachegrind (perf has no hardware counters in this VM). The run-to-run noise is about ±5M.

File Before After
X86/HmacInit 17,474M 17,481M
Arm/HmacInit 17,769M 17,770M
X86_64/HmacInit 14,285M 14,291M
AArch64/HmacInit 26,539M 26,507M
Shared lemmas 5,795M (both modules) 3,911M (merged MdKeys)

Validation

  • A full lake build, then lake env lean --run Emit.lean --check. The axiom, compiler-override and Spec-origin audits pass, and src/ is unchanged.
  • check_lean_imports, check_lean_speed, check_vectors, check_arch_gates, check_variants and check_mcdt all pass.
  • cargo fmt --check passes.

🤖 Generated with Claude Code

https://claude.ai/code/session_01RjfTK5YMk2jDsiKRYs2dbn


Generated by Claude Code

#586 (ARMv7, x86) and #587 (x86-64, AArch64) each added a
target-independent module of lemmas for HMAC's `init` over a
Merkle-Damgard hash: Proof/Pbkdf2/MdInit.lean and Proof/Pbkdf2/MdKeys.lean.
Several of their facts were the same. Keep one module, MdKeys, with each
fact proven once in its most general form, and delete MdInit:

* `Md.repr_block` (the general form) replaces `Md.repr_of_block`, which
  also took the initial hash value as `stateAt m p`: x86-64 and AArch64
  now pass `e.trans (congrArg (compress · _) iv)`.
* `xorOpad_ipad` replaces the identical `xorPad_6a`.
* `writeW_xorRep` (any repeated byte) replaces `writeW_xorOpad` (0x6a
  only); `xorOpad_mem` rewrites with `c6a` first.
* `xor_byte` is stated for any width of at least a byte (an auto-param),
  replacing MdInit's 32-bit one and AArch64 HmacInit's 64-bit copy.

The rest of MdInit's lemmas (`writeW_rep`, `c6a`, `bytes_over`,
`blockKey_short`, `xorPad_short`) move to MdKeys unchanged. Proof-only:
the emitter's output is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjfTK5YMk2jDsiKRYs2dbn
@alex
alex enabled auto-merge October 2, 2026 14:25
@alex
alex added this pull request to the merge queue Oct 2, 2026
Merged via the queue into main with commit 5a99276 Oct 2, 2026
41 checks passed
@alex
alex deleted the claude/inspiring-pascal-labmxq-hmac-init-lemmas branch October 2, 2026 15:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants