feat(GPV): generic GPV hash-and-sign framework with EUF-CMA collision bounds#478
feat(GPV): generic GPV hash-and-sign framework with EUF-CMA collision bounds#478alik-eth wants to merge 13 commits into
Conversation
…ion + programmed-preimage) Sound GPV hash-and-sign EUF-CMA bounds (euf_cma_split_bound / euf_cma_collision_bound / forgery_yields_collision[_or_exact_match]) reducing forgery to a collision branch + an exact-match programmed-preimage branch (factor qSign+qHash) + birthday salt term, on honestly generated keys. Plus the machine-checked non-vacuity witness Examples/GPVNonVacuity. Claude-Session: https://claude.ai/code/session_01C7GAM6ykxZoXwDXmtdLqrA
… drop stale sorry/campaign narration Rewrite proof-development narration into intrinsic, accurate docstrings. Remove the false status claims (the file is sorry-free): the `reduction` "open constructor sorry" and the "single isolated sorry of this declaration" lines now describe the proven content (`reduction` is a complete def; the joint coupling is supplied by `reservoir_embed_commute_winner`). Strip round-N / banked / frontier / block-N campaign wording and de-campaign 14 section headers; keep conditional lemmas' hypothesis wording and all mathematical explanation. Comment-only: no statement, signature, or proof changed (build green, headline axioms unchanged by construction). Claude-Session: https://claude.ai/code/session_01C7GAM6ykxZoXwDXmtdLqrA
… of GPVHashAndSign Per CONTRIBUTING attribution policy (substantial rewrites), `GPVHashAndSign.lean` grew from a 426-line stub to a ~11.8k-line proof; add the author of that material to the header alongside the original author Quang Dao. Claude-Session: https://claude.ai/code/session_01C7GAM6ykxZoXwDXmtdLqrA
…d declarations Repair the WriterT-log reconstruction proof for the new definitional appendInputLog (route the sign-body splice through an explicit congrArg step with the simp-normal handler stack), switch to the evalDist_simulateQ_run_congr name, drop the unused simp arguments flagged by CI linters, underscore now-unused coupling-lemma binders, and remove the two unconsumed declarations hashQueryBound and gpv_advantage_le_unforgeableExpNoFresh. Claude-Session: https://claude.ai/code/session_01DaNGD9nDo3Grwk58nsjS77
…as at their root-level names Claude-Session: https://claude.ai/code/session_01DaNGD9nDo3Grwk58nsjS77
…ry of phase modules Split the single-file development into twelve modules under VCVio/CryptoFoundations/GPVHashAndSign/, one per proof phase (Basic through Security), each 200-2000 lines, chained by imports along the original order. The original module path remains as an umbrella importing all pieces, so consumers and fully-qualified names are unchanged. Claude-Session: https://claude.ai/code/session_01DaNGD9nDo3Grwk58nsjS77
Reduce the oracle-spec sum projection explicitly in the two combined-handler simpa checks, drop a no-op empty simp, replace deprecated zero_le', and drop two now-unused simp arguments. Claude-Session: https://claude.ai/code/session_01DaNGD9nDo3Grwk58nsjS77
…stency-only Label the witness example as a logical consistency (inhabitance) witness with no quantitative security content, and state the formalized birthday bound in the umbrella docstring. Claude-Session: https://claude.ai/code/session_01DaNGD9nDo3Grwk58nsjS77
…ollisionBound GPVHashAndSign.collisionBound now counts random-oracle queries as well (birthday bound over qSign + qHash salts), so the two sorried Falcon placeholder statements pass qHash explicitly. The Falcon security layer is rewritten wholesale in the follow-up idealized-Falcon PR; this keeps the generic GPV slice building standalone. Claude-Session: https://claude.ai/code/session_01DaNGD9nDo3Grwk58nsjS77
🤖 PR Summary
PR Overview: Generic GPV Hash-and-Sign Framework with EUF-CMA Collision BoundsMathematical FormalizationThis PR introduces a self-contained generic hash-and-sign framework in Main Security Theorems (all in
|
| Metric | Count |
|---|---|
| 📝 Files Changed | 20 |
| ✅ Lines Added | 12991 |
| ❌ Lines Removed | 376 |
Lean Declarations
✏️ Removed: 18 declaration(s)
VCVio/CryptoFoundations/GPVHashAndSign.lean (18)
abbrev CollisionAdversaryabbrev ProgrammedPreimageAdversarydef Correct (psf : PreimageSampleableFunction PK SK Domain Range) : Propdef GPVHashAndSigndef collisionFindingExp [DecidableEq Domain]def hashQueryBound {S' α : Type}def programmedPreimageExp [DecidableEq Domain]def signHashQueryBound {S' α : Type}noncomputable def collisionBound (qSign : ℕ) : ENNRealnoncomputable def collisionFindingAdvantage [DecidableEq Domain]noncomputable def programmedPreimageAdvantage [DecidableEq Domain]noncomputable def programmedPreimageReductionnoncomputable def reductionnoncomputable def runtime :theorem euf_cma_collision_bound [DecidableEq Domain]theorem euf_cma_split_bound [DecidableEq Domain]theorem forgery_yields_collision [DecidableEq Domain]theorem forgery_yields_collision_or_exact_match [DecidableEq Domain]
✏️ Added: 360 declaration(s)
Examples/GPVNonVacuity.lean (10)
def bijPSF : PreimageSampleableFunction Unit Unit Bool Bool wheredef hr : GenerableRelation Unit Unit (fun _ _ => true) wherelemma step_caches (pk : Unit)noncomputable def adv :noncomputable def domainSample : Unit → ProbComp Booltheorem adv_signHashQueryBound (pk : Unit) :theorem bijPSF_correct : bijPSF.Correcttheorem bijPSF_hForge :theorem bijPSF_regularity : bijPSF.Regularitytheorem gpv188_hyps_inhabited :
VCVio/CryptoFoundations/GPVHashAndSign/AppendQuery.lean (12)
def appendForgeQuerylemma advantage_eq_keygen_average_realGameVerifyFreshlemma appendForgeQuery_mainlemma gpvRealImplFlagFresh_run_liftM_query (pk : PK) (sk : SK) (mc : Salt × M)lemma gpvRealImplFlagFresh_run_read_bind_run_read (pk : PK) (sk : SK) (mc : Salt × M)lemma progGameRunImplNoRecFlagFresh_read_caches (domainSample : PK → ProbComp Domain)theorem advantage_appendForgeQuerytheorem euf_cma_split_bound_of_queryBound [DecidableEq Domain]theorem forgesQueriedPoint_appendForgeQuerytheorem realGameVerifyFresh_appendForgeQuery (pk : PK) (sk : SK)theorem signHashQueryBound_appendForgeQuerytheorem withCaching_run_bind_run_self (so : QueryImpl spec m) (t : spec.Domain)
VCVio/CryptoFoundations/GPVHashAndSign/Basic.lean (12)
abbrev CollisionAdversaryabbrev ProgrammedPreimageAdversarydef Correct (psf : PreimageSampleableFunction PK SK Domain Range) : Propdef CorrectAt (psf : PreimageSampleableFunction PK SK Domain Range) (pk : PK) (sk : SK) : Propdef GPVHashAndSigndef Regularity [SampleableType Range]def collisionFindingExp [DecidableEq Domain]def programmedPreimageExp [DecidableEq Domain]def signHashQueryBound {S' α : Type}noncomputable def collisionFindingAdvantage [DecidableEq Domain]noncomputable def programmedPreimageAdvantage [DecidableEq Domain]noncomputable def runtime :
VCVio/CryptoFoundations/GPVHashAndSign/CollisionTelescope.lean (18)
lemma probEvent_mem_uniformSample (cache : Finset Salt) :lemma probEvent_salt_collision_le_collisionBound (qSign qHash : ℕ)lemma sum_range_div_card_le_collisionBound (qSign qHash : ℕ) :noncomputable def collisionBound (qSign qHash : ℕ) : ENNRealnoncomputable def reductionnoncomputable def saltSeq (c : ℕ → Finset Salt) : (n : ℕ) → ProbComp Boolnoncomputable def signRunF {St : Type} (step : ℕ → St → Salt → ProbComp St)theorem evalDist_signRunF_bind_const {St γ : Type} [Nonempty Salt]theorem probEvent_saltSeq_le (c : ℕ → Finset Salt) (n : ℕ) :theorem probEvent_saltSeq_le_collisionBound (qSign qHash : ℕ)theorem probEvent_saltSeq_succ (c : ℕ → Finset Salt) (n : ℕ) :theorem signRunF_neverFail {St : Type} [Nonempty Salt]theorem signRunF_tvDist_le_collisionBound {St : Type} [Finite Salt] [Nonempty Salt]theorem signRunF_tvDist_le_saltSeq {St : Type} [Finite Salt]theorem signRunF_tvDist_le_saltSeq_aux {St : Type} [Finite Salt]theorem tsum_probOutput_uniformSample_ite (s : Finset Salt) (q : ℝ≥0∞) :theorem tvDist_bind_le_of_forall_le {α β : Type} (mx : ProbComp α) (f g : α → ProbComp β)theorem tvDist_signStep_real_programmed_le_collision [Nonempty Salt] {β : Type}
VCVio/CryptoFoundations/GPVHashAndSign/CombinedHandler.lean (40)
def combinedCacheImpliesTableInv (pk : PK)def combinedCacheTableInv (pk : PK)def combinedTableInDomainInv (M Salt : Type) (domainSample : PK → ProbComp Domain) (pk : PK)lemma combinedCacheImpliesTableInv_step (domainSample : PK → ProbComp Domain) (pk : PK)lemma combinedCacheTableInv_step (domainSample : PK → ProbComp Domain) (pk : PK)lemma combinedTableInDomainInv_step (domainSample : PK → ProbComp Domain) (pk : PK)lemma embedAtIndexImpl_run_inl_inl (domainSample : PK → ProbComp Domain) (pk : PK)lemma embedAtIndexImpl_run_inl_inr (domainSample : PK → ProbComp Domain) (pk : PK)lemma embedAtIndexImpl_run_inr (domainSample : PK → ProbComp Domain) (pk : PK)lemma embedTrapImpl_run_inl_inl (pk : PK) (sk : SK)lemma embedTrapImpl_run_inl_inr (pk : PK) (sk : SK)lemma embedTrapImpl_run_inr (pk : PK) (sk : SK)lemma evalDist_embedAtIndex_step_eq_embedTraplemma evalDist_progGameRunImplCombined_step_eq_traplemma evalDist_run_embedAtIndexImpl_eq_embedTrap {β : Type}lemma evalDist_run_progGameRunImplCombinedTrap_eq {β : Type}lemma map_run_progGameRunImplCombined_proj_reduction (domainSample : PK → ProbComp Domain) (pk : PK)lemma map_run_progGameRunImplCombined_proj_table (domainSample : PK → ProbComp Domain) (pk : PK)lemma progGameRunImplCombinedTrap_run_inl_inl (pk : PK)lemma progGameRunImplCombinedTrap_run_inl_inr (pk : PK)lemma progGameRunImplCombinedTrap_run_inr (pk : PK)lemma progGameRunImplCombined_proj_reduction (domainSample : PK → ProbComp Domain) (pk : PK)lemma progGameRunImplCombined_proj_table (domainSample : PK → ProbComp Domain) (pk : PK)lemma progGameRunImplCombined_run_cacheImpliesTable (domainSample : PK → ProbComp Domain) (pk : PK)lemma progGameRunImplCombined_run_inl_inl (domainSample : PK → ProbComp Domain) (pk : PK)lemma progGameRunImplCombined_run_inl_inr (domainSample : PK → ProbComp Domain) (pk : PK)lemma progGameRunImplCombined_run_inr (domainSample : PK → ProbComp Domain) (pk : PK) (msg : M)lemma progGameRunImplCombined_run_inv (domainSample : PK → ProbComp Domain) (pk : PK)lemma progGameRunImplCombined_run_tableInDomain (domainSample : PK → ProbComp Domain) (pk : PK)lemma progGameRunImplNoRec_run_inl_inl (domainSample : PK → ProbComp Domain) (pk : PK)lemma progGameRunImplNoRec_run_inl_inr (domainSample : PK → ProbComp Domain) (pk : PK)lemma reductionImpl_run_inl_inl (domainSample : PK → ProbComp Domain) (pk : PK)lemma reductionImpl_run_inl_inr (domainSample : PK → ProbComp Domain) (pk : PK)lemma reductionImpl_run_inr (domainSample : PK → ProbComp Domain) (pk : PK) (msg : M)lemma reduction_eq_run_reductionImplnoncomputable def embedAtIndexImpl (domainSample : PK → ProbComp Domain) (pk : PK)noncomputable def embedTrapImpl (pk : PK) (sk : SK)noncomputable def progGameRunImplCombined (domainSample : PK → ProbComp Domain) (pk : PK) :noncomputable def progGameRunImplCombinedTrap (pk : PK) (sk : SK) :noncomputable def reductionImpl (domainSample : PK → ProbComp Domain) (pk : PK) :
VCVio/CryptoFoundations/GPVHashAndSign/EmbedIndex.lean (20)
lemma embedTrapFreshIdxSigImpl_proj (pk : PK) (sk : SK)lemma embedTrapFreshIdxSigImpl_run_inl_inl (pk : PK) (sk : SK) (q : unifSpec.Domain)lemma embedTrapFreshIdxSigImpl_run_inl_inr (pk : PK) (sk : SK) (q : (Salt × M →ₒ Range).Domain)lemma embedTrapFreshIdxSigImpl_run_inr (pk : PK) (sk : SK) (msg : M)lemma embedTrapIdxSigImpl_fresh_idx_cache_eq (pk : PK) (sk : SK) (j : ℕ) (y : Range)lemma embedTrapIdxSigImpl_fresh_idx_cache_eq_general (pk : PK) (sk : SK) (j : ℕ) (y : Range) :lemma embedTrapIdxSigImpl_proj (pk : PK) (sk : SK) (j : ℕ) (y : Range)lemma embedTrapIdxSigImpl_run_inl_inl (pk : PK) (sk : SK) (j : ℕ) (y : Range)lemma embedTrapIdxSigImpl_run_inl_inr (pk : PK) (sk : SK) (j : ℕ) (y : Range)lemma embedTrapIdxSigImpl_run_inr (pk : PK) (sk : SK) (j : ℕ) (y : Range) (msg : M)lemma embedTrapIdxSigImpl_run_step_count_le (pk : PK) (sk : SK) (j : ℕ) (y : Range)lemma embedTrapIdxSigImpl_run_step_eq_embedTrapFreshIdxSig (pk : PK) (sk : SK) (j : ℕ) (y : Range)lemma evalDist_frontDraw_embedTrapIdxSigImpl_eq_embedTrapFreshSigImpl [Inhabited Range]lemma evalDist_run_embedTrapIdxSigImpl_eq_embedTrapFreshIdxSig_of_lt (pk : PK) (sk : SK) (j : ℕ)lemma map_run_embedTrapFreshIdxSigImpl_proj (pk : PK) (sk : SK)lemma map_run_embedTrapIdxSigImpl_proj (pk : PK) (sk : SK) (j : ℕ) (y : Range)lemma progGameRunImplCombinedTrapCount_table_support (pk : PK) (sk : SK) :lemma tsum_probOutput_embedTrapFreshIdxSig_mul_eq_frontDraw [Inhabited Range]noncomputable def embedTrapFreshIdxSigImpl (pk : PK) (sk : SK) :noncomputable def embedTrapIdxSigImpl (pk : PK) (sk : SK) (j : ℕ) (y : Range) :
VCVio/CryptoFoundations/GPVHashAndSign/Factorization.lean (9)
def AdaptiveFactorizesSignRunF [Nonempty Salt] {α : Type}noncomputable def gpvStepProg (pk : PK) (domainSample : PK → ProbComp Domain) (msgs : ℕ → M) :noncomputable def gpvStepReal (pk : PK) (sk : SK) (msgs : ℕ → M) :theorem evalDist_gpvSignBody_run_eq_gpvStepProg (pk : PK) (domainSample : PK → ProbComp Domain)theorem evalDist_gpvSignBody_run_eq_gpvStepReal (pk : PK) (sk : SK) (msgs : ℕ → M) (n : ℕ)theorem factorized_advantage_le_collisionBound [Finite Salt] [Nonempty Salt] {α : Type}theorem gpvStepReal_neverFail (pk : PK) (sk : SK) (msgs : ℕ → M)theorem gpvStep_agree (pk : PK) (sk : SK) (msgs : ℕ → M)theorem regularity_signAnswer_agree (hreg : psf.Regularity) (pk : PK) (sk : SK) :
VCVio/CryptoFoundations/GPVHashAndSign/FlagHandlers.lean (45)
lemma gpvRealImplFlagFresh_bad_mono (pk : PK) (sk : SK)lemma gpvRealImplFlagFresh_proj (pk : PK) (sk : SK)lemma gpvRealImplFlagFresh_proj_flag (pk : PK) (sk : SK)lemma gpvRealImplFlagFresh_run_inl (pk : PK) (sk : SK)lemma gpvRealImplFlagFresh_run_inr (pk : PK) (sk : SK) (msg : M)lemma gpvRealImplFlag_bad_mono (pk : PK) (sk : SK)lemma gpvRealImplFlag_proj_fst (pk : PK) (sk : SK)lemma gpvRealImplFlag_run_inl (pk : PK) (sk : SK)lemma gpvRealImplFlag_run_inr (pk : PK) (sk : SK) (msg : M)lemma gpvRealImplFresh_run_inl (pk : PK) (sk : SK)lemma gpvRealImplFresh_run_inr (pk : PK) (sk : SK) (msg : M)lemma keyedSalts_cacheQuery_card_le (cache : (Salt × M →ₒ Range).QueryCache)lemma keyedSalts_randomOracle_run_card_le (mc : Salt × M)lemma map_run_gpvRealImplFlagFresh_eq (pk : PK) (sk : SK)lemma map_run_gpvRealImplFlagFresh_proj_flag (pk : PK) (sk : SK) {β : Type}lemma map_run_gpvRealImplFlag_eq (pk : PK) (sk : SK)lemma map_run_progGameRunImplNoRecFlag_eq (domainSample : PK → ProbComp Domain) (pk : PK)lemma probEvent_flag_gpvRealImplFlagFresh_eq (pk : PK) (sk : SK)lemma probOutput_flagSignedTag_false {α' : Type}lemma progGameRunImplNoRecFlagFresh_bad_mono (domainSample : PK → ProbComp Domain) (pk : PK)lemma progGameRunImplNoRecFlagFresh_proj (domainSample : PK → ProbComp Domain) (pk : PK)lemma progGameRunImplNoRecFlagFresh_run_inl (domainSample : PK → ProbComp Domain) (pk : PK)lemma progGameRunImplNoRecFlagFresh_run_inr (domainSample : PK → ProbComp Domain) (pk : PK)lemma progGameRunImplNoRecFlag_bad_mono (domainSample : PK → ProbComp Domain) (pk : PK)lemma progGameRunImplNoRecFlag_proj_fst (domainSample : PK → ProbComp Domain) (pk : PK)lemma progGameRunImplNoRecFlag_run_inl (domainSample : PK → ProbComp Domain) (pk : PK)lemma progGameRunImplNoRecFlag_run_inr (domainSample : PK → ProbComp Domain) (pk : PK) (msg : M)noncomputable def gpvRealImplFlag (pk : PK) (sk : SK) :noncomputable def gpvRealImplFlagFresh (pk : PK) (sk : SK) :
…and 210 more not listed.
sorry Tracking
✅ Removed: 4 `sorry`(s)
VCVio/CryptoFoundations/GPVHashAndSign.lean (4)
noncomputable def programmedPreimageReduction(L283)noncomputable def reduction(L270)theorem forgery_yields_collision [DecidableEq Domain](L332)theorem forgery_yields_collision_or_exact_match [DecidableEq Domain](L363)
Coverage Notes
- AI file summarization partially analyzed 6 file(s) because their individual diffs exceeded the per-file size budget. Statistics and Lean signal tracking still cover the full PR.
Partially Analyzed Files
VCVio/CryptoFoundations/GPVHashAndSign/CombinedHandler.lean(+1103/-0)VCVio/CryptoFoundations/GPVHashAndSign/FlagHandlers.lean(+1394/-0)VCVio/CryptoFoundations/GPVHashAndSign/GameRuns.lean(+1252/-0)VCVio/CryptoFoundations/GPVHashAndSign/Security.lean(+1958/-0)VCVio/CryptoFoundations/GPVHashAndSign/TrapCount.lean(+1351/-0)VCVio/CryptoFoundations/GPVHashAndSign/VerificationBridge.lean(+1399/-0)
📄 **Per-File Summaries**
- Examples.lean: Added an import of
Examples.GPVNonVacuity, making the definitions and theorems from that module (related to proving non‑vacuity of the GPV construction) accessible in theExamplesfile. - Examples/GPVNonVacuity.lean: This new file provides a logical consistency (inhabitance) witness for the side conditions of the GPV hash-and-sign EUF-CMA bounds (
GPVHashAndSign.forgery_yields_collision_or_exact_matchand itseuf_cma_*corollaries). It defines a concrete bijective PSFbijPSFoverBoolwith keys inUnit(identityeval, inversetrapdoorSample, constantly‑true shortness), a trivial generable relationhr, and a query‑then‑forge adversaryadvthat queries the random oracle once at((), ())and forges at the same point. The file includes proofs ofbijPSF_correct,bijPSF_regularity,bijPSF_hForge(the forger queries its forgery point), andadv_signHashQueryBound(zero signing, one random‑oracle query). These are assembled into the conjunctiongpv188_hyps_inhabited, which shows all four side conditions are simultaneously satisfiable. - LatticeCrypto/Falcon/Security.lean: The diff modifies two theorems in
LatticeCrypto/Falcon/Security.lean. Ineuf_cma_security, the call toGPVHashAndSign.collisionBoundnow takes an additional argumentqHash(the number of hash queries), changing its signature fromcollisionBound Salt qSigntocollisionBound Salt qSign qHash. The docstring ofeuf_cma_security_bytes40is updated to reflect that the collision term is now(qSign + qHash)² / (2 · 2^320)instead ofqSign² / (2 · 2^320), and the corresponding call tocollisionBoundin that theorem is similarly updated to includeqHash. These changes incorporate the hash query count into the collision bound calculation, making the security bound more accurate. - VCVio.lean: The file
VCVio.leannow imports 14 new submodules fromVCVio.CryptoFoundations.GPVHashAndSign, adding definitions and theorems includingAppendQuery,Basic,CollisionTelescope,CombinedHandler,EmbedIndex,Factorization,FlagHandlers,GameIdentification,GameRuns,MinEntropy,SamplerTransport,Security,TapeFactorization,TrapCount, andVerificationBridge. These imports expand the available API for the GPV hash-and-sign signature scheme, enabling downstream use of the corresponding constructs and proofs. - VCVio/CryptoFoundations/GPVHashAndSign.lean: This file was entirely restructured: instead of containing the full GPV hash-and-sign scheme definition, security reductions, and theorem statements inline, it became a thin umbrella module that imports and re-exports the content from 13 submodules (
Basic,MinEntropy,CollisionTelescope,Factorization,GameRuns,TapeFactorization,FlagHandlers,CombinedHandler,GameIdentification,VerificationBridge,TrapCount,EmbedIndex,Security,AppendQuery,SamplerTransport). ThePreimageSampleableFunctionstructure,GPVHashAndSigndefinition, all reduction functions (reduction,programmedPreimageReduction), the query bound predicates (hashQueryBound,signHashQueryBound), the game-hopping experiments (collisionFindingExp,programmedPreimageExp), and all security theorems (forgery_yields_collision,forgery_yields_collision_or_exact_match,euf_cma_collision_bound,euf_cma_split_bound) were moved out of this file. The module-level docstring was updated to describe the new modular layout and to note that the birthday bound now uses(qSign + qHash)² / (2 · |Salt|)(GPVHashAndSign.collisionBound) instead of the simplerqSign² / (2 · |Salt|); the authors list was extended to include Oleksandr Vovkotrub. - VCVio/CryptoFoundations/GPVHashAndSign/AppendQuery.lean: This new file
AppendQuery.leanintroduces a compilerappendForgeQuerythat transforms an arbitrary GPV Hash-and-Sign EUF-CMA adversary into one satisfying theForgesQueriedPointconvention (the forger queries the random oracle at its forgery point). The file proves three key properties:forgesQueriedPoint_appendForgeQuerystates the compiled adversary unconditionally meets the convention;signHashQueryBound_appendForgeQueryshows the query bound increases by one hash (qHash + 1) with unchanged signing count;advantage_appendForgeQueryproves the EUF-CMA advantage is preserved exactly, using absorption lemmasgpvRealImplFlagFresh_run_read_bind_run_readandQueryImpl.withCaching_run_bind_run_self. The final theoremeuf_cma_split_bound_of_queryBounddischarges theForgesQueriedPointhypothesis from the headline bound, yielding a corollary that applies to any adversary given only a query bound. The file contains nosorryoradmitstatements. - VCVio/CryptoFoundations/GPVHashAndSign/Basic.lean: This new file introduces the GPV hash-and-sign signature framework in the random-oracle model. It defines the
PreimageSampleableFunctionstructure (with fieldseval,trapdoorSample, andisShort) together with itsCorrect,CorrectAt, andRegularityproperties. It then defines theGPVHashAndSignsignature scheme, parameterized by a PSF, a generable key relation, a salt type, and message type, as aSignatureAlgusing the random oracle. The file also provides: the noncomputableruntimebundle for the oracle world; the structural query boundsignHashQueryBoundthat separates signing-oracle and random-oracle query counts; the keyedCollisionAdversaryandcollisionFindingExp(with correspondingcollisionFindingAdvantage); and theProgrammedPreimageAdversaryandprogrammedPreimageExp(withprogrammedPreimageAdvantage) for the exact-match programmed-preimage experiment, which are the adversary interfaces used in the EUF-CMA proof. - VCVio/CryptoFoundations/GPVHashAndSign/CollisionTelescope.lean: This new file introduces the salt-collision telescope for the GPV Hash-and-Sign security proof, defining the reduction adversary
reduction, the birthday boundcollisionBound, the salt-drawing collision processsaltSeq, the flag-carrying signing processsignRunF, and proving coupling theorems (signRunF_tvDist_le_saltSeq,signRunF_tvDist_le_collisionBound) that bound the total variation distance between real and programmed runs by the salt-collision probability. It also includes per-draw probability lemmas (probEvent_mem_uniformSample) and the arithmetic core (sum_range_div_card_le_collisionBound) leading to the collisionBound, as well as the inclusion-exclusion identitytsum_probOutput_uniformSample_iteand the per-step coupling primitivetvDist_signStep_real_programmed_le_collision. The file is entirely new and contains nosorryoradmit. - VCVio/CryptoFoundations/GPVHashAndSign/CombinedHandler.lean: This new file introduces the combined handler
progGameRunImplCombinedthat runs the programmed freshness game and the collision reduction in lockstep, threading the game state((cache × signedSet) × flag)together with the reduction’s hidden preimage table(Salt × M) → Option Domain. It defines the collision‑reduction internal handlerreductionImpland the pre‑sampled‑index handlerembedAtIndexImpl(with its trapdoor‑uniform siblingembedTrapImpl), along with one‑step unfolding lemmas and per‑step/run‑level equidistribution lemmas (evalDist_embedAtIndex_step_eq_embedTrap,evalDist_run_embedAtIndexImpl_eq_embedTrap,evalDist_progGameRunImplCombined_step_eq_trap,evalDist_run_progGameRunImplCombinedTrap_eq) under GPV regularity. The file also provides projection lemmas (progGameRunImplCombined_proj_table,map_run_progGameRunImplCombined_proj_table,progGameRunImplCombined_proj_reduction,map_run_progGameRunImplCombined_proj_reduction) that recover the game handlerprogGameRunImplNoRecFlagFreshand the reduction handlerreductionImplfrom the combined run. Two coherence invariants (combinedCacheTableInv,combinedCacheImpliesTableInv) and their preservation lemmas (combinedCacheTableInv_step,progGameRunImplCombined_run_inv,combinedCacheImpliesTableInv_step,progGameRunImplCombined_run_cacheImpliesTable) certify that the cache and table stay consistent throughout the simulation. Finally, the incomplete predicatecombinedTableInDomainInvis introduced. Nosorryoradmitappear in the visible portion of the file. - VCVio/CryptoFoundations/GPVHashAndSign/EmbedIndex.lean: This new file
EmbedIndex.leanintroduces signed-set-augmented variants of the index-embedding query handlers for the GPV Hash-and-Sign construction. It definesembedTrapIdxSigImplandembedTrapFreshIdxSigImpl, which extend the existingembedTrapIdxImplandembedTrapFreshIdxImplwith a passiveFinset Msigned set that is updated only on signing queries. The file provides per-query and run-level projection lemmas (embedTrapIdxSigImpl_proj,map_run_embedTrapIdxSigImpl_proj, and theirFreshcounterparts) showing that dropping the signed set recovers the original handlers. It also proves equivalence lemmas between the two signed-set-augmented handlers off the winner slot (embedTrapIdxSigImpl_run_step_eq_embedTrapFreshIdxSig) and after the counter passes the winner index (evalDist_run_embedTrapIdxSigImpl_eq_embedTrapFreshIdxSig_of_lt), a front-loading lift (evalDist_frontDraw_embedTrapIdxSigImpl_eq_embedTrapFreshSigImpland its expectation formtsum_probOutput_embedTrapFreshIdxSig_mul_eq_frontDraw), a freshness-confined winner-slot cache invariant (embedTrapIdxSigImpl_fresh_idx_cache_eq_generaland its specializationembedTrapIdxSigImpl_fresh_idx_cache_eq), and a write-only trapdoor-table support invariant (progGameRunImplCombinedTrapCount_table_support). - VCVio/CryptoFoundations/GPVHashAndSign/Factorization.lean: This new file (306 lines) formalizes the factorization of the adaptive GPV Hash-and-Sign game through fixed-step
signRunFrecursion. It introduces theregularity_signAnswer_agreetheorem, which witnesses the distributional agreement (under PSF regularity) between the real cache-miss signing answer (uniform target, trapdoor preimage) and the programmed signing answer (forward-sample preimage, derived target). It defines theAdaptiveFactorizesSignRunFpredicate as a typedProppackaging the existence of handler states, real/programmed step handlers, a recorded-cache sequence with cardinality boundcard (c j) ≤ j + qHash, and a shared post-processor such that both adaptive runs equal the correspondingsignRunFdistributions. Thefactorized_advantage_le_collisionBoundtheorem uses this predicate to bound the total-variation distance between adaptive real and programmed runs bycollisionBound Salt qSign qHash.toReal, leveraging the data-processing inequality and the unconditionalsignRunF_tvDist_le_collisionBound. It then provides concrete GPV witnesses:gpvStepReal(cache-miss: uniform target, trapdoor preimage) andgpvStepProg(sign-then-hash: forward-sample, program cache), along withgpvStepReal_neverFail(never-fail guarantee given total trapdoor sampler),gpvStep_agree(distributional agreement of the two handlers under regularity),evalDist_gpvSignBody_run_eq_gpvStepReal(equality of real signing-body cache transition withgpvStepRealon a cache miss), andevalDist_gpvSignBody_run_eq_gpvStepProg(equality of programmed simulator signing-body cache transition withgpvStepProgwith front-loaded salt draw). Nosorryoradmitare present. - VCVio/CryptoFoundations/GPVHashAndSign/FlagHandlers.lean: This file introduces flag-instrumented versions of the original inline-salt GPV hash-and-sign handlers and a freshness-tracking vehicle for the verify-Bool coupling. It defines
gpvRealImplFlagandprogGameRunImplNoRecFlag, which thread a collision flag (set when an inline-drawn signing salt collides with the random-oracle cache) through the real and programmed game runs, and proves per-query and run-level projection lemmas (gpvRealImplFlag_proj_fst,map_run_gpvRealImplFlag_eq, etc.) showing that dropping the flag recovers the original handlers. It establishes bad-monotonicity (gpvRealImplFlag_bad_mono,progGameRunImplNoRecFlag_bad_mono) and the universal off-bad per-query agreementgpvImplFlag_h_agree_good, which together with the framework lemmatvDist_simulateQ_run_le_probEvent_output_badyields the main reductiongpv_tvDist_orig_run_le_probEvent_flagbounding the total-variation distance between the real and programmed game runs by the run-level collision-flag probability. The file then proves the cardinality-telescope boundgpv_orig_flag_le_collisionBound(via the auxiliarygpv_orig_flag_le_collisionBound_aux), showing that the flag probability is at mostcollisionBound Salt qSign qHash, and extends this to the verify-Bool couplinggpv_tvDist_orig_verify_le_collisionBoundwhere a signing-free verification continuation is appended. Finally, it introduces freshness-tracking handlersgpvRealImplFlagFreshandprogGameRunImplNoRecFlagFreshthat additionally record the set of signed messages, providing the vehicle for the EUF-CMA freshness mask. - VCVio/CryptoFoundations/GPVHashAndSign/GameIdentification.lean: Summary unavailable — error: Expecting value: line 1251 column 1 (char 6875)
- VCVio/CryptoFoundations/GPVHashAndSign/GameRuns.lean: This new file,
GameRuns.lean, is a 1252-line addition to the GPV Hash-and-Sign formal verification project. It defines the pinned game-run distributionsrealGameRunandprogGameRunfor the sign-then-hash hop, along with several normalizations that collapse theruntimebundle and drop preimage-record components, putting both runs on the sameStateT QueryCache ProbComprandom-oracle surface. The file also builds GPV-specific tape-consuming handler implementations (gpvRealImplTapeandprogGameRunImplTape), flag-instrumented versions of these tape handlers for the identical-until-bad coupling, and provides per-query splicing lemmas relating the tape signing steps to thesignRunFgpvStepReal/gpvStepProghandlers. Finally, it includes a proof of the per-query off-bad agreement of the tape handlers under a PSF regularity condition (evalDist_gpvImplTape_run_sign_miss_eq). - VCVio/CryptoFoundations/GPVHashAndSign/MinEntropy.lean: This new file
MinEntropy.leanintroduces the min-entropy analysis for the programmed-preimage experiment of the GPV Hash-and-Sign construction. It definestrapdoorGuessingProbabilityas the supremum over honest keys and targets of the maximal pointwise output probability ofpsf.trapdoorSample, corresponding to2^(-H∞)for the sampler's min-entropy. It then proves the main boundprogrammedPreimageAdvantage_le_trapdoorGuessingProbability, showing that any programmed-preimage adversary's advantage is at most this guessing probability, and also provides the hypothesis formprogrammedPreimageAdvantage_le_of_probOutput_trapdoorSample_le, which directly bounds advantage by a uniform pointwise mass boundεon the sampler at honest keys. These results are designed to supply the exact-match branch ofGPVHashAndSign.euf_cma_collision_boundwith a negligible term when instantiated with a concrete bound (e.g., from a discrete-Gaussian trapdoor sampler). - VCVio/CryptoFoundations/GPVHashAndSign/SamplerTransport.lean: This new file (
SamplerTransport.lean) introduces the adaptive sampler-transport accumulation for the GPV hash-and-sign scheme. It defines lemmas establishing that swapping the probabilistic trapdoor sampler while keeping the deterministiceval/isShortcomponents fixed leaves certain operations unchanged:gpvVerifyRead_trapdoorSwapshows verification reads are identical, andgpvRealImplFlagFresh_run_inl_trapdoorSwapshows non-signing handler steps are invariant. The per-signing-step total-variation budget is bounded bytvDist_run_gpvRealImplFlagFresh_sign_le, and the adaptive run-level accumulation is proved intvDist_run_simulateQ_gpvRealImplFlagFresh_trapdoorSwap_le. The main theorems areprobOutput_realGameVerifyFresh_le_trapdoorSwap_add(per-key game hop),advantage_le_advantage_add_of_trapdoorSample_tvDist(one-sided EUF-CMA advantage accumulation), andabs_advantage_toReal_sub_le_of_trapdoorSample_tvDist(symmetric two-sided real-form bound). Nosorryoradmitare present. - VCVio/CryptoFoundations/GPVHashAndSign/Security.lean: This new file
Security.leanformalizes the security proof for the GPV Hash-and-Sign signature scheme, establishing several key lemmas and theorems. Specifically, it proves: (1)evalDist_map_run_simulateQ_eq_of_query_evalDist_map_eq— a distribution-level state-projection transport theorem for oracle simulations; (2)progGameRunImplCombinedTrapCount_freshSig_projandmap_run_progGameRunImplCombinedTrapCount_freshSig_proj— per-query and run-level distributional projections from the trap-count-augmented run to the fresh-signature run; (3)freshSig_winnerSlot_deferred_le_embed— a bound relating the freshness-confined winner-slot deferred-trapdoor functional to the per-target embedding win; (4)progGameRunImplCombinedTrapCount_signedSet_grows— monotonicity of the signed set; (5)progGameRunImplCombinedTrapCount_frozen— frozenness of programmed, unsigned keys; (6)progGameRunImplCombinedTrapCount_table_indep— table-independence of expectations; (7)progGameRunImplCombinedTrapCount_table_frozen_eq— frozen-table expectation factorization; (8)progGameRunImplCombinedTrapCount_table_defer— per-step deferral of a write-only trapdoor draw; (9)trap_freshSig_le_winnerSlot_deferred— the trap-side table-defer bound; and (10)reservoir_embed_commute_winner_floorFree— the floor-free per-slot front-loading deferred-sampling coupling. - VCVio/CryptoFoundations/GPVHashAndSign/TapeFactorization.lean: This new file introduces the "front salt-tape factorization" for the GPV Hash-and-Sign security proof. It provides two key lemmas (
evalDist_gpvRealImpl_eq_drawList_gpvRealImplTapeandevalDist_progGameRunImplNoRec_eq_drawList_progGameRunImplTape) that rephrase the real and programmed game runs as a single front block ofdrawList ($ᵗ Salt) qSignsigning salts followed by a tape-consuming simulation. It then builds the bridging theoremsrealGameRun_eq_drawList_gpvRealImplTapeandprogGameRun_eq_drawList_progGameRunImplTapeto express the actual game definitions in this factored form. The file also definestapeCheck(a salt-collision predicate on a list of salts), provesdrawList_tapeCheck_eq_saltSeq(relating it to thesaltSeqbirthday process), and establishesprobEvent_tapeCheck_drawList_le_collisionBound(a birthday bound for the tape check). To support the off-bad path agreement of the tape handlers, it providesgpvImplTapeFlag_h_agree_good(a universalh_agree_goodhypothesis for the flag-instrumented tape handlers) together with helper lemmasevalDist_eval_domainSample_eq_uniform,gpvImplTape_run_unif_eq,gpvImplTape_run_read_hit_eq, andevalDist_gpvImplTape_run_read_miss_eq. The reduction from the factored games to the TV distance bound is provided bytvDist_drawList_bind_le. Nosorryoradmitare present. - VCVio/CryptoFoundations/GPVHashAndSign/TrapCount.lean: This file introduces the counter-augmented trap run
progGameRunImplCombinedTrapCount, which extendsprogGameRunImplCombinedTrapwith a passive(idxTable, counter)instrument that records the programming index at each cache miss or signing step. It proves the instrument is distributionally passive (map_run_progGameRunImplCombinedTrapCount_proj) and that the preimage table and insertion-index table stay in lockstep (progGameRunImplCombinedTrapCount_idx_iff_table). It establishes counter bounds (progGameRunImplCombinedTrapCount_run_count_le) and index bounds (progGameRunImplCombinedTrapCount_idx_lt_count,progGameRunImplCombinedTrapCount_idx_lt_budget). It also defines the inline-fresh embed handlerembedTrapFreshImpland proves the GPV Step-2 front-loading equalityevalDist_frontDraw_embedTrapImpl_eq_embedTrapFresh, which states that averagingembedTrapImplover an external target draw equals the inline-fresh run. Finally, it introduces index-augmented versionsembedTrapIdxImplandembedTrapFreshIdxImplwith passive insertion-index tables and proves their projection lemmas (embedTrapIdxImpl_proj,map_run_embedTrapIdxImpl_proj,embedTrapFreshIdxImpl_proj). - VCVio/CryptoFoundations/GPVHashAndSign/VerificationBridge.lean: This new file,
VerificationBridge.lean, introduces the O1 data-processing bridge connecting the GPV hash-and-sign Step-1 bound to the post-processed verification game, the forger-queries-its-forgery-point predicate, and the programmed verify-game machinery. It adds the theoremgpv_realGameVerify_le_progGameVerify_add_collisionBound, which uses the data-processing inequality to transfer the total-variation distance bound fromrealGameRun/progGameRunto any verification post-processor. The theoremprobOutput_unforgeableExp_eq_keygen_averagepeels the keygen average out of the GPV unforgeability experiment viawithStateOracle_evalDist_liftM_bind. The lemmasimulateQ_writerImpl_verify_foldfolds the verification continuation into the adversary computation, andsignedSet_eq_wasQueriedidentifies the WriterT signing log with the reconstructed signed-set for the per-key game-identification. The main reduction theoremgpv_advantage_le_progGameVerifyFreshAvg_add_collisionBoundchains the keygen-averaging peel, the per-key reconstruction, and the real↔programmed coupling hop to bound the GPV EUF-CMA advantage by the keygen-averaged programmed freshness verify-Bool game pluscollisionBound. The file defines the predicateForgesQueriedPointand provides the lemmascollisionFindingAdvantage_reduction_eq,isShort_of_mem_support_domainSample,run_combined_gpvVerifyRead_of_cache_hit,run_combined_verifyKont_of_cache_hit,combined_cache_forge_point_ne_none,progGameVerifyFresh_eq_probEvent_combined,reduction_collision_eq_probEvent_combined,distinct_implies_collision_pointwise,combinedTableSupport,combinedTableSupport_write_card_le,combinedTableSupport_run_card_le,combined_run_table_card_le,gpv_perKey_distinct_le_collision,probOutput_reservoirStep_win,probEvent_reservoirStep_miss,reservoirWinnerIndex,reservoirWinnerIndex_succ,tsum_reservoirStep_survival,probOutput_reservoirStep_ne, andprobOutput_reservoirStep_eq, which establish the forger-queries-its-forgery-point property, the table-passive nature of verification reads on cache hits, the equivalence of game success to a combined run event, the collision-reduction success as a table event, the distinct-collision pointwise transfer, and the reservoir-sampling embedding probabilities. The file introduces nosorryoradmit.
Last updated: 2026-07-13 12:53 UTC.
…y bound and hForge discharge Add `GPVHashAndSign.AppendQuery`: the `appendForgeQuery` adversary compiler appends a single ambient random-oracle query at the forgery point. The compiled adversary satisfies `ForgesQueriedPoint` unconditionally (the appended query is the last step, so the final cache is defined at the forgery point) and obeys `signHashQueryBound` at `qHash + 1` with the signing count unchanged. Also bank the generic cache-hit absorption lemma `QueryImpl.withCaching_run_bind_run_self` (re-running a caching step from its own output state is a deterministic hit), the term-level engine for the upcoming advantage-preservation proof. Claude-Session: https://claude.ai/code/session_01DaNGD9nDo3Grwk58nsjS77
…rving compiler and all-adversaries split bound Prove `advantage_appendForgeQuery`: the compiled adversary has exactly the EUF-CMA advantage of the original. The appended random-oracle query targets the point the verifier immediately re-queries, so under the lazy-caching real handler the two adjacent reads collapse to one (`gpvRealImplFlagFresh_run_read_bind_run_read`, a term-level equality built on `QueryImpl.withCaching_run_bind_run_self`); the game-level identity `realGameVerifyFresh_appendForgeQuery` then transfers to the advantage through the game-identification prefix (`advantage_eq_keygen_average_realGameVerifyFresh`). Headline: `euf_cma_split_bound_of_queryBound`, the split GPV PFDH bound for *any* adversary obeying the query bound — no `ForgesQueriedPoint` hypothesis — at hash budget `qHash + 1` in all three RHS terms. All declarations are sorry-free and kernel-verified at [propext, Classical.choice, Quot.sound]. Claude-Session: https://claude.ai/code/session_01DaNGD9nDo3Grwk58nsjS77
|
The disclosed hForge caveat is now discharged: pushed
All twelve new declarations kernel-check at |
…wap accumulation Add GPVHashAndSign.SamplerTransport: swapping the trapdoor sampler of the GPV scheme (shared deterministic eval/isShort) moves the EUF-CMA advantage by at most qSign * eps when the two samplers are within total-variation distance eps at every target on honest keys. The per-call budget telescopes adaptively across the run via tvDist_simulateQ_run_le_queryBoundP_mul on the freshness verify-Bool vehicle; the signing step is the only charged step, uniform/RO steps are implementation-identical, and the verification read is sampler-free. Includes the one-sided ENNReal accumulation advantage_le_advantage_add_of_trapdoorSample_tvDist and the two-sided real corollary abs_advantage_toReal_sub_le_of_trapdoorSample_tvDist. All declarations sorry-free and axiom-clean. Claude-Session: https://claude.ai/code/session_01DaNGD9nDo3Grwk58nsjS77
|
Pushed one more generic module: |
…e sampler guessing probability Add GPVHashAndSign/MinEntropy.lean: trapdoorGuessingProbability (the sup of the trapdoor sampler's pointwise output masses over honest keys and all targets, i.e. 2^(-Hoo)), the generic bound programmedPreimageAdvantage_le_trapdoorGuessingProbability via the standard best-guess-vs-max-mass argument, and its hypothesis-form corollary matching the hMinEntropy slot of euf_cma_collision_bound. Claude-Session: https://claude.ai/code/session_01DaNGD9nDo3Grwk58nsjS77
Extracts the generic GPV development out of #466 into its own self-contained PR, per @quangvdao's review there. #466 will be rebased on top of this branch and retitled to carry only the idealized-Falcon instantiation.
What this adds
A generic hash-and-sign framework in
VCVio/CryptoFoundations/GPVHashAndSign/following [GPV08], parameterized by a preimage-sampleable function (PSF), with the EUF-CMA reduction of [FGdG+25, Thm 1] shape:GPVHashAndSign.euf_cma_split_bound— the headline: any EUF-CMA forger's advantage is bounded by a PSF-collision adversary's advantage, plus an exact-match term(qSign + qHash) · programmedPreimageAdvantage, plus the salt-collision birthday bound(qSign + qHash)² / (2 · |Salt|).GPVHashAndSign.euf_cma_collision_bound— the collision-only corollary under a preimage-min-entropy hypothesis.GPVHashAndSign.forgery_yields_collision_or_exact_match/forgery_yields_collision— the core game hops (pre-sampled embed index, never-overwrite cache; no reservoir overwrite-restore).Examples/GPVNonVacuity.lean— a hypothesis-consistency (inhabitance) witness: a toy bijective PSF instance satisfying all side conditions simultaneously. Logical consistency only; no quantitative security content.Module layout
Split along proof phases per review of #465/#466:
Basic → CollisionTelescope → Factorization → GameRuns → TapeFactorization → FlagHandlers → CombinedHandler → GameIdentification → VerificationBridge → TrapCount → EmbedIndex → Security, re-exported by the umbrella module (no consumer or name changes).The only touch outside the new framework is an 8-line arity adaptation of the two sorried legacy Falcon placeholder statements (
collisionBoundnow takesqHash); that file is rewritten wholesale in #466.Verification
lake build ToMathlib VCVio FFI LatticeCrypto HashSig Examples VCVioWidgetsgreen onleanprover/lean4:v4.31.0, zero non-sorry warnings.[propext, Classical.choice, Quot.sound].Scope caveats (disclosed in the code)
hForge) is the standard ROM WLOG, stated as a hypothesis; the append-query compiler discharging it is planned follow-up work (feat(Falcon): idealized-model EUF-CMA via GPV, down to NTRU-SIS (#188) #466 thread).signHashQueryBoundhypothesis; reductions are not cost-tracked.https://claude.ai/code/session_01DaNGD9nDo3Grwk58nsjS77