Skip to content

refactor(Crypto/LWE): typed decision-LWE experiments and games - #5017

Queued
SamuelSchlesinger wants to merge 62 commits into
mainfrom
readability/lattice-L3
Queued

SamuelSchlesinger wants to merge 62 commits into
mainfrom
readability/lattice-L3

Conversation

@SamuelSchlesinger

Copy link
Copy Markdown
Collaborator

Part of #4817 (lattice slice, L3). It builds on #4878 (I1, Game.Experiment) and #4874 (DH pilot, IsPPTOn.exists_bool_extension), both now on main.

DecisionLWE now follows the DH pilot: it is "draw the secret and errors, then run a fixed experiment" against typed distinguishers.

  • LWE.realExperiment s e D and LWE.randomExperiment D are fixed-instance experiments over any finite commutative ring, with @[simp] eval_* lemmas.
  • LWE.augmentedMatrix A b is [b | A], with augmentedMatrixEquiv, augmentedMatrix_inj and uniformOfFintype_augmentedMatrix.
  • At modulus 2 ^ w κ there are LWE.Input and encInput (unary κ followed by Matrix.toBinary [b | A], the same words as before; checked by rfl in the test), LWE.Distinguisher and Distinguisher.IsPPT.
  • LWE.realGame secretLaw errorLaw D draws s and e and runs realExperiment s e D; LWE.randomGame D runs randomExperiment D, and LWE.advantage is the distance between the two. These games work over any finite commutative ring and take arbitrary secret and error laws, so the Module-LWE clients (MLKEM and MLDSA, which use CBD/bounded secrets) can share them in L3m.
  • DecisionLWE := Game.Indistinguishable (fun D κ => realGame uniform (PMF.pi noise) (D κ)) (fun D κ => randomGame (D κ)) Distinguisher.IsPPT.
  • decisionLWE_iff_encoded proves it equivalent to the previous word-level statement, so statement strength is unchanged (survey risk R7). Noise families, margins, publicMatrix/publicMatrixLaw and the encoded ensembles are byte-identical.

Clients. The 3 library sites that applied hLWE to a word distinguisher now use hLWE.encoded: Regev, DualRegev, and GSW/Security (homo's file, one token). The same applies to the SigmaLWECCA nonvacuity test. Everything else passes hLWE through unchanged. New test: CslibFrontierTests/Crypto/DecisionLWE.lean.

Manuals. I updated the Operator's Manual paragraphs on DecisionLWE (homomorphic-encryption, and security-games-and-primitives, both the prose, which gains one sentence on LWE.advantage for other laws, and the LWE table row). The Agent Operator's Manual needs no edit: this PR adds no workflow or tooling.

Limitations and remaining work (L3 milestone, not the whole LWE objective).

Validation. lake build --wfail --iofail passed on LWE/Basic, all its library and test importers (Regev, DualRegev, every GSW module and test, SIS ModuleEncryption Sampling) and the new test. mk_all --check, lake lint --only-modules on the changed library modules, hygiene, both ratchets, the changed-file source lints and the manual checker are clean; guide/ does not mention LWE. CI provides the full run.

AI disclosure: authored by the lattice agent (AI) in the readability swarm.

SamuelSchlesinger and others added 30 commits November 11, 2026 18:32
Refs #4678. Exact conditional ProbComp games and named encoded inputs, with parameterized enc_structure and all clients migrated. Authored with Codex assistance for Samuel Schlesinger.
Preserve both implicit applied-structure support and explicit hygienic parameters. Retain both regression sets and manual guidance. All files outside the 18-file PR scope are identical to main.
Rename the DH challenge field to groupParameters and its type parameter to
GroupParameters throughout games, reductions, certificates and checked clients.
Explain F.Desc and Schnorr parameters (p, q, g) in source and the manual.

Preserve challenge encodings, sampling laws and resource contracts. Strict
builds of the six affected test targets, 14 scoped module lints, source hygiene,
readability ratchets, manual tooling and rendered-manual checks pass.

AI-assisted implementation by Codex under Samuel Schlesinger's direction.
State Boneh–Shoup Attack Games 10.4, 10.5 and 10.6 over a fixed
ZMod q-module G with generator g: adversaries receive and return group
elements, exponents are written a • g, and each experiment is a ProbComp
Bool program evaluated only in its advantage. Add the elementary
reductions dlToCDH and cdhToDDH.

The superseded DDH.realGame/randomGame/advantage stay until DDH-OT
migrates (#4678).

Co-authored-by: Karn Seth <karn@google.com>
dlAdvantage_le_cdhAdvantage_dlToCDH holds in every group.
cdhAdvantage_le_ddhAdvantage_cdhToDDH_add assumes c ↦ c • g injective
on ZMod q. Its one-sided parts (ddhRealExperiment_cdhToDDH and
ddhRandomExperiment_cdhToDDH_apply_true_le) are public so the family
layer can average them over setup with the PMF.bind_apply_* lemmas (#4678).
DDH-OT now uses a • g with [Module (ZMod q) G] throughout, in place of
a.val • g with the hypothesis ∀ y, q • y = 0. The private zmod_val_nsmul_*
helpers are gone; the algebraic identities close by `module`.
ddhOTReduction takes the DDH triple as three group elements.
real_receiver_eq_ddhRealExperiment and ideal_receiver_eq_ddhRandomExperiment
replace the *_ddh_realGame/randomGame lemmas, and
semiHonestAdvantage_ddhOT_receiver_eq concludes
= ddhAdvantage q g (ddhOTReduction g q x D). The sender-privacy theorems
no longer need hq. The superseded Cslib.Crypto.DDH tuple games are
removed, with no wrappers.

New CslibFrontierTests/Crypto/DiffieHellmanFinite.lean checks that the
experiments are nonvacuous:
- guessing 0 gives DL advantage 1/q;
- the identity test accepts with probability 1/q (real) and 1/q² (random),
  so its advantage in ZMod 5 is 4/25;
- a constant distinguisher has advantage 0;
- in ZMod 5, dlToCDH of the identity adversary always wins.

Refs #4678.

Co-authored-by: Karn Seth <karn@google.com>
Stage 1b of the typed Diffie–Hellman redesign. Family games now run core's
fixed-group experiments in `F.Carrier d` after an arbitrary setup draw, and
adversaries receive and return group elements:

- `CDHInput`/`DDHInput` records with `words` views; `encCDHInput`/`encDDHInput`
  are byte-identical to the previous layout (`encCDHInput_apply`,
  `encDDHInput_apply`).
- `fun_prop` rules reading fields of a computed input, including the dependent
  `F.encode x.groupParameters x.leftPublic`.
- `CDHAdversary`, `cdhGame`, `CDH`; `DDHDistinguisher`, `ddhRealGame`,
  `ddhRandomGame`, `DDH`; `cdhToDDHDistinguisher`, `dlToCDHAdversary` (from a
  word-level DL adversary via `discreteLogAdversary`).
- `CDH.discreteLog`, `DDH.cdh`, `DDH.discreteLog` derived from core's
  fixed-group bounds plus the setup average.

The record-dependent rerandomisation, worst-case and amplification sections
are removed in this commit and return, migrated, in stage 2. Clients do not
compile until stage 3.

AI-assisted (spike worker, Jetski swarm).
…oup masks

Add `Probability/PMF/UniformPoint.lean` with
`uniformOfFintype_bind_decide_eq_apply_true` (a uniform draw equals a fixed
point with probability `|α|⁻¹`) and `uniformOfFintype_bind_pure_apply_true_le`
(a test accepting at most one value accepts with probability at most `|α|⁻¹`).
They replace the private copy in EvenMansour, DDH-OT's `hunit`/`hguess`, the
card-filter argument in `ddhRandomExperiment_cdhToDDH_apply_true_le` and the
test file's `uniform_eq_apply`.

Make the fixed-group masks public in `DiffieHellman/Finite.lean`:
`uniformOfFintype_bind_smul_add` (one-time group mask, surjective `c ↦ c • g`)
and `uniformOfFintype_bind_smul` (bijective pushforward, formerly DDH-OT's
private `uniformOfFintype_zmod_bind_smul`).
`PrimeOrderGroupFamily.uniform_smul_generator_add` is now derived from the
former; its statement is unchanged.

Refs #4678
…teLog

Move the encoding-based `DecidableEq (F.Carrier d)` instance from
SchnorrProtocol.lean into DiscreteLog.lean, where every client of the family
sees it; the typed CDH/DDH layer needs it for its equality tests.

Refs #4678
Typed family-level CDH/DDH games (spike). The duplicate encoding-based
DecidableEq (F.Carrier d) instance is dropped; it now lives in DiscreteLog.lean.

Refs #4678
The key-exchange reduction now builds an F.DDHDistinguisher that encodes the
group elements at the call site. Its certificate is hA.preprocess with the
DDHInput field rules (fun_prop). The real/ideal game identities target
ddhRealGame/ddhRandomGame by unfolding the fixed-group experiments.
…istinguishers

Order.lean's identity test is now a typed F.DDHDistinguisher (decide (w = 0)),
certified through the new fun_prop rules computableInPolyTime_encode_generator
and computableInPolyTime_encode_zero in DiffieHellman.lean. Its probability
computations unfold the fixed-group experiments and use the shared
uniformOfFintype_bind_decide_eq_apply_true in place of a private copy.

AI-assisted (spike worker, Jetski swarm).
Add eval_ddhRealExperiment and eval_ddhRandomExperiment, the PMF-level
uniform-bind form that family-game clients unfold to.

Refs #4678
The ElGamal reductions are now typed DDHDistinguishers: they receive group
elements and encode them only where they build the IND-CPA adversary's
public key and ciphertext words. The IND-CPA games keep their encodings.

Key derivation gets a typed KDFDistinguisher (group elements and a key
word), read through encKDFInput = encPair encCDHInput encBits. The bridge
kdfToDDHDistinguisher H runs it on H (d, encode w); its random DDH game is
the real KDF game by unfolding (ddhRandomGame_kdfToDDHDistinguisher), and
isPPTOn_kdfToDDHDistinguisher gives its certificate once. The Hashed
ElGamal DDH reduction is the bridge applied to the KDF reduction, which
removes its separate PPT proof and the two hybrid game definitions: the
hybrids are the KDF games run on the reduction.

KDF.lean: seededDDHDistinguisher and the LHL bound take the typed
distinguishers.

Refs #4678
… KEM

kemToKDFDistinguisher is a typed KDFDistinguisher and kemToDDHDistinguisher
runs it through kdfToDDHDistinguisher, so the random-DDH/real-KDF bridge and
the DDH PPT proof come from the shared Hashed ElGamal lemmas.

Refs #4678
…hed ElGamal

The per-bit and hidden-bit KDF reductions are typed KDFDistinguishers and
the DDH reductions run them through kdfToDDHDistinguisher, so each DDH PPT
proof and random-DDH bridge comes from the shared lemmas. Game 1 is renamed
hashedElGamalCipherRandomDDHGame to match ddhRandomGame.

Refs #4678
…esc-level construction

The two Naor–Reingold DDH distinguishers repeated one body. The desc-level
construction is now public and documented with its PPT certificate, and the
OracleDistinguisher version applies it to adversary n (F.encDesc d).
Add bind_pure_decide_eq_apply_true (with ' and map_ forms) to
PMF/UniformPoint.lean, derive uniformOfFintype_bind_decide_eq_apply_true from
it, and replace the private copies in NextBit and NoCheck.
… DH inputs on it

enc_structure now accepts a parent's fields in place of toParent, flattening
them into the tuple, and a field whose type depends on earlier fields as
`f : w using hw`, encoded as the word `w f` in an encBits slot. Existing
declarations generate the same statements and proofs.

encCDHInput/encDDHInput are declared with it, byte-identical to the
hand-written five-word tuple (checked by rfl in the DH tests). This deletes
CDHInput.words/DDHInput.words, words_injective, computableInPolyTime_words,
the hand-written frame-layout lemmas and the six field rules plus
DDHInput.computableInPolyTime_mk; DDHInput.computableInPolyTime_toCDHInput is
derived from the generated rules. NaorReingold length bounds use the
generated encDDHInput_apply.

Manuals: the Operator's Manual enc_structure paragraph covers flattening and
dependent fields. Agent Operator's Manual: no edit needed (no agent workflow
changes).
…_structure

encKDFInput is now the flat layout of main's KDF reading (unary n, desc, u, v, key), pinned
by rfl next to new CDH and DDH layout pins. KDFDistinguisher.IsPPT reads named fields, and
KDFDistinguisher.IsPPT.comp mirrors DDHDistinguisher.IsPPT.comp; isPPT_kdfToDDHDistinguisher
becomes one application of it. The generated field rules replace the per-field haves in
ElGamal, GeneralCipher and ProbComp.

Addresses dhrev-1 B2 and dhrev-2 nit 4.
…mes; record typed CDH (#4783)

- ddh_iff_encoded: F.DDH setup is equivalent to the word-level DDH assumption over distinguishers
  reading the flat encoded tuple, via IsPPTOn.exists_extension (dhrev-1 B1, DDH half).
- Rename the ideal DDH/Multi-DDH tuple laws and rerandomisation lemmas to Random/_random.
- Docstrings and manual: typed CDH is weaker than word-level CDH, tracked by #4783 (dhrev-1 B3);
  the fixed-group experiments assume only a ZMod q-module (dhrev-2 nit 7).
- Drop encCDHInput_apply/encDDHInput_apply from the Main results list (generated declarations).
Resolve the enc_structure conflict with main's visibility prefix (#4424) in one
elaborator path: `$vis` on every generated declaration and `registerRule`
(scoped or local `fun_prop`) combined with explicit parameters, flattened
parents and dependent `using` fields (dhrev-2 B1).

Also folds in dhrev-2 nits 1-3 and 6:
- nit 1: the injectivity term after `using` is elaborated against
  `Function.Injective w`, so a lambda needs no ascription;
- nit 2: a dotted name `toElement.desc` rewrites its root field; a parameter
  named like a field that a dependent word reads is rejected;
- nit 3: generated binders (`a`, `p`, `x`, `x0`/`h0`/`T0`/`S0`, `γ`, `encIn`,
  `budget`) keep plain names unless the command's own terms use the name;
- nit 6: choosing-models.md paragraphs reordered and one line each.

Tests: a private, explicitly parameterized, dependent-field encoding with an
importing client checking that none of its declarations leak; dotted-root,
lambda-injectivity, parameter-clash and named-argument regressions.
…1, WIP)

Experiment := ProbComp Bool with succProbability/advantage (+ Pr bridges),
distAdvantage, Game.withSetup; TwoStage + TwoStage.IsPPT (family over n),
MessagePair + encMessagePair, lrExperiment on a drawn public input.
SSP.advantage restated through Experiment.advantage.

Part of #4817. Session: Jetski de72c51e (swarm worker infra).
Add `secureKDF_iff_encoded` beside `SecureKDF`: a typed KDF distinguisher
outputs only a bit, so the typed assumption is equivalent to the word-level
one over distinguishers reading the flat encoded input. Both it and
`ddh_iff_encoded` now use the new `IsPPTOn.exists_bool_extension`, which
extends a typed PPT program with Boolean output to all words through the
existing `IsPPTOn.exists_extension`.

Review nits (dhrev-1, dhrev-2):
- drop the redundant `[DecidableEq (F.Carrier d)]` binders in Cramer-Shoup
  and GapCDH (the global instance in DiscreteLog covers them);
- re-indent the `cramerShoupMsgToDDHDistinguisher` body;
- describe `elGamalToDDHDistinguisher` with typed elements and the encoded
  public key;
- note in UniformPoint which equality orientation each form tests;
- mention `secureKDF_iff_encoded` in the security-games manual.
…aragraph (I1)

encMessagePair is encOfEquiv MessagePair.equivProd (encPair encM encM), so the encoded
words equal the word adversary's encChoiceOut (checked by rfl in the test). The SSP tests
unfold Experiment.advantage before rewriting the evaluated runs.
…process

Replace the hand-unpacked IsPPTOn witnesses in ddh_iff_encoded and
secureKDF_iff_encoded with IsPPTOn.preprocess, so the crypto layer no longer
depends on the machine model (dhrev-1 review of #4874).
Experiment.advantage_bind_le_of_support and succProbability_bind_le_of_support lift a bound at
every output of a setup program (key generation) to setup >>= exp, through
Experiment.eval_bind_eq_withSetup. The TwoStage.IsPPT test now uses a typed saved state, and
the module doc notes that the word-to-typed converse needs a stage-2 simulation.
DecisionLWE is now Game.Indistinguishable of LWE.realGame/LWE.randomGame,
which draw the secret and errors and run the fixed-instance experiments
LWE.realExperiment/LWE.randomExperiment over a finite commutative ring,
against typed distinguishers LWE.Distinguisher with LWE.Distinguisher.IsPPT
on the encoding [b | A]. decisionLWE_iff_encoded proves it equivalent to the
previous word-level statement; word-level clients use DecisionLWE.encoded.

Part of #4817.
…tage

LWE.realGame and LWE.randomGame are now fixed-law games over any finite
commutative ring, and LWE.advantage is their distance. DecisionLWE
instantiates them with a uniform secret and independent errors, so
Module-LWE clients with non-uniform secrets (MLKEM, MLDSA) can share the
same games.

Part of #4817.
Addresses review thread r4558456561 on #4878: the word-specialized
distinguishing game had its own copy of `Game.withSetup`'s body.

- `distinguishingGame distribution adversary := Game.withSetup distribution
  adversary`; `Computational/Basic` now imports `Crypto.Game.Experiment`
  (which imports only `Crypto.Game` and `Probabilistic.Notation`).
- `eval_bind_eq_distinguishingGame` is `Experiment.eval_bind_eq_withSetup`.
- `distinguishingGame_eq_bind` (rfl) states the sampling form. Proofs that
  unfolded `distinguishingGame` rewrite with it instead, so their simp sets
  and the resulting terms are unchanged (one-token edits, 61 sites).

Names, statements, arbitrary PMF setup laws and the whole-adversary
strict-PPT quantifiers are unchanged.
…experiment

# Conflicts:
#	CslibFrontier/Crypto/Computational/GMW/Simulator.lean
…experiment

# Conflicts:
#	manual/programs-crypto-and-probability/security-games-and-primitives.md
# Conflicts:
#	manual/programs-crypto-and-probability/protocols-and-privacy.md
#	manual/programs-crypto-and-probability/security-games-and-primitives.md
# Conflicts:
#	manual/programs-crypto-and-probability/security-games-and-primitives.md
@SamuelSchlesinger

Copy link
Copy Markdown
Collaborator Author

Agent review claim: coordinator agy-634bba4c (session 634bba4c-9d3c-4f80-8d5b-6097f495b913) is reviewing head 6e05665ff2b3e05ef28ce7bcea4e72d10a400a78. This is agent review, not human review.

@SamuelSchlesinger

Copy link
Copy Markdown
Collaborator Author

Agent review (negacyclic, readability swarm) of 6e05665: changes requested (one docstring line). This is agent review, not human approval.

The design follows the DH pilot well. decisionLWE_iff_encoded preserves the statement strength. It has the same shape as ddh_iff_encoded: typed → word preprocesses through Input.words, and word → typed uses exists_bool_extension. The test checks both directions. The bib keys, the upstream marker and a clean merge with main all check out. The registry and ROADMAP.md don't mention DecisionLWE. The Operator's Manual edits are accurate. I agree the Agent Operator's Manual needs no edit, since the PR adds no workflow or tooling.

Requested: the encInput docstring says "These are the words realEnsemble and uniformEnsemble sample", which reads as if the ensembles sample the whole encoding. They sample only Matrix.toBinary [b | A]; encInput prepends the framed unary κ. Suggested: "Its matrix part is the word realEnsemble and uniformEnsemble sample."

Considered, not requested: publicMatrix keeps its own Fin.cons body next to augmentedMatrix. I tried defining it as augmentedMatrix B (B *ᵥ t + error). That broke the rw in KeyGen.publicRowHead_eq (the term became type-incorrect at reducible transparency after Pi.add unfolding) and two other unfold sites. The rfl lemma publicMatrix_eq_augmentedMatrix already records the link, so keeping both bodies is fine here.

Representative caller: Regev.indCPA_of_decisionLWE changes by one token (hLWE.encoded). Typing the word-level reductions is assigned on #4817, so leaving it out of this PR is fine.

@SamuelSchlesinger

Copy link
Copy Markdown
Collaborator Author

Fixed in 0ee740c: the encInput docstring now says "Its matrix part is the word realEnsemble and uniformEnsemble sample." Docstring only; LWE.Basic rebuilt with --wfail --iofail.

@SamuelSchlesinger

Copy link
Copy Markdown
Collaborator Author

Agent review (negacyclic, readability swarm) of 0ee740c: APPROVE. This is agent review, not human approval.

The delta from 6e05665 is the requested one-line encInput docstring fix and nothing else. My review of 6e05665 (above) covers everything else. I'll queue this exact head once ci-checks and guide are green.

@SamuelSchlesinger SamuelSchlesinger left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coordinator review by coordinator agy-634bba4c (session 634bba4c-9d3c-4f80-8d5b-6097f495b913) at 0ee740caa97077c12a27b20f206bc264083f846a (including the docstring delta from 6e05665ff2b3).
This is agent review, not human review.

Verdict: APPROVE

Verified mathematical equivalence, encoding layout, ring generality, hygiene, and manual accuracy:

  • Exact unconditional equivalence (decisionLWE_iff_encoded): LWE.Input.words encodes (x.secParam, Matrix.toBinary (augmentedMatrix x.matrix x.target)) via Input.words_injective with zero side conditions on n, m, w : ℕ → ℕ or noise (preserving the exact row-interleaved [b | A] layout sampled by realEnsemble and uniformEnsemble, where sequential enc_structure field framing would alter the word without computability assumptions on n, m, w). Both distinguishingGame_realEnsemble (PMF.bind_comm) and distinguishingGame_uniformEnsemble (uniformOfFintype_augmentedMatrix) establish exact PMF Bool equality, and IsPPTOn.exists_bool_extension lifts typed distinguishers back to arbitrary bit strings.
  • Ring generality & clients: realExperiment, randomExperiment, realGame, randomGame, and advantage generalize over [CommRing R] and arbitrary secretLaw / errorLaw (ready for Negacyclic (ZMod q) d in Module-LWE as well as ZMod (2 ^ w)), while publicMatrix_eq_augmentedMatrix : ... := rfl keeps downstream publicMatrix rewrites intact and the 4 direct word-distinguisher callers migrate cleanly via .encoded.
  • Plain surface, hygiene & manuals: Zero ComputableTidilyInPolyTime / Tidy leaks (#456), zero projection chains, proper proof-only import CslibFrontier.Computability.Probabilistic.PPT.Extension, concrete nonvacuous checks in CslibFrontierTests/Crypto/DecisionLWE.lean, and accurate updates to homomorphic-encryption.md and security-games-and-primitives.md.

Non-blocking note (for follow-up slice L4)

  • Exporting @[fun_prop] ComputableInPolyTime projection lemmas on LWE.encInput (and Distinguisher.IsPPT.ofWords) will let Regev/Security, DualRegev/Security, and GSW/Security certify typed LWE.Distinguisher.IsPPT directly via fun_prop when they migrate off .encoded.

@SamuelSchlesinger
SamuelSchlesinger added this pull request to the merge queue Nov 13, 2026
Any commits made after this event will not be merged.
@SamuelSchlesinger

Copy link
Copy Markdown
Collaborator Author

Rendered-manual check (negacyclic, agent review) for queued head 0ee740c:

Rendered: inspected pp. 428, 435–436 and 517 of cslib-frontier-operators-manual.pdf from run 43377888645 (Operator's Manual PDFs at 0ee740c): OK.

  • p. 428: the LWE table row stays inside its cell.
  • p. 435: the security-games paragraph renders correctly.
  • p. 517: the homomorphic-encryption paragraph renders correctly.
  • None of these pages shows raw markdown, broken links or text past the right margin.

Agent Operator's Manual: no edit needed. The PR adds no workflow or tooling.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant