Fiat-Shamir forking infrastructure #
Wraps a managed-RO NMA adversary against FiatShamir into a single-oracle
OracleComp (unifSpec + (Unit →ₒ Chal)) computation that ReplayFork can
fork. Collects the forgery, the adversary's cache, the live query log, and a
verified flag, and exposes a forkPoint that picks the index at which to
rewind.
The main export is Fork.replayForkingBound: the Fiat-Shamir-specific
analogue of Firsov-Janku's forking_lemma_ro, stated at the OracleComp
level. Callers in FiatShamir.Sigma.Security compose it with
ReplayFork.forkReplay_propertyTransfer to drive the NMA-to-extraction step
of euf_nma_bound.
Trace used by the Fiat-Shamir forking reduction for managed-RO NMA adversaries.
Fields:
forgery: the final(message, (commitment, response))triple produced by the adversary.advCache: snapshot of the adversary's locally programmed random oracle. Only the reduction side reads from it:runTrace.verifiedand the forking bound treat it purely as bookkeeping. In the managed-RO model every adversary challenge query is routed through the live oracle, so programmed entries that ever actually influence a verified forgery also appear inroCache; this is the invariant thateuf_cma_to_nmais responsible for establishing when it bridgesadvCache-only entries back to the live log.roCache: the live random-oracle cache populated by managed-RO queries during the run.queryLog: the list of(message, commitment)hash points actually queried (live). The forking lemma rewinds at a position of this list.verified: whether the forgery successfully verifies against a cached challenge for its target.runTraceconsults onlyroCachefor this flag (see its docstring).
- advCache : (unifSpec + OracleSpec.ofFn fun (x : M × Commit) => Chal).QueryCache
- roCache : (OracleSpec.ofFn fun (x : M × Commit) => Chal).QueryCache
- verified : Bool
Instances For
Rewinding point extracted from a managed-RO fork trace. The fork is usable exactly when the final forgery verifies and its hash point appears in the live query log.
Instances For
Wrapped oracle spec used by runTrace: uniform sampling plus a single counted challenge
oracle exposing the random-oracle entropy.
Instances For
Forwards a uniform-spec query through to the wrapped spec's Sum.inl summand without
touching the simulator state.
Instances For
Caching random-oracle implementation: on a cache hit the recorded answer is returned,
on a cache miss a fresh Sum.inr () query is issued, the answer is cached, and the
miss input (msg, c) is appended to the trace's internal queryLog.
Instances For
Replay a managed-RO NMA adversary against a single counted challenge oracle, keeping both the adversary-returned cache and the live query log that the forking lemma can rewind.
The verified flag is computed strictly from the live roCache so that a successful
forkPoint extraction always pins the verifying challenge to the live random-oracle
answer at the corresponding outer-log position. Forgeries whose verification depends only
on programmed entries the adversary supplies in advCache are not counted: this is a
strict strengthening over an advCache-fallback variant and strictly shrinks
Fork.advantage. The residual obligation, "every advCache-only forgery that would have
verified also has a corresponding live RO query", is a caller-side invariant that must be
discharged by the managed-RO CMA→NMA reduction. Downstream, this is the role of
euf_cma_to_nma in FiatShamir/Sigma/Security.lean, whose sigma→NMA simulation ensures
that every advCache programming step is mirrored by a live query into roCache.
Instances For
Forkable managed-RO NMA experiment. Success means the final forged transcript verifies and the corresponding hash point appears in the live query log, so the forking lemma can rewind it.
Instances For
The forkable success probability of a managed-RO NMA adversary.
Instances For
Specialization of queryLog_length_eq_outer_inr_count to runTrace's initial state
(∅, []): the trace's queryLog has the same length as the count of Sum.inr () outer
queries in the recorded log.
Specialization of queryLog_cache_outer_lockstep to runTrace's initial state
(∅, []): the trace's queryLog[i] is cached in x.roCache, and the cached value matches
the outer log's i-th Sum.inr () response.
Decoding the verified flag of a trace produced by runTrace. If the trace's
verified field is true, then there is a cached challenge ω for x.target and the
corresponding σ.verify succeeds. Used by forkSupportInvariant_of_mem_replayFirstRun.
The forkPoint-based reachability invariant for runTrace: whenever
forkPoint qH x = some s, the outer QueryLog of replayFirstRun (runTrace ...) has a
Sum.inr () query at position ↑s. This holds because each cache miss in runTrace's
roImpl issues exactly one Sum.inr () query and appends one entry to the trace's
internal queryLog, so the trace's logical fork index s (an offset into
trace.queryLog) always corresponds to a real outer-log query at the same position.
Determinism of runTrace's inner queryLog from the outer-log prefix. If the outer
logs of two runs of runTrace share a prefix p followed by a Sum.inr () query (whose
response may differ across runs), then the traces' internal queryLogs coincide on the first
p.countQ (· = Sum.inr ()) + 1 entries. This is the runTrace specialization of
inner_prefix_det_one_more_inr, rephrased at the replayFirstRun-visible level.
Managed-RO replay-fork convenience theorem at a fixed public key, stated at the
OracleComp (unifSpec + (Unit →ₒ Chal)) level.
This is the Fiat-Shamir-specific analogue of Firsov-Janku's forking_lemma_ro at
fsec/proof/ForkingRO.ec:443. It packages the replay
quantitative bound with the distinct-answer and postcondition-transfer facts for the wrapped
managed random-oracle trace experiment, composing le_probEvent_isSome_forkReplay
(quantitative bound) and forkReplay_propertyTransfer (postcondition transfer).
On the level of the statement. We state the bound at the OracleComp level rather than
lifting through simulateQ to ProbComp. Each caller (e.g. euf_nma_bound) can bridge to
ProbComp in one line using uniformSampleImpl.probEvent_simulateQ when needed, keeping this
lemma focused on the forking-lemma content.
On the target-equality conjunct. A maximally-informative version would also conclude
x₁.target = x₂.target (i.e. message-commit pair coincidence at the fork point), matching
Firsov-Janku's forking_lemma_ro. In the Lean formalization this conjunct is consumed by the
downstream reduction euf_nma_bound to align the cached challenges ω_i = x_i.roCache target.
Since it relies on a value-level log-prefix invariant across replayRunWithTraceValue plus a
correspondence between the adversary's internal queryLog and the outer QueryLog, it is
extracted through the caller-provided P_out transfer predicate: the caller may choose P_out
so that P_out x log pins x.target to a deterministic function of (log, cf x), and then
derive target-equality from the distinct-answer disagreement on the outer log.
On the hreach hypothesis. CfReachable ensures that whenever forkPoint selects an
index s for a trace x, the outer QueryLog actually has an i = Sum.inr () query at
position ↑s. For the FiatShamir setting this follows from the correspondence between the
trace's internal queryLog : List (M × Commit) and the outer QueryLog of Sum.inr ()
queries: each cache miss in roImpl appends to both simultaneously, so a logical index s
into the trace's list corresponds to the same physical position in the outer log. Callers
discharge hreach by establishing this correspondence at the level of runTrace.
On typeclass requirements. The wrappedSpec Chal oracle space is
unifSpec + (Unit →ₒ Chal), and the quantitative section of ReplayFork.lean requires the
typeclass [OracleSpec.LawfulSubSpec unifSpec spec] (to factor probOutput_uniformSample
through liftComp on the forkReplay side). This instance is discharged by Mathlib
automation at this call site.
Currently conditional on the two B1 prefix-faithfulness sorrys (transitively via
le_probEvent_isSome_forkReplay → sq_probOutput_main_le_noGuardReplayComp
→ evalDist_uniform_bind_fst_replayRunWithTraceValue_takeBeforeForkAt
and tsum_probOutput_replayFirstRun_weight_takeBeforeForkAt).