SHA-384/512/512-224/512-256 streaming on x86 through the shared MdStream code - #600
Merged
Merged
Conversation
Generalise Impl/MdStream/X86 and Proof/MdStream/X86 over the block and length-field sizes, instantiate them for SHA-384/512/512-224/512-256, and delete the bespoke x86 SHA-512 streaming code and proofs. src/asm is not regenerated yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01167c4d5NdJ5cbpxrYD2uEs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01167c4d5NdJ5cbpxrYD2uEs
… code Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01167c4d5NdJ5cbpxrYD2uEs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01167c4d5NdJ5cbpxrYD2uEs
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.
This came out of a review that looked for duplicated code pointing to missing abstractions.
Summary
On x86-64, the SHA-512 family's streaming
updateandfinalizealready run on the shared Merkle–Damgård code (Impl/MdStream/X86_64). On 32-bit x86 they did not: the shared code only handled 64-byte blocks with an 8-byte length field, so SHA-512 had its own streaming code (Impl/Sha512/X86/Stream.lean) and about 2,500 lines of its own proofs.This PR makes the x86 code generic over the block size and length-field size, as x86-64 already is. The SHA-512 family becomes one more instance of it, and its own streaming code and proofs are deleted.
Does not touch
Spec/orTCB/.The abstraction
Impl/MdStream/X86.leanParamsgainsB(block size) andL(length-field size).B - 1,log₂ B,B,B - LorB - L + 1.out64writes 64-bit words, stored little-endian, out big-endian.len64is split intoloadCount ++ len64Of. The instructions are unchanged. The split lets SHA-512's 128-bit length field readcountbefore writing anything.Proof/MdStream/X86/Common.leanDimsgainsB ∈ {64, 128}and0 < L ≤ 16, plus lemmas forx mod B,x / Band the shift amount (Dims.and,Dims.shr,Dims.lg,Dims.mod,Dims.mod_append).ShapeandCalleeOkare overMd P.B P.N P.L.Proof/MdStream/X86/Finalize.lean(theupdateandfinalizeproofs) is generalised throughout.finalizeproof now shows thatfinalizeonly reads its arguments (finK); it never wrote them.Finalize.verifiedderives the old, looser contract (finKw, arguments writable) from that withVerified.narrowTo, so MD5, SHA-1 and SHA-256 keep their per-target contracts unchanged.Proof/MdStream/X86/Words.leanout_wordsis generic over the word size;out32_okand the newout64_okboth use it.len64Of_okandloadCount_ok.Copies removed
Impl/Sha512/X86/Stream.lean: 143 → 51 lines (now justinitplusparams).Proof/Sha512/X86/Stream/Common.lean: 324 lines, deleted.Proof/Sha512/X86/Stream/Update.lean: 1038 → 46 lines.Proof/Sha512/X86/Stream/Finalize.lean: 1152 → 150 lines (the length field and digest ofshape, andfinalize_verified).Proof/Pbkdf2/Md/X86/Hashes.lean: its own SHA-512 digest proof (out512_okand its step) is gone. It now getsOutOkfrom the family'sshape, as it already did for MD5 and SHA-1.src/asm: +1252 / −3540.Proof/Sha256/X86/Stream/{Finalize,Common}.leanstay. Onmain(with #583 merged) they are still imported byProof/Sha256/X86/Shared.lean,Proof/Scrypt/X86/Salsa.lean,Proof/Sha512/X86/Rounds.lean,Proof/Hmac/X86/Finalize.leanandProof/Hmac/Generic/X86/Hash.lean.Emitted code
Only the SHA-512 family's x86 files change:
x86/sha512.rs:updateandfinalizeare now the shared code.x86/hmac_sha{384,512,512_224,512_256}.rsandx86/pbkdf2_sha{384,512,512_224,512_256}.rs: only the digest writer changes. It is now the family'sout64, which usesecxwhere the old code usededx, with the same instruction count.All other
src/asmfiles are byte-for-byte identical, including MD5, SHA-1, SHA-224, SHA-256 and the SHA-NI variants.Instructions per call, i686, counted by valgrind/callgrind, including the compression function:
mainupdate, 0 Bupdate, 64 Bupdate, 1 KiBupdate, 16 KiBfinalizeupdatenow compresses whole blocks directly from the input instead of copying every byte through the buffer.Proof cost
Hardware counters are unavailable in the VM I used (
perf stat -e instructions:ureports<not supported>), so these are single-threaded wall-clock times (-j1 -DElab.async=false, best of 2, idle machine, same toolchain):mainMdStream/X86/CommonMdStream/X86/FinalizeMdStream/X86/WordsMd5/X86/Stream/MdSha1/X86/Stream/MdSha256/X86/SharedVariants/Sha256/X86/ShaNiSha512/X86/Stream/*(Common + Update + Finalize)Sha512/X86/SharedNo heartbeat or other resource limits are set.
Validation (run locally)
lake buildafter mergingmain.lake env lean --run Emit.lean --check: the axiom, compiler-override and Spec-origin audits all pass.src/asmdiffed againstmain; the diff is as described above.check_lean_imports,check_lean_speed,check_vectors,check_arch_gates,check_variants,check_mcdtandalgorithms_tableall pass. The README tables are unchanged.cargo fmt --checkandcargo clippy --all-targets -- -D warningson the host.cargo testwith Wycheproof on the host (254 passed) and oni686-unknown-linux-musl(238 passed).🤖 Generated with Claude Code
https://claude.ai/code/session_01167c4d5NdJ5cbpxrYD2uEs
Generated by Claude Code