Secure Messaging

9.1. SCKA Definitions🔗

Definition9.1.1
Group: SCKA. (3)
Group member previews
Preview
Definition 9.1.2
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
uses 0
Used by 11
Reverse dependency previews
Preview
Definition 9.1.2
Loading preview
Reverse dependency preview content is loaded from the rendered-fragment cache.
✓L∃∀N

Adapted from Auerbach et al. (2025), Definition 3.1 and Figure 1.

An SCKA scheme is defined by the parameters and algorithms described below, with explicit randomness-leaking send variants.

\textsf{Notation}
  • \lambda: security parameter.

  • \mathcal{I}_{\mathsf{CKA}}: initial key space.

  • \mathcal{I}: derived key space.

  • \stA, \stB: local states of A and B.

  • \rho: protocol message.

  • (t,I)\in(\mathbb{N}\times\mathcal{I})\cup\{(\bot,\bot)\}: an epoch and its derived key, or (\bot,\bot) if no key is derived.

  • t_\A^\mathsf{snd},t_\B^\mathsf{snd}\in\mathbb{N}: key epochs safe for sending messages.

  • t_\A^\mathsf{rcv},t_\B^\mathsf{rcv}\in\mathbb{N}: sending epochs of received messages.

\textsf{Algorithms}

\Init\text{-}\KeyGen(1^\lambda) \to I_{\mathsf{CKA}}\in\mathcal{I}_{\mathsf{CKA}}: On input the security parameter 1^\lambda, output an initial key I_{\mathsf{CKA}}\in\mathcal{I}_{\mathsf{CKA}}.

Party A

\InitA(I_{\mathsf{CKA}})\to\stA: On input an initial key I_{\mathsf{CKA}}\in\mathcal{I}_{\mathsf{CKA}}, output an initial state \stA for party A.

\SendA(\stA)\to((t_{I_\A},I_\A),\rho,t^\mathsf{snd}_\A,\stA'): On input a state \stA of party A, output a pair (t_{I_\A},I_\A)\in(\mathbb{N}\times\mathcal{I})\cup\{(\bot,\bot)\} of epoch counter and key, a message \rho, a sending epoch t^\mathsf{snd}_\A, and an updated state \stA'.

\SendARLeak(\stA)\to((t_{I_\A},I_\A),\rho,t^\mathsf{snd}_\A,\stA',r): As \SendA, also outputting the randomness r used for the send.

\RecA(\stA,\rho)\to((t_{I_\B},I_\B),t^\mathsf{rcv}_\A,\stA'): On input a state \stA of party A and a message \rho, output a pair (t_{I_\B},I_\B)\in(\mathbb{N}\times\mathcal{I})\cup\{(\bot,\bot)\} of epoch counter and key, a receiving epoch t^\mathsf{rcv}_\A, and an updated state \stA'. This algorithm is deterministic.

Party B

\InitB(I_{\mathsf{CKA}})\to\stB: On input an initial key I_{\mathsf{CKA}}\in\mathcal{I}_{\mathsf{CKA}}, output an initial state \stB for party B.

\SendB(\stB)\to((t_{I_\B},I_\B),\rho,t^\mathsf{snd}_\B,\stB'): On input a state \stB of party B, output a pair (t_{I_\B},I_\B)\in(\mathbb{N}\times\mathcal{I})\cup\{(\bot,\bot)\} of epoch counter and key, a message \rho, a sending epoch t^\mathsf{snd}_\B, and an updated state \stB'.

\SendBRLeak(\stB)\to((t_{I_\B},I_\B),\rho,t^\mathsf{snd}_\B,\stB',r): As \SendB, also outputting the randomness r used for the send.

\RecB(\stB,\rho)\to((t_{I_\A},I_\A),t^\mathsf{rcv}_\B,\stB'): On input a state \stB of party B and a message \rho, output a pair (t_{I_\A},I_\A)\in(\mathbb{N}\times\mathcal{I})\cup\{(\bot,\bot)\} of epoch counter and key, a receiving epoch t^\mathsf{rcv}_\B, and an updated state \stB'. This algorithm is deterministic.

SCKA algorithms and their input and output types

structure SCKAScheme (m : Type → Type u) [Monad m] (IK StA StB I Rho Rand : Type) where /-- Samples the initial common value. -/ initKeyGen : m IK /-- Initializes A's local state from the initial key. -/ initA : IK → m StA /-- Initializes B's local state from the initial key. -/ initB : IK → m StB /-- Party A's send: returns an optional (epoch,key) pair, the message sent to B, the sending epoch, and A's next state. -/ sendA : StA → m (Option (Option (ℕ × I) × Rho × ℕ × StA)) /-- Party A's randomness-leaking send: also returns the randomness used for the send. -/ sendArleak : StA → m (Option (Option (ℕ × I) × Rho × ℕ × StA × Rand)) /-- Party A's receive: returns the optional derived (epoch,key) pair, the receiving epoch, and A's next state. -/ recvA : StA → Rho → Option (Option (ℕ × I) × ℕ × StA) /-- Party B's send: returns an optional (epoch,key) pair, the message sent to A, the sending epoch, and B's next state. -/ sendB : StB → m (Option (Option (ℕ × I) × Rho × ℕ × StB)) /-- Party B's randomness-leaking send: also returns the randomness used for the send. -/ sendBrleak : StB → m (Option (Option (ℕ × I) × Rho × ℕ × StB × Rand)) /-- Party B's receive: returns the optional derived (epoch,key) pair, the receiving epoch, and B's next state. -/ recvB : StB → Rho → Option (Option (ℕ × I) × ℕ × StB)
\textsf{Illustration}

One possible schedule: either party may send repeatedly without waiting for a reply.

\begin{array}{rcccl} & \textsf{Party A} & & \textsf{Party B} & \\ & \boxed{\InitA} & \xleftarrow{\hspace{1.5em}I\hspace{1.5em}}\boxed{\Init\text{-}\KeyGen}\xrightarrow{\hspace{1.5em}I\hspace{1.5em}} & \boxed{\InitB} & \\ & \Big\downarrow\mathrlap{\,\scriptstyle\mathsf{st}} & & \Big\downarrow\mathrlap{\,\scriptstyle\mathsf{st}} & \\ & \boxed{\SendA} & \xrightarrow{\hspace{7em}\rho_1\hspace{7em}} & \boxed{\RecB} & \\ & \Big\downarrow\mathrlap{\,\scriptstyle\mathsf{st}} & & \Big\downarrow\mathrlap{\,\scriptstyle\mathsf{st}} & \\ & \boxed{\SendA} & \xrightarrow{\hspace{7em}\rho_2\hspace{7em}} & \boxed{\RecB} & \\ & \Big\downarrow\mathrlap{\,\scriptstyle\mathsf{st}} & & \Big\downarrow\mathrlap{\,\scriptstyle\mathsf{st}} & \\ & \boxed{\RecA} & \xleftarrow{\hspace{7em}\rho_3\hspace{7em}} & \boxed{\SendB}\mathrlap{\to(t,I_\B)} & \phantom{\to(t,I_\B)} \\ & \Big\downarrow\mathrlap{\,\scriptstyle\mathsf{st}} & & \Big\downarrow\mathrlap{\,\scriptstyle\mathsf{st}} & \\ & \boxed{\RecA} & \xleftarrow{\hspace{7em}\rho_4\hspace{7em}} & \boxed{\SendB} & \\ & \Big\downarrow\mathrlap{\,\scriptstyle\mathsf{st}} & & \Big\downarrow\mathrlap{\,\scriptstyle\mathsf{st}} & \\ \phantom{(t,I_\A)\gets} & \mathllap{(t,I_\A)\gets}\boxed{\RecA} & \xleftarrow{\hspace{7em}\rho_5\hspace{7em}} & \boxed{\SendB} & \\ & & I_\A\overset{?}{=}I_\B & & \end{array}

Lean code for Definition9.1.1●1 definition
  • structure(9 fields)defined in SecureMessaging/SCKA/Defs.lean
    complete
    structure SCKAScheme.{u} (m : Type → Type u) [Monad m]
      (IK StA StB I Rho Rand : Type) : Type u
    structure SCKAScheme.{u} (m : Type → Type u)
      [Monad m]
      (IK StA StB I Rho Rand : Type) : Type u
    A sparse continuous key agreement scheme.
    
    - `IK`: initial common value,
    - `StA`: local state for party A,
    - `StB`: local state for party B,
    - `I`: epoch-key space,
    - `Rho`: protocol-message space,
    - `Rand`: randomness space used by sending algorithms.
    
    initKeyGen : m IK
    Samples the initial common value. 
    initA : IK → m StA
    Initializes A's local state from the initial key. 
    initB : IK → m StB
    Initializes B's local state from the initial key. 
    sendA : StA → m (Option (Option (ℕ × I) × Rho × ℕ × StA))
    Party A's send: returns an optional (epoch,key) pair, the message sent to B,
    the sending epoch, and A's next state. 
    sendArleak : StA → m (Option (Option (ℕ × I) × Rho × ℕ × StA × Rand))
    Party A's randomness-leaking send: also returns the randomness used for the send. 
    recvA : StA → Rho → Option (Option (ℕ × I) × ℕ × StA)
    Party A's receive: returns the optional derived (epoch,key) pair, the receiving
    epoch, and A's next state. 
    sendB : StB → m (Option (Option (ℕ × I) × Rho × ℕ × StB))
    Party B's send: returns an optional (epoch,key) pair, the message sent to A,
    the sending epoch, and B's next state. 
    sendBrleak : StB → m (Option (Option (ℕ × I) × Rho × ℕ × StB × Rand))
    Party B's randomness-leaking send: also returns the randomness used for the send. 
    recvB : StB → Rho → Option (Option (ℕ × I) × ℕ × StB)
    Party B's receive: returns the optional derived (epoch,key) pair, the receiving
    epoch, and B's next state. 
Definition9.1.2
Group: SCKA. (3)
Group member previews
Preview
Definition 9.1.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
uses 1
Used by 4
Reverse dependency previews
Preview
Definition 9.1.3
Loading preview
Reverse dependency preview content is loaded from the rendered-fragment cache.
✓L∃∀N

Game state and oracles adapted from Auerbach et al. (2025), Figure 1. We extend the vulnerable-epoch model to randomness leakage and modify the leaking-send oracles accordingly. The changes are boxed.

\textsf{Vulnerable epochs}

For each party X\in\{\A,\B\}, let \mathsf{St}_X be its state space and R_X the space of randomness values returned by its leaking-send algorithm. The game is parametrised by

  • \mathsf{vuln}^{\mathsf{corr}}_X:\mathsf{St}_X\to\mathcal P_{\mathrm{fin}}(\mathbb N), the epochs exposed by corruption of a state \mathsf{st}\in\mathsf{St}_X;

  • \boxed{\mathsf{vuln}^{\mathsf{rleak}}_X:\mathsf{St}_X\times R_X\to\mathcal P_{\mathrm{fin}}(\mathbb N)}, the epochs exposed by leaking the randomness r\in R_X of a send operation from state \mathsf{st}\in\mathsf{St}_X.

Epochs exposed by corruption and randomness leakage

structure VulnerableEpochs (St Rand : Type) where /-- Vulnerable epochs following state exposure. -/ corrupt : St → Finset ℕ /-- Vulnerable epochs following randomness leakage, for the coins of a send from the given state. -/ rleak : St → Rand → Finset ℕ
\textsf{Illustration: key material and vulnerable epochs}
O-Send-X-rleak party X O-Corr-X st(0) t−1 t t+1 st(1) t t−1 t t+1 st(2) t t−1 t t+1 st(3) t t−1 t t+1 st(4) t−1 t t+1 Send r(1) t−1 t t+1 Rec Send r(3) t−1 t t+1 Rec (t, It) erases t secret key material of epoch t, in a state or in the coins of a send vulnerable epochs: keys computable by leaking party state or random coins
\textsf{Game state}

The game state consists of:

  • \stA, \stB: local protocol states for parties A and B.

  • \mathsf{Key}[\A,t], \mathsf{Key}[\B,t]: keys output by A and B for epoch t, retained in the game after local erasure.

  • \mathsf{Msg}[\A,n], \mathsf{Msg}[\B,n]: n-th messages sent by A and B, with their sending epochs.

  • n_\A, n_\B: numbers of successful sends by A and B.

  • t^\mathsf{cur}_\A, t^\mathsf{cur}_\B: current epochs of A and B.

  • \mathsf{Exposed}\subseteq\mathbb{N}: epochs exposed by corruption and randomness leakage oracle calls.

  • \mathsf{Challenged}\subseteq\mathbb{N}: epochs t for which \OChall(t) has returned a key.

  • \mathsf{correct}: whether all correctness assertions have held.

Protocol states, key and message tables, and exposed and challenged epochs

structure GameState (StA StB I Rho : Type) where /-- Local protocol state for party A. -/ stA : StA /-- Local protocol state for party B. -/ stB : StB /-- Key table for A: `Key[A, t]`. -/ keyA : ℕ → Option I /-- Key table for B: `Key[B, t]`. -/ keyB : ℕ → Option I /-- Transit array for A's messages: `Msg[A, n] = (ρ, t^snd)`. -/ msgA : ℕ → Option (Rho × ℕ) /-- Transit array for B's messages: `Msg[B, n] = (ρ, t^snd)`. -/ msgB : ℕ → Option (Rho × ℕ) /-- Number of messages A has sent. -/ nA : ℕ /-- Number of messages B has sent. -/ nB : ℕ /-- A's current epoch `t^cur_A`. -/ tcurA : ℕ /-- B's current epoch `t^cur_B`. -/ tcurB : ℕ /-- Epochs exposed through corruption or randomness leakage. -/ exposed : Finset ℕ /-- Epochs whose challenges were successfully answered. -/ challenged : Finset ℕ /-- Whether all correctness asserts have held so far. -/ correct : Bool
\OSendA

\begin{array}{l} \pcommentline{\text{Send from A to B}} \\ ((t_{I_\A},I_\A),\rho,t^\mathsf{snd}_\A,\stA') \sample \SendA(\stA); \\ \pcommentline{\text{Correctness: no rollback of current epoch}} \\ \mathsf{assert}\;t^\mathsf{snd}_\A\ge t^\mathsf{cur}_\A; \\ t^\mathsf{cur}_\A\gets t^\mathsf{snd}_\A; \\ \pif\;(t_{I_\A},I_\A)\ne(\bot,\bot)\;\pthen \\ \quad\pcommentline{\text{Correctness: epoch output only once}} \\ \quad\mathsf{assert}\;\mathsf{Key}[\A,t_{I_\A}]=\bot; \\ \quad\pcommentline{\text{Correctness: keys agree when both defined}} \\ \quad\mathsf{assert}\;\mathsf{Key}[\B,t_{I_\A}]\in\{I_\A,\bot\}; \\ \quad\mathsf{Key}[\A,t_{I_\A}]\gets I_\A; \\ \pcommentline{\text{Correctness: keys known through sending epoch}} \\ \mathsf{assert}\;\forall t\in\{1,\ldots,t^\mathsf{snd}_\A\},\; \mathsf{Key}[\A,t]\ne\bot; \\ \pcommentline{\text{Record message for delivery}} \\ \mathsf{Msg}[\A,{+}{+}n_\A]\gets(\rho,t^\mathsf{snd}_\A); \\ \stA\gets\stA'; \\ \Return(t^\mathsf{snd}_\A,t_{I_\A},\rho) \end{array}

A's send oracle and correctness checks

def oracleSendA [DecidableEq I] (scka : SCKAScheme ProbComp IK StA StB I Rho Rand) : QueryImpl (Unit →ₒ Option (ℕ × Option ℕ × Rho)) (StateT (GameState StA StB I Rho) ProbComp) := fun () => do let state ← get match ← liftM (scka.sendA state.stA) with | none => pure none | some (keyOpt, ρ, tsnd, stA') => let assertMonotonicity := state.tcurA ≤ tsnd let assertKnownPrefix (keyA : ℕ → Option I) := (List.range (tsnd + 1)).all (fun t => t = 0 || (keyA t).isSome) let nA' := state.nA + 1 let msgA' := Function.update state.msgA nA' (some (ρ, tsnd)) match keyOpt with | none => set { state with stA := stA', tcurA := tsnd, msgA := msgA', nA := nA', correct := state.correct && assertMonotonicity && assertKnownPrefix state.keyA } return some (tsnd, none, ρ) | some (tI, key) => let assertUniqueEpochs := (state.keyA tI).isNone let assertConsistentKeys := (state.keyB tI).isNone || state.keyB tI == some key let keyA' := Function.update state.keyA tI (some key) set { state with stA := stA', tcurA := tsnd, keyA := keyA', msgA := msgA', nA := nA', correct := state.correct && assertMonotonicity && assertUniqueEpochs && assertConsistentKeys && assertKnownPrefix keyA' } return some (tsnd, some tI, ρ)
\OSendB

\begin{array}{l} \pcommentline{\text{Send from B to A}} \\ ((t_{I_\B},I_\B),\rho,t^\mathsf{snd}_\B,\stB') \sample \SendB(\stB); \\ \pcommentline{\text{Correctness: no rollback of current epoch}} \\ \mathsf{assert}\;t^\mathsf{snd}_\B\ge t^\mathsf{cur}_\B; \\ t^\mathsf{cur}_\B\gets t^\mathsf{snd}_\B; \\ \pif\;(t_{I_\B},I_\B)\ne(\bot,\bot)\;\pthen \\ \quad\pcommentline{\text{Correctness: epoch output only once}} \\ \quad\mathsf{assert}\;\mathsf{Key}[\B,t_{I_\B}]=\bot; \\ \quad\pcommentline{\text{Correctness: keys agree when both defined}} \\ \quad\mathsf{assert}\;\mathsf{Key}[\A,t_{I_\B}]\in\{I_\B,\bot\}; \\ \quad\mathsf{Key}[\B,t_{I_\B}]\gets I_\B; \\ \pcommentline{\text{Correctness: keys known through sending epoch}} \\ \mathsf{assert}\;\forall t\in\{1,\ldots,t^\mathsf{snd}_\B\},\; \mathsf{Key}[\B,t]\ne\bot; \\ \pcommentline{\text{Record message for delivery}} \\ \mathsf{Msg}[\B,{+}{+}n_\B]\gets(\rho,t^\mathsf{snd}_\B); \\ \stB\gets\stB'; \\ \Return(t^\mathsf{snd}_\B,t_{I_\B},\rho) \end{array}

B's send oracle and correctness checks

def oracleSendB [DecidableEq I] (scka : SCKAScheme ProbComp IK StA StB I Rho Rand) : QueryImpl (Unit →ₒ Option (ℕ × Option ℕ × Rho)) (StateT (GameState StA StB I Rho) ProbComp) := fun () => do let state ← get match ← liftM (scka.sendB state.stB) with | none => pure none | some (keyOpt, ρ, tsnd, stB') => let assertMonotonicity := state.tcurB ≤ tsnd let assertKnownPrefix (keyB : ℕ → Option I) := (List.range (tsnd + 1)).all (fun t => t = 0 || (keyB t).isSome) let nB' := state.nB + 1 let msgB' := Function.update state.msgB nB' (some (ρ, tsnd)) match keyOpt with | none => set { state with stB := stB', tcurB := tsnd, msgB := msgB', nB := nB', correct := state.correct && assertMonotonicity && assertKnownPrefix state.keyB } return some (tsnd, none, ρ) | some (tI, key) => let assertUniqueEpochs := (state.keyB tI).isNone let assertConsistentKeys := (state.keyA tI).isNone || state.keyA tI == some key let keyB' := Function.update state.keyB tI (some key) set { state with stB := stB', tcurB := tsnd, keyB := keyB', msgB := msgB', nB := nB', correct := state.correct && assertMonotonicity && assertUniqueEpochs && assertConsistentKeys && assertKnownPrefix keyB' } return some (tsnd, some tI, ρ)
\OSendARLeak

\begin{array}{l} \pcommentline{\text{Send from A to B; reveal randomness}} \\ ((t_{I_\A},I_\A),\rho,t^\mathsf{snd}_\A,\stA',r) \sample \SendARLeak(\stA); \\ \pcommentline{\text{Vulnerable epochs following randomness leakage}} \\ \boxed{\mathsf{vuln}\gets\mathsf{vuln}^{\mathsf{rleak}}_\A(\stA,r)}; \\ \pcommentline{\text{Reject exposure of challenged epochs}} \\ \req\;\mathsf{vuln}\cap\mathsf{Challenged}=\emptyset; \\ \mathsf{Exposed}\gets\mathsf{Exposed}\cup\mathsf{vuln}; \\ \pcommentline{\text{Correctness: no rollback of current epoch}} \\ \mathsf{assert}\;t^\mathsf{snd}_\A\ge t^\mathsf{cur}_\A; \\ t^\mathsf{cur}_\A\gets t^\mathsf{snd}_\A; \\ \pif\;(t_{I_\A},I_\A)\ne(\bot,\bot)\;\pthen \\ \quad\pcommentline{\text{Correctness: epoch output only once}} \\ \quad\mathsf{assert}\;\mathsf{Key}[\A,t_{I_\A}]=\bot; \\ \quad\pcommentline{\text{Correctness: keys agree when both defined}} \\ \quad\mathsf{assert}\;\mathsf{Key}[\B,t_{I_\A}]\in\{I_\A,\bot\}; \\ \quad\mathsf{Key}[\A,t_{I_\A}]\gets I_\A; \\ \pcommentline{\text{Correctness: keys known through sending epoch}} \\ \mathsf{assert}\;\forall t\in\{1,\ldots,t^\mathsf{snd}_\A\},\; \mathsf{Key}[\A,t]\ne\bot; \\ \pcommentline{\text{Record message for delivery}} \\ \mathsf{Msg}[\A,{+}{+}n_\A]\gets(\rho,t^\mathsf{snd}_\A); \\ \stA\gets\stA'; \\ \Return(t^\mathsf{snd}_\A,t_{I_\A},\rho,r) \end{array}

A's leaking-send oracle and exposure guard

def oracleSendArleak [DecidableEq I] (vulnRleakA : StA → Rand → Finset ℕ) (scka : SCKAScheme ProbComp IK StA StB I Rho Rand) : QueryImpl (Unit →ₒ Option (ℕ × Option ℕ × Rho × Rand)) (StateT (GameState StA StB I Rho) ProbComp) := fun () => do let state ← get match ← liftM (scka.sendArleak state.stA) with | none => pure none | some (keyOpt, ρ, tsnd, stA', rand) => let vuln' := vulnRleakA state.stA rand -- req vuln' ∩ Challenged = ∅ if vuln' ∩ state.challenged ≠ ∅ then pure none else let exposed' := state.exposed ∪ vuln' let assertMonotonicity := state.tcurA ≤ tsnd let assertKnownPrefix (keyA : ℕ → Option I) := (List.range (tsnd + 1)).all (fun t => t = 0 || (keyA t).isSome) let nA' := state.nA + 1 let msgA' := Function.update state.msgA nA' (some (ρ, tsnd)) match keyOpt with | none => set { state with stA := stA', tcurA := tsnd, exposed := exposed', msgA := msgA', nA := nA', correct := state.correct && assertMonotonicity && assertKnownPrefix state.keyA } return some (tsnd, none, ρ, rand) | some (tI, key) => let assertUniqueEpochs := (state.keyA tI).isNone let assertConsistentKeys := (state.keyB tI).isNone || state.keyB tI == some key let keyA' := Function.update state.keyA tI (some key) set { state with stA := stA', tcurA := tsnd, exposed := exposed', keyA := keyA', msgA := msgA', nA := nA', correct := state.correct && assertMonotonicity && assertUniqueEpochs && assertConsistentKeys && assertKnownPrefix keyA' } return some (tsnd, some tI, ρ, rand)
\OSendBRLeak

\begin{array}{l} \pcommentline{\text{Send from B to A; reveal randomness}} \\ ((t_{I_\B},I_\B),\rho,t^\mathsf{snd}_\B,\stB',r) \sample \SendBRLeak(\stB); \\ \pcommentline{\text{Vulnerable epochs following randomness leakage}} \\ \boxed{\mathsf{vuln}\gets\mathsf{vuln}^{\mathsf{rleak}}_\B(\stB,r)}; \\ \pcommentline{\text{Reject exposure of challenged epochs}} \\ \req\;\mathsf{vuln}\cap\mathsf{Challenged}=\emptyset; \\ \mathsf{Exposed}\gets\mathsf{Exposed}\cup\mathsf{vuln}; \\ \pcommentline{\text{Correctness: no rollback of current epoch}} \\ \mathsf{assert}\;t^\mathsf{snd}_\B\ge t^\mathsf{cur}_\B; \\ t^\mathsf{cur}_\B\gets t^\mathsf{snd}_\B; \\ \pif\;(t_{I_\B},I_\B)\ne(\bot,\bot)\;\pthen \\ \quad\pcommentline{\text{Correctness: epoch output only once}} \\ \quad\mathsf{assert}\;\mathsf{Key}[\B,t_{I_\B}]=\bot; \\ \quad\pcommentline{\text{Correctness: keys agree when both defined}} \\ \quad\mathsf{assert}\;\mathsf{Key}[\A,t_{I_\B}]\in\{I_\B,\bot\}; \\ \quad\mathsf{Key}[\B,t_{I_\B}]\gets I_\B; \\ \pcommentline{\text{Correctness: keys known through sending epoch}} \\ \mathsf{assert}\;\forall t\in\{1,\ldots,t^\mathsf{snd}_\B\},\; \mathsf{Key}[\B,t]\ne\bot; \\ \pcommentline{\text{Record message for delivery}} \\ \mathsf{Msg}[\B,{+}{+}n_\B]\gets(\rho,t^\mathsf{snd}_\B); \\ \stB\gets\stB'; \\ \Return(t^\mathsf{snd}_\B,t_{I_\B},\rho,r) \end{array}

B's leaking-send oracle and exposure guard

def oracleSendBrleak [DecidableEq I] (vulnRleakB : StB → Rand → Finset ℕ) (scka : SCKAScheme ProbComp IK StA StB I Rho Rand) : QueryImpl (Unit →ₒ Option (ℕ × Option ℕ × Rho × Rand)) (StateT (GameState StA StB I Rho) ProbComp) := fun () => do let state ← get match ← liftM (scka.sendBrleak state.stB) with | none => pure none | some (keyOpt, ρ, tsnd, stB', rand) => let vuln' := vulnRleakB state.stB rand if vuln' ∩ state.challenged ≠ ∅ then pure none else let exposed' := state.exposed ∪ vuln' let assertMonotonicity := state.tcurB ≤ tsnd let assertKnownPrefix (keyB : ℕ → Option I) := (List.range (tsnd + 1)).all (fun t => t = 0 || (keyB t).isSome) let nB' := state.nB + 1 let msgB' := Function.update state.msgB nB' (some (ρ, tsnd)) match keyOpt with | none => set { state with stB := stB', tcurB := tsnd, exposed := exposed', msgB := msgB', nB := nB', correct := state.correct && assertMonotonicity && assertKnownPrefix state.keyB } return some (tsnd, none, ρ, rand) | some (tI, key) => let assertUniqueEpochs := (state.keyB tI).isNone let assertConsistentKeys := (state.keyA tI).isNone || state.keyA tI == some key let keyB' := Function.update state.keyB tI (some key) set { state with stB := stB', tcurB := tsnd, exposed := exposed', keyB := keyB', msgB := msgB', nB := nB', correct := state.correct && assertMonotonicity && assertUniqueEpochs && assertConsistentKeys && assertKnownPrefix keyB' } return some (tsnd, some tI, ρ, rand)
\ORecA(n)

\begin{array}{l} \pcommentline{\text{Deliver B's message n to A}} \\ \req\;\mathsf{Msg}[\B,n]\ne\bot; \\ (\rho,t^\mathsf{snd}_\B)\gets\mathsf{Msg}[\B,n]; \\ r\getsval\RecA(\stA,\rho); \\ \pcommentline{\text{Correctness: honest delivery succeeds}} \\ \pif\;r=\bot\;\pthen\; \mathsf{correct}\gets\mathsf{false};\;\Return\bot; \\ ((t_{I_\B},I_\B),t^\mathsf{rcv}_\A,\stA')\gets r; \\ \pcommentline{\text{Correctness: receive epoch matches sender}} \\ \mathsf{assert}\;t^\mathsf{rcv}_\A=t^\mathsf{snd}_\B; \\ t^\mathsf{cur}_\A\gets \max(t^\mathsf{cur}_\A,t^\mathsf{rcv}_\A); \\ \pif\;(t_{I_\B},I_\B)\ne(\bot,\bot)\;\pthen \\ \quad\pcommentline{\text{Correctness: epoch output only once}} \\ \quad\mathsf{assert}\;\mathsf{Key}[\A,t_{I_\B}]=\bot; \\ \quad\pcommentline{\text{Correctness: keys agree when both defined}} \\ \quad\mathsf{assert}\;\mathsf{Key}[\B,t_{I_\B}]\in\{I_\B,\bot\}; \\ \quad\mathsf{Key}[\A,t_{I_\B}]\gets I_\B; \\ \pcommentline{\text{Correctness: keys known through current epoch}} \\ \mathsf{assert}\;\forall t\in\{1,\ldots,t^\mathsf{cur}_\A\},\; \mathsf{Key}[\A,t]\ne\bot; \\ \stA\gets\stA'; \\ \Return(t^\mathsf{rcv}_\A,t_{I_\B}) \end{array}

Delivery of a recorded message to A

def oracleRecvA [DecidableEq I] (scka : SCKAScheme ProbComp IK StA StB I Rho Rand) : QueryImpl (ℕ →ₒ Option (ℕ × Option ℕ)) (StateT (GameState StA StB I Rho) ProbComp) := fun (n : ℕ) => do let state ← get -- req Msg[B, n] ≠ ⊥ match state.msgB n with | none => pure none | some (ρ, tsndB) => match scka.recvA state.stA ρ with | none => -- honest delivery should succeed; failure is a correctness violation. set { state with correct := false } return none | some (keyOpt, trcv, stA') => let tcurA' := max state.tcurA trcv let assertMatchingEpoch := trcv == tsndB let assertKnownPrefix (keyA : ℕ → Option I) := (List.range (tcurA' + 1)).all (fun t => t = 0 || (keyA t).isSome) match keyOpt with | none => set { state with stA := stA', tcurA := tcurA', correct := state.correct && assertMatchingEpoch && assertKnownPrefix state.keyA } return some (trcv, none) | some (tI, key) => let assertUniqueEpochs := (state.keyA tI).isNone let assertConsistentKeys := (state.keyB tI).isNone || state.keyB tI == some key let keyA' := Function.update state.keyA tI (some key) set { state with stA := stA', tcurA := tcurA', keyA := keyA', correct := state.correct && assertMatchingEpoch && assertUniqueEpochs && assertConsistentKeys && assertKnownPrefix keyA' } return some (trcv, some tI)
\ORecB(n)

\begin{array}{l} \pcommentline{\text{Deliver A's message n to B}} \\ \req\;\mathsf{Msg}[\A,n]\ne\bot; \\ (\rho,t^\mathsf{snd}_\A)\gets\mathsf{Msg}[\A,n]; \\ r\getsval\RecB(\stB,\rho); \\ \pcommentline{\text{Correctness: honest delivery succeeds}} \\ \pif\;r=\bot\;\pthen\; \mathsf{correct}\gets\mathsf{false};\;\Return\bot; \\ ((t_{I_\A},I_\A),t^\mathsf{rcv}_\B,\stB')\gets r; \\ \pcommentline{\text{Correctness: receive epoch matches sender}} \\ \mathsf{assert}\;t^\mathsf{rcv}_\B=t^\mathsf{snd}_\A; \\ t^\mathsf{cur}_\B\gets \max(t^\mathsf{cur}_\B,t^\mathsf{rcv}_\B); \\ \pif\;(t_{I_\A},I_\A)\ne(\bot,\bot)\;\pthen \\ \quad\pcommentline{\text{Correctness: epoch output only once}} \\ \quad\mathsf{assert}\;\mathsf{Key}[\B,t_{I_\A}]=\bot; \\ \quad\pcommentline{\text{Correctness: keys agree when both defined}} \\ \quad\mathsf{assert}\;\mathsf{Key}[\A,t_{I_\A}]\in\{I_\A,\bot\}; \\ \quad\mathsf{Key}[\B,t_{I_\A}]\gets I_\A; \\ \pcommentline{\text{Correctness: keys known through current epoch}} \\ \mathsf{assert}\;\forall t\in\{1,\ldots,t^\mathsf{cur}_\B\},\; \mathsf{Key}[\B,t]\ne\bot; \\ \stB\gets\stB'; \\ \Return(t^\mathsf{rcv}_\B,t_{I_\A}) \end{array}

Delivery of a recorded message to B

def oracleRecvB [DecidableEq I] (scka : SCKAScheme ProbComp IK StA StB I Rho Rand) : QueryImpl (ℕ →ₒ Option (ℕ × Option ℕ)) (StateT (GameState StA StB I Rho) ProbComp) := fun (n : ℕ) => do let state ← get match state.msgA n with | none => pure none | some (ρ, tsndA) => match scka.recvB state.stB ρ with | none => set { state with correct := false } return none | some (keyOpt, trcv, stB') => let tcurB' := max state.tcurB trcv let assertMatchingEpoch := trcv == tsndA let assertKnownPrefix (keyB : ℕ → Option I) := (List.range (tcurB' + 1)).all (fun t => t = 0 || (keyB t).isSome) match keyOpt with | none => set { state with stB := stB', tcurB := tcurB', correct := state.correct && assertMatchingEpoch && assertKnownPrefix state.keyB } return some (trcv, none) | some (tI, key) => let assertUniqueEpochs := (state.keyB tI).isNone let assertConsistentKeys := (state.keyA tI).isNone || state.keyA tI == some key let keyB' := Function.update state.keyB tI (some key) set { state with stB := stB', tcurB := tcurB', keyB := keyB', correct := state.correct && assertMatchingEpoch && assertUniqueEpochs && assertConsistentKeys && assertKnownPrefix keyB' } return some (trcv, some tI)
\OChall(t)

\begin{array}{l} \pcommentline{\text{Return a real or random epoch key}} \\ \pcommentline{\text{Reject exposed or previously challenged epochs}} \\ \req\;t\notin\mathsf{Exposed}\cup\mathsf{Challenged}; \\ \pcommentline{\text{Use either party's derived key}} \\ \pif\;\mathsf{Key}[\A,t]\ne\bot\;\pthen \\ \quad K\gets\mathsf{Key}[\A,t]; \\ \pelse \\ \quad K\gets\mathsf{Key}[\B,t]; \\ \pcommentline{\text{A party must have derived the key}} \\ \req\;K\ne\bot; \\ \pcommentline{\text{Replace the key in the random case}} \\ \pif\;b=1\;\pthen\;K\sample I; \\ \pcommentline{\text{Record this epoch to prevent another challenge}} \\ \mathsf{Challenged}\gets\mathsf{Challenged}\cup\{t\}; \\ \Return K \end{array}

Real or random key challenge for an unexposed epoch

def oracleChall (isRandom : Bool) (StA StB I Rho : Type) [SampleableType I] : QueryImpl (ℕ →ₒ Option I) (StateT (GameState StA StB I Rho) ProbComp) := fun (t : ℕ) => do let state ← get -- req t ∉ Exposed ∪ Challenged if t ∈ state.exposed ∨ t ∈ state.challenged then pure none else let key? := match state.keyA t with | some k => some k | none => state.keyB t match key? with | none => pure none -- req K ≠ ⊥ | some k => let outK ← if isRandom then liftM ($ᵗ I : ProbComp I) else pure k set { state with challenged := insert t state.challenged } return some outK
\OCorrA

\begin{array}{l} \pcommentline{\text{Vulnerable epochs following corruption of A}} \\ \mathsf{vuln}\gets\mathsf{vuln}^{\mathsf{corr}}_\A(\stA); \\ \pcommentline{\text{Reject exposure of challenged epochs}} \\ \req\;\mathsf{vuln}\cap\mathsf{Challenged}=\emptyset; \\ \pcommentline{\text{Record exposed epochs}} \\ \mathsf{Exposed}\gets\mathsf{Exposed}\cup\mathsf{vuln}; \\ \Return\stA \end{array}

A's state-corruption oracle and exposure guard

def oracleCorruptA (vulnCorrA : StA → Finset ℕ) (StB I Rho : Type) : QueryImpl (Unit →ₒ Option StA) (StateT (GameState StA StB I Rho) ProbComp) := fun () => do let state ← get let vuln := vulnCorrA state.stA if vuln ∩ state.challenged ≠ ∅ then pure none else set { state with exposed := state.exposed ∪ vuln } return some state.stA
\OCorrB

\begin{array}{l} \pcommentline{\text{Vulnerable epochs following corruption of B}} \\ \mathsf{vuln}\gets\mathsf{vuln}^{\mathsf{corr}}_\B(\stB); \\ \pcommentline{\text{Reject exposure of challenged epochs}} \\ \req\;\mathsf{vuln}\cap\mathsf{Challenged}=\emptyset; \\ \pcommentline{\text{Record exposed epochs}} \\ \mathsf{Exposed}\gets\mathsf{Exposed}\cup\mathsf{vuln}; \\ \Return\stB \end{array}

B's state-corruption oracle and exposure guard

def oracleCorruptB (vulnCorrB : StB → Finset ℕ) (StA I Rho : Type) : QueryImpl (Unit →ₒ Option StB) (StateT (GameState StA StB I Rho) ProbComp) := fun () => do let state ← get let vuln := vulnCorrB state.stB if vuln ∩ state.challenged ≠ ∅ then pure none else set { state with exposed := state.exposed ∪ vuln } return some state.stB
\textsf{Oracle sets for correctness and security}

\Ocor=\{\mathsf{O\text{-}Unif},\OSendA,\OSendB, \ORecA(n),\ORecB(n)\}

\begin{array}{ll} \mathsf{O\text{-}Unif} & \text{Sample uniform randomness.} \\ \OSendA & \text{Trigger A to send a message to B.} \\ \OSendB & \text{Trigger B to send a message to A.} \\ \ORecA(n) & \text{Deliver B's recorded message }n\text{ to A.} \\ \ORecB(n) & \text{Deliver A's recorded message }n\text{ to B.} \end{array}

Correctness oracle interface

abbrev sckaCorrectnessSpec (Rho : Type) := unifSpec -- Uniform randomness + (Unit →ₒ Option (ℕ × Option ℕ × Rho)) -- O-Send-A + (Unit →ₒ Option (ℕ × Option ℕ × Rho)) -- O-Send-B + (ℕ →ₒ Option (ℕ × Option ℕ)) -- O-Recv-A + (ℕ →ₒ Option (ℕ × Option ℕ)) -- O-Recv-B

Correctness oracle implementation

def sckaCorrectnessImpl [DecidableEq I] (scka : SCKAScheme ProbComp IK StA StB I Rho Rand) : QueryImpl (sckaCorrectnessSpec Rho) (StateT (GameState StA StB I Rho) ProbComp) := oracleUnif StA StB I Rho + oracleSendA scka + oracleSendB scka + oracleRecvA scka + oracleRecvB scka

Correctness adversary

abbrev SCKACorrectnessAdversary (Rho : Type) := OracleComp (sckaCorrectnessSpec Rho) Bool

\Osec=\Ocor\cup \{\OSendARLeak,\OSendBRLeak,\OChall(t),\OCorrA,\OCorrB\}

In addition to \Ocor:

\begin{array}{ll} \OSendARLeak & \text{Trigger A to send and reveal the randomness used.} \\ \OSendBRLeak & \text{Trigger B to send and reveal the randomness used.} \\ \OChall(t) & \text{Real or random key challenge for epoch }t\text{.} \\ \OCorrA & \text{Reveal A's current local state.} \\ \OCorrB & \text{Reveal B's current local state.} \end{array}

Security oracle interface

abbrev sckaSecuritySpec (StA StB I Rho Rand : Type) := sckaCorrectnessSpec Rho + (Unit →ₒ Option (ℕ × Option ℕ × Rho × Rand)) -- O-Send-A-rleak + (Unit →ₒ Option (ℕ × Option ℕ × Rho × Rand)) -- O-Send-B-rleak + (ℕ →ₒ Option I) -- O-Chall t + (Unit →ₒ Option StA) -- O-Corrupt-A + (Unit →ₒ Option StB) -- O-Corrupt-B

Security oracle implementation

def sckaSecurityImpl (isRandom : Bool) (vulnA : VulnerableEpochs StA Rand) (vulnB : VulnerableEpochs StB Rand) [SampleableType I] [DecidableEq I] (scka : SCKAScheme ProbComp IK StA StB I Rho Rand) : QueryImpl (sckaSecuritySpec StA StB I Rho Rand) (StateT (GameState StA StB I Rho) ProbComp) := sckaCorrectnessImpl scka + oracleSendArleak vulnA.rleak scka + oracleSendBrleak vulnB.rleak scka + oracleChall isRandom StA StB I Rho + oracleCorruptA vulnA.corrupt StB I Rho + oracleCorruptB vulnB.corrupt StA I Rho

Security adversary

abbrev SCKAAdversary (StA StB I Rho Rand : Type) := OracleComp (sckaSecuritySpec StA StB I Rho Rand) Bool
\textsf{Illustration: adversarial scheduling and vulnerable epochs}
Party AParty B Init-A Init-KeyGen Init-B II Adversary 𝒜 O-Corr-A stA stA Exposed ← Exposed ∪ vulnAcorr(stA) stst stst stst stst stst stst ρA,3 hold deliver second ρA,1 ρA,1 ρA,2 deliver first ρB,1, r drop message; retain randomness Exposed ← Exposed ∪ vulnBrleak(stB,r) ρB,2 ρB,3 O-Send-A Send-A O-Send-A Send-A O-Rec-B(2) Rec-B O-Rec-B(1) Rec-B O-Send-A Send-A O-Rec-B(3) Rec-B O-Send-B-rleak Send-B-rleak O-Send-B Send-B O-Rec-A(2) Rec-A O-Send-B Send-B O-Rec-A(3) Rec-A (t, I) (t, I) K O-Chall(t) K = I or random I′ requires t ∉ Exposed ∪ Challenged
Lean code for Definition9.1.2●17 definitions
  • structure(2 fields)defined in SecureMessaging/SCKA/Defs.lean
    complete
    structure SCKAScheme.VulnerableEpochs (St Rand : Type) : Type
    structure SCKAScheme.VulnerableEpochs
      (St Rand : Type) : Type
    Vulnerable epochs of one party: the sets of epochs that the security game excludes from
    challenges once material of the party is revealed, by state exposure or by randomness leakage.
    They should contain every epoch whose key becomes computable from the revealed material and may
    over-approximate it (cf. Remark 3.2 of [SCKA]). 
    corrupt : St → Finset ℕ
    Vulnerable epochs following state exposure. 
    rleak : St → Rand → Finset ℕ
    Vulnerable epochs following randomness leakage, for the coins of a send from the
    given state. 
  • structure(13 fields)defined in SecureMessaging/SCKA/Defs.lean
    complete
    structure SCKAScheme.GameState (StA StB I Rho : Type) : Type
    structure SCKAScheme.GameState
      (StA StB I Rho : Type) : Type
    Internal state of the SCKA game.
    
    - `stA`, `stB`: per-party protocol state.
    - `keyA`, `keyB`: tables with epoch keys derived by each party.
    - `msgA`, `msgB`: arrays storing sent messages and their epochs.
    - `nA`, `nB`: per-party send counters (number of messages sent so far).
    - `tcurA`, `tcurB`: per-party current epoch (latest usable epoch).
    - `exposed`: epochs exposed by corruption or randomness leakage.
    - `challenged`: epochs whose challenges were successfully answered.
    - `correct`: whether all correctness properties have held so far. 
    stA : StA
    Local protocol state for party A. 
    stB : StB
    Local protocol state for party B. 
    keyA : ℕ → Option I
    Key table for A: `Key[A, t]`. 
    keyB : ℕ → Option I
    Key table for B: `Key[B, t]`. 
    msgA : ℕ → Option (Rho × ℕ)
    Transit array for A's messages: `Msg[A, n] = (ρ, t^snd)`. 
    msgB : ℕ → Option (Rho × ℕ)
    Transit array for B's messages: `Msg[B, n] = (ρ, t^snd)`. 
    nA : ℕ
    Number of messages A has sent. 
    nB : ℕ
    Number of messages B has sent. 
    tcurA : ℕ
    A's current epoch `t^cur_A`. 
    tcurB : ℕ
    B's current epoch `t^cur_B`. 
    exposed : Finset ℕ
    Epochs exposed through corruption or randomness leakage. 
    challenged : Finset ℕ
    Epochs whose challenges were successfully answered. 
    correct : Bool
    Whether all correctness asserts have held so far. 
  • complete
    def SCKAScheme.oracleSendA {IK StA StB I Rho Rand : Type} [DecidableEq I]
      (scka : SCKAScheme ProbComp IK StA StB I Rho Rand) :
      QueryImpl (OracleSpec.ofFn fun x ↦ Option (ℕ × Option ℕ × Rho))
        (StateT (SCKAScheme.GameState StA StB I Rho) ProbComp)
    def SCKAScheme.oracleSendA
      {IK StA StB I Rho Rand : Type}
      [DecidableEq I]
      (scka :
        SCKAScheme ProbComp IK StA StB I Rho
          Rand) :
      QueryImpl
        (OracleSpec.ofFn fun x ↦
          Option (ℕ × Option ℕ × Rho))
        (StateT
          (SCKAScheme.GameState StA StB I Rho)
          ProbComp)
    **O-Send-A** (plain, `rleak = 0`).
    ```text
    Send-A:
      ((tIA, IA), ρ, t^snd_A, stA) ←$ scka.sendA(stA)
      assert t^snd_A ≥ t^cur_A          -- monotonicity
      t^cur_A ← t^snd_A
      if (tIA, IA) ≠ (⊥, ⊥):            -- new key derived
         assert Key[A, tIA] = ⊥         -- unique epochs
         assert Key[B, tIA] ∈ {IA, ⊥}   -- consistent keys
         Key[A, tIA] ← IA
      assert ∀ t ≤ t^snd_A : Key[A, t] ≠ ⊥     -- known prefix
      Msg[A, ++nA] ← (ρ, t^snd_A)
      return (t^snd_A, tIA, ρ)
    ``` 
  • complete
    def SCKAScheme.oracleSendB {IK StA StB I Rho Rand : Type} [DecidableEq I]
      (scka : SCKAScheme ProbComp IK StA StB I Rho Rand) :
      QueryImpl (OracleSpec.ofFn fun x ↦ Option (ℕ × Option ℕ × Rho))
        (StateT (SCKAScheme.GameState StA StB I Rho) ProbComp)
    def SCKAScheme.oracleSendB
      {IK StA StB I Rho Rand : Type}
      [DecidableEq I]
      (scka :
        SCKAScheme ProbComp IK StA StB I Rho
          Rand) :
      QueryImpl
        (OracleSpec.ofFn fun x ↦
          Option (ℕ × Option ℕ × Rho))
        (StateT
          (SCKAScheme.GameState StA StB I Rho)
          ProbComp)
    **O-Send-B** (plain, `rleak = 0`).
    ```text
    Send-B:
      ((tIB, IB), ρ, t^snd_B, stB) ←$ scka.sendB(stB)
      assert t^snd_B ≥ t^cur_B                  -- monotonicity
      t^cur_B ← t^snd_B
      if (tIB, IB) ≠ (⊥, ⊥):                   -- new key derived
         assert Key[B, tIB] = ⊥               -- unique epochs
         assert Key[A, tIB] ∈ {IB, ⊥}         -- consistent keys
         Key[B, tIB] ← IB
      assert ∀ t ≤ t^snd_B : Key[B, t] ≠ ⊥    -- known prefix
      Msg[B, ++nB] ← (ρ, t^snd_B)
      return (t^snd_B, tIB, ρ)
    ``` 
  • complete
    def SCKAScheme.oracleSendArleak {IK StA StB I Rho Rand : Type}
      [DecidableEq I] (vulnRleakA : StA → Rand → Finset ℕ)
      (scka : SCKAScheme ProbComp IK StA StB I Rho Rand) :
      QueryImpl (OracleSpec.ofFn fun x ↦ Option (ℕ × Option ℕ × Rho × Rand))
        (StateT (SCKAScheme.GameState StA StB I Rho) ProbComp)
    def SCKAScheme.oracleSendArleak
      {IK StA StB I Rho Rand : Type}
      [DecidableEq I]
      (vulnRleakA : StA → Rand → Finset ℕ)
      (scka :
        SCKAScheme ProbComp IK StA StB I Rho
          Rand) :
      QueryImpl
        (OracleSpec.ofFn fun x ↦
          Option (ℕ × Option ℕ × Rho × Rand))
        (StateT
          (SCKAScheme.GameState StA StB I Rho)
          ProbComp)
    **O-Send-A-rleak** (`rleak = 1`).
    Run `sendArleak`. For a successful output with state `stA'` and coins `rand`,
    compute `E = vulnRleakA stA rand` and require `E ∩ Challenged = ∅`.
    Acceptance records the send, adds `E` to `Exposed`, and returns the coins.
    Rejection returns `none` and retains the game state.
    
    ```text
    Send-A-rleak:
      ((tIA, IA), ρ, t^snd_A, stA', rand) ←$ scka.sendArleak(stA)
      E ← vulnRleakA(stA, rand)
      req  E ∩ Challenged = ∅
      Exposed ← Exposed ∪ E
      assert t^snd_A ≥ t^cur_A                -- monotonicity
      t^cur_A ← t^snd_A
      if (tIA, IA) ≠ (⊥, ⊥):
         assert Key[A, tIA] = ⊥               -- unique epochs
         assert Key[B, tIA] ∈ {IA, ⊥}         -- consistent keys
         Key[A, tIA] ← IA
      assert ∀ t ≤ t^snd_A : Key[A, t] ≠ ⊥    -- known prefix
      Msg[A, ++nA] ← (ρ, t^snd_A)
      stA ← stA'
      return (t^snd_A, tIA, ρ, rand)
    ``` 
  • complete
    def SCKAScheme.oracleSendBrleak {IK StA StB I Rho Rand : Type}
      [DecidableEq I] (vulnRleakB : StB → Rand → Finset ℕ)
      (scka : SCKAScheme ProbComp IK StA StB I Rho Rand) :
      QueryImpl (OracleSpec.ofFn fun x ↦ Option (ℕ × Option ℕ × Rho × Rand))
        (StateT (SCKAScheme.GameState StA StB I Rho) ProbComp)
    def SCKAScheme.oracleSendBrleak
      {IK StA StB I Rho Rand : Type}
      [DecidableEq I]
      (vulnRleakB : StB → Rand → Finset ℕ)
      (scka :
        SCKAScheme ProbComp IK StA StB I Rho
          Rand) :
      QueryImpl
        (OracleSpec.ofFn fun x ↦
          Option (ℕ × Option ℕ × Rho × Rand))
        (StateT
          (SCKAScheme.GameState StA StB I Rho)
          ProbComp)
    **O-Send-B-rleak** (`rleak = 1`).
    Run `sendBrleak`. For a successful output with state `stB'` and coins `rand`,
    compute `E = vulnRleakB stB rand` and require `E ∩ Challenged = ∅`.
    Acceptance records the send, adds `E` to `Exposed`, and returns the coins.
    Rejection returns `none` and retains the game state.
    
    ```text
    Send-B-rleak:
      ((tIB, IB), ρ, t^snd_B, stB', rand) ←$ scka.sendBrleak(stB)
      E ← vulnRleakB(stB, rand)
      req  E ∩ Challenged = ∅
      Exposed ← Exposed ∪ E
      assert t^snd_B ≥ t^cur_B              -- monotonicity
      t^cur_B ← t^snd_B
      if (tIB, IB) ≠ (⊥, ⊥):
         assert Key[B, tIB] = ⊥              -- unique epochs
         assert Key[A, tIB] ∈ {IB, ⊥}        -- consistent keys
         Key[B, tIB] ← IB
      assert ∀ t ≤ t^snd_B : Key[B, t] ≠ ⊥   -- known prefix
      Msg[B, ++nB] ← (ρ, t^snd_B)
      stB ← stB'
      return (t^snd_B, tIB, ρ, rand)
    ``` 
  • complete
    def SCKAScheme.oracleRecvA {IK StA StB I Rho Rand : Type} [DecidableEq I]
      (scka : SCKAScheme ProbComp IK StA StB I Rho Rand) :
      QueryImpl (OracleSpec.ofFn fun x ↦ Option (ℕ × Option ℕ))
        (StateT (SCKAScheme.GameState StA StB I Rho) ProbComp)
    def SCKAScheme.oracleRecvA
      {IK StA StB I Rho Rand : Type}
      [DecidableEq I]
      (scka :
        SCKAScheme ProbComp IK StA StB I Rho
          Rand) :
      QueryImpl
        (OracleSpec.ofFn fun x ↦
          Option (ℕ × Option ℕ))
        (StateT
          (SCKAScheme.GameState StA StB I Rho)
          ProbComp)
    **O-Recv-A n.**
    Deliver `Msg[B, n]` to A (`req Msg[B, n] ≠ ⊥`), run A's receive, check the matching
    epoch and key correctness asserts, and return `(t^rcv, t_I?)`.
    
    ```text
    Receive-A(n):
     1  req Msg[B, n] ≠ ⊥
     2  (ρ, t^snd_B) ← Msg[B, n]
     3  ((tIB, IB), t^rcv_A, stA) ← scka.recvA(stA, ρ)
     4  assert t^rcv_A = t^snd_B        -- matching epoch
     5  t^cur_A ← max(t^cur_A, t^rcv_A)
     6  if (tIB, IB) ≠ (⊥, ⊥):          -- new key derived
     7     assert Key[A, tIB] = ⊥       -- unique epochs
     8     assert Key[B, tIB] ∈ {IB, ⊥}        -- consistent keys
     9     Key[A, tIB] ← IB
    10  assert ∀ t ≤ t^cur_A : Key[A, t] ≠ ⊥   -- known prefix
    11  return (t^rcv_A, tIB)
    ``` 
  • complete
    def SCKAScheme.oracleRecvB {IK StA StB I Rho Rand : Type} [DecidableEq I]
      (scka : SCKAScheme ProbComp IK StA StB I Rho Rand) :
      QueryImpl (OracleSpec.ofFn fun x ↦ Option (ℕ × Option ℕ))
        (StateT (SCKAScheme.GameState StA StB I Rho) ProbComp)
    def SCKAScheme.oracleRecvB
      {IK StA StB I Rho Rand : Type}
      [DecidableEq I]
      (scka :
        SCKAScheme ProbComp IK StA StB I Rho
          Rand) :
      QueryImpl
        (OracleSpec.ofFn fun x ↦
          Option (ℕ × Option ℕ))
        (StateT
          (SCKAScheme.GameState StA StB I Rho)
          ProbComp)
    **O-Recv-B n.**
    Deliver `Msg[A, n]` to B (`req Msg[A, n] ≠ ⊥`), run B's receive, check the matching
    epoch and key correctness asserts, and return `(t^rcv, t_I?)`.
    
    ```text
    Receive-B(n):
     1  req Msg[A, n] ≠ ⊥
     2  (ρ, t^snd_A) ← Msg[A, n]
     3  ((tIA, IA), t^rcv_B, stB) ← scka.recvB(stB, ρ)
     4  assert t^rcv_B = t^snd_A      -- matching epoch
     5  t^cur_B ← max(t^cur_B, t^rcv_B)
     6  if (tIA, IA) ≠ (⊥, ⊥):
     7     assert Key[B, tIA] = ⊥       -- unique epochs
     8     assert Key[A, tIA] ∈ {IA, ⊥}        -- consistent keys
     9     Key[B, tIA] ← IA
    10  assert ∀ t ≤ t^cur_B : Key[B, t] ≠ ⊥   -- known prefix
    11  return (t^rcv_B, tIA)
    ``` 
  • complete
    def SCKAScheme.oracleChall (isRandom : Bool) (StA StB I Rho : Type)
      [SampleableType I] :
      QueryImpl (OracleSpec.ofFn fun x ↦ Option I)
        (StateT (SCKAScheme.GameState StA StB I Rho) ProbComp)
    def SCKAScheme.oracleChall (isRandom : Bool)
      (StA StB I Rho : Type)
      [SampleableType I] :
      QueryImpl
        (OracleSpec.ofFn fun x ↦ Option I)
        (StateT
          (SCKAScheme.GameState StA StB I Rho)
          ProbComp)
    **O-Chall t.**
    `req t ∉ Exposed ∪ Challenged`; take the recorded key for epoch `t`;
    return the real key (`isRandom = false`) or a
    freshly sampled uniform key (`isRandom = true`); record `t` as challenged.
    
    ```text
    Chall(t):
     1  req t ∉ Exposed ∪ Challenged
     2  if Key[A, t] ≠ ⊥:  K ← Key[A, t]
     4  else            :  K ← Key[B, t]
     5  req K ≠ ⊥
     6  if b = 1:  K ←$ I                               // replace with random key
     8  Challenged ← Challenged ∪ {t}
     9  return K
    ``` 
  • complete
    def SCKAScheme.oracleCorruptA {StA : Type} (vulnCorrA : StA → Finset ℕ)
      (StB I Rho : Type) :
      QueryImpl (OracleSpec.ofFn fun x ↦ Option StA)
        (StateT (SCKAScheme.GameState StA StB I Rho) ProbComp)
    def SCKAScheme.oracleCorruptA {StA : Type}
      (vulnCorrA : StA → Finset ℕ)
      (StB I Rho : Type) :
      QueryImpl
        (OracleSpec.ofFn fun x ↦ Option StA)
        (StateT
          (SCKAScheme.GameState StA StB I Rho)
          ProbComp)
    **O-Corrupt-A.**
    `req vulnCorrA(stA) ∩ Challenged = ∅`; expose `vulnCorrA(stA)`; return A's state.
    
    ```text
    Corr-A():
     1  req vulnCorrA(stA) ∩ Challenged = ∅                    // no challenge of a vulnerable epoch
     2  Exposed ← Exposed ∪ vulnCorrA(stA)
     3  return stA
    ``` 
  • complete
    def SCKAScheme.oracleCorruptB {StB : Type} (vulnCorrB : StB → Finset ℕ)
      (StA I Rho : Type) :
      QueryImpl (OracleSpec.ofFn fun x ↦ Option StB)
        (StateT (SCKAScheme.GameState StA StB I Rho) ProbComp)
    def SCKAScheme.oracleCorruptB {StB : Type}
      (vulnCorrB : StB → Finset ℕ)
      (StA I Rho : Type) :
      QueryImpl
        (OracleSpec.ofFn fun x ↦ Option StB)
        (StateT
          (SCKAScheme.GameState StA StB I Rho)
          ProbComp)
    **O-Corrupt-B.**
    `req vulnCorrB(stB) ∩ Challenged = ∅`; expose `vulnCorrB(stB)`; return B's state.
    
    ```text
    Corr-B():
     1  req vulnCorrB(stB) ∩ Challenged = ∅                    // no challenge of a vulnerable epoch
     2  Exposed ← Exposed ∪ vulnCorrB(stB)
     3  return stB
    ``` 
  • complete
    abbrev SCKAScheme.sckaCorrectnessSpec (Rho : Type) :
      OracleSpec ((((ℕ ⊕ Unit) ⊕ Unit) ⊕ ℕ) ⊕ ℕ)
    abbrev SCKAScheme.sckaCorrectnessSpec
      (Rho : Type) :
      OracleSpec
        ((((ℕ ⊕ Unit) ⊕ Unit) ⊕ ℕ) ⊕ ℕ)
    Oracle spec for the SCKA correctness game: uniform randomness, send and receive oracles. 
  • complete
    def SCKAScheme.sckaCorrectnessImpl {IK StA StB I Rho Rand : Type}
      [DecidableEq I] (scka : SCKAScheme ProbComp IK StA StB I Rho Rand) :
      QueryImpl (SCKAScheme.sckaCorrectnessSpec Rho)
        (StateT (SCKAScheme.GameState StA StB I Rho) ProbComp)
    def SCKAScheme.sckaCorrectnessImpl
      {IK StA StB I Rho Rand : Type}
      [DecidableEq I]
      (scka :
        SCKAScheme ProbComp IK StA StB I Rho
          Rand) :
      QueryImpl
        (SCKAScheme.sckaCorrectnessSpec Rho)
        (StateT
          (SCKAScheme.GameState StA StB I Rho)
          ProbComp)
    Oracle set for the SCKA correctness game: uniform randomness, plain send oracles,
    and receive oracles. 
  • complete
    abbrev SCKAScheme.SCKACorrectnessAdversary (Rho : Type) : Type
    abbrev SCKAScheme.SCKACorrectnessAdversary
      (Rho : Type) : Type
    SCKA correctness adversary: access to the restricted send/receive oracles. 
  • complete
    abbrev SCKAScheme.sckaSecuritySpec (StA StB I Rho Rand : Type) :
      OracleSpec
        (((((((((ℕ ⊕ Unit) ⊕ Unit) ⊕ ℕ) ⊕ ℕ) ⊕ Unit) ⊕ Unit) ⊕ ℕ) ⊕ Unit) ⊕
          Unit)
    abbrev SCKAScheme.sckaSecuritySpec
      (StA StB I Rho Rand : Type) :
      OracleSpec
        (((((((((ℕ ⊕ Unit) ⊕ Unit) ⊕ ℕ) ⊕ ℕ) ⊕
                  Unit) ⊕
                Unit) ⊕
              ℕ) ⊕
            Unit) ⊕
          Unit)
    Oracle spec for the SCKA security game: the correctness spec extended with the
    randomness-leaking send oracles, the challenge oracle, and the corruption oracles. 
  • complete
    def SCKAScheme.sckaSecurityImpl {IK StA StB I Rho Rand : Type}
      (isRandom : Bool) (vulnA : SCKAScheme.VulnerableEpochs StA Rand)
      (vulnB : SCKAScheme.VulnerableEpochs StB Rand) [SampleableType I]
      [DecidableEq I] (scka : SCKAScheme ProbComp IK StA StB I Rho Rand) :
      QueryImpl (SCKAScheme.sckaSecuritySpec StA StB I Rho Rand)
        (StateT (SCKAScheme.GameState StA StB I Rho) ProbComp)
    def SCKAScheme.sckaSecurityImpl
      {IK StA StB I Rho Rand : Type}
      (isRandom : Bool)
      (vulnA :
        SCKAScheme.VulnerableEpochs StA Rand)
      (vulnB :
        SCKAScheme.VulnerableEpochs StB Rand)
      [SampleableType I] [DecidableEq I]
      (scka :
        SCKAScheme ProbComp IK StA StB I Rho
          Rand) :
      QueryImpl
        (SCKAScheme.sckaSecuritySpec StA StB I
          Rho Rand)
        (StateT
          (SCKAScheme.GameState StA StB I Rho)
          ProbComp)
    SCKA security oracles (Figure 1): ordinary sends and receives, randomness-leaking sends,
    challenges, and corruptions. Eligible challenges return recorded keys if `isRandom = false`
    and independent uniform keys if `isRandom = true`. 
  • complete
    abbrev SCKAScheme.SCKAAdversary (StA StB I Rho Rand : Type) : Type
    abbrev SCKAScheme.SCKAAdversary
      (StA StB I Rho Rand : Type) : Type
    SCKA security adversary: access to all oracles of `sckaSecuritySpec`. 
Definition9.1.3
Group: SCKA. (3)
Group member previews
Preview
Definition 9.1.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
Statement uses 2
Statement dependency previews
Preview
Definition 9.1.1
Loading preview
Statement dependency preview content is loaded from the rendered-fragment cache.
Used by 5
Reverse dependency previews
Preview
Theorem 9.2.2
Loading preview
Reverse dependency preview content is loaded from the rendered-fragment cache.
✓L∃∀N
\Exp{\textsf{cor}}{\textsf{SCKA}}(\adv)

\begin{array}{l} \pcommentline{\text{Check correctness under adversarial scheduling}} \\ \pcommentline{\text{Initialize both parties with a shared key}} \\ ik\sample\mathsf{InitKeyGen}(); \\ \stA\sample\InitA(ik);\quad\stB\sample\InitB(ik); \\ \pcommentline{\text{Initialize the game records}} \\ \mathsf{Key}[P,t]\gets\bot;\quad\mathsf{Msg}[P,n]\gets\bot; \\ n_\A,n_\B,t^\mathsf{cur}_\A,t^\mathsf{cur}_\B\gets0; \\ \mathsf{Exposed},\mathsf{Challenged}\gets\emptyset;\quad \mathsf{correct}\gets\mathsf{true}; \\ \pcommentline{\text{Let the adversary schedule sends and deliveries}} \\ (\_,\mathsf{state})\getsval\adv^{\Ocor}; \\ \pcommentline{\text{Accept iff all correctness conditions held}} \\ \Return\mathsf{state.correct} \end{array}

Correctness experiment

def correctnessExp [DecidableEq I] (scka : SCKAScheme ProbComp IK StA StB I Rho Rand) (adversary : SCKACorrectnessAdversary Rho) : ProbComp Bool := do let ik ← scka.initKeyGen let stA ← scka.initA ik let stB ← scka.initB ik let (_, state) ← (simulateQ (sckaCorrectnessImpl scka) adversary).run (initGameState stA stB) return state.correct
Lean code for Definition9.1.3●1 definition
  • complete
    def SCKAScheme.correctnessExp {IK StA StB I Rho Rand : Type} [DecidableEq I]
      (scka : SCKAScheme ProbComp IK StA StB I Rho Rand)
      (adversary : SCKAScheme.SCKACorrectnessAdversary Rho) : ProbComp Bool
    def SCKAScheme.correctnessExp
      {IK StA StB I Rho Rand : Type}
      [DecidableEq I]
      (scka :
        SCKAScheme ProbComp IK StA StB I Rho
          Rand)
      (adversary :
        SCKAScheme.SCKACorrectnessAdversary
          Rho) :
      ProbComp Bool
    **Correctness experiment** (§3.1 of [SCKA]).
    Run the adversary against the restricted send/receive oracles and return whether
    all correctness invariants (Monotonicity, Matching epoch, Unique epochs,
    Consistent keys, Known prefix) held throughout. 
Definition9.1.4
Group: SCKA. (3)
Group member previews
Preview
Definition 9.1.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
Statement uses 2
Statement dependency previews
Preview
Definition 9.1.1
Loading preview
Statement dependency preview content is loaded from the rendered-fragment cache.
Used by 5
Reverse dependency previews
Preview
Theorem 9.2.4
Loading preview
Reverse dependency preview content is loaded from the rendered-fragment cache.
✓L∃∀N
\Exp{\textsf{sec}}{\textsf{SCKA}}(\adv)

\begin{array}{l} \pcommentline{\text{Distinguish real epoch keys from random keys}} \\ \pcommentline{\text{Initialize both parties with a shared key}} \\ ik\sample\mathsf{InitKeyGen}(); \\ \stA\sample\InitA(ik);\quad\stB\sample\InitB(ik); \\ \pcommentline{\text{Initialize the game records}} \\ \mathsf{Key}[P,t]\gets\bot;\quad\mathsf{Msg}[P,n]\gets\bot; \\ n_\A,n_\B,t^\mathsf{cur}_\A,t^\mathsf{cur}_\B\gets0; \\ \mathsf{Exposed},\mathsf{Challenged}\gets\emptyset;\quad \mathsf{correct}\gets\mathsf{true}; \\ \pcommentline{b=0:\text{ real keys; }b=1:\text{ random keys}} \\ b\sample\{0,1\}; \\ \pcommentline{\text{Run the adversary with the security oracles}} \\ (b',\_)\getsval\adv^{\Osec}; \\ \pcommentline{\text{Accept iff the adversary guesses the hidden bit}} \\ \Return[b'=b] \end{array}

Security experiment

def securityExp [SampleableType I] [DecidableEq I] (scka : SCKAScheme ProbComp IK StA StB I Rho Rand) (adversary : SCKAAdversary StA StB I Rho Rand) (vulnA : VulnerableEpochs StA Rand) (vulnB : VulnerableEpochs StB Rand) : ProbComp Bool := do let ik ← scka.initKeyGen let stA ← scka.initA ik let stB ← scka.initB ik let b ← $ᵗ Bool let (b', _) ← (simulateQ (sckaSecurityImpl b vulnA vulnB scka) adversary).run (initGameState stA stB) return (b == b')

\mathsf{Adv}^{\mathsf{guess}}_{\mathsf{SCKA}}(\adv) =\left|\Pr\left[\Exp{\mathsf{sec}}{\mathsf{SCKA}}(\adv)=1\right] -\frac12\right| =\left|\Pr[b'=b]-\frac12\right|

Guessing advantage

noncomputable def sckaGuessAdvantage [SampleableType I] [DecidableEq I] (scka : SCKAScheme ProbComp IK StA StB I Rho Rand) (adversary : SCKAAdversary StA StB I Rho Rand) (vulnA : VulnerableEpochs StA Rand) (vulnB : VulnerableEpochs StB Rand) : ℝ := |(Pr[= true | securityExp scka adversary vulnA vulnB]).toReal - 1 / 2|
Lean code for Definition9.1.4●2 definitions
  • complete
    def SCKAScheme.securityExp {IK StA StB I Rho Rand : Type} [SampleableType I]
      [DecidableEq I] (scka : SCKAScheme ProbComp IK StA StB I Rho Rand)
      (adversary : SCKAScheme.SCKAAdversary StA StB I Rho Rand)
      (vulnA : SCKAScheme.VulnerableEpochs StA Rand)
      (vulnB : SCKAScheme.VulnerableEpochs StB Rand) : ProbComp Bool
    def SCKAScheme.securityExp
      {IK StA StB I Rho Rand : Type}
      [SampleableType I] [DecidableEq I]
      (scka :
        SCKAScheme ProbComp IK StA StB I Rho
          Rand)
      (adversary :
        SCKAScheme.SCKAAdversary StA StB I Rho
          Rand)
      (vulnA :
        SCKAScheme.VulnerableEpochs StA Rand)
      (vulnB :
        SCKAScheme.VulnerableEpochs StB
          Rand) :
      ProbComp Bool
    **Security experiment** (Fig. 1).
    Initialize both parties, sample a challenge bit, run the adversary with the full
    game oracles, and return whether it guessed the bit. 
  • complete
    def SCKAScheme.sckaGuessAdvantage {IK StA StB I Rho Rand : Type}
      [SampleableType I] [DecidableEq I]
      (scka : SCKAScheme ProbComp IK StA StB I Rho Rand)
      (adversary : SCKAScheme.SCKAAdversary StA StB I Rho Rand)
      (vulnA : SCKAScheme.VulnerableEpochs StA Rand)
      (vulnB : SCKAScheme.VulnerableEpochs StB Rand) : ℝ
    def SCKAScheme.sckaGuessAdvantage
      {IK StA StB I Rho Rand : Type}
      [SampleableType I] [DecidableEq I]
      (scka :
        SCKAScheme ProbComp IK StA StB I Rho
          Rand)
      (adversary :
        SCKAScheme.SCKAAdversary StA StB I Rho
          Rand)
      (vulnA :
        SCKAScheme.VulnerableEpochs StA Rand)
      (vulnB :
        SCKAScheme.VulnerableEpochs StB
          Rand) :
      ℝ
    SCKA guess advantage: `|Pr[Win] - 1/2|`.