Documentation

Starlib.OracleReduction.ProtocolSpec.SeqCompose

Sequential Composition of Protocol Specifications #

This file collects all definitions and theorems about sequentially composing ProtocolSpecs and their associated data.

Composition of Two Protocol Specifications #

@[reducible, inline]
abbrev ProtocolSpec.cons {n : } (pSpec : ProtocolSpec n) (dir : Direction) (Message : Type) :

Adding a round with direction dir and type Message to the beginning of a ProtocolSpec

Instances For
    @[reducible, inline]
    abbrev ProtocolSpec.concat {n : } (pSpec : ProtocolSpec n) (dir : Direction) (Message : Type) :

    Concatenate a round with direction dir and type Message to the end of a ProtocolSpec

    Instances For
      @[reducible, inline]
      abbrev ProtocolSpec.append {m n : } (pSpec : ProtocolSpec m) (pSpec' : ProtocolSpec n) :

      Appending two ProtocolSpecs

      Instances For
        @[simp]
        theorem ProtocolSpec.append_cast_left {n m : } {pSpec : ProtocolSpec n} {pSpec' : ProtocolSpec m} (n' : ) (h : n + m = n' + m) :
        dcast h (pSpec ++ₚ pSpec') = dcast pSpec ++ₚ pSpec'
        @[simp]
        theorem ProtocolSpec.append_cast_right {n m : } (pSpec : ProtocolSpec n) (pSpec' : ProtocolSpec m) (m' : ) (h : n + m = n + m') :
        dcast h (pSpec ++ₚ pSpec') = pSpec ++ₚ dcast pSpec'
        @[simp]
        theorem ProtocolSpec.append_left_cancel_iff {m n : } {pSpec : ProtocolSpec n} {p1 p2 : ProtocolSpec m} :
        p1 ++ₚ pSpec = p2 ++ₚ pSpec p1 = p2
        @[simp]
        theorem ProtocolSpec.append_right_cancel_iff {m n : } {pSpec : ProtocolSpec m} {p1 p2 : ProtocolSpec n} :
        pSpec ++ₚ p1 = pSpec ++ₚ p2 p1 = p2
        @[simp]
        theorem ProtocolSpec.snoc_take {n : } {pSpec : ProtocolSpec n} (k : ) (h : k < n) :
        take k pSpec ++ₚ { dir := ![pSpec.dir k, h], «Type» := ![pSpec.Type k, h] } = take (k + 1) h pSpec
        @[simp]
        theorem ProtocolSpec.take_append_left {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} :
        take m (pSpec₁ ++ₚ pSpec₂) = pSpec₁
        @[simp]
        theorem ProtocolSpec.take_append_left' {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} :
        (pSpec₁ ++ₚ pSpec₂):m = pSpec₁
        @[simp]
        theorem ProtocolSpec.rtake_append_right {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} :
        rtake n (pSpec₁ ++ₚ pSpec₂) = pSpec₂
        def ProtocolSpec.Transcript.fst {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} {k : Fin (m + n + 1)} (T : Transcript k (pSpec₁ ++ₚ pSpec₂)) :
        Transcript min (↑k) m, pSpec₁

        The first half of a partial transcript for a concatenated protocol, up to round k < m + n + 1.

        This is defined to be the full transcript for the first half if k ≥ m.

        Instances For
          def ProtocolSpec.Transcript.snd {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} {k : Fin (m + n + 1)} (T : Transcript k (pSpec₁ ++ₚ pSpec₂)) :
          Transcript k - m, pSpec₂

          The second half of a partial transcript for a concatenated protocol.

          Instances For
            def ProtocolSpec.FullTranscript.append {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} (T₁ : pSpec₁.FullTranscript) (T₂ : pSpec₂.FullTranscript) :
            (pSpec₁ ++ₚ pSpec₂).FullTranscript

            Appending two transcripts for two ProtocolSpecs

            Instances For
              def ProtocolSpec.FullTranscript.concat {n : } {pSpec : ProtocolSpec n} {NextMessage : Type} (T : pSpec.FullTranscript) (dir : Direction) (msg : NextMessage) :
              (pSpec ++ₚ { dir := !v[dir], «Type» := !v[NextMessage] }).FullTranscript

              Adding a message with a given direction and type to the end of a Transcript

              Instances For
                @[simp]
                theorem ProtocolSpec.FullTranscript.take_append_left {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} (T : pSpec₁.FullTranscript) (T' : pSpec₂.FullTranscript) :
                take m (T ++ₜ T') = FullTranscript.cast T
                @[simp]
                theorem ProtocolSpec.FullTranscript.rtake_append_right {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} (T : pSpec₁.FullTranscript) (T' : pSpec₂.FullTranscript) :
                rtake n (T ++ₜ T') = FullTranscript.cast T'
                def ProtocolSpec.FullTranscript.fst {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} (T : (pSpec₁ ++ₚ pSpec₂).FullTranscript) :

                The first half of a transcript for a concatenated protocol

                Instances For
                  def ProtocolSpec.FullTranscript.snd {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} (T : (pSpec₁ ++ₚ pSpec₂).FullTranscript) :

                  The second half of a transcript for a concatenated protocol

                  Instances For
                    @[simp]
                    theorem ProtocolSpec.FullTranscript.append_fst {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} (T₁ : pSpec₁.FullTranscript) (T₂ : pSpec₂.FullTranscript) :
                    (T₁ ++ₜ T₂).fst = T₁
                    @[simp]
                    theorem ProtocolSpec.FullTranscript.append_snd {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} (T₁ : pSpec₁.FullTranscript) (T₂ : pSpec₂.FullTranscript) :
                    (T₁ ++ₜ T₂).snd = T₂
                    def ProtocolSpec.MessageIdx.inl {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} (i : pSpec₁.MessageIdx) :
                    (pSpec₁ ++ₚ pSpec₂).MessageIdx
                    Instances For
                      def ProtocolSpec.MessageIdx.inr {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} (i : pSpec₂.MessageIdx) :
                      (pSpec₁ ++ₚ pSpec₂).MessageIdx
                      Instances For
                        def ProtocolSpec.MessageIdx.sumEquiv {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} :
                        pSpec₁.MessageIdx pSpec₂.MessageIdx (pSpec₁ ++ₚ pSpec₂).MessageIdx
                        Instances For
                          @[simp]
                          theorem ProtocolSpec.MessageIdx.sumEquiv_apply {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} (a✝ : pSpec₁.MessageIdx pSpec₂.MessageIdx) :
                          @[simp]
                          theorem ProtocolSpec.MessageIdx.sumEquiv_symm_apply {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} (x✝ : (pSpec₁ ++ₚ pSpec₂).MessageIdx) :
                          sumEquiv.symm x✝ = if hi : x✝ < m then Sum.inl x✝, hi, else Sum.inr x✝ - m, ,
                          def ProtocolSpec.ChallengeIdx.inl {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} (i : pSpec₁.ChallengeIdx) :
                          (pSpec₁ ++ₚ pSpec₂).ChallengeIdx
                          Instances For
                            def ProtocolSpec.ChallengeIdx.inr {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} (i : pSpec₂.ChallengeIdx) :
                            (pSpec₁ ++ₚ pSpec₂).ChallengeIdx
                            Instances For
                              def ProtocolSpec.ChallengeIdx.sumEquiv {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} :
                              pSpec₁.ChallengeIdx pSpec₂.ChallengeIdx (pSpec₁ ++ₚ pSpec₂).ChallengeIdx
                              Instances For
                                @[simp]
                                theorem ProtocolSpec.ChallengeIdx.sumEquiv_symm_apply {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} (x✝ : (pSpec₁ ++ₚ pSpec₂).ChallengeIdx) :
                                sumEquiv.symm x✝ = if hi : x✝ < m then Sum.inl x✝, hi, else Sum.inr x✝ - m, ,
                                @[simp]
                                theorem ProtocolSpec.ChallengeIdx.sumEquiv_apply {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} (a✝ : pSpec₁.ChallengeIdx pSpec₂.ChallengeIdx) :
                                @[inline]
                                def ProtocolSpec.seqCompose {m : } {n : Fin m} (pSpec : (i : Fin m) → ProtocolSpec (n i)) :

                                Sequential composition of a family of ProtocolSpecs, indexed by i : Fin m.

                                Defined for definitional equality, so that:

                                • seqCompose !v[] = !p[]
                                • seqCompose !v[pSpec₁] = pSpec₁
                                • seqCompose !v[pSpec₁, pSpec₂] = pSpec₁ ++ₚ pSpec₂
                                • seqCompose !v[pSpec₁, pSpec₂, pSpec₃] = pSpec₁ ++ₚ (pSpec₂ ++ₚ pSpec₃)
                                • and so on.

                                TODO: add notation ∑ i, pSpec i for seqCompose

                                Instances For
                                  @[simp]
                                  theorem ProtocolSpec.seqCompose_dir {m : } {n : Fin m} {pSpec : (i : Fin m) → ProtocolSpec (n i)} :
                                  (seqCompose pSpec).dir = Fin.vflatten fun (i : Fin m) => (pSpec i).dir
                                  @[simp]
                                  theorem ProtocolSpec.seqCompose_type {m : } {n : Fin m} {pSpec : (i : Fin m) → ProtocolSpec (n i)} :
                                  (seqCompose pSpec).Type = Fin.vflatten fun (i : Fin m) => (pSpec i).Type
                                  @[simp]
                                  theorem ProtocolSpec.seqCompose_zero {n : Fin 0} {pSpec : (i : Fin 0) → ProtocolSpec (n i)} :
                                  @[simp]
                                  theorem ProtocolSpec.seqCompose_one {n : Fin 1} {pSpec : (i : Fin 1) → ProtocolSpec (n i)} :
                                  seqCompose pSpec = pSpec 0
                                  @[simp]
                                  theorem ProtocolSpec.seqCompose_two_eq_append {n : Fin 2} {pSpec : (i : Fin 2) → ProtocolSpec (n i)} :
                                  seqCompose pSpec = pSpec 0 ++ₚ pSpec 1
                                  @[simp]
                                  theorem ProtocolSpec.seqCompose_succ_eq_append {m : } {n : Fin (m + 1)} {pSpec : (i : Fin (m + 1)) → ProtocolSpec (n i)} :
                                  seqCompose pSpec = pSpec 0 ++ₚ seqCompose fun (i : Fin m) => pSpec i.succ
                                  @[simp]
                                  theorem ProtocolSpec.seqCompose_succ_dir {m : } {n : Fin (m + 1)} {pSpec : (i : Fin (m + 1)) → ProtocolSpec (n i)} :
                                  (seqCompose pSpec).dir = Fin.vflatten fun (i : Fin (m + 1)) => (pSpec i).dir
                                  @[simp]
                                  theorem ProtocolSpec.seqCompose_succ_type {m : } {n : Fin (m + 1)} {pSpec : (i : Fin (m + 1)) → ProtocolSpec (n i)} :
                                  (seqCompose pSpec).Type = Fin.vflatten fun (i : Fin (m + 1)) => (pSpec i).Type
                                  @[inline]
                                  def ProtocolSpec.FullTranscript.seqCompose {m : } {n : Fin m} {pSpec : (i : Fin m) → ProtocolSpec (n i)} (T : (i : Fin m) → (pSpec i).FullTranscript) :

                                  Sequential composition of a family of FullTranscripts, indexed by i : Fin m.

                                  Defined for definitional equality, so that the following holds definitionally:

                                  TODO: add notation ∑ i, T i for seqCompose

                                  Instances For
                                    @[simp]
                                    theorem ProtocolSpec.FullTranscript.seqCompose_zero {n : Fin 0} {pSpec : (i : Fin 0) → ProtocolSpec (n i)} {T : (i : Fin 0) → (pSpec i).FullTranscript} :
                                    @[simp]
                                    theorem ProtocolSpec.FullTranscript.seqCompose_succ_eq_append {m : } {n : Fin (m + 1)} {pSpec : (i : Fin (m + 1)) → ProtocolSpec (n i)} {T : (i : Fin (m + 1)) → (pSpec i).FullTranscript} :
                                    seqCompose T = T 0 ++ₜ seqCompose fun (i : Fin m) => T i.succ
                                    @[simp]
                                    theorem ProtocolSpec.FullTranscript.seqCompose_embedSum {m : } {n : Fin m} {pSpec : (i : Fin m) → ProtocolSpec (n i)} {T : (i : Fin m) → (pSpec i).FullTranscript} (i : Fin m) (j : Fin (n i)) :
                                    seqCompose T (i.embedSum j) = cast (T i j)
                                    @[implicit_reducible, inline]
                                    instance ProtocolSpec.instSampleableTypeChallengeAppend {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} [h₁ : (i : pSpec₁.ChallengeIdx) → SampleableType (pSpec₁.Challenge i)] [h₂ : (i : pSpec₂.ChallengeIdx) → SampleableType (pSpec₂.Challenge i)] (i : (pSpec₁ ++ₚ pSpec₂).ChallengeIdx) :
                                    SampleableType ((pSpec₁ ++ₚ pSpec₂).Challenge i)

                                    If two protocols have sampleable challenges, then their concatenation also has sampleable challenges.

                                    @[implicit_reducible, inline]
                                    instance ProtocolSpec.instInhabitedChallengeAppend {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} [h₁ : (i : pSpec₁.ChallengeIdx) → Inhabited (pSpec₁.Challenge i)] [h₂ : (i : pSpec₂.ChallengeIdx) → Inhabited (pSpec₂.Challenge i)] (i : (pSpec₁ ++ₚ pSpec₂).ChallengeIdx) :
                                    Inhabited ((pSpec₁ ++ₚ pSpec₂).Challenge i)

                                    If two protocols' challenge types are inhabited, then their concatenation's challenge types are also inhabited.

                                    @[implicit_reducible, inline]
                                    instance ProtocolSpec.instFintypeChallengeAppend {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} [h₁ : (i : pSpec₁.ChallengeIdx) → Fintype (pSpec₁.Challenge i)] [h₂ : (i : pSpec₂.ChallengeIdx) → Fintype (pSpec₂.Challenge i)] (i : (pSpec₁ ++ₚ pSpec₂).ChallengeIdx) :
                                    Fintype ((pSpec₁ ++ₚ pSpec₂).Challenge i)

                                    If two protocols' challenge types are finite, then their concatenation's challenge types are also finite.

                                    @[implicit_reducible]
                                    instance ProtocolSpec.instOracleInterfaceMessageAppend {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} [O₁ : (i : pSpec₁.MessageIdx) → OracleInterface (pSpec₁.Message i)] [O₂ : (i : pSpec₂.MessageIdx) → OracleInterface (pSpec₂.Message i)] (i : (pSpec₁ ++ₚ pSpec₂).MessageIdx) :
                                    OracleInterface ((pSpec₁ ++ₚ pSpec₂).Message i)

                                    If two protocols' messages have oracle representations, then their concatenation's messages also have oracle representations.

                                    @[implicit_reducible]
                                    instance ProtocolSpec.instOracleInterfaceChallengeAppend {m n : } {pSpec₁ : ProtocolSpec m} {pSpec₂ : ProtocolSpec n} (i : (pSpec₁ ++ₚ pSpec₂).ChallengeIdx) :
                                    OracleInterface ((pSpec₁ ++ₚ pSpec₂).Challenge i)
                                    def ProtocolSpec.sigmaChallengeIdxToSeqCompose {m : } {n : Fin m} {pSpec : (i : Fin m) → ProtocolSpec (n i)} (i : Fin m) (j : (pSpec i).ChallengeIdx) :
                                    Instances For
                                      def ProtocolSpec.seqComposeChallengeIdxToSigma {m : } {n : Fin m} {pSpec : (i : Fin m) → ProtocolSpec (n i)} (k : (seqCompose pSpec).ChallengeIdx) :
                                      (i : Fin m) × (pSpec i).ChallengeIdx
                                      Instances For
                                        def ProtocolSpec.seqComposeChallengeEquiv {m : } {n : Fin m} (pSpec : (i : Fin m) → ProtocolSpec (n i)) :
                                        (i : Fin m) × (pSpec i).ChallengeIdx (seqCompose pSpec).ChallengeIdx

                                        The equivalence between the challenge indices of the individual protocols and the challenge indices of the sequential composition.

                                        Instances For
                                          def ProtocolSpec.sigmaMessageIdxToSeqCompose {m : } {n : Fin m} {pSpec : (i : Fin m) → ProtocolSpec (n i)} (i : Fin m) (j : (pSpec i).MessageIdx) :
                                          Instances For
                                            def ProtocolSpec.seqComposeMessageIdxToSigma {m : } {n : Fin m} {pSpec : (i : Fin m) → ProtocolSpec (n i)} (k : (seqCompose pSpec).MessageIdx) :
                                            (i : Fin m) × (pSpec i).MessageIdx
                                            Instances For
                                              def ProtocolSpec.seqComposeMessageEquiv {m : } {n : Fin m} {pSpec : (i : Fin m) → ProtocolSpec (n i)} :
                                              (i : Fin m) × (pSpec i).MessageIdx (seqCompose pSpec).MessageIdx

                                              The equivalence between the message indices of the individual protocols and the message indices of the sequential composition.

                                              Instances For
                                                @[implicit_reducible]
                                                instance ProtocolSpec.instSampleableTypeChallengeSeqCompose {m : } {n : Fin m} {pSpec : (i : Fin m) → ProtocolSpec (n i)} [inst : (i : Fin m) → (j : (pSpec i).ChallengeIdx) → SampleableType ((pSpec i).Challenge j)] (k : (seqCompose pSpec).ChallengeIdx) :
                                                @[implicit_reducible]
                                                instance ProtocolSpec.instInhabitedChallengeSeqCompose {m : } {n : Fin m} {pSpec : (i : Fin m) → ProtocolSpec (n i)} [inst : (i : Fin m) → (j : (pSpec i).ChallengeIdx) → Inhabited ((pSpec i).Challenge j)] (k : (seqCompose pSpec).ChallengeIdx) :
                                                @[implicit_reducible]
                                                instance ProtocolSpec.instFintypeChallengeSeqCompose {m : } {n : Fin m} {pSpec : (i : Fin m) → ProtocolSpec (n i)} [inst : (i : Fin m) → (j : (pSpec i).ChallengeIdx) → Fintype ((pSpec i).Challenge j)] (k : (seqCompose pSpec).ChallengeIdx) :
                                                @[implicit_reducible]
                                                instance ProtocolSpec.instOracleInterfaceMessageSeqCompose {m : } {n : Fin m} {pSpec : (i : Fin m) → ProtocolSpec (n i)} [Oₘ : (i : Fin m) → (j : (pSpec i).MessageIdx) → OracleInterface ((pSpec i).Message j)] (k : (seqCompose pSpec).MessageIdx) :

                                                If all protocols' messages have oracle interfaces, then the messages of their sequential composition also have oracle interfaces.