Documentation

VCVio.Interaction.TwoParty.Strategy

Role-dependent strategies and counterparts #

Spec.Strategy.withRoles is the prover / focal party: owned nodes are effectful move/continuation packages, while non-owned nodes respond to the other party's move. Spec.Counterpart is the dual type. withRolesAndMonads and runWithRolesAndMonads extend this with per-node BundledMonad data from MonadDecoration.

This module also contains the public-coin specialization needed for verifier-side Fiat-Shamir. The ordinary Counterpart type is the right shape for execution, but at receiver nodes it hides the continuation behind an opaque monadic sample. Spec.PublicCoinCounterpart refines that node shape to expose:

This makes transcript replay definable without changing the core two-party interaction model.

Instances For
    Instances For
      @[reducible, inline]
      abbrev Interaction.Spec.Strategy.withRoles (m : Type u → Type u) (spec : Spec) (roles : RoleDecoration spec) (Output : spec.TranscriptType u) :

      Focal strategy: Role.Action at each decorated node (choose vs. respond).

      Instances For
        @[simp]
        theorem Interaction.Spec.Strategy.withRoles_done {m : Type u → Type u} {Output : PUnitType u} :
        @[simp]
        theorem Interaction.Spec.Strategy.withRoles_sender_eq {m : Type u → Type u} {X : Type u} {rest : XSpec} {rRest : (x : X) → RoleDecoration (rest x)} {Output : (node X rest).TranscriptType u} :
        withRoles m (node X rest) (Role.sender, rRest) Output = m ((x : X) × withRoles m (rest x) (rRest x) fun (tr : (rest x).Transcript) => Output x, tr)
        @[simp]
        theorem Interaction.Spec.Strategy.withRoles_receiver_eq {m : Type u → Type u} {X : Type u} {rest : XSpec} {rRest : (x : X) → RoleDecoration (rest x)} {Output : (node X rest).TranscriptType u} :
        withRoles m (node X rest) (Role.receiver, rRest) Output = ((x : X) → m (withRoles m (rest x) (rRest x) fun (tr : (rest x).Transcript) => Output x, tr))
        @[reducible, inline]
        abbrev Interaction.Spec.CounterpartFamily (Sender Receiver : (X : Type u) → (XType u)Type u) (spec : Spec) (roles : RoleDecoration spec) (Output : spec.TranscriptType u) :

        A generic counterpart family parameterized by separate sender- and receiver-side node representations.

        Sender nodes model how the environment follows a move chosen by the focal party. Receiver nodes model how the environment chooses a move itself. Both ordinary Counterpart and replayable PublicCoinCounterpart are specializations of this single recursion.

        Instances For
          def Interaction.Spec.CounterpartFamily.mapOutput (Sender Receiver : (X : Type u) → (XType u)Type u) (mapSender : {X : Type u} → {A B : XType u} → ((x : X) → A xB x)Sender X ASender X B) (mapReceiver : {X : Type u} → {A B : XType u} → ((x : X) → A xB x)Receiver X AReceiver X B) {spec : Spec} {roles : RoleDecoration spec} {A B : spec.TranscriptType u} :
          ((tr : spec.Transcript) → A trB tr)CounterpartFamily Sender Receiver spec roles ACounterpartFamily Sender Receiver spec roles B
          Instances For
            @[reducible, inline]
            abbrev Interaction.Spec.Counterpart (m : Type u → Type u) (spec : Spec) (roles : RoleDecoration spec) (Output : spec.TranscriptType u) :

            Counterpart / environment type with transcript-dependent output: dual actions at each node, producing Output ⟨⟩ at .done. For a no-output counterpart (the old behavior), use Counterpart m spec roles (fun _ => PUnit).

            Instances For
              def Interaction.Spec.Counterpart.mapReceiver {m : Type u → Type u} [Functor m] {X : Type u} {A B : XType u} :
              ((x : X) → A xB x)m ((x : X) × A x)m ((x : X) × B x)

              Map a receiver-family output through a sender-owned sampled move.

              Instances For
                def Interaction.Spec.Counterpart.mapSender {m : Type u → Type u} [Functor m] {X : Type u} {A B : XType u} :
                ((x : X) → A xB x)((x : X) → m (A x))(x : X) → m (B x)

                Map outputs through an effectful sender-side observation.

                Instances For
                  def Interaction.Spec.Strategy.mapOutputWithRoles {m : Type u → Type u} [Functor m] {spec : Spec} {roles : RoleDecoration spec} {A B : spec.TranscriptType u} :
                  ((tr : spec.Transcript) → A trB tr)withRoles m spec roles AwithRoles m spec roles B

                  Functorial output map for role-dependent strategies.

                  Instances For
                    @[simp]
                    theorem Interaction.Spec.Strategy.mapOutputWithRoles_id {m : Type u → Type u} [Functor m] [LawfulFunctor m] {spec : Spec} {roles : RoleDecoration spec} {A : spec.TranscriptType u} (σ : withRoles m spec roles A) :
                    mapOutputWithRoles (fun (x : spec.Transcript) (x_1 : A x) => x_1) σ = σ

                    Pointwise identity on outputs is the identity on role-dependent strategies.

                    def Interaction.Spec.Counterpart.mapOutput {m : Type u → Type u} [Functor m] {spec : Spec} {roles : RoleDecoration spec} {A B : spec.TranscriptType u} :
                    ((tr : spec.Transcript) → A trB tr)Counterpart m spec roles ACounterpart m spec roles B

                    Functorial output map for counterparts.

                    Instances For
                      @[reducible, inline]
                      abbrev Interaction.Spec.PublicCoinCounterpart (m : Type u → Type u) (spec : Spec) (roles : RoleDecoration spec) (Output : spec.TranscriptType u) :

                      A verifier counterpart with replayable public-coin receiver nodes.

                      An ordinary Counterpart m represents a receiver node as an opaque monadic action returning both the sampled challenge and the continuation. That is the right shape for execution, but it is too weak for verifier-side Fiat-Shamir: given a prescribed challenge x, there is no way to recover the continuation for x unless that continuation is exposed separately.

                      PublicCoinCounterpart factors each receiver node into:

                      • sample : m X — how the verifier samples the next public challenge
                      • next : (x : X) → ... — how the rest of the verifier depends on that challenge

                      This is exactly the extra structure needed to replay a prescribed transcript through the verifier.

                      Instances For
                        def Interaction.Spec.PublicCoinCounterpart.mapOutput {m : Type u → Type u} [Functor m] {spec : Spec} {roles : RoleDecoration spec} {A B : spec.TranscriptType u} :
                        ((tr : spec.Transcript) → A trB tr)PublicCoinCounterpart m spec roles APublicCoinCounterpart m spec roles B

                        Functorial output map for public-coin counterparts. The challenge samplers are unchanged; only the terminal output carried by continuations is mapped.

                        Instances For
                          def Interaction.Spec.PublicCoinCounterpart.toCounterpart {m : Type u → Type u} [Monad m] {spec : Spec} {roles : RoleDecoration spec} {Output : spec.TranscriptType u} :
                          PublicCoinCounterpart m spec roles OutputCounterpart m spec roles Output

                          Forget the public-coin factorization and recover the ordinary executable counterpart.

                          Instances For
                            def Interaction.Spec.PublicCoinCounterpart.replay {m : Type u → Type u} [Monad m] {spec : Spec} {roles : RoleDecoration spec} {Output : spec.TranscriptType u} :
                            PublicCoinCounterpart m spec roles Output(tr : spec.Transcript) → m (Output tr)

                            Replay a prescribed transcript through a public-coin counterpart. Sender messages are read from the transcript; receiver samplers are ignored and the stored continuation family is followed at the recorded challenge.

                            Instances For
                              @[simp]
                              theorem Interaction.Spec.Counterpart.mapOutput_id {m : Type u → Type u} [Functor m] [LawfulFunctor m] {spec : Spec} {roles : RoleDecoration spec} {A : spec.TranscriptType u} (c : Counterpart m spec roles A) :
                              mapOutput (fun (x : spec.Transcript) (x_1 : A x) => x_1) c = c

                              Pointwise identity on outputs is the identity on counterparts.

                              def Interaction.Spec.Counterpart.liftId {m : Type u → Type u} [Monad m] {spec : Spec} {roles : RoleDecoration spec} {Output : spec.TranscriptType u} :
                              Counterpart Id spec roles OutputCounterpart m spec roles Output

                              Lift a deterministic counterpart (Counterpart Id) into any monad.

                              At sender nodes the observational branch structure is unchanged. At receiver nodes the chosen move and continuation are simply wrapped in pure. This is a generic utility for reusing deterministic environments inside monadic execution machinery such as runWithRoles.

                              Instances For
                                def Interaction.Spec.Strategy.runWithRoles {m : Type u → Type u} [Monad m] (spec : Spec) (roles : RoleDecoration spec) {OutputP OutputC : spec.TranscriptType u} :
                                withRoles m spec roles OutputPCounterpart m spec roles OutputCm ((tr : spec.Transcript) × OutputP tr × OutputC tr)

                                Execute withRoles against a Counterpart, producing transcript, prover output, and counterpart output.

                                Instances For
                                  @[simp]
                                  theorem Interaction.Spec.Strategy.runWithRoles_done {m : Type u → Type u} [Monad m] {OutputP OutputC : done.TranscriptType u} (outP : OutputP PUnit.unit) (outC : OutputC PUnit.unit) :
                                  @[simp]
                                  theorem Interaction.Spec.Strategy.runWithRoles_sender {m : Type u → Type u} [Monad m] {X : Type u} {rest : XSpec} {rRest : (x : X) → RoleDecoration (rest x)} {OutputP OutputC : (node X rest).TranscriptType u} (send : m ((x : X) × withRoles m (rest x) (rRest x) fun (tr : (rest x).Transcript) => OutputP x, tr)) (dualFn : (x : X) → m (Counterpart m (rest x) (rRest x) fun (tr : (rest x).Transcript) => OutputC x, tr)) :
                                  runWithRoles (node X rest) (Role.sender, rRest) send dualFn = do let __discrsend match __discr with | x, next => do let dualNextdualFn x let __discrrunWithRoles (rest x) (rRest x) next dualNext match __discr with | tail, (outP, outC) => pure x, tail, (outP, outC)
                                  @[simp]
                                  theorem Interaction.Spec.Strategy.runWithRoles_receiver {m : Type u → Type u} [Monad m] {X : Type u} {rest : XSpec} {rRest : (x : X) → RoleDecoration (rest x)} {OutputP OutputC : (node X rest).TranscriptType u} (respond : (x : X) → m (withRoles m (rest x) (rRest x) fun (tr : (rest x).Transcript) => OutputP x, tr)) (dualSample : m ((x : X) × Counterpart m (rest x) (rRest x) fun (tr : (rest x).Transcript) => OutputC x, tr)) :
                                  runWithRoles (node X rest) (Role.receiver, rRest) respond dualSample = do let __discrdualSample match __discr with | x, dualRest => do let nextrespond x let __discrrunWithRoles (rest x) (rRest x) next dualRest match __discr with | tail, (outP, outC) => pure x, tail, (outP, outC)
                                  theorem Interaction.Spec.Strategy.runWithRoles_mapOutputWithRoles_mapOutput {m : Type u → Type u} [Monad m] [LawfulMonad m] {spec : Spec} {roles : RoleDecoration spec} {OutputP OutputP' OutputC OutputC' : spec.TranscriptType u} (fP : (tr : spec.Transcript) → OutputP trOutputP' tr) (fC : (tr : spec.Transcript) → OutputC trOutputC' tr) (strat : withRoles m spec roles OutputP) (cpt : Counterpart m spec roles OutputC) :
                                  runWithRoles spec roles (mapOutputWithRoles fP strat) (Counterpart.mapOutput fC cpt) = (fun (z : (tr : spec.Transcript) × OutputP tr × OutputC tr) => z.fst, (fP z.fst z.snd.fst, fC z.fst z.snd.snd)) <$> runWithRoles spec roles strat cpt

                                  Running runWithRoles after mapping both participant outputs is the same as running first and mapping the final triple.

                                  theorem Interaction.Spec.Strategy.runWithRoles_mapOutputWithRoles_mapOutput.go {m : Type u → Type u} [Monad m] [LawfulMonad m] (spec : Spec) (roles : RoleDecoration spec) {OutputP OutputP' OutputC OutputC' : spec.TranscriptType u} (fP : (tr : spec.Transcript) → OutputP trOutputP' tr) (fC : (tr : spec.Transcript) → OutputC trOutputC' tr) (strat : withRoles m spec roles OutputP) (cpt : Counterpart m spec roles OutputC) :
                                  runWithRoles spec roles (mapOutputWithRoles fP strat) (Counterpart.mapOutput fC cpt) = (fun (z : (tr : spec.Transcript) × OutputP tr × OutputC tr) => z.fst, (fP z.fst z.snd.fst, fC z.fst z.snd.snd)) <$> runWithRoles spec roles strat cpt
                                  @[reducible, inline]
                                  abbrev Interaction.Spec.Strategy.withRolesAndMonads (spec : Spec) (roles : RoleDecoration spec) (md : spec.MonadDecoration) (Output : spec.TranscriptType u) :

                                  withRoles using the monad attached at each node (from MonadDecoration). See Counterpart.withMonads for the dual.

                                  Instances For
                                    @[reducible, inline]
                                    abbrev Interaction.Spec.Counterpart.withMonads (spec : Spec) (roles : RoleDecoration spec) (md : spec.MonadDecoration) (Output : spec.TranscriptType u) :

                                    Counterpart with per-node monads and transcript-dependent output.

                                    This is the primary type for oracle verifiers: OracleCounterpart (in Oracle/Core.lean) is defined as Counterpart.withMonads with a MonadDecoration computed from the oracle decoration via toMonadDecoration. At sender nodes the monad is Id (pure observation); at receiver nodes it is OracleComp with the accumulated oracle access. All generic Counterpart.withMonads composition combinators (e.g., withMonads.append, withMonads.stateChainComp) therefore apply directly to oracle counterparts.

                                    Instances For
                                      def Interaction.Spec.Counterpart.withMonads.mapOutput (spec : Spec) (roles : RoleDecoration spec) (md : spec.MonadDecoration) {Output₁ Output₂ : spec.TranscriptType u} (f : (tr : spec.Transcript) → Output₁ trOutput₂ tr) :
                                      withMonads spec roles md Output₁withMonads spec roles md Output₂

                                      Map the transcript-indexed output of a monadic counterpart. This is the counterpart-side analog of Strategy.mapOutputWithRoles, specialized to Counterpart.withMonads.

                                      Instances For
                                        @[simp]
                                        theorem Interaction.Spec.Counterpart.withMonads.mapOutput_done {Output₁ Output₂ : PUnitType u} (md : PUnit) (f : (tr : PUnit) → Output₁ trOutput₂ tr) (cpt : withMonads done PUnit.unit md Output₁) :
                                        @[simp]
                                        theorem Interaction.Spec.Counterpart.withMonads.mapOutput_sender_eq {X : Type u} {rest : XSpec} {rRest : (x : X) → RoleDecoration (rest x)} {bm : BundledMonad} {mdRest : (x : X) → (rest x).MonadDecoration} {Output₁ Output₂ : (node X rest).TranscriptType u} (f : (tr : (node X rest).Transcript) → Output₁ trOutput₂ tr) (cpt : withMonads (node X rest) (Role.sender, rRest) (bm, mdRest) Output₁) :
                                        mapOutput (node X rest) (Role.sender, rRest) (bm, mdRest) f cpt = fun (x : X) => (mapOutput (rest x) (rRest x) (mdRest x) fun (tr : (rest x).Transcript) => f x, tr) <$> cpt x
                                        @[simp]
                                        theorem Interaction.Spec.Counterpart.withMonads.mapOutput_receiver_eq {X : Type u} {rest : XSpec} {rRest : (x : X) → RoleDecoration (rest x)} {bm : BundledMonad} {mdRest : (x : X) → (rest x).MonadDecoration} {Output₁ Output₂ : (node X rest).TranscriptType u} (f : (tr : (node X rest).Transcript) → Output₁ trOutput₂ tr) (cpt : withMonads (node X rest) (Role.receiver, rRest) (bm, mdRest) Output₁) :
                                        mapOutput (node X rest) (Role.receiver, rRest) (bm, mdRest) f cpt = (fun (xc : (x : X) × (fun (x : X) => Interaction.Spec.counterpartMonadicSyntax✝.Family PUnit.unit (rest x) ((fun (x : X) => Decoration.ofOver (fun (x : Type u) (x_1 : Role) => BundledMonad) (rest x) (rRest x) ((fun (x : X) => RoleDecoration.monadsOver (rest x) (rRest x) (mdRest x)) x)) x) fun (tr : (rest x).Transcript) => Output₁ x, tr) x) => xc.fst, mapOutput (rest xc.fst) (rRest xc.fst) (mdRest xc.fst) (fun (tr : (rest xc.fst).Transcript) => f xc.fst, tr) xc.snd) <$> cpt
                                        def Interaction.Spec.Strategy.runWithRolesAndMonads {m : Type u → Type u} [Monad m] (liftStrat liftCpt : (bm : BundledMonad) → {α : Type u} → bm.M αm α) (spec : Spec) (roles : RoleDecoration spec) (stratDeco cptDeco : spec.MonadDecoration) {OutputP OutputC : spec.TranscriptType u} :
                                        withRolesAndMonads spec roles stratDeco OutputPCounterpart.withMonads spec roles cptDeco OutputCm ((tr : spec.Transcript) × OutputP tr × OutputC tr)
                                        Instances For