feat(Falcon): idealized-model EUF-CMA via GPV, down to NTRU-SIS (#188)#466
feat(Falcon): idealized-model EUF-CMA via GPV, down to NTRU-SIS (#188)#466alik-eth wants to merge 24 commits into
Conversation
🤖 PR Summary
Mathematical Formalization
Proof Completion (sorries removed)
Refactoring
Infrastructure / CI
Documentation
Notes on the diffThis PR is stacked on #478 (generic GPV framework). The diff currently includes the GPV submodule additions; once #478 lands, a rebase will shrink the diff to the Falcon‑specific files ( Statistics
Lean Declarations ✏️ Removed: 22 declaration(s)
✏️ Added: 419 declaration(s)
…and 269 more not listed.
✅ Removed: 8 `sorry`(s)
Coverage Notes
Partially Analyzed Files
📄 **Per-File Summaries**
Last updated: 2026-07-13 12:51 UTC. |
|
Rebased onto main now that #465 is merged — the diff is down to this PR's own commits. The file split requested above is in |
|
I have a local branch with some Flacon stuff on it, let me check what progress I'd made and whether there's anything complementary. |
|
@alexanderlhicks Happy to coordinate — here's a quick map to make diffing your branch easy. What this PR covers: the generic GPV/PFDH EUF-CMA bounds ( Deliberately out of scope here — i.e. the complementary slots:
Anything of yours in those slots composes with this PR rather than colliding. If you did touch the same files, happy to coordinate a rebase order. |
… GPV/#466 Rebased onto #466 (pr/falcon); adds the complementary correctness + hardness-bridge layer on top of the now-proven GPV EUF-CMA chain. D — move `verify_sign_correct` into `LatticeCrypto/Falcon/Correctness.lean`, keeping `Security.lean` security-only (per review suggestion); adapt `NonVacuity` to the `FalconTree.leaf` arity. B — `ntruPSFCollisionProblem → ntruKeyedSISProblem` kernel-vector bridge: - `ntruSISProblemWithSample` (parameterized by challenge sampler + norm bound); `ntruKeyedSISProblem hr bound` (key-distributed `h`); `ntruSISProblem` = idealized uniform-`h` / `betaSquared`. - `collisionToNTRUSISSolution` + `ntruPSFCollisionToKeyedSISAdversary` (the reduction). - `ntruPSFCollision_to_keyedSIS_valid`: a valid collision differences to a valid keyed-SIS solution at bound `4·betaSquared` (kernel via `negacyclicMul_sub_left`; norm via new centered-residue triangle lemmas). - `ntruPSFCollision_advantage_le_keyedSIS`: the keyed adversary wins with ≥ the collision advantage (two nested `probOutput_bind_mono`, `⟨pk.h⟩ = pk` eta). - `euf_cma_security_ntruSIS`: EUF-CMA bound terminating at `ntruKeyedSISProblem (4·betaSquared)`, composing `euf_cma_security` with the advantage bridge. `Ring/Norms.lean`: `centeredRepr_sub_natAbs_le` (valMinAbs triangle, no wraparound hypothesis) + `l2NormSq_sub_le_two_mul_add` / `pairL2NormSq_sub_le_two_mul_add`. All new declarations standard-axioms-only (`propext, Classical.choice, Quot.sound`); no new `sorry` (Falcon count stays 7 = FPRBridge ×5 + NTRUSolver ascent ×2). #466's proven headline theorems are untouched. Full `LatticeCrypto` build green. Co-Authored-By: Oleksandr (Alik.eth) Vovkotrub <8048195+alik-eth@users.noreply.github.com> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
quangvdao
left a comment
There was a problem hiding this comment.
Thank you for the substantial work here. The generic GPV game-hopping development is valuable, sorry-free, and much easier to review after the split into phase modules. I am requesting changes because the Falcon-facing theorem currently claims more than its assumptions establish. I do not expect this PR to prove security of every concrete Falcon implementation detail (compression, floating point, exact sampler implementation, etc.). A meaningful theorem for a reasonably faithful idealized Falcon model—exact real arithmetic and an ideal Gaussian sampler are fine—is a good target.
The main changes I need are:
-
State the scope as an idealized Falcon/GPV model.
falconSignatureAlgis currently the genericGPVHashAndSignscheme with the full(s₁,s₂)preimage, rather than the concreteFalcon.Signature/sign/verify path. This can still be a reasonable abstraction, but the theorem and documentation need to say precisely which Falcon features are modeled and which are idealized. Concrete encoding/compression and floating-point implementation security are not blockers for this PR. -
Replace
hTransportwith materially weaker assumptions and prove the adaptive composition. As written,hTransportassumes the central concrete/approximate-sampler-to-ideal-adversary step wholesale: it directly supplies an ideal adversary with the desired advantage inequality, queried-point property, and query bound. The declaredSamplerQuality/Rényi infrastructure is not used. Please formulate a local sampler approximation hypothesis (or another appropriately weak per-key/per-call condition) and prove how it accumulates across adaptive signing queries and retries. If the Rényi API is not the right route, remove it from this PR rather than presenting it as the justification. -
Finish or accurately expose the two remaining cryptographic residuals. The current result stops at
ntruPSFCollisionProblem, which is the GPV collision predicate repackaged as a problem, while the standard algebraic NTRU-SIS/kernel-vector bridge is not established. The exact-match/programmed-preimage term is also left unbounded. Please either:- prove the collision-to-standard-NTRU relation and an appropriate min-entropy/regularity bound for the exact-match term; or
- export a deliberately intermediate theorem whose name and documentation expose both residual assumptions without calling it Falcon security “down to NTRU.”
The latter is acceptable if it gives us a clean, meaningful staging point. The important thing is that the assumptions be strictly weaker than the conclusion we want, rather than restatements of the hard reduction steps.
-
Formalize the queried-forgery WLOG step.
ForgesQueriedPointcurrently restricts every supported adversary output, including losing outputs. Please implement the standard transformation that appends the final RO query and account for the extra query, or clearly keep the generic theorem restricted and provide the unrestricted corollary through that transformation. -
Reframe the non-vacuity example. The degree-one, unit-salt,
samplerLoss = 1witness proves logical inhabitance of the hypothesis type, not meaningful Falcon security. Please label it explicitly as a consistency/inhabitance witness and avoid quantitative “non-vacuity” language. -
Small correctness/maintenance items. The prose mentions a
qSign²/(2|Salt|)collision term while the theorem uses(qSign+qHash)²/(2|Salt|); please reconcile this. Some generic WriterT/state-projection and query-bound lemmas should eventually live below the GPV namespace, though that extraction can be a follow-up if moving them now creates unnecessary proof churn.
There is also no formal PPT/cost preservation yet. Please mention this limitation briefly rather than trying to solve it here. #460 is dtumad's ongoing work toward the machine/PPT infrastructure; until that lands, reviewers should manually check that the constructed reductions are plausibly efficient and do not use exhaustive/noncomputable steps in the cryptographic path.
Finally, #477 is already merged, so please update this branch to current main and rerun CI.
My preferred landing shape is: first the generic GPV theorem with its exact restrictions; then a carefully named idealized Falcon instantiation with the weakest assumptions we can reasonably achieve. Concrete implementation fidelity can remain future work.
|
@quangvdao Thank you for the careful review — itemized response:
Proposal on landing shape, per your preference: extract the generic GPV development (the |
|
sounds good please do the split. more pre each with self contained slice for review is better |
|
Will do — extracting the generic GPV development (the |
…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
|
Split executed as promised: the generic GPV framework is now #478 (self-contained, builds standalone, headlines kernel-checked axiom-clean), and this PR is rebased on top of it carrying only the idealized-Falcon layer — retitled and body rewritten accordingly. Until #478 merges, the diff here still shows the GPV commits; it shrinks to Also addressed in this round, per the review:
|
…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
|
Review point 4 (hForge WLOG) is closed on the base branch: #478 now contains the append-forgery-query compiler and the all-adversaries corollary |
…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
|
Review point 2 (hTransport decomposition) is done — the "intended refinement" promised in the docstring is now formalized, sorry-free:
Honest accounting note (in the docstrings): the TV-additive All new declarations |
…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
Close Falcon.euf_cma_security / _bytes40 (conditional, axiom-clean): reduce Falcon EUF-CMA to NTRU-SIS + programmed-preimage + birthday + an explicit finite-precision sampler-transport term, on honest keys, via the strengthened GPV bound and the collision bridge collisionFindingAdvantage_eq_ntruPSF. Plus the non-vacuity witness Falcon/NonVacuity. Claude-Session: https://claude.ai/code/session_01C7GAM6ykxZoXwDXmtdLqrA
…n EUF-CMA security `verify_sign_correct` was unprovable as stated: its only handle on the signature was `sig ∈ support (Falcon.sign …)` with `Falcon.sign := sorry`, and any real proof additionally needs PSF correctness (`s₁ + s₂·h = c` on honest keys), which is not a `Primitives.Laws` field and routes through the opaque floating-point inverse-FFT rounding in `fromFFTPreimage`. Remove the theorem along with the `Falcon.sign` and `Falcon.keyGenFromSeed` `:= sorry` placeholders (the latter unused), keeping the sorry-free scheme defs (`signAttempt`, `verify`, the GPV bridge). `Scheme.lean` and `Security.lean` are now sorry-free in what they claim; machine-checked verification correctness is documented as future work (the float boundary). The EUF-CMA security headlines are unaffected and remain axiom-clean [propext, Classical.choice, Quot.sound]: `Falcon.euf_cma_security`, `Falcon.euf_cma_security_bytes40`, `Falcon.collisionFindingAdvantage_eq_ntruPSF`, plus the non-vacuity witness `Examples.FalconNonVacuity.falcon_eufcma_hyps_inhabited`. Claude-Session: https://claude.ai/code/session_01C7GAM6ykxZoXwDXmtdLqrA
The kernel-SIS `ntruSISProblem` required `‖(s₁,s₂)‖₂² ≤ betaSquared`, but a kernel vector obtained from a Falcon-PSF collision is the difference `x - x'` of two β-short preimages, whose squared ℓ₂ norm is at most `(‖x‖₂ + ‖x'‖₂)² ≤ (2β)² = 4·betaSquared`. The old target was too tight by a factor of 4, so a `ntruPSFCollisionProblem → ntruSISProblem` translation could not go through. Correct the bound and document that this translation is not yet formalized (the reduction in `euf_cma_security` terminates at `ntruPSFCollisionProblem`). `ntruSISProblem` is currently scaffolding for that future step and is not referenced by the headline, so no proof changes. Claude-Session: https://claude.ai/code/session_01C7GAM6ykxZoXwDXmtdLqrA
A valid ntruPSFCollisionProblem solution maps to a valid ntruSISProblem solution by taking the preimage difference: nonzero by distinctness, in the kernel by left-linearity of the negacyclic product, and within 4·betaSquared by the coefficientwise centered-representative bound (a-b)^2 <= 2a^2 + 2b^2. Ships the witness-level bridge, the keyed-challenge NTRU-SIS problem at the honest key distribution, the adversary transform with its advantage transfer, and euf_cma_security_ntruSIS, the EUF-CMA bound with the collision term replaced by the keyed NTRU-SIS advantage. The gap between the honest key distribution and the uniform challenge of ntruSISProblem is exactly a decisional-NTRU assumption, documented and out of scope. Claude-Session: https://claude.ai/code/session_01DaNGD9nDo3Grwk58nsjS77
…odel scope Remove SamplerQuality and HasUniformSamplerLoss (nothing consumed them; the sampler transport is the single hTransport hypothesis, whose per-call decomposition is planned separately). The module docstring now states the idealized Falcon/GPV model precisely, including the absence of a machine- checked cost model, and the stated bound formula matches the formalized (qSign + qHash)^2 birthday term. Claude-Session: https://claude.ai/code/session_01DaNGD9nDo3Grwk58nsjS77
Falcon half of the witness-reframing pass: present the toy n=1 instance in NonVacuity as a logical-consistency (inhabitance) witness only, with no quantitative security content. Claude-Session: https://claude.ai/code/session_01DaNGD9nDo3Grwk58nsjS77
… sampler bound Add Falcon.samplerTransport, the per-call finite-precision sampler-approximation bound ([FGdG+25]'s per-query Renyi term read at total-variation distance) on honestly generated keys, with the trivial eps_step = 1 witness samplerTransport_one. Derive euf_cma_security_of_samplerTransport: the euf_cma_security conclusion at samplerLoss = qSign * eps_step with the monolithic hTransport package replaced by samplerTransport, the adaptive accumulation across signing queries proven by the banked GPV trapdoor-sampler-swap lemma. Also derive euf_cma_security_of_samplerTransport_queryBound, dropping the ForgesQueriedPoint convention via the append-forgery-query compiler at hash budget qHash + 1. euf_cma_security itself is unchanged. Claude-Session: https://claude.ai/code/session_01DaNGD9nDo3Grwk58nsjS77
Extend the degree-one consistency certificate to the decomposed headline: toy_samplerTransport witnesses Falcon.samplerTransport at the trivial budget eps_step = 1 (the toy concrete/ideal samplers do not coincide, so no exact eps_step = 0 claim), toyAdvQ retypes the query-then-forge adversary at the concrete scheme, and falcon_eufcma_samplerTransport_hyps_inhabited certifies the joint inhabitance of every euf_cma_security_of_samplerTransport hypothesis. toy_euf_cma_security_of_samplerTransport applies the derived headline end-to-end at the toy instance. Consistency-only framing throughout; no quantitative claim. Claude-Session: https://claude.ai/code/session_01DaNGD9nDo3Grwk58nsjS77
… a named min-entropy bound Add idealSamplerGuessBound (per-call pointwise-mass / min-entropy bound on the ideal trapdoor sampler at honest keys, satisfiable at 1 via idealSamplerGuessBound_one) and euf_cma_collision_security: the euf_cma_security_of_samplerTransport_queryBound bound with the programmed-preimage term collapsed to (qSign + qHash + 1) * epp via the generic guessing-probability lemma. The docstring records the literature value (2^(-Hoo) of the coset Gaussian, GPV08 Lemma 2.10) and the precise discrete-Gaussian mass lemmas still missing for a numeric epp. Claude-Session: https://claude.ai/code/session_01DaNGD9nDo3Grwk58nsjS77
…bound Extend the degree-one consistency certificate to euf_cma_collision_security: the deterministic toy sampler pure (c, 0) has pointwise maximum exactly 1 (toy_trapdoorSample_probOutput_self, zero min-entropy), so the budget epp = 1 of toy_idealSamplerGuessBound is tight for the toy sampler, and toy_euf_cma_collision_security applies the collision-only headline end-to-end with every hypothesis discharged. Consistency-only as before. Claude-Session: https://claude.ai/code/session_01DaNGD9nDo3Grwk58nsjS77
|
Review point 3(b) — the exact-match/min-entropy residual — is closed (the 3(a) NTRU-SIS bridge landed earlier via
With this, every item from the review is addressed: 1 (headline soundness via the split bound), 2 (transport decomposed), 3(a) (SIS bridge), 3(b) (this), 4 (hForge WLOG formalized). All new declarations |
Closes #188.
Instantiates the generic GPV hash-and-sign EUF-CMA bounds (now PR #478) for Falcon, reducing forgery to the NTRU-PSF collision problem and onward to short NTRU-SIS kernel vectors.
Falcon layer (
LatticeCrypto/Falcon/{Security,SISBridge,NonVacuity,Scheme}.lean)Falcon.euf_cma_security/euf_cma_security_bytes40— EUF-CMA of the Falcon signature scheme reduced tontruPSFCollisionProblem+ the explicit programmed-preimage residual + the salt birthday bound(qSign + qHash)² / (2 · |Salt|)+ a transport termsamplerLoss. The GPV laws are carried on an ideal PSF sharing Falcon'seval/isShort; the concrete→ideal transport (hTransport) is assumed as a single hypothesis, the way MLWE/SIS hardness is assumed. Decomposing it into a per-call sampler-approximation bound with a proven adaptive accumulation is the intended refinement (the unused Rényi API scaffolding was dropped from this PR).SISBridge.lean):euf_cma_security_ntruSISextends the reduction one hop further — a PSF collision(s₁,s₂) ≠ (s₁',s₂')withh·s₁ + s₂ = h·s₁' + s₂'yields a nonzero kernel vector of length² ≤4·betaSquared(ntruSISProblem_isValid_sub, via coefficientwise negacyclic-convolution arithmetic and centered-representative norm bounds).ntruSISProblemKeyedstates the honest-key variant; the gap to uniformhis decisional NTRU, documented rather than assumed silently.collisionFindingAdvantage_eq_ntruPSF— definitional bridge: the GPV collision experiment is the NTRU-PSF collision search problem.Examples.FalconNonVacuity.falcon_eufcma_hyps_inhabited— the full hypothesis set ofeuf_cma_securitywitnessed jointly at a toy parameter set with a genuinely NTRU-valid key (fG − gF = q). Presented as a logical-consistency (inhabitance) witness only — no quantitative security content.(s₁,s₂)preimages, exact arithmetic, no cost model. The unfinished sorry-backed correctness cluster (sign,keyGenFromSeed,verify_sign_correct) is deleted; verification correctness routes through floating-point inverse-FFT rounding and is complementary work (see Falcon faithfulness & soundness remediation — concrete keygen, verify_sign_correct, verify bridge #471).Verification
lake buildof the full CI library set at this tip onleanprover/lean4:v4.31.0: green, zero non-sorry warnings.#print axiomson all headline theorems (includingeuf_cma_security_ntruSISand the six SIS-bridge declarations) and both consistency witnesses:[propext, Classical.choice, Quot.sound]— nosorryAx, no custom axioms.Review follow-ups tracked
hTransportdecomposition into per-call sampler bounds.