# VCVio — AI Agent Guide Machine-checked cryptographic proofs in Lean, built on Mathlib. ## Fast Start 1. Run `lake exe cache get && lake build`. 2. Read `Examples/OneTimePad/Basic.lean` for a compact modern proof (correctness and privacy). 3. Choose the work area by task: use `VCVio/` for oracle/probability/program-logic work, `LatticeCrypto/` for lattice schemes and reductions, and `LatticeCryptoTest/` for vectors or differential tests. 4. If probability lemmas fail unexpectedly, first check for `[IsProbabilitySpec spec]` or `[IsUniformSpec spec]` as appropriate. `AGENTS.md` is the canonical guide. `CLAUDE.md` is a symlink to this file. ## Attribution, Headers, And Docstrings Follow [`CONTRIBUTING.md`](CONTRIBUTING.md) for the repo's explicit attribution policy. - New Lean files should use the standard copyright / license / authors header and a module docstring. - For ordinary Lean source files, use the standard prologue layout: header, blank line, imports, blank line, module docstring. - Docstrings must be intrinsic and descriptive. Cross-reference live sibling definitions when helpful, but do not mention removed or renamed declarations, change history, or use reactive wording such as "replaces" or "renamed from". - Preserve existing headers on routine edits. - Only rewrite attribution when a file is genuinely new or materially replaced. - Do not add a separate AI-attribution line. - For inline section breaks within a Lean file, use Mathlib-style doc-comment headers `/-! ## Title -/` (or the multi-line `/-! ## Title \n\n explanation -/` form). **Do not use ASCII banners** such as `-- ====...===` flanking a `-- § Title` line. The `/-!` form is rendered by `doc-gen4`; ASCII banners are not, and they make the file feel artificially partitioned. If a section is large enough to want a loud header, it is usually large enough to want its own `namespace` or its own file. See *Section Headers Within A File* in [`CONTRIBUTING.md`](CONTRIBUTING.md). ## What This Project Is VCVio is a framework for formal cryptographic proofs built around `OracleComp spec α`, the free monad on the polynomial functor induced by an oracle signature `OracleSpec ι := ι → Type`. Its universal fold `simulateQ impl : OracleComp spec α → r α` is the unique monad morphism extending any `impl : QueryImpl spec r` to the free monad. For `OracleComp`, `support` is definitionally `simulateQ` into `SetM` with queries interpreted by `Set.univ`; `evalDist` / `probOutput` / `Pr[…]` are definitionally `simulateQ` into `PMF` using the per-query distributions supplied by `[IsProbabilitySpec spec]`. Uniform cardinality lemmas and the `support`/probability bridge use `[IsUniformSpec spec]`, which bundles `[spec.Fintype]`, `[spec.Inhabited]`, and uniform sampling. `ProbComp α := OracleComp unifSpec α` specializes to computations whose only oracle is uniform selection. The repo also includes a first-class lattice cryptography library under `LatticeCrypto/`, built on top of the `VCVio` framework. That layer contains generic lattice algebra plus ML-DSA, ML-KEM, and Falcon specifications, security statements, concrete implementations, and tests; the native FFI bridges live in the separate `Extern/` library. ## Repo Map - `VCVio/`: generic oracle-computation framework, program logic, crypto abstractions, and generic reductions. - `ToMathlib/`: local Mathlib-facing utilities and lemmas intended to remain below the framework layer. - `Extern/`: native FFI surface — the `@[extern]` bindings (SHA-3/SHAKE, ML-KEM, ML-DSA, Falcon) and the FFI-backed concrete instances that reach them. No proof library may import it; the backing `extern_lib`s become empty stubs when `third_party/` submodules are absent. - `LatticeCrypto/`: lattice-specific algebra, hardness assumptions, scheme definitions, security theorems, and concrete implementations. - `HashSig/`: hash-based signatures — SLH-DSA (SPHINCS+, FIPS 205) proof-level specs and security. Peer of `LatticeCrypto/`; depends on `VCVio`/`ToMathlib` but nothing in those imports it back. - `LatticeCryptoTest/`: ACVP vectors, executable regression tests, and cross-checks against native backends. - `VCVioTest/`: framework smoke tests and test support modules. - `VCVioWidgets/`: optional widget experiments and visualizations. - `Examples/`: compact framework examples such as OneTimePad, ElGamal, Schnorr, and program-logic tactic walkthroughs. - `Interop/`: experimental bridges to Rust verification frontends (hax, aeneas). **Strict TCB isolation**: nothing in core VCVio depends on it. See `docs/agents/interop.md`. - `csrc/`: C FFI shims used for differential testing against native ML-DSA, ML-KEM, and Falcon code. - `third_party/`: native backends as git submodules; when they are not checked out (fresh clones, Lake dependency checkouts), the native `extern_lib` targets build as empty stub archives. ## Module Layering For `VCVio/`: ``` ToMathlib → Prelude → EvalDist/Defs → OracleComp core → EvalDist bridge → {SimSemantics, QueryTracking, Constructions, Coercions, ProbComp} → {ProgramLogic, CryptoFoundations, CryptoFoundations/Asymptotics} → Examples ``` New files must respect this DAG. `EvalDist/` must never import from `OracleComp/`. For `LatticeCrypto/`, the rough dependency direction is: ``` {Ring/*, DiscreteGaussian} → HardnessAssumptions → {MLDSA, MLKEM, Falcon} → Concrete implementations / security wrappers → Extern (FFI bindings + FFI-backed instances) → LatticeCryptoTest ``` Scheme-specific code in `LatticeCrypto/` may depend on `VCVio/CryptoFoundations`, but not the other way around. The native FFI surface lives in `Extern/`: it may import `VCVio`, `LatticeCrypto`, and `ToMathlib`, but no proof library (`VCVio/`, `ToMathlib/`, `LatticeCrypto/`, `HashSig/`, `Examples/`, `VCVioWidgets/`, `Interop/`) may import `Extern.…`. That keeps every proof library — and any downstream Lake project requiring VCVio — link-safe when the `third_party/` submodules are absent. Enforced by `scripts/check-extern-isolation.sh` on every PR. For `Interop/`, the dependency contract is one-way: ``` Interop/{Hax,Aeneas,Rust}/ → VCVio/, ToMathlib/, (Hax.…), (Aeneas.…) ``` `Interop/**` may **never** be imported from `VCVio/`, `LatticeCrypto/`, `LatticeCryptoTest/`, `Examples/`, `ToMathlib/`, `Extern/`, `VCVioWidgets/`, or `VCVioTest/`. This contract is enforced by `scripts/check-interop-isolation.sh` and the `Interop TCB Isolation` GitHub workflow on every PR. ## Critical Gotchas 1. **Probability assumptions are explicit.** `support` on `OracleComp spec` works for arbitrary specs. `evalDist` / `Pr[...]` need `[IsProbabilitySpec spec]`; uniform/cardinality lemmas and `support ↔ Pr[= _] ≠ 0` need `[IsUniformSpec spec]`. Use `IsUniformSpec.ofFintypeInhabited` when you have `[spec.Fintype] [spec.Inhabited]` and intend uniform semantics. 2. **`autoImplicit = false` is set globally in `lakefile.lean`**. Do not add `set_option autoImplicit false` in individual files. Every variable must be explicitly declared. 3. **`evalDist` IS `simulateQ`** with `IsProbabilitySpec.toPMF`; under `[IsUniformSpec spec]` this is uniform. This is definitional (`rfl`). 4. **`++ₒ` is dead** — use `+` for combining oracle specs. 5. **Commented-out code is legacy** — follow only uncommented code. Use `Examples/OneTimePad/Basic.lean` as canonical reference. 6. **Preserve partial proofs** with `stop` instead of deleting large proof blocks. 7. **Do not disable linters to silence errors**. Do not use `set_option linter.* false`, `set_option weak.linter.* false`, or add repo-level `leanOptions` that turn lints off to dodge a fixable issue. Fix the root cause instead. (The one deliberate, documented exception is `weak.linter.unicodeLinter, false` in `lakefile.lean`, off so FIPS-204 math notation and diacritics in cited author names are allowed.) 8. **Interop TCB isolation is mandatory**. Core VCVio (`VCVio/`, `ToMathlib/`, `LatticeCrypto/`, `Examples/`, `LatticeCryptoTest/`, `Extern/`, `VCVioWidgets/`, `VCVioTest/`) must never `import Interop.…`, `import Hax.…`, or `import Aeneas.…`. CI fails the PR if it does. See `docs/agents/interop.md`. 9. **Extern link-safety isolation is mandatory**. Proof libraries (`VCVio/`, `ToMathlib/`, `LatticeCrypto/`, `HashSig/`, `Examples/`, `VCVioWidgets/`, `Interop/`) must never `import Extern.…`: the native backends behind it are built as empty stubs whenever the `third_party/` submodules are absent — always the case for Lake dependency checkouts — so importing `Extern` would break downstream executable links. Test libraries may import it. Enforced by `scripts/check-extern-isolation.sh` in CI. For the full list, see `docs/agents/gotchas.md`. ## Naming Conventions Follow Mathlib convention: `{head_symbol}_{operation}_{rhs_form}`. Examples: `probOutput_bind_eq_tsum`, `support_pure`, `simulateQ_map`. Structures use UpperCamelCase: `SecExp`, `SymmEncAlg`, `RelTriple`. ## Canonical Examples - Compact modern crypto proof: `Examples/OneTimePad/Basic.lean` - ElGamal IND-CPA via the generic one-time DDH lift: `Examples/ElGamal/Basic.lean` - Schnorr sigma protocol (completeness, soundness, HVZK): `Examples/Schnorr/SigmaProtocol.lean` - Oracle computation core: `VCVio/OracleComp/OracleComp.lean` - Probability lemmas: `VCVio/EvalDist/Monad/Basic.lean` - SubSpec / coercions: `VCVio/OracleComp/Coercions/SubSpec.lean` - `QueryImpl` instrumentation primitives (`preInsert` / `postInsert` and their bridge lemmas): `VCVio/OracleComp/SimSemantics/QueryImpl/Constructions.lean`. Prefer these (or their downstream wrappers `withTraceBefore` / `withTrace` / `withCost` / `withLogging`) when wrapping a `QueryImpl` with a per-query side effect, so the generic theory in that file applies. - DLog / CDH / DDH via HHS: `VCVio/CryptoFoundations/HardnessAssumptions/DiffieHellman.lean` - Cost model / polynomial time: `VCVio/OracleComp/QueryTracking/CostModel.lean` - Query cost / weighted expected cost: `VCVio/OracleComp/QueryTracking/QueryCost.lean`, `VCVio/OracleComp/QueryTracking/WriterCost.lean` - Asymptotic security games: `VCVio/CryptoFoundations/Asymptotics/Security.lean` - Negligible function algebra: `VCVio/CryptoFoundations/Asymptotics/Negligible.lean` - Query enforcement: `VCVio/OracleComp/QueryTracking/Enforcement.lean` - Seeded (Bellare-Neven) forking lemma: `VCVio/CryptoFoundations/SeededFork.lean` - Replay-based forking lemma: `VCVio/CryptoFoundations/ReplayFork.lean` - Fischlin transform: `VCVio/CryptoFoundations/Fischlin.lean` - Interaction spec and transcript: `PolyFun/Interaction/Basic/Spec.lean` - Two-party roles and strategies: `PolyFun/Interaction/TwoParty/Strategy.lean` - Two-party composition and factorization: `PolyFun/Interaction/TwoParty/Compose.lean` - Multiparty local views: `PolyFun/Interaction/Multiparty/Core.lean` - Concurrent specs and frontiers: `PolyFun/Interaction/Concurrent/Spec.lean`, `PolyFun/Interaction/Concurrent/Frontier.lean` - Concurrent processes and execution: `PolyFun/Interaction/Concurrent/Process.lean` - Open systems (interfaces, composition): `PolyFun/Interaction/UC/OpenTheory.lean` - Open processes (boundary traffic, UC bridge): `PolyFun/Interaction/UC/OpenProcess.lean` (monad-parametric `OpenProcess m Party Δ` with intrinsic `stepSampler` field and `OpenStep.boundaryTrace`) - Concrete open-theory model: `PolyFun/Interaction/UC/OpenProcessModel.lean` (`openTheory m Party schedulerSampler` threads `Spec.Sampler` through `map` / `par` / `wire` / `plug`) - UC emulation and security: `PolyFun/Interaction/UC/Emulates.lean` - Computational UC observation layer: `VCVio/Interaction/UC/Computational.lean` - Per-node samplers as data (`Spec.Sampler m spec` = `Decoration (fun X => m X) spec`): `PolyFun/Interaction/Basic/Sampler.lean` - `Spec.Fintype` ornament + canonical uniform sampler: `PolyFun/Interaction/Basic/SpecFintype.lean`, `VCVio/Interaction/UC/Runtime.lean` - Oracle-aware runtime semantics (monad-parametric process execution, `processSemanticsOracle`): `VCVio/Interaction/UC/Runtime.lean` (no `sampler` argument; pulled from `process.stepSampler`) - End-to-end UC `ObservedCompEmulates 0` at a three-port boundary: `Examples/OneTimePad/UC.lean` - Interaction examples: `PolyFun/Interaction/TwoParty/Examples.lean`, `PolyFun/Interaction/Multiparty/Examples.lean`, `PolyFun/Interaction/Concurrent/Examples.lean` - Program logic tactics: `VCVio/ProgramLogic/Tactics.lean` - Program logic tactic walkthroughs: `Examples/ProgramLogic/` - Generic lattice ring layer: `LatticeCrypto/Ring/Core.lean`, `LatticeCrypto/Ring/Kernel.lean`, `LatticeCrypto/Ring/VectorBackend.lean`, `LatticeCrypto/Ring/Transform.lean`, `LatticeCrypto/Ring/Norms.lean`, `LatticeCrypto/Ring/Rounding.lean` - ML-DSA proof-level IDS: `LatticeCrypto/MLDSA/Scheme.lean` - ML-DSA FIPS signing layer: `LatticeCrypto/MLDSA/Signature.lean` - ML-KEM internal deterministic core: `LatticeCrypto/MLKEM/Internal.lean` - ML-KEM top-level KEM wrapper: `LatticeCrypto/MLKEM/KEM.lean` - Falcon GPV instantiation: `LatticeCrypto/Falcon/Scheme.lean` - Lattice hardness assumptions: `LatticeCrypto/HardnessAssumptions/LearningWithErrors.lean`, `LatticeCrypto/HardnessAssumptions/ShortIntegerSolution.lean` - Differential and vector tests: `LatticeCryptoTest/` - Rust verification interop (hax / aeneas): `Interop/Rust/Common.lean`, `Interop/README.md`, `scripts/check-interop-isolation.sh` ## Program Logic Tactics For new program-logic proofs, import `VCVio.ProgramLogic.Tactics`. `VCVio.ProgramLogic.Notation` keeps notation plus compatibility macros, but `Tactics.lean` is the canonical interactive proof mode. For the tactic reference, proof-mode entry points, and workflow details, see [`docs/agents/program-logic.md`](docs/agents/program-logic.md). The two `@[vcspec]` and `@[wpStep]` registries are indexed via `Lean.Meta.Sym.Pattern` / `Lean.Meta.Sym.DiscrTree`. `Sym.*` is under active development in core Lean; see the *Internal Architecture* and *SymM Stability Note* sections of that doc for the churn classes to watch at each toolchain bump and the re-entry plan for the deferred `mvcgen'`/`SymM` rewriter bridge (when it lands, `Sym.Simp.mkTheoremFromDecl` rebuilds the bundle on demand). ## Building ```bash lake exe cache get && lake build ``` CI runs the timed build on the non-test Lean libraries: `ToMathlib`, `VCVio`, `LatticeCrypto`, `Extern`, `HashSig`, `Examples`, and `VCVioWidgets`. The dormant `Interop` target remains excluded. The timing report parses per-file build times only for that same set. Test libraries and test executables are not part of the timed build; CI only times the smoke module separately with `lake env lean VCVioTest/Smoke.lean`. After adding new `.lean` files: `./scripts/update-lib.sh` Lean toolchain and Mathlib must stay in sync (both currently `v4.32.0`). Keep files reasonably sized, but there is no hard line-count limit (the file-length linter is off). ## Further Reading Before working in a specific area, read the relevant guide in `docs/agents/`: - **Interaction runtime and UC integration**: [`docs/agents/interaction.md`](docs/agents/interaction.md) - **Interop with Rust verification frontends (hax, aeneas)**: [`docs/agents/interop.md`](docs/agents/interop.md) - **LatticeCrypto layout and workflows**: [`docs/agents/lattice.md`](docs/agents/lattice.md) - **OracleComp / SubSpec / SimSemantics**: [`docs/agents/oracle-comp.md`](docs/agents/oracle-comp.md) - **Query tracking / weighted cost / expected runtime**: [`docs/agents/query-tracking.md`](docs/agents/query-tracking.md) - **Probability reasoning (EvalDist, ProbComp)**: [`docs/agents/probability.md`](docs/agents/probability.md) - **Crypto primitives and reductions**: [`docs/agents/crypto.md`](docs/agents/crypto.md) - **End-to-end crypto examples**: [`docs/agents/end-to-end-examples.md`](docs/agents/end-to-end-examples.md) - **Program logic tactics**: [`docs/agents/program-logic.md`](docs/agents/program-logic.md) - **All notation**: [`docs/agents/notation.md`](docs/agents/notation.md) - **Proof workflows (game-hopping, reductions)**: [`docs/agents/proof-workflows.md`](docs/agents/proof-workflows.md) - **Gotchas and troubleshooting**: [`docs/agents/gotchas.md`](docs/agents/gotchas.md)