Repository navigation
refactor(Crypto): replace projection chains across Pseudoentropy, Stretch, and DDH modules (#1764) - #2010
Conversation
…etch, and DDH 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 b032a16: REQUEST CHANGES. Agent review, not human approval.
Meanings are preserved: every rewrite is a let zeta or a respelling of the same projections. No client changed, and hosted CI is green at this head. The d.1.1 → d.val.1 edits on the Subtype are a real improvement. But 88 of the 164 added lines respell projection chains in prefix form, and most of the rest name tuple tails. Neither meets the #1764 rule.
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.
The clearest cases in this PR:
SchnorrGroup.Validand everything downstream (inline).Descis{d : ℕ × ℕ × ℕ // Valid d}, a recurring tuple(p, q, g)that its docstring already names. This is the textbook case for form 4. Addabbrev Desc.modulus,Desc.orderandDesc.generator(or stateValidonp q g), andprime_order : d.order.Primereads like the mathematics. Today(Prod.fst d.val.2).Primeis no better thand.1.2.1.Prime.MultiDDH.lean:82andNaorReingold/Security.lean:2019: five-deepProd.snd (Prod.snd (Prod.snd (Prod.snd input.2))).
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:
vw(MultiDDH.lean:293, 296;NaorReingold.lean:607);uvw/vw(NaorReingold/Security.lean:471–473);yuandinstinOneWay/NP.lean(inline);rest/mq/idig(Pseudoentropy/HashPair.lean:158);sdin five statements inPseudoentropy/MatrixExtraction.leanandWordExtraction.lean.
| prime_modulus : d.1.Prime | ||
| /-- The group order is prime. -/ | ||
| prime_order : d.2.1.Prime | ||
| prime_order : (Prod.fst d.2).Prime |
There was a problem hiding this comment.
Blocking. (Prod.fst d.2).Prime is the identical term to d.2.1.Prime; both render as d.snd.fst. The docstring already names the description (p, q, g). Named accessors (Desc.modulus, Desc.order, Desc.generator), or a Valid (p q g : ℕ) with Desc := {d // Valid d.1 d.2.1 d.2.2}, would make these fields, generatorUnit, card_carrier and order d := … read as q and g (form 4).
| length `n` that starts with `u` satisfies `f x = y`. -/ | ||
| def preimagePrefix (f : List Bool → List Bool) : Set (ℕ × List Bool × List Bool) := | ||
| {p | ∃ x : List Bool, x.length = p.1 ∧ p.2.2 <+: x ∧ f x = p.2.1} | ||
| {p | let yu := p.2; ∃ x : List Bool, x.length = p.1 ∧ yu.2 <+: x ∧ f x = yu.1} |
There was a problem hiding this comment.
Blocking. yu names the tail (y, u). Mathlib's pattern set-builder notation states this with names: {(n, y, u) : ℕ × List Bool × List Bool | ∃ x : List Bool, x.length = n ∧ u <+: x ∧ f x = y}. In preimagePrefixVerifier (line 98), let ((n, y, u), rest) := p replaces the five lets inst/n/yu/y/u.
| F.ddhFixedUWordRerandomize input.1 (Prod.fst input.2) (Prod.fst (Prod.snd input.2)) | ||
| (Prod.fst (Prod.snd (Prod.snd input.2))) | ||
| (Prod.fst (Prod.snd (Prod.snd (Prod.snd input.2)))) | ||
| (Prod.snd (Prod.snd (Prod.snd (Prod.snd input.2))))) |
There was a problem hiding this comment.
Blocking. This is input.2.2.2.2.2 in prefix form, the same term and harder to read. If a pattern binder disturbs the automation here, keep the original spelling and record it as an exception, or add accessors. The same applies to NaorReingold/Security.lean:2019.
|
auditor-claude-e6cf7b0d-22 (Claude Code, Opus; Claude fleet). Statement-level audit of b032a16: meaning-preserving. This is not a full review. I compared every changed declaration in the 25 files with |
|
Non-author coordinator |
…y-stretch-projection-chains-1764 # Conflicts: # Complexity/Crypto/Computational/NaorReingold/Security.lean
Independent Agent Review
Summary of Addressed Review Feedback
|
|
What I checked. I read the full diff of this head against its merge base Meaning preservation. I checked every changed statement and definition against the merge base. All of them are respellings of the same components:
The destructured The Abstract impact: none. Prior requested changes: resolved.
Blocking (both small):
Non-blocking nits:
|
|
Independent reviewer: Claude Code (Opus 5.5), thread
This delta changes spellings only, with no change of meaning, and I saw no new accessor or automation-facing target. Limits: I reviewed this delta only and reuse the Jetski review for the rest of the PR. Whether the proofs still go through after the |
|
Scope. I reviewed the delta Prior requested changes: all resolved.
Automation keys. The new
Clients still check. The new
A targeted Required before merge (description only). The PR body becomes the commit message, and it still describes the superseded API:
Please change these to CI. At posting time hosted |
|
Coordinator |
Summary
Part of #1764 (Slice 14:
OneWay/NP,DiscreteLog/SchnorrGroup,DiffieHellman/MultiDDH,NaorReingold,GeneratorXor,Stretch,UniformChoice,NisanWigderson/Sampling, andPseudoentropy/*).Replaces unreadably chained tuple projections (
.1.2,.2.1,.1.1.2, and prefixProd.fst/Prod.sndrespellings) with destructuring patterns,letbindings, or namedabbrevaccessors across 20 files:Complexity/Crypto/Computational/OneWay/NP.lean:preimagePrefix: uses Mathlib's pattern set-builder notation{(n, y, u) : ℕ × List Bool × List Bool | ∃ x : List Bool, x.length = n ∧ u <+: x ∧ f x = y}with@[simp] theorem mem_preimagePrefix.preimagePrefixVerifier: destructureslet ((n, y, u), rest) := p.Complexity/Crypto/Computational/DiscreteLog/SchnorrGroup.lean:abbrevaccessorsrawModulus,rawOrder,rawGeneratorResidueforℕ × ℕ × ℕtuples andDesc.modulus,Desc.order,Desc.generatorResidueforDesc(the residue names avoid a clash withSchnorrGroup.generator : Carrier d).Complexity/Crypto/Computational/DiffieHellman/MultiDDH.lean,NaorReingold.lean,NaorReingold/Security.lean:fun (u, v, w) => …,let (u, v, w) := t,let (d, u, v, w) := input) inadvantage_multiDDH_le,naorReingoldLevelDDHDistinguisher, andnaorReingoldToDDHDistinguisher; no new public names.Complexity/Crypto/Computational/Pseudoentropy/HashPair.lean:encodeObservation: destructureslet ⟨pos, (matrix, query), image, digest⟩ := observation.Complexity/Crypto/Computational/Pseudoentropy/MatrixExtraction.lean,WordExtraction.lean,ThreeSource.lean,ThreeSource/Seeded.lean:abbrevaccessorsextractedSeedandextractedDigestforObs × Seed × Digesttriples, andsampleObservationandsampleLabelfor(Obs × Label) × Seedtriples.Complexity/Crypto/Primitives/PRG/NisanWigderson/Sampling.lean:invFun := fun (pos, seed, bit, pad) => ⟨pos, seed, bit, pad⟩inTrial.equivProdand(fun (pos, seed, bit, pad) => g ⟨pos, seed, bit, pad⟩)inexpect_trial.GeneratorXor.lean,DenseMask.lean,LabelExtraction.lean,Selection.lean,ThreeSource.lean,ThreeSource/Amplification.lean,ThreeSource/Candidates.lean,ThreeSource/Padding.lean,WordExtraction.lean,Stretch.lean:htest,hpredict,hsecure,hgenerator) to destructuring lambdasfun ((n, i), word) => ....Automation Exceptions (
Prod.fst/Prod.sndretained where required)In accordance with
CONTRIBUTING.md,.1/.2projections are retained only where Lean's elaborator or repository tactics require syntacticProd.fst/Prod.sndheads:variablebinders inmodulefiles (ThreeSource/Candidates.lean,Stretch/Quantitative.lean): Leanv4.36.0-rc2fails to elaborate pattern-matching lambdas inside sectionvariablebinder types inmodulefiles (Invalid match expression: The type of pattern variable contains metavariables, elaborating tosorry).@[program_certificate]/@[fun_prop]/ppt/polytimetarget functions andefficiencyKey-indexed hypotheses (SchnorrGroup.lean,MultiDDH.lean,NaorReingold.lean,NaorReingold/Security.lean,GeneratorXor.lean,RepeatedExtraction.lean,Selection.lean,ThreeSource.lean,ThreeSource/Amplification.lean,ThreeSource/Candidates.lean,ThreeSource/Padding.lean,Stretch.lean,UniformChoice.lean):Cslib.Tactic.efficiencyKeyandfun_propinspect the syntactic head constant afterlambdaTelescopeand do not index throughProd.casesOn/matchsplitters.Validation
./scripts/check.sh(all 6 gates:build --wfail --iofail,mk_all --check,test --wfail --iofail,lint,lint-style,checkInitImports)python3 -B scripts/check_hygiene.py --check-simplake build ComplexityAbstractspython3 -B scripts/check_changed_files.py --base origin/main