9.1. SCKA Definitions
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}
|
|
\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
| Party B
|
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
Associated Lean declarations
-
SCKAScheme[complete]
-
SCKAScheme[complete]
-
structuredefined in SecureMessaging/SCKA/Defs.leancomplete
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.
Fields
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.
-
SCKAScheme.VulnerableEpochs[complete] -
SCKAScheme.GameState[complete] -
SCKAScheme.oracleSendA[complete] -
SCKAScheme.oracleSendB[complete] -
SCKAScheme.oracleSendArleak[complete] -
SCKAScheme.oracleSendBrleak[complete] -
SCKAScheme.oracleRecvA[complete] -
SCKAScheme.oracleRecvB[complete] -
SCKAScheme.oracleChall[complete] -
SCKAScheme.oracleCorruptA[complete] -
SCKAScheme.oracleCorruptB[complete] -
SCKAScheme.sckaCorrectnessSpec[complete] -
SCKAScheme.sckaCorrectnessImpl[complete] -
SCKAScheme.SCKACorrectnessAdversary[complete] -
SCKAScheme.sckaSecuritySpec[complete] -
SCKAScheme.sckaSecurityImpl[complete] -
SCKAScheme.SCKAAdversary[complete]
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 randomnessr\in R_Xof 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}\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 epocht, 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}: epochstfor 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-BCorrectness 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 sckaCorrectness 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-BSecurity 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 RhoSecurity adversary
abbrev SCKAAdversary (StA StB I Rho Rand : Type) :=
OracleComp (sckaSecuritySpec StA StB I Rho Rand) Bool\textsf{Illustration: adversarial scheduling and vulnerable epochs}Lean code for Definition9.1.2●17 definitions
Associated Lean declarations
-
SCKAScheme.VulnerableEpochs[complete]
-
SCKAScheme.GameState[complete]
-
SCKAScheme.oracleSendA[complete]
-
SCKAScheme.oracleSendB[complete]
-
SCKAScheme.oracleSendArleak[complete]
-
SCKAScheme.oracleSendBrleak[complete]
-
SCKAScheme.oracleRecvA[complete]
-
SCKAScheme.oracleRecvB[complete]
-
SCKAScheme.oracleChall[complete]
-
SCKAScheme.oracleCorruptA[complete]
-
SCKAScheme.oracleCorruptB[complete]
-
SCKAScheme.sckaCorrectnessSpec[complete]
-
SCKAScheme.sckaCorrectnessImpl[complete]
-
SCKAScheme.SCKACorrectnessAdversary[complete]
-
SCKAScheme.sckaSecuritySpec[complete]
-
SCKAScheme.sckaSecurityImpl[complete]
-
SCKAScheme.SCKAAdversary[complete]
-
SCKAScheme.VulnerableEpochs[complete] -
SCKAScheme.GameState[complete] -
SCKAScheme.oracleSendA[complete] -
SCKAScheme.oracleSendB[complete] -
SCKAScheme.oracleSendArleak[complete] -
SCKAScheme.oracleSendBrleak[complete] -
SCKAScheme.oracleRecvA[complete] -
SCKAScheme.oracleRecvB[complete] -
SCKAScheme.oracleChall[complete] -
SCKAScheme.oracleCorruptA[complete] -
SCKAScheme.oracleCorruptB[complete] -
SCKAScheme.sckaCorrectnessSpec[complete] -
SCKAScheme.sckaCorrectnessImpl[complete] -
SCKAScheme.SCKACorrectnessAdversary[complete] -
SCKAScheme.sckaSecuritySpec[complete] -
SCKAScheme.sckaSecurityImpl[complete] -
SCKAScheme.SCKAAdversary[complete]
-
structuredefined in SecureMessaging/SCKA/Defs.leancomplete
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]).
Fields
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.
-
structuredefined in SecureMessaging/SCKA/Defs.leancomplete
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.
Fields
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.
-
defdefined in SecureMessaging/SCKA/Defs.leancomplete
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, ρ) ``` -
defdefined in SecureMessaging/SCKA/Defs.leancomplete
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, ρ) ``` -
defdefined in SecureMessaging/SCKA/Defs.leancomplete
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) ``` -
defdefined in SecureMessaging/SCKA/Defs.leancomplete
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) ``` -
defdefined in SecureMessaging/SCKA/Defs.leancomplete
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) ``` -
defdefined in SecureMessaging/SCKA/Defs.leancomplete
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) ``` -
defdefined in SecureMessaging/SCKA/Defs.leancomplete
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 ``` -
defdefined in SecureMessaging/SCKA/Defs.leancomplete
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 ```
-
defdefined in SecureMessaging/SCKA/Defs.leancomplete
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 ```
-
abbrevdefined in SecureMessaging/SCKA/Defs.leancomplete
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.
-
defdefined in SecureMessaging/SCKA/Defs.leancomplete
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.
-
abbrevdefined in SecureMessaging/SCKA/Defs.leancomplete
abbrev SCKAScheme.SCKACorrectnessAdversary (Rho : Type) : Type
abbrev SCKAScheme.SCKACorrectnessAdversary (Rho : Type) : Type
SCKA correctness adversary: access to the restricted send/receive oracles.
-
abbrevdefined in SecureMessaging/SCKA/Defs.leancomplete
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.
-
defdefined in SecureMessaging/SCKA/Defs.leancomplete
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`.
-
abbrevdefined in SecureMessaging/SCKA/Defs.leancomplete
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`.
\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.correctLean code for Definition9.1.3●1 definition
Associated Lean declarations
-
SCKAScheme.correctnessExp[complete]
-
SCKAScheme.correctnessExp[complete]
-
defdefined in SecureMessaging/SCKA/Defs.leancomplete
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.
-
SCKAScheme.securityExp[complete] -
SCKAScheme.sckaGuessAdvantage[complete]
\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
Associated Lean declarations
-
SCKAScheme.securityExp[complete]
-
SCKAScheme.sckaGuessAdvantage[complete]
-
SCKAScheme.securityExp[complete] -
SCKAScheme.sckaGuessAdvantage[complete]
-
defdefined in SecureMessaging/SCKA/Defs.leancomplete
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.
-
defdefined in SecureMessaging/SCKA/Defs.leancomplete
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|`.