Repository navigation
Conversation
`pArith` divides X (p_len octets) by q with the RSA key operations' bit-serial division, which shifts, subtracts from and selects the remainder over all w + 1 digits of p's width in each of its 32 w steps. The remainder stays below q, which has v = q_len / 4 digits, so `Impl/Dsa/PPC64LE/DivN.lean`'s division keeps the quotient's shift over w digits but runs the remainder's shift, subtraction and selection over v + 1 digits. It zeroes the remainder's digits from v + 1 at the end, so that its array holds the remainder as a w-digit number as before. `DivN.div_ok` (in `Proof/Dsa/PPC64LE/Gen/KSDiv.lean`) proves it as `Proof/Rsa/PPC64LE/DivLoop.lean` proves the RSA division, with the same `divStep` iteration and loop lemmas. `pDivide_vp` gives it q < 2^(8 q_len). No `Spec/`, `TCB/` or RSA file changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TKUFHEf743DNZVAyToasZ6
alex
force-pushed
the
claude/ppc64le-dsa-prime-r2
branch
from
November 8, 2026 20:41
abfa4cd to
0edfcd7
Compare
alex
force-pushed
the
claude/ppc64le-dsa-parith
branch
from
November 8, 2026 20:41
3b7b10c to
a265731
Compare
Member
Author
|
Closing this: the gain doesn't justify the code. It adds a DSA-only division module with about 400 lines of proof. In return, parameter generation was 3–6% faster at 1024 and 3072 bits, and the 2048-bit result was too noisy to read (run 42521443256). I had estimated the division at 20–25% of parameter generation, which turned out to be too high. Most of the time is in the Miller–Rabin rounds. #4709 (the Miller–Rabin R² setup by Generated by Claude Code |
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 #4141 (finding 7 of the PPC64LE audit: DSA parameter generation). Stacked on #4709, which is stacked on #4678 (in the merge queue), so this stays a draft until those merge. It changes no
Spec/,TCB/or RSA file, and no Rust code outside the generated PPC64LE crate.What was slow
Each p candidate's
pArithcomputes p = X − (X mod 2q) + 1 and (p − 1)/q by dividing X by q. It used the RSA key operations' bit-serial division (Impl/Rsa/PPC64LE/Div.lean), which works over p's full width:But the remainder is always below q, which is at most 256 bits.
What changed
Impl/Dsa/PPC64LE/DivN.lean'sdiv q r d t v, where v = q_len / 4 is q's number of digits:aRmholds the remainder as a w-digit number. The rest ofpArithis unchanged.Its loop counts depend only on w and the constant v, as before.
Proofs (
Proof/Dsa/PPC64LE/Gen/KSDiv.lean):DivN.div_okfollowsProof/Rsa/PPC64LE/DivLoop.lean's proof of the RSA division. It uses the samedivStep/divIteriteration and the same loop lemmas (shlLoop_ok,subLoop_ok,selLoop_ok,zeroLoop_ok).numV).step_arithtakes the divisor's bound separately from the quotient's.div_vptakes q < 2^(32 v) instead ofTopAll.pDivide_vpgets that bound from q's q_len octets.Numbers
Benchmarks run 42521443256: POWER9,
dsa_generate_parameters, base = #4709's head (0edfcd7), one run of each side.dsa_generate_parameters/1024dsa_generate_parameters/2048dsa_generate_parameters/3072This is a smaller gain than I expected. I had estimated the division at 20–25% of parameter generation, and that estimate was too high.
The 2048-bit row is noise on the head side, not a slowdown:
I have not rerun it, per the benchmarking rules. A reviewer may want a scoped run of the 2048-bit group before merging.
Most of parameter generation is still the Miller–Rabin rounds, which belong to the bignum work. Shifting the quotient over p's full width is now the main cost left in this division. Reading the dividend's bits in place instead would remove that, but it needs new step math, and on these numbers it would gain little.
Checks
mainafter PPC64LE DSA: signing, key generation and key checks by four-bit windows (powWin) #4667 merged.lake buildof the whole project passes, and the full emitter leaves the tree clean. It regenerates onlydsa.rs/dsa.sof the PPC64LE crate (vg_dsa_parameter_search).check_lean_public_imports.pyis OK on the edited modules.cargo check --target powerpc64le-unknown-linux-gnu --libbuilds the crate. CI's ppc64le jobs run the tests.🤖 Generated with Claude Code
https://claude.ai/code/session_01TKUFHEf743DNZVAyToasZ6