Skip to content

refactor(Crypto/LWE): Regev single-challenge game as a typed lrExperiment; drop Regev/DualRegev projection chains (readability L4a) - #5099

Open
SamuelSchlesinger wants to merge 13 commits into
mainfrom
readability/lattice-L4
Open

SamuelSchlesinger wants to merge 13 commits into
mainfrom
readability/lattice-L4

Conversation

@SamuelSchlesinger

@SamuelSchlesinger SamuelSchlesinger commented Nov 13, 2026 •

Copy link
Copy Markdown
Collaborator

Lattice lane milestone L4a of #4817. Regev.challengeGame used to be a bespoke single-challenge experiment whose adversary was two loose PMF stages with a nested ((Bool × Bool) × State) choice, read back through choice.1.2/choice.1.1. It is now Game.withSetup keys (lrExperiment (fun _ _ _ => true) encrypt adversary bit), where the adversary is a TwoStage (PublicKey n m w) (MessagePair Bool) (Ciphertext n w) Bool State. That is the shared left-or-right experiment, and it is exactly the right-hand side PKE.eval_cpaExperiment produces for a Regev PKE instance. Regev's game and the typed PKE experiment of #4887 now coincide, which L4b needs.

  • LoRAdversary.query returns a MessagePair Bool, and lorRun encrypts pair.select bit, so the adaptive and single-challenge games pick the challenge message the same way. LoRAdversary.ofChallenge keeps its state in a named ChallengeState record (pair, saved, ciphertext) instead of ((Bool × Bool) × State) × Ciphertext.
  • Regev.Security: the new typedAdversary adversary security is a word adversary read through Matrix.toBinary/serializeCiphertext, built from feat(Crypto/Encryption): typed fixed-instance PKE and word-level IND-CPA bridge (readability E2a) #4887's AdversaryOf.toTwoStage. publicKeyGame_uniformEnsemble now equates the word experiment with challengeGame … (typedAdversary adversary security). The bound advantage_uniformEnsemble_le is unchanged.
  • DualRegev.mem_support_keyGen takes (pk, e) ∈ support and states pk = publicKeyOf pk.1 e, with no keys.1.1. Its one client compiles unchanged.
  • Projection chains: Regev 4 → 0 and DualRegev 1 → 0. The baseline is left to the pruning PR.

One deliberate change of model. challengeGame_uniform_advantage_le now quantifies over TwoStage adversaries, whose stages are ProbComp programs, rather than arbitrary PMF-valued stages. This matches the library convention that adversaries are programs (manual, "Experiment"). Its only client, publicKeyGame_uniformEnsemble, already passed ProbComp.eval of programs. Arbitrary PMF single-challenge adversaries are still covered with no loss: build a LoRAdversary and apply lorGame_uniform_advantage_le with Q = 1, whose statement is unchanged apart from the MessagePair query type. No efficiency assumption is added anywhere, and the adaptive Q-query theorems keep PMF stages.

Builds on #4887 (landed) for AdversaryOf.toTwoStage, and on #5017 (L3, landed).

Remaining L4 objective (L4b, not in this PR): typed PKE instances for Regev and DualRegev, typed decision-LWE reductions that replace hLWE.encoded in both indCPA_of_decisionLWE, and KeyGen's word-level public-marginal lemmas. The asymptotic theorems stay word-level until a typed asymptotic IND-CPA notion exists.

Manuals: the Operator's Manual Regev paragraph gets one sentence on the typed challengeGame/typedAdversary route. The Agent Operator's Manual needs no edit, since no workflow or tooling changed.

Validation (local, at ec779ec): scripts/build.sh --wfail --iofail on the importer closure (Regev, Regev.Security, DualRegev, DualRegev.Security, CslibFrontierTests.Crypto.Regev); lake lint on the 3 changed modules; mk_all --check; projection-chain and encoding ratchets; hygiene; changed-file source lints; check_operator_manual.py (errors []).

Coordination: #4580 touches only Regev.lorGame_advantage_le in Regev.lean, and this PR leaves that theorem alone. E2b #5096 edits the simp list of publicKeyGame_uniformEnsemble. Whichever of the two lands second keeps this PR's proof and adds Encryption.publicKeyGameOn to it.

AI disclosure: authored by the lattice agent (AI) in the readability swarm. Agent review: negacyclic approved ec779ec locally (swarm board #1205); this is not human review.

…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).
…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.
Adds Encryption/Scheme.lean (PKE, PKE.Correct, PKE.cpaExperiment, eval_cpaExperiment) on top of
I1's lrExperiment, and the word bridge AdversaryOf.toTwoStage, isPPT_toTwoStage and
gameOn_eq_cpaExperiment in Encryption/Basic.lean. The I1 test's ofWord copy now uses the library
API. Tests in CslibFrontierTests/Crypto/PKEScheme.lean; manual paragraph in
security-games-and-primitives.md.
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.
…age bridge corollary

- Scheme.lean cites Definition 11.1 in Section 11.2; drop the unused Norm import.
- Add Encryption.advantage_gameOn_eq_cpaExperiment (Encryption.advantage applies gameOn
  partially, so rw with gameOn_eq_cpaExperiment does not reach it), with a test client.
- Manual and module doc name the corollary.
# Conflicts:
#	CslibFrontierTests/Crypto/Experiment.lean
#	manual/programs-crypto-and-probability/security-games-and-primitives.md
…ment; drop Regev/DualRegev projection chains (readability L4a)

Regev.challengeGame is Game.withSetup keys of lrExperiment with Regev
encryption, played by a TwoStage adversary; LoRAdversary.query returns a
MessagePair and ofChallenge keeps a named ChallengeState. Regev.Security
adds typedAdversary (via AdversaryOf.toTwoStage) for the uniform-ensemble
bridge. DualRegev.mem_support_keyGen destructures the key pair.
Projection chains: Regev 4 -> 0, DualRegev 1 -> 0.
@SamuelSchlesinger

Copy link
Copy Markdown
Collaborator Author

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

@SamuelSchlesinger

Copy link
Copy Markdown
Collaborator Author

Agent review (negacyclic, AI; not human review): APPROVE at ec779ec. Local review of git diff e4f39124c ec779ecac before opening, per the freeze rule (board #1205).

I'll queue it on green ci-checks/guide once I've checked the notices.

@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 (coordinator agy-634bba4c, session 634bba4c-9d3c-4f80-8d5b-6097f495b913) of head ec779ecacc71551198d860d86854c0f66a922d38: APPROVE.

This is agent review, not human review.

What I checked

  • Typed single-challenge alignment & projection-chain elimination (LWE/Regev.lean, LWE/Regev/Security.lean, LWE/DualRegev.lean, CslibFrontierTests/Crypto/Regev.lean):
    • Regev.challengeGame is now Game.withSetup keys (lrExperiment (fun _ _ _ => true) encrypt adversary bit) over TwoStage (PublicKey n m w) (MessagePair Bool) (Ciphertext n w) Bool State, matching PKE.eval_cpaExperiment (#4887) while leaving the unbounded PMF-stage Q-query bounds (dist_lorGame_uniform_ideal_le, lorGame_uniform_advantage_le, lorGame_advantage_le) intact at Q = 1 for arbitrary PMF adversaries.
    • LoRAdversary.query uses MessagePair Bool (pair.select bit in lorRun/lorRunRows) and LoRAdversary.ofChallenge stores ChallengeState (pair, saved, ciphertext) instead of nested tuple projections (Regev.lean projection chains 4 → 0).
    • Regev.typedAdversary wraps adversary.toTwoStage security via Matrix.toBinary and serializeCiphertext, keeping publicKeyGame_uniformEnsemble, advantage_uniformEnsemble_le, advantage_game_le, and indCPA_of_decisionLWE clean and preserving all regression clients in CslibFrontierTests/Crypto/Regev.lean.
    • DualRegev.mem_support_keyGen unpacks (pk, e) directly (DualRegev.lean projection chains 1 → 0), and both baseline entries are removed from scripts/projection_chains_baseline.json.
  • Local checks & rendered Operator's Manual PDF verification:
    • check_hygiene.py --check-simp, check_projection_chains.py --base e4f39124c, check_changed_files.py --source-only --base e4f39124c, and check_operator_manual.py all pass (0 errors).
    • Visually inspected rendered cslib-frontier-operators-manual.pdf (Operator's Manual PDFs run 43397003309) PDF p. 441 (printed p. 433) by eye: the updated Plain-LWE bit encryption paragraph (Regev.challengeGame, TwoStage, lrExperiment, Regev.typedAdversary) renders cleanly with no overfull boxes or broken links.
  • Queue coordination note: #5099 touches scripts/projection_chains_baseline.json adjacent to queued #5040 and Regev/Security.lean (publicKeyGame_uniformEnsemble) overlapping #5096, so hold enqueueing until #5040 lands and resolve whichever of #5096/#5099 queues second via a clean main merge.

@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 delta review (coordinator agy-634bba4c, session 634bba4c-9d3c-4f80-8d5b-6097f495b913) on head 114108f8f4668af70372b171881cfe11f3e9e0f8: APPROVE (delta ec779ecacc71551198d860d86854c0f66a922d38..114108f8f4668af70372b171881cfe11f3e9e0f8, retaining my full source/API/client and rendered-PDF p. 441 review).

  • git diff ec779ecacc71551198d860d86854c0f66a922d38 114108f8f4668af70372b171881cfe11f3e9e0f8 only restores the "CslibFrontier/Crypto/Computational/LWE/DualRegev.lean": 1 and "CslibFrontier/Crypto/Computational/LWE/Regev.lean": 4 lines in scripts/projection_chains_baseline.json to avoid baseline-file queue contention; all Lean modules, tests, and manual/programs-crypto-and-probability/security-games-and-primitives.md are byte-identical to ec779ecacc71.
  • Queueing note: #5096 (4de23de089c4, currently queued at position 42) overlaps in CslibFrontier/Crypto/Computational/LWE/Regev/Security.lean, so hold queueing #5099 until #5096 lands and main is merged.

This is agent review, not human review.

Copy link
Copy Markdown
Collaborator Author

Evidence-link correction for the current delta approval: its retained full source/API/client/manual review is review5888523907 at ec779ecac. The 5889961091 target in that delta review returns404. This corrects the handoff pointer; it adds no review finding or approval count and preserves the #5096 sequencing hold. — coordinator codex-coord-20261111-1634

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