Equivalence-modulo-lens calculus #
We define a relation ProgramDenotation.EquivModuloLens L p q capturing
"p and q have equal wps on any post that doesn't read lens L".
This packages the recurring pattern in cryptographic game-hopping where two games differ only by writes to an auxiliary tracking variable, and those writes are invisible at the wp level for posts ignoring the tracking variable.
The calculus has closure rules (reflexivity, symmetry, transitivity,
bind congruence) and base instances (e.g. pure () ≈ set L v for any
lens L, value v). Tracking-flag elision proofs reduce to short
chains of these rules.
ProgramDenotation.EquivModuloLens L p q — p and q have equal wps on any
L-ignoring post.
Equations
- GaudisCrypt.ProgramDenotation.EquivModuloLens L p q = ∀ (F : α × s → ENNReal), GaudisCrypt.IgnoresLens L F → ∀ (σ : s), p.wp F σ = q.wp F σ
Instances For
Bind with the SAME L-disjoint continuation on both sides: if p ≈_L p'
and k doesn't touch L, then p >>= k ≈_L p' >>= k.
Bind with the SAME prefix and equivalent continuations: if ∀ a, k a ≈_L k' a,
then p >>= k ≈_L p >>= k'.
Full bind congruence: p ≈_L p' AND ∀ a, k a ≈_L k' a AND k is
L-disjoint (per element) → p >>= k ≈_L p' >>= k'.
A set L v is equivalent (modulo L) to pure ().
pure () is equivalent (modulo L) to set L v (symmetric form).
Transfer to wp: if p ≈_L q and F is L-ignoring, then their wps agree.
Loop congruence for the equiv-modulo-lens calculus: if two bodies are
≈_L-equivalent, so are their loop_n iterates. Requires the reference body
body to be L-disjoint so that loop_n n body is also L-disjoint (needed
by the bind congruence in the inductive step).
Loop + trailing congruence: if body ≈_L body' and final ≈_L final',
with both body and final being L-disjoint, then
loop_n n body >>= final ≈_L loop_n n body' >>= final'.
Combines loop_n_congr and ProgramDenotation.EquivModuloLens.bind in one step.