Consuming ={glob A}: the whole-game coupling from glob-equal initial states #
The produce side (output_glob_transfer_games, TransferInstantiate.lean) starts the
lazy and eager games from equal states. This file relaxes the precondition to
EasyCrypt's ={glob A} — the initial states need only agree on everything A may
touch.
Architecture (chained by prhl2.trans):
G_lazy σ₁ ~[same-program glob rule]~ G_lazy σ₂ ~[produce side, σ₂ = σ₂]~ G_eager σ₂
PGlob A— the invariant threaded through the body induction:={glob A}plus equal oracle tables. Glob-equality alone is too weak (the per-query coupling needs equal tables); the tables conjunct is established bylazy_init(lazy_init_coupling_glob) rather than assumed of the initial states.glob_self_coupling_lazy— the same-program whole-game rule: from={glob A}, two runs of the lazy game couple with equal results and={glob A}finals. Assembled from the init coupling and the oracle-generic body machinery (instantiate_of_fvP_genateagerInst := lazyInst := RO_lazy, with the same-side hole wrapperro_hhole_prhl_lazy).output_glob_transfer_games_of_glob— the endpoint:={glob A}precondition,u.1 = v.1 ∧ ={glob A}postcondition, lazy vs eager.
Both obligations of the original skeleton are discharged, so the endpoint needs
only the footprint disjointness hdisj:
the same-side per-query coupling (
lazy_query_self_coupling) — cache hits agree on the shared cached value, cache misses couple the samples diagonally; andthe glob adversary rule (
footprintCompat_PGlob) — everyA-confined program self-couples fromPGlob-related states, via per-orbit-step map-fcouplings (inFootprint_subprob) chained byprhl2.refl/symm/trans(prhl2_self_of_orbit), the reduce/lift bridge (lifted_step_mem_fvP_proc_compl), and per-leg table preservation re-attached through the coupling marginals.
The consume-side invariant: agreement on everything A may touch (={glob A})
plus equal oracle tables. The tables conjunct is what makes the per-query
self-coupling satisfiable; it is established by the initialisation, not assumed
of the initial states.
Equations
- GaudisCrypt.Lib.RO.Instantiate.PGlob A g₁ g₂ = ((GaudisCrypt.FVP.glob A).get g₁ = (GaudisCrypt.FVP.glob A).get g₂ ∧ random_oracle_state.get g₁ = random_oracle_state.get g₂)
Instances For
The per-query self-coupling #
lazy_query applied is a point mass on a cache hit and a uniform sample + table
write on a miss. With equal tables the two sides take the same branch: a hit
returns the shared cached value; a miss couples the samples diagonally.
ProgramDenotation bind, applied: the StateT plumbing, definitionally.
ProgramDenotation.get random_oracle_state, applied: a point mass on the table.
ProgramDenotation.set random_oracle_state Z, applied: the deterministic write.
ProgramDenotation.uniform, applied: sample, thread the state (definitional).
lazy_query applied on a cache hit: a point mass, state unchanged.
lazy_query applied on a cache miss: sample uniformly, cache, return.
Same-side per-query coupling (generic): for any invariant P that implies
equal oracle tables and is preserved by equal RO writes, two lazy_querys
couple with equal results and P preserved.
The per-query obligation for PGlob A: lazy-vs-lazy queries self-couple —
tables are equal by the invariant, glob-agreement survives the write
(glob_ro_set_invariant), and the written tables coincide.
Same-side analogue of ro_hhole_prhl: the lazy-vs-lazy oracle hole preserves
the invariant, given the per-query self-coupling h.
From ={glob A} initial states, the two lazy_inits couple and establish the
full invariant: glob-agreement survives the RO write (glob_ro_set_invariant),
and both tables are reset to fun _ => none.
The glob adversary rule: FootprintCompat (PGlob A) (fvP_proc A) #
An A-confined program self-couples from PGlob-related states. The glob-equality
precondition is an orbit fact — the two global states are joined by a zig-zag of
(FVP.fvP_proc A)ᶜ-updates (Quotient.exact). Each such update, lifted through
globalL (fixing the locals), commutes with everything A may touch as a procedure
(lifted_step_mem_fvP_proc_compl, via the reduce/lift algebra), so a confined p
maps one leg onto the other pointwise (inFootprint_subprob), giving a per-step
coupling; prhl2.refl/symm/trans chain the zig-zag (prhl2_self_of_orbit). The
final states remain in a lifted orbit — equal locals and ={glob A} globals
(glob_locals_of_lifted_orbit) — while the tables conjunct is re-attached from the
per-leg supports (inFootprint_preserves_touched through the coupling marginals).
Self-coupling along an orbit of confined-complement updates. A program confined
to F couples with itself across any zig-zag of updates from U ⊆ Fᶜ: each step is
mapped through p pointwise (inFootprint_subprob), and prhl2.refl/symm/trans
compose the zig-zag. The coupled final states are again U-orbit-related.
The update set driving the orbit coupling: global (FVP.fvP_proc A)ᶜ-updates lifted
through globalL (fixing the locals).
Equations
- One or more equations did not get rendered due to their size.
Instances For
The bridge: a global update commuting with everything A may touch globally
((FVP.fvP_proc A)ᶜ), lifted through globalL, commutes with everything A may
touch as a procedure ((fvP_proc A)ᶜ). Both fvP_procs decompose (definitionally)
into body ⊔ return, with the global one the globalL-reduction of the procedure one;
per component the commutation transfers by Footprint.liftSubProbability_comm_reduce_compl.
Pre-transport: a global (FVP.fvP_proc A)ᶜ-orbit lifts to a liftedGlobSteps
orbit of procedure states with any fixed locals.
Post-transport: liftedGlobSteps-orbit-related procedure states have equal locals
and ={glob A} globals (each step fixes the locals and is invisible to glob A).
The glob adversary rule: every program confined to fvP_proc A self-couples
from PGlob A-related states — the last obligation of the consume-side endpoint.
The same-program whole-game glob rule (lazy side): from ={glob A} initial
states, two runs of the lazy game couple with equal results and ={glob A} final
states. lazy_init establishes PGlob A; the body preserves it via the
oracle-generic machinery at eagerInst := lazyInst := RO_lazy.
The endpoint — ={glob A} consumed and produced. From initial states that
agree on everything A may touch, the lazy and eager whole games couple with
equal results and ={glob A} final states. Chains the same-program glob rule
(glob_self_coupling_lazy, taking σ₁ to σ₂ on the lazy side) with the
produce-side coupling (output_glob_transfer_games, lazy to eager at σ₂) by
prhl2.trans.
Win-form of the endpoint: any event decided by A's output transfers between
the lazy and eager games from ={glob A} initial states, with ={glob A} final
states.