Repository navigation
crypto: P-256 special reduction, Booth windows, joint ECDSA verify (parity item 8a) - #1000
Merged
Merged
Conversation
…rify P-256 and P-384 multiplied by a bit-serial double-and-add, each bit a doubling and a complete addition that itself doubled, and ECDSA verify ran two such multiplications, an addition and an inversion. - Field: the CIOS core is a const fn shared by every modulus. P-256's prime takes its special step (Gueron and Krasnov 2015): the quotient digit is the low word, q 2^32 lands at word one from two shifts, and only q p3 is multiplied. - Secret multiplication (ECDH, key generation): Booth's signed 5-bit windows over the table P, 2P, ..., 16P. Each window is five doublings and one complete addition of a masked table read, which reads all 16 entries and negates Y by mask; the digits come from public bit positions by arithmetic, d = (u + 1) / 2 - 32 u_5. 52 windows for P-256, 77 for P-384, against 256 or 384 bits. - ECDSA verify: u1 G + u2 Q in one doubling chain over width-5 NAFs of both (Straus), with odd-multiple tables built per call, in variable time through a PublicScalar type the secret path cannot pass. Additions branch on the public points' values instead of masking. The result is checked projectively, X = r Z^2 or X = (r + n) Z^2 where r + n < p, with no inversion. - The width-w NAF is one module, shared with Ed25519's verification. Generated code on both ToyOS targets in [profile.toyos]: the Booth path's branches are its window and doubling counters and booth's public bit positions, and the table read's loop counter. New tests: Booth digits in [-16, 16] recomposing the scalar for both curves, with +16 and -16 both reached; the NAF at 384 bits; the Booth multiplication against the public joint path; and the public path's sums of equal and opposite points. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Japabu
force-pushed
the
wt/toyos-crypto-perf-4
branch
from
October 22, 2026 03:33
196ae3d to
264138f
Compare
Japabu
force-pushed
the
wt/toyos-crypto-perf-5
branch
from
October 22, 2026 03:33
d098a66 to
2594dd3
Compare
Collaborator
Author
Review of #1000, round 1 (head 2594dd3, item 8a)What I read and did not run
Architecture
Correctness, checked by hand
Shipped-profile inspectionI spot-checked the branch walks.
The claim holds on both targets. Secret-dependent timing in #1000's P-256 pathAt the code level, I see none.
What remains is instruction-level data dependence. This is inference, not established:
Controls
FindingsNo blockers. SUGGESTION
Evidence
Verdict: LAND (suggestions optional; landing is the orchestrator's). |
Japabu
marked this pull request as ready for review
October 22, 2026 05:15
Japabu
enabled auto-merge
October 22, 2026 05:15
Japabu
added a commit
that referenced
this pull request
Oct 22, 2026
…measure russh's `p384` is on its `bignum` backend under #1005, so the fiat record names the dependency as one no guest build selects. The T14's P-256 finding is re-measured on #1000's arithmetic, now on main, with a boot that sets DOITM beside the one that does not. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XqpxbTfpvcbx1FJEy3Eny9
Japabu
added a commit
that referenced
this pull request
Oct 22, 2026
…measure russh's `p384` is on its `bignum` backend under #1005, so the fiat record names the dependency as one no guest build selects. The T14's P-256 finding is re-measured on #1000's arithmetic, now on main, with a boot that sets DOITM beside the one that does not. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XqpxbTfpvcbx1FJEy3Eny9
This was referenced Oct 22, 2026
Japabu
added a commit
that referenced
this pull request
Oct 22, 2026
M2 on both benches put a dual-carry-chain Montgomery row at 0.40x (T14) and 0.43x (AMD bench) of the mulx-and-addcarry intrinsics form for a 2048-bit modulus, and RSA-2048 verify was 2.14x ring on the T14 at #1000, its exponentiation the remaining cost. The kernel is one asm! block per word of b: a product row and a reduction row over the modulus's words, each four words per loop step, with mulx for the products and the low and high halves added on two independent carry chains, CF through adcx and OF through adox (Intel SDM Vol. 2A). The loop counts with lea and jrcxz, which leave both flags alone. Rust keeps the outer loop and the final subtraction; all RSA data is public. CPUID leaf 7 EBX bit 19 now admits ADX beside BMI2, and the hosted x86-64 dispatch takes the kernel where both are present; elsewhere the portable CIOS multiplication runs, now `mul_portable`. Keys use whole groups of four words: the zero words above a modulus only enlarge R. A unit test holds the dispatched multiplication to the portable one for five modulus lengths and the largest residues; it compares two runs of the portable code on CPUs without ADX, and so checks the kernel only on x86-64 hosts that have it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXEk8BBMDT8tXu4AnENB9Q
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.
Builds on #999 (merged).
Problem
On the T14 (#932's baseline, and still after #990's constants and doubling), P-256 ECDH was 8.56x ring, ECDSA P-256 verify 9.33x, P-384 ECDH 2.49x and ECDSA P-384 verify 2.57x.
This is item 8a: the analysis's N1 (special P-256 reduction), N3 (Booth windows) and D1–D2 (joint variable-time verify, projective check), for P-256 and P-384 alike. These are left for 8b: N4 (the P-256 base-point comb, which also needs a const table), N5 (an addition-chain inversion), a static G table for verify, and a dedicated square.
What changes
const fnshared by every modulus, so 8b's tables can use it. P-256's prime takes a special reduction step (Gueron and Krasnov 2015): the quotient digit is the low word, q·2^32 lands at word one from two shifts, and only q·p3 is multiplied. This is u128 code, with noasm!and no mulx, as you directed after M2.PublicScalartype that the secret path cannot pass.naf.rs), used by Ed25519's verify too.Generated code
Both ToyOS targets in
[profile.toyos], from P-256 and P-384agreeandpublic_key.Point::mul's branches are its window and doubling counters, plusbooth's tests of its public bit position.Point::lookup's only branch is its 16-entry loop counter.Residue::mulbranches only on its row counter.Checks
All at d098a66. Logs: https://github.com/ToyOSOrg/evidence/tree/8b4c9443c9456133f72799484c323a2f434d112a/pr-1000/r1
cargo run -- --ci host: exit 0, 87 steps green.cargo clippy -p toyos-crypto --all-targets(adopted lints,-D warnings) andcargo test -p toyos-crypto --release, in the three CI forms: exit 0 each.cargo test --test toyos-build -- crypto_instrument_prints_its_table(QEMU x86_64): exit 0. The log's first line names the revision.booth_digits_recompose_the_scalar: both curves; digits in [−16, 16], with +16 and −16 both reached.naf_digits_recompose_384_bit_scalars.booth_multiplication_matches_the_public_path: the fixed schedule against the joint NAF path.public_sums_of_equal_and_opposite_points.--features sign --release --no-fail-fast, and reverted in the same run:public_sums_of_equal_and_opposite_points(green before that test was added)Measurements
Readback staged at d098a66 (
crypto_instrument,cryptocase; exit 2 = Staged). The rows this moves are p-256/ecdh, p-384/ecdh, and both ECDSA verify rows.This is not a bench measurement.
Risks
🤖 Generated with Claude Code