Repository navigation
feat(proofs): prove P-256's generator has order n - #384
Conversation
Quest-Claim: 6535c316b186acc8
…eygen, signing, and a key pair's verification The kernel computes (n - 1)·G by doubling and adding, checking each sum with addOk, and finds -G, so n·G is infinity and G's order is the prime n. Key generation, the ECDH and ECDSA public keys, signing, and verifying with a key pair's own public key no longer assume P256Order; only verification with a parsed public key does, as ECDH's fault case for a peer's point stays. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…6-generator-order
|
Your OpenCode Go account is out of credit. Top it up, then re-trigger Pullfrog. OpenCode Go's response
|
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 20 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed head: b1842ae
Findings: No actionable correctness issues found in the seven-file diff and supporting proof definitions.
Direction: The separation of unconditional group laws from per-point nonzero-multiple requirements is sound. mulCheck_spec checks the generated coordinates through addOk, so the Euclidean inverse implementation does not expand the trust base. The generator-order result is threaded through key generation, signing, and key-pair verification while retaining the parsed-public-key assumption and ECDH fault case.
Verification limits: GitHub-only source review; I did not run Lean, admin/prove, just check, just ci, or performance measurements. The existing axiom guards cover the affected public theorems and remain unchanged. The GitHub prove job is still running, so its result remains outstanding.

Problem
The aarch64 P-256 theorems assumed that a multiple of G by a scalar in [1, n) is a finite point. ECDH's public key took it as a hypothesis, and ECDSA's key generation, signing, and verification took
P256Order: every finite point has order n, which needs a count of the curve's points that Mathlib lacks.Closes the quest P-256's generator is proven to have order n.
Approach
N256Prime.lean).n256_nsmul_GinP256Multiples.lean):decide +kernelcomputes (n - 1)·G by doubling and adding (mulCheck), and gets -G. It checks every sum with moq-dev/rind#343's inverse-freeaddOk, so the extended-Euclid inverse that produces the coordinates (invEuclid) is untrusted. Nonative_decide, and no new axiom:Axioms.lean's pins are unchanged.addOrderOf_eq_primegives G's order n (g_mult). Every multiple d·G with d in [1, n) also has order n (g_mult_order).P256Orderis now per point.P256OrderOf Pis the property for one point,P256Lawsno longer carries an order, andp256Lawsproves it with no hypothesis. The verify chain takesP256OrderOf Qfor its key's point.p256_public_keytakes the scalar's range [1, n) instead of a finite multiple. Every key has a scalar in that range, asp256_generateandp256_from_private_keystate.p256_ecdsa_generate,p256_ecdsa_from_private_key_and_public_key, andp256_ecdsa_signloseP256Order. So doesp256_ecdsa_key_pair_verify, since its Q = d·G.p256_ecdsa_public_key_new(a parsed peer point) keepsP256Order, andp256_agreekeeps its fault case. Its docstring says why: a peer's point needs the group's order n, a point count beyond Mathlib (Hasse's bound at least).Cost
P256Multiples.leantakes 15.9 s alone, against 8.1 s on main, so about 8 s more. Its peak memory is 4.0 GB, against 3.1 GB. The first version used Fermat inverses and took 16 s more; extended Euclid halved that. The file sits on the aarch64 P-256 path, which runs in parallel with the x86_64 modules.Impact
proofs/and the quest tree change.p256_public_key's conclusion is nowp256PublicKey d b.val, which moved toP256.lean.P256Laws.of_orderis nowp256Laws.Alternatives
Follow-ups
benchmarks/verified.toml(and soBENCHMARKS.md) still says the aarch64 ECDSA ✓ assumesP256_GROUP_ELEMENT_ORDER. That is still true, but now only for verification with a parsed public key. I left it alone, to keep this PR toproofs/while moq-dev/rind#383 is open.Validation
admin/provepasses on the merged head b1842ae (CARGO_BUILD_JOBS=3, Lean capped at 6 GB).just checkandjust cipass.Review
Codex (gpt-6.1-sol, medium effort), round 1 on head b1842ae: no findings.
(Written by Claude Opus 5.5)
🤖 Generated with Claude Code