Deep Embedding: ProofFrog-Style Transformations #
This file provides ProofFrog-style code transformations for the deep embedding.
Unlike the shallow embedding tactics in CatCrypt/Tactics/ProofFrog.lean, these
operate directly on RawCode syntax trees, matching ProofFrog's approach.
Overview #
ProofFrog performs automatic game transformations by:
- Parsing games into ASTs
- Applying canonicalization and simplification passes
- Using Z3 to check equivalence
Our deep embedding (RawCode) similarly represents code as syntax trees,
enabling structural transformations with machine-checked proofs.
Important: Semantic vs Syntactic Equality #
RawCode is a free monad where bind is a constructor, not a function.
This means the monad laws do NOT hold syntactically:
RawCode.bind (RawCode.ret x) f ≠ f x(syntactically)- They ARE equal after
evalto distributions
All transformations in this file are proven at the evaluation level, which is the correct semantics for game-based cryptographic proofs.
Main Theorems #
Monad Laws (Semantic) #
eval_ret_bind- Left identity at evaluation leveleval_bind_ret- Right identity at evaluation leveleval_bind_assoc- Associativity at evaluation level
Dead Code Elimination (Semantic) #
dead_sample_eval- Unused sample can be eliminateddead_ret_eval- Unused pure value can be eliminated
Copy Propagation (Semantic) #
copy_ret_eval- Pure value substitution
Comparison with ProofFrog #
| ProofFrog | Deep Embedding |
|---|---|
| AST in Python | RawCode inductive |
| Automatic passes | Explicit lemmas |
| Z3 for equivalence | Lean's kernel |
| Syntactic rewriting | Semantic (eval) equality |
References #
- ProofFrog: https://github.com/ProofFrog/ProofFrog
- [Barbosa et al., "Mechanizing Proofs about Adversaries"]
Semantic Monad Laws #
Since RawCode.bind is a constructor (free monad), monad laws only hold after
evaluation to distributions. These are the fundamental laws for reasoning.
Associativity: ((m >>= f) >>= g).eval = (m >>= (λ x => f x >>= g)).eval
Uses the axioms from Eval.lean and SPComp.bind_assoc.
Dead Code Elimination #
When a computation's result is not used, it can be eliminated (for pure/terminating computations). All results are at the evaluation level.
Dead sample at evaluation level: unused sample produces same distribution.
Key insight: sample returns (uniform α).bind (fun a => pure (a, h)),
so when we ignore the result and continue with k, we get:
(uniform α).bind (fun _ => k.eval h) = k.eval h by uniform_bind_const
Copy Propagation #
When a value is bound and then used, substitute directly.
Structural Equality Lemmas #
These help prove two RawCode values have equal evaluations.
Canonicalization #
Put code into a standard form for easier comparison.
Summary #
This file provides the deep embedding counterparts to ProofFrog's transformations:
| ProofFrog Pass | Deep Embedding Lemma |
|---|---|
| Inline | RawCode.eval_ret_bind |
| Dead code | RawCode.dead_sample_eval, RawCode.dead_ret_eval |
| Copy propagation | RawCode.copy_ret_eval |
| Canonicalize | RawCode.eval_bind_assoc, RawCode.eval_bind_ret |
Key difference from ProofFrog:
ProofFrog operates on ASTs where Seq(Return x, k) = k(x) syntactically.
CatCrypt's RawCode is a free monad where bind (ret x) k ≠ k x syntactically.
All equalities are at the semantic (evaluation/distribution) level.
This is actually more correct for cryptographic proofs:
- What matters is that games produce the same distribution, not that they have identical syntax
- Semantic equality captures the security-relevant notion of indistinguishability
Line Count Comparison #
| Component | ProofFrog | CatCrypt Deep |
|---|---|---|
| Dead code elimination | ~20 lines Python | ~20 lines Lean |
| Copy propagation | ~15 lines Python | ~10 lines Lean |
| Canonicalization | ~25 lines Python | ~15 lines Lean |
| Total | ~60 lines | ~45 lines |
The line counts are comparable because we prove semantic equivalence directly, avoiding the need for complex syntactic transformations. CatCrypt provides machine-checked soundness for each transformation.
Proof basis #
The soundness theorems rest on:
- the axioms
eval_ret,eval_bind,eval_samplefrom Eval.lean - the SPComp monad laws:
pure_bind,bind_pure,bind_assoc - the SDistr lemma:
uniform_bind_const