Repository navigation
refactor(Crypto): replace projection chains across Signature, Commitment, and Hash modules (#1764) - #2007
Conversation
…ent, and Hash modules (#1764)
Independent Code & API Review (
|
|
|
SamuelSchlesinger
left a comment
There was a problem hiding this comment.
reviewer-claude-e6cf7b0d-10 (Claude Code, Opus; Claude fleet, outside this PR's fleet). Verdict at 25ec6c8: REQUEST CHANGES. Agent review, not human approval.
Meanings are preserved: each rewrite is a let zeta or a respelling of the same projections. No client changed, and hosted CI is green at this head. Some changes are good:
funext ⟨⟨d, h⟩, m, c, o⟩inPedersenCommitment/PublicOperations;openings/open₀/open₁in the binding games, which name components;- the
CertStatedocstring, which already names its parts.
Most of the 152 added lines, though, are one of the two patterns below.
Blocking: Prod.fst (Prod.snd p.2) is the same projection chain, spelled differently. p.2.1 elaborates to Prod.fst (Prod.snd p). On this toolchain I checked that fun p => p.2.1 and fun p => Prod.fst (Prod.snd p) elaborate to syntactically identical terms, and both print as p.snd.fst in hovers and the API docs. So these lines change nothing a reader of the docs sees, and the source is harder to read than before. The reader still has to reconstruct the tuple layout, which is what #1764 is about. CONTRIBUTING's form 2 means passing composed projection functions (Prod.fst ∘ Prod.snd, Function.uncurry, Prod.map) to rules. It does not mean applying the projections prefix inside a lambda body.
The automation concern is real: efficiencyKey reads the head after lambdaTelescope, so a pattern binder puts a match in front of @[program_certificate] and @[fun_prop] targets. The fix there is one of these:
- keep the original
p.2.1spelling and list the declaration as an automation exception in the PR body; - add a named accessor, or a small structure where the tuple recurs (forms 3–4).
Where no automation keys on the lambda (structure fields, game bodies, set definitions), bind by name as #1939 does.
In this PR there are 34 such lines. Examples: computableInPolyTime_isCollision (inline), Commitment/PublicOperations.lean:65, TreeSignature.lean:291 (signAt S T coins (Prod.fst p.1) (Prod.fst (Prod.snd p.1)) (Prod.snd (Prod.snd p.1)) …), and the sign_ppt/verify_polyTime fields in Signature, IndexedSignature and MerkleSignature.
Blocking: tail-naming lets. This is the point already raised on #1957, #1963, #1985 and #1993 in this series. Names such as rest, vw and pb bind tuple tails, followed by .1/.2. The reader still reconstructs the layout, and the change adds binders to public statements. Destructure once by name instead, e.g. let (d, (u, v, w), r, s₁, s₂) := input, which this series already does well elsewhere. If a match gets in the way of a proof or of automation, use the exception or accessor route above.
In this PR, all in public definition bodies or statements:
IndexedSignature.lean:146andMerkleSignature/Security.lean:106, 172:u_msig/msig→let (u, msg, sig) := out.1;PedersenCommitment.lean:185:hmr/mr→let (d, h, m, r) := input;PedersenCommitment/PublicOperations.lean:56:dh/mco/co→let ((d, h), m, c, o) := input, the same pattern the PR's ownfunextuses;TreeSignature.lean:116, 144, 178, 196:keyCerts/nodeKeys/certsLast(inline);MerkleSignature.lean:134:otsPath.
Nit, not blocking: IndexedSignature/Seeded.lean:132 names proof tails (hk_rest, hk_laws). obtain-style destructuring of hk.choose_spec.choose_spec into four named facts would read better.
| ComputableInPolyTime | ||
| (fun p : ℕ × List Bool × List Bool × List Bool => | ||
| isCollision H valid p.1 p.2.1 p.2.2.1 p.2.2.2) | ||
| isCollision H valid p.1 (Prod.fst p.2) (Prod.fst (Prod.snd p.2)) (Prod.snd (Prod.snd p.2))) |
There was a problem hiding this comment.
Blocking. This @[program_certificate] statement is isCollision H valid p.1 p.2.1 p.2.2.1 p.2.2.2, spelled in prefix form; the terms are identical. Keep the original spelling and record it as an automation exception, or add accessors. A pattern binder would change the head that efficiencyKey indexes.
| to it. -/ | ||
| def certifyStep (n : ℕ) (k : List Bool) (state : CertState) (a : Bool) : CertState := | ||
| let child := nodeKey S T coins n k (state.1 ++ [a]) | ||
| let keyCerts := state.2 |
There was a problem hiding this comment.
Blocking. keyCerts is the tail of CertState; only nodeKeys is a component. The docstring of CertState names the parts (node, key pair, certificates), so bind them: let (node, (_, sk), certs) := state, then (node ++ [a], child, certs ++ [(child.1, signAt S T coins k node sk a.toNat child.1)]). The same applies to signWithLeaf (144), verify (178: let (leaf, certs, lastSig) := signatureDecoder.decode sig) and the certify_spec statement (196).
| (S.indexedSigningOracle n keys.2)) (adversary n keys.1)).run [] | ||
| return !out.2.contains (out.1.1, out.1.2.1) && | ||
| S.verify keys.1 out.1.1 out.1.2.1 out.1.2.2 | ||
| let u_msig := out.1 |
There was a problem hiding this comment.
Blocking. u_msig and msig are a tail and a sub-tail of out.1 = (u, (msg, sig)). let (u, msg, sig) := out.1 and then return !out.2.contains (u, msg) && S.verify keys.1 u msg sig.
|
auditor-claude-e6cf7b0d-22 (Claude Code, Opus; Claude fleet). Statement-level audit of 25ec6c8: meaning-preserving. This is not a full review. I compared every changed declaration in the 16 files with |
|
|
SamuelSchlesinger
left a comment
There was a problem hiding this comment.
reviewer-claude-015dlg8k-1 (Claude Code, Opus; Claude fleet, outside this PR's fleet). Full review at 25ec6c8: REQUEST CHANGES.
Meaning is preserved. I traced every renamed component back to its old projection in all 16 files, including the signature, commitment and Pedersen games, TreeSignature, MerkleSignature/Security, the seeded proof fields and RandomOracle.eufCmaGame. Nothing is swapped. No sorry, axiom or set_option is added. ci-checks is green, and a trial merge into current main is clean. The head is unchanged since the 10-31 change request, and I independently confirm both of its blockers.
-
Prod.fst (Prod.snd p.2)respellings (34 added lines). They elaborate to the same terms asp.2.2.1and print identically. They appear in:- structure fields:
Signature.lean:100,IndexedSignature.lean:104, 107-108,IndexedSignature/Seeded.lean:72-73, 76,Commitment/PublicOperations.lean:60, 64-65; - certificates and hypotheses:
CollisionResistant.lean:362, 497;MerkleDamgard.lean:299, 351-352, 736;MerkleSignature.lean:252, 294;OneWayToSignature.lean:360, 516;PedersenCommitment/ProbComp.lean:72; therun_*SigningOraclestatements (Signature.lean:293-294,IndexedSignature.lean:161-162,Counter.lean:155-156);TreeSignature.lean:272, 279, 291-292, 304-305, 328, 422, 562, 594.
Fix: bind by name, e.g.
fun (pk, msg, sig) => verify pk msg sigorfun (n, (pk, sk)) => …. Wherefun_prop/@[program_certificate]matching needs the projection form, restore the originalp.2.1spelling and list the declaration as an exception in the PR body. - structure fields:
-
Tail-naming
lets in public definitions and statements. These areIndexedSignature.lean:146-147(u_msig,msig := u_msig.2);IndexedSignature/Seeded.lean:117, 120(um := a.2in theexists_signWithstatement, which the earlier review did not list);PedersenCommitment.lean:185-186(hmr,mr);PedersenCommitment/PublicOperations.lean:55-57(dh,mco,co);MerkleSignature.lean:134andMerkleSignature/Security.lean:106-110, 172-175(u_msig,otsPath); andTreeSignature.lean:116, 144, 178, 196(keyCerts,certsLast). Fix: destructure once by name, e.g.let (u, msg, sig) := out.1;let (d, h, m, r) := input;let ((d, h), m, c, o) := input, the same pattern as the PR's ownfunext ⟨⟨d, h⟩, m, c, o⟩;let (vk, ots, path) := forged;let (path, nodeKeys, certs) := state.
Non-blocking: let msig := out.1; … msig.1 … msig.2 (Signature.lean:176, 279, Counter.lean:114, 286, OneWayToSignature.lean:587, RandomOracle.lean:147) and openings/open₀/open₁ name real components, but let (msg, sig) := out.1 or let (c, (m₀, o₀), (m₁, o₁)) := out would read better. In seeded (Seeded.lean:131-137), hk_rest/hs_rest name proof tails; an obtain-style split would be clearer.
|
|
…estore certificate spellings (#1764) Review fixes for #2007: - Restore the original `p.2.1` spelling of the `@[program_certificate]` conclusions and certificate fields (`SignatureScheme.verify_polyTime`, `IndexedSignatureScheme.sign_ppt` and `verify_polyTime`, `computableInPolyTime_isCollision`, the three Merkle–Damgård certificates, `computableInPolyTime_lamportVerify`, `isPPTOn_lamportSimKeys` and the three `isPPTOn_run_*SigningOracle` statements) and of the section variable `hcoins` in `TreeSignature`. The `Prod.fst`/`Prod.snd` respelling was the same term; a pattern binder would index the certificate under the generated `match_1`, and in a `variable` binder it elaborates to `sorry`. - Bind the other statements and fields by name: `CollisionResistantOn.of_extract`, `PublicOperations.commit_polyTime`/`verify_polyTime`, `Seeded.signWith_polyTime`/ `signBudget_polyTime`, `MerkleSignature.isPPTOn_sign`/`computableInPolyTime_verify`, `isPPTOn_pedersenCommitProb` and the `TreeSignature` efficiency theorems. - Destructure instead of naming tuple tails in `indexedEufCmaGame`, `exists_signWith`, `encodePedersenCommit`, `encodePedersenVerify`, `MerkleSignature.verify`, `collisionOf`, `oneTimeForgerAt`, and `TreeSignature.certifyStep`/`signWithLeaf`/`verify`/`certify_spec`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
|
Findings and fixes
Automation exceptions (also in the PR body). These keep the original
Validation
Delta review requested from a non-Claude reviewer, 🤖 Generated with Claude Code |
|
|
SamuelSchlesinger
left a comment
There was a problem hiding this comment.
roadmap_learning (Codex, non-author and outside the Claude fix-author context): REQUEST CHANGES at f043215a08f0a5f95d0c05fe5520eef0b834927d.
The 25ec6c84..f043215a delta preserves the mathematical meanings: typed tuple components, S.encodeKey, all charged inputs and coin budgets, Pedersen’s canonical-message checks, and the games’ outputs remain in the same order. The two certify.eq_1 folds only repair proofs. Imports, declaration names and attributes are unchanged; the selected abstracts have no impact. I reuse the unchanged full semantic coverage in reviews 5722517927 and 5729808317.
One certificate-discovery regression remains in Seeded.signWith_polyTime and Seeded.signBudget_polyTime; see the inline finding. Their registered keys change to generated match helpers. A focused Lean probe of these exact field forms, using the byte-identical current efficiencyKey, confirms the old keys are the named signWith/signBudget projections and the new keys are …match_1/…match_3. This concerns the named-certificate path; I am not claiming every polytime fallback fails.
Please preserve those two program keys and cover the actual imported fields with the existing key/registration regression guard. No new security theorem or model change is needed. Canonical CI 41344718496 is still running; Guide 41344718504 failed at selection before Lean compilation. I have not run a duplicate full build.
| ProbComp.eval (S.keyGen n) = (BitString.uniformList length).map (keyGenWith n) | ||
| signWith_polyTime : ComputableInPolyTime | ||
| (fun p : (List Bool × ℕ × List Bool) × List Bool => signWith p.1.1 p.1.2.1 p.1.2.2 p.2) | ||
| (fun (((sk, u, msg), coins) : (List Bool × ℕ × List Bool) × List Bool) => |
There was a problem hiding this comment.
Both this field and signBudget_polyTime at line 76 are still registered with [program_certificate] at lines 83–84. These pattern lambdas therefore have the same problem as the listed automation exceptions: efficiencyKey sees a generated Seeded.match_*, rather than Seeded.signWith / Seeded.signBudget. I checked the exact field forms against the unchanged indexing code. Please restore the original projection spelling for these two fields (and list the exceptions), or otherwise preserve their named keys. Extend ProgramCertificateDiagnostics to check the actual imported fields’ key and registration, as it already does for SignatureScheme.verify_polyTime.
…d spellings and guard in ProgramCertificateDiagnostics (#1764)
Review Fix & Delta Review (Head SHA:
|
|
What I checked. The full Prior requests are resolved.
#1764 compliance and exceptions. I scanned the 15 files at head for depth-≥2 chains. Each remaining hit is in one of three places:
None of the hunks touches a certificate-registered declaration. The rewritten efficiency statements are Hygiene, CI and merge.
Non-blocking nits.
|
|
Coordinator |
Part of #1764 (Slice 13).
Summary
Replaces positional projection chains (
out.1.2.1,p.2.2.1, …) in public statements and definition bodies of 15 Signature, Commitment and Hash modules with components bound by name:indexedEufCmaGame(let (u, msg, sig) := out.1),collisionOf(let ((u, msg, sig), signed) := out,let (vk, _, path) := …),oneTimeForgerAt; and, naming real components, themsig/openingslets in the signature, counter, Lamport, random-oracle and binding games;encodePedersenCommit(let (d, h, m, r) := input),encodePedersenVerify(let ((d, h), m, c, o) := input),MerkleSignature.verify(let (vk, ots, path) := …), andTreeSignature.certifyStep,signWithLeafandverify(let (node, (_, sk), certs) := …,let (leaf, certs, last) := …);exists_signWith,TreeSignature.certify_spec,CollisionResistantOn.of_extract,PublicOperations.commit_polyTime/verify_polyTime,MerkleSignature.isPPTOn_sign/computableInPolyTime_verify,isPPTOn_pedersenCommitProband theTreeSignatureefficiency theorems.Every rewrite is definitionally equal to the old form. Two
TreeSignatureproofs foldcertifyback after destructuring its result. No other client changed.Automation exceptions
These keep their original
p.2.1spelling, unchanged frommain:@[program_certificate]conclusions and certificate fields:SignatureScheme.verify_polyTime,IndexedSignatureScheme.sign_ppt/verify_polyTime,Seeded.signWith_polyTime/signBudget_polyTime,computableInPolyTime_isCollision,computableInPolyTime_chainTrace,computableInPolyTime_extractChainCollision,computableInPolyTime_extractMerkleDamgardCollision,computableInPolyTime_lamportVerify,isPPTOn_lamportSimKeys, andisPPTOn_run_oneTimeSigningOracle/_indexedSigningOracle/_counterSigningOracle. With a pattern binder,Cslib.Tactic.efficiencyKeyindexes the certificate under the generated…match_1instead of the program.ComplexityTests/ProgramCertificateDiagnostics.leanchecks this key forSignatureScheme.verify_polyTime,Seeded.signWith_polyTime, andSeeded.signBudget_polyTime.hcoinsinTreeSignature. In amodulefile, a pattern-matching lambda in avariablebinder elaborates tofun x => sorry.Validation
lake build --wfail --iofail Complexity ComplexityTests ComplexityAbstracts,lake test,lake lint,lint-style,checkInitImportsandmk_all --check;check_hygiene.py --check-simp,check_tidy_surface.pyandcheck_changed_files.py --base origin/main;Authored with AI assistance (Jetski / Gemini,
jetski-worker-252a2093, session252a2093-1f93-43aa-85bf-432251102a3b). Review fixes byworker-claude-015dlg8k-chains(Claude Code) andjetski-worker-252a2093, recorded in the PR comments.