Secure Messaging

9.3. Opp-BiKEM-CKA🔗

Definition9.3.1
Group: Opp-BiKEM-CKA. (2)
Group member previews
Preview
Theorem 9.3.2
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
Statement uses 2
Statement dependency previews
Preview
Definition 4.1.1
Loading preview
Statement dependency preview content is loaded from the rendered-fragment cache.
Used by 2
Reverse dependency previews
Preview
Theorem 9.3.2
Loading preview
Reverse dependency preview content is loaded from the rendered-fragment cache.
✓L∃∀N

Figures 17 and 18 of Auerbach et al. (2025).

Instead of directly following the paper's presentation of A's (Figure 17) and B's (Figure 18) protocols, we implement shared functions, parameterized by Role. These functions specialize for A or B by using the Role.offset variable, that distinguishes between roles at different indices that A and B play.

We make the following corrections with respect to the pseudocode (marked with surrounding boxes in the pseudocode):

  • In Figure 18, \mathsf{CKA}\text{-}\SendB, lines 8, 9, and 13, replace \boxed{t_{\mathrm{res}\text{-}A}\mapsto t_{\mathrm{res}\text{-}B}}. B's local state contains B's responder counter.

  • In Figure 17, \mathsf{CKA}\text{-}\mathsf{Rec}\text{-}\A, line 22, replace \boxed{\mathit{ct}_A\mapsto\mathit{ct}_B}. Lines 23 and 27 already use B's ciphertext.

  • Public-key acknowledgement indices are corrected at both ends of each message: in Figure 17, Send-A line 21 uses \boxed{t_{\mathrm{req}\text{-}A}-1} and Rec-A line 8 uses \boxed{t_{\mathrm{req}\text{-}B}+1}; in Figure 18, Send-B line 21 uses \boxed{t_{\mathrm{req}\text{-}B}+1} and Rec-B line 8 uses \boxed{t_{\mathrm{req}\text{-}A}-1}. These are the public-key entries set by decoding. The printed formulas advertise different entries, leaving the first public keys unacknowledged.

\textsf{Initialisation}

\begin{array}{l} \mathsf{CKA}\text{-}\mathsf{InitA}(I_{\mathsf{CKA}}=\bot): \\ \quad \mathsf{EK}_{B}[t]\gets\bot,\ \mathsf{DK}_{A}[t]\gets\bot\quad\text{for all }t \\ \quad (\mathsf{ACK}[t].\mathsf{ekRec},\mathsf{ACK}[t].\mathsf{ctRec}) \\ \qquad\gets(\mathsf{false},\mathsf{false})\quad\text{for all }t \\ \quad (\mathsf{ACK}[-1].\mathsf{ctRec},\mathsf{ACK}[0].\mathsf{ctRec}) \\ \qquad\gets(\mathsf{true},\mathsf{true}) \\ \quad \mathsf{st}_{\mathrm{res}}\gets(-1,\mathsf{EK}_{B},\bot,0) \\ \quad \mathsf{st}_{\mathrm{req}}\gets(0,\mathsf{DK}_{A},\bot,\emptyset) \\ \quad \mathsf{return}\;(\mathsf{st}_{\mathrm{res}},\mathsf{st}_{\mathrm{req}},\mathsf{ACK}) \end{array}

\begin{array}{l} \mathsf{CKA}\text{-}\mathsf{InitB}(I_{\mathsf{CKA}}=\bot): \\ \quad \mathsf{EK}_{A}[t]\gets\bot,\ \mathsf{DK}_{B}[t]\gets\bot\quad\text{for all }t \\ \quad (\mathsf{ACK}[t].\mathsf{ekRec},\mathsf{ACK}[t].\mathsf{ctRec}) \\ \qquad\gets(\mathsf{false},\mathsf{false})\quad\text{for all }t \\ \quad (\mathsf{ACK}[-1].\mathsf{ctRec},\mathsf{ACK}[0].\mathsf{ctRec}) \\ \qquad\gets(\mathsf{true},\mathsf{true}) \\ \quad \mathsf{st}_{\mathrm{res}}\gets(0,\mathsf{EK}_{A},\bot,0) \\ \quad \mathsf{st}_{\mathrm{req}}\gets(-1,\mathsf{DK}_{B},\bot,\emptyset) \\ \quad \mathsf{return}\;(\mathsf{st}_{\mathrm{res}},\mathsf{st}_{\mathrm{req}},\mathsf{ACK}) \end{array}

def init (role : Role) (_ik : Unit) : m (State PK SK C Sym) := pure { req := { reqEpoch := if role = .A then 0 else -1 dk := [], ek := none, receivedChunks := ∅ } res := { resEpoch := if role = .A then -1 else 0 ekPeer := fun _ => none ct := none, ich := 0 } ack := { ekRec := ∅, ctRec := {-1, 0} } }
\textsf{Vulnerable epochs}

\begin{array}{l} \mathsf{st}_A.\mathsf{vuln}:\quad\mathsf{return}\;\{t:\mathsf{DK}_A[t]\ne\bot\} \end{array} \begin{array}{l} \mathsf{st}_B.\mathsf{vuln}:\quad\mathsf{return}\;\{t:\mathsf{DK}_B[t]\ne\bot\} \end{array}

def vuln (st : State PK SK C Sym) : Finset ℕ := let storedEpochs := (st.req.dk.map Prod.fst).toFinset let positiveEpochs := storedEpochs.filter fun t => 0 < t positiveEpochs.image Int.toNat /-- Positive epochs whose secret decapsulation keys remain in A's state. -/ def vulnA (st : StA PK SK C Sym) : Finset ℕ := vuln st /-- Positive epochs whose secret decapsulation keys remain in B's state. -/ def vulnB (st : StB PK SK C Sym) : Finset ℕ := vuln st
\textsf{Specialized calls for A and B}

A call to the shared function that discards randomness

def send (role : Role) (kem : KEMScheme m K PK SK C) (ecEk : ErasureCodePayload PK Sym) (ecCt : ErasureCodePayload C Sym) (st : State PK SK C Sym) : m (Option (Option (ℕ × K) × Message Sym × ℕ × State PK SK C Sym)) := do let out ← sendWith role (do let keys ← kem.keygen; pure (keys, ())) (fun pk => do let out ← kem.encaps pk; pure (out, ())) ecEk ecCt st pure (out.map fun (key?, ρ, t, st, _) => (key?, ρ, t, st))

Send-A without leaking randomness

/-- Run A's send step. -/ def sendA (kem : KEMScheme m K PK SK C) (ecEk : ErasureCodePayload PK Sym) (ecCt : ErasureCodePayload C Sym) (stA : StA PK SK C Sym) := send .A kem ecEk ecCt stA

Send-A with leaking randomness

/-- Run A's send step, also returning randomness used for key generation and encapsulation. -/ def sendArleak (kem : KEMScheme m K PK SK C) (ecEk : ErasureCodePayload PK Sym) (ecCt : ErasureCodePayload C Sym) (leak : kem.RandLeak) (stA : StA PK SK C Sym) := sendWith .A leak.keygenRleak leak.encapsRleak ecEk ecCt stA

Send-B without leaking randomness

/-- Run B's send step. -/ def sendB (kem : KEMScheme m K PK SK C) (ecEk : ErasureCodePayload PK Sym) (ecCt : ErasureCodePayload C Sym) (stB : StB PK SK C Sym) := send .B kem ecEk ecCt stB

Send-B with leaking randomness

/-- Run B's send step, also returning randomness used for key generation and encapsulation. -/ def sendBrleak (kem : KEMScheme m K PK SK C) (ecEk : ErasureCodePayload PK Sym) (ecCt : ErasureCodePayload C Sym) (leak : kem.RandLeak) (stB : StB PK SK C Sym) := sendWith .B leak.keygenRleak leak.encapsRleak ecEk ecCt stB
\textsf{Specialized receive calls for A and B}

Receive-A

/-- Process a message at A (by specializing `recv` function) -/ def recvA (kem : KEMScheme m K PK SK C) [DecidableEq Sym] (hDet : kem.DeterministicDecaps) (ecEk : ErasureCodePayload PK Sym) (ecCt : ErasureCodePayload C Sym) (stA : StA PK SK C Sym) (ρ : Message Sym) := recv .A kem hDet ecEk ecCt stA ρ

Receive-B

/-- Process a message at B (by specializing `recv` function) -/ def recvB (kem : KEMScheme m K PK SK C) [DecidableEq Sym] (hDet : kem.DeterministicDecaps) (ecEk : ErasureCodePayload PK Sym) (ecCt : ErasureCodePayload C Sym) (stB : StB PK SK C Sym) (ρ : Message Sym) := recv .B kem hDet ecEk ecCt stB ρ
\textsf{Shared send implementation}

For party P, the shared send follows Figures 17–18 with offset \delta_P, where \delta_A=1 and \delta_B=-1. We write \bar P for the peer of party P.

\begin{array}{l} (t_{\mathrm{res}\text{-}P},\mathsf{EK}_{\bar P},\mathit{ct}_P,i_{\mathrm{ch}})\gets\mathsf{st}_{\mathrm{res}} \\ (t_{\mathrm{req}\text{-}P},\mathsf{DK}_P,\mathit{ek}_P,L_{\mathrm{ch}})\gets\mathsf{st}_{\mathrm{req}} \\ I_P\gets\bot,\ t_{I_P}\gets\bot,\ \mathit{ch}\gets\bot,\ b\gets\bot \\ \mathsf{if}\;\mathit{ek}_P=\bot\wedge\mathsf{ACK}[t_{\mathrm{res}\text{-}P}].\mathsf{ctRec} \\ \qquad\wedge\mathsf{ACK}[t_{\mathrm{res}\text{-}P}+\delta_P].\mathsf{ctRec}\;\mathsf{then} \\ \quad t_{\mathrm{res}\text{-}P}\gets t_{\mathrm{res}\text{-}P}+2,\quad i_{\mathrm{ch}}\gets0 \\ \quad (\mathit{ek}_P,\mathit{dk}_P)\sample\KeyGen \\ \quad \mathsf{DK}_P[t_{\mathrm{res}\text{-}P}+\delta_P]\gets\mathit{dk}_P \\ \mathsf{if}\;\neg\mathsf{ACK}[t_{\mathrm{res}\text{-}P}+\delta_P].\mathsf{ekRec}\;\mathsf{then} \\ \quad i_{\mathrm{ch}}\gets i_{\mathrm{ch}}+1,\quad b\gets0 \\ \quad \mathit{ch}\gets\mathsf{Encode}(\mathit{ek}_P,i_{\mathrm{ch}}) \\ \mathsf{else\ if}\;\neg\mathsf{ACK}[t_{\mathrm{res}\text{-}P}].\mathsf{ctRec}\;\mathsf{then} \\ \quad\mathsf{if}\;\mathit{ct}_P=\bot\wedge\mathsf{ACK}[t_{\mathrm{res}\text{-}P}].\mathsf{ekRec}\;\mathsf{then} \\ \qquad t_{I_P}\gets t_{\mathrm{res}\text{-}P},\quad i_{\mathrm{ch}}\gets0 \\ \qquad(\mathit{ct}_P,I_P)\sample\Encaps(\mathsf{EK}_{\bar P}[t_{\mathrm{res}\text{-}P}]) \\ \quad i_{\mathrm{ch}}\gets i_{\mathrm{ch}}+1,\quad b\gets1 \\ \quad \mathit{ch}\gets\mathsf{Encode}(\mathit{ct}_P,i_{\mathrm{ch}}) \\ t^{\mathrm{snd}}_P\gets\max\{t:\mathsf{ACK}[t].\mathsf{ctRec} \\ \qquad\wedge\mathsf{ACK}[t-1].\mathsf{ctRec}\} \\ \mathit{ack}\gets(\mathsf{ACK}[t_{\mathrm{req}\text{-}P}-\delta_P].\mathsf{ekRec},\mathsf{ACK}[t_{\mathrm{req}\text{-}P}].\mathsf{ctRec}) \\ \rho\gets(\mathit{ch},t_{\mathrm{res}\text{-}P},t_{\mathrm{req}\text{-}P},t^{\mathrm{snd}}_P,\mathit{ack},b) \\ \mathsf{st}_{\mathrm{res}}\gets(t_{\mathrm{res}\text{-}P},\mathsf{EK}_{\bar P},\mathit{ct}_P,i_{\mathrm{ch}}) \\ \mathsf{st}_{\mathrm{req}}\gets(t_{\mathrm{req}\text{-}P},\mathsf{DK}_P,\mathit{ek}_P,L_{\mathrm{ch}}) \\ \mathsf{return}\;((t_{I_P},I_P),\rho,t^{\mathrm{snd}}_P, \\ \qquad(\mathsf{st}_{\mathrm{res}},\mathsf{st}_{\mathrm{req}},\mathsf{ACK})) \end{array}

def sendWith {RKey REnc : Type} (role : Role) (keygen : m ((PK × SK) × RKey)) (encaps : PK → m ((C × K) × REnc)) (ecEk : ErasureCodePayload PK Sym) (ecCt : ErasureCodePayload C Sym) (st : State PK SK C Sym) : m (Option (Option (ℕ × K) × Message Sym × ℕ × State PK SK C Sym × SendRand RKey REnc)) := do let mut ⟨tRes, ekPeer, ct, ich⟩ := st.res let mut ⟨tReq, dk, ek, receivedChunks⟩ := st.req let ack := st.ack let mut key? : Option (ℕ × K) := none let mut ch? : Option (ℕ × Sym) := none let mut bit? : Option Bit := none let mut rKey? : Option RKey := none let mut rEnc? : Option REnc := none -- if ready to advance the epoch (Line 4 in the paper CKA-Send-P) if ek.isNone && decide (tRes ∈ ack.ctRec ∧ tRes + role.offset ∈ ack.ctRec) then let ((newEk, newDk), rKey) ← keygen tRes := tRes + 2 -- the epoch for which the decapsulation key was generated -- (tRes+1 in CKA-Send-A, line 8; tRes-1 in CKA-Send-B, line 8) let keyEpoch := tRes + role.offset dk := (keyEpoch, newDk) :: dk.filter (fun p => p.1 != keyEpoch) ek := some newEk ich := 0 rKey? := some rKey -- if the encapsulation key was not yet received by the peer (lines 9-12 in CKA-Send-P) if tRes + role.offset ∉ ack.ekRec then -- Per paper's convention: if there is no key, return error let some localEk := ek | return none ich := ich + 1 ch? := some (ecEk.encode localEk ich) bit? := some 0 -- if the encapsulation key was received, but ciphertext was **not** yet received by the peer else if tRes ∉ ack.ctRec then -- if no ciphertext is stored and the peer's encapsulation key has been received -- (lines 14-16 in CKA-Send-P) if ct.isNone && decide (tRes ∈ ack.ekRec) then -- Receipt was recorded, so encapsulation now requires this key. let some peerEk := ekPeer tRes | return none let ((newCt, key), rEnc) ← encaps peerEk ct := some newCt key? := some (tRes.toNat, key) ich := 0 rEnc? := some rEnc ich := ich + 1 -- Waiting for the peer's public key can legitimately leave ct absent. ch? := ct.map (fun ciphertext => ecCt.encode ciphertext ich) bit? := some 1 let st : State PK SK C Sym := { res := ⟨tRes, ekPeer, ct, ich⟩ req := ⟨tReq, dk, ek, receivedChunks⟩ ack } let ρ : Message Sym := { ch := ch?, bit := bit?, tRes, tReq -- Largest nonnegative index with two adjacent acknowledged ciphertexts -- (both t and t-1 in ack.ctRec). -- The empty maximum is zero; honest states initially acknowledge `-1` and `0`. sendingEpoch := (ack.ctRec.filter fun t => t - 1 ∈ ack.ctRec).sup Int.toNat ack := { ekRec := decide (tReq - role.offset ∈ ack.ekRec) ctRec := decide (tReq ∈ ack.ctRec) } } return some (key?, ρ, ρ.sendingEpoch, st, { keygenRand := rKey?, encapsRand := rEnc? })
\textsf{Shared receive implementation}

For party P, the shared receive follows Figures 17–18 with offset \delta_P, where \delta_A=1 and \delta_B=-1. We write \bar P for the peer of party P.

\begin{array}{l} (t_{\mathrm{res}\text{-}P},\mathsf{EK}_{\bar P},\mathit{ct}_P,i_{\mathrm{ch}})\gets\mathsf{st}_{\mathrm{res}} \\ (t_{\mathrm{req}\text{-}P},\mathsf{DK}_P,\mathit{ek}_P,L_{\mathrm{ch}})\gets\mathsf{st}_{\mathrm{req}} \\ (\mathit{ch},t_{\mathrm{res}\text{-}\bar P},t_{\mathrm{req}\text{-}\bar P},t^{\mathrm{snd}}_{\bar P},\mathit{ack},b)\gets\rho \\ I_{\bar P}\gets\bot,\quad t_{I_{\bar P}}\gets\bot \\ \mathsf{if}\;\mathit{ack}.\mathsf{ctRec}\;\mathsf{then} \\ \quad\mathsf{ACK}[t_{\mathrm{req}\text{-}\bar P}].\mathsf{ctRec}\gets\mathsf{true} \\ \mathsf{if}\;\mathit{ack}.\mathsf{ekRec}\;\mathsf{then} \\ \quad\mathsf{ACK}[t_{\mathrm{req}\text{-}\bar P}+\delta_P].\mathsf{ekRec}\gets\mathsf{true} \\ \mathsf{if}\;t_{\mathrm{res}\text{-}\bar P}<t_{\mathrm{req}\text{-}P}\;\mathsf{then}\;\mathsf{break} \\ \mathsf{else\ if}\;t_{\mathrm{res}\text{-}\bar P}>t_{\mathrm{req}\text{-}P}\;\mathsf{then}\;t_{\mathrm{req}\text{-}P}\gets t_{\mathrm{req}\text{-}P}+2 \\ \mathsf{if}\;\mathsf{EK}_{\bar P}[t_{\mathrm{req}\text{-}P}-\delta_P]=\bot\wedge b=0\;\mathsf{then} \\ \quad L_{\mathrm{ch}}\gets L_{\mathrm{ch}}\cup\{\mathit{ch}\} \\ \quad \mathit{ek}_{\bar P}\gets\mathsf{Decode}(L_{\mathrm{ch}}) \\ \quad\mathsf{if}\;\mathit{ek}_{\bar P}\ne\bot\;\mathsf{then} \\ \qquad L_{\mathrm{ch}}\gets\emptyset \\ \qquad\mathsf{EK}_{\bar P}[t_{\mathrm{req}\text{-}P}-\delta_P]\gets\mathit{ek}_{\bar P} \\ \qquad\mathsf{ACK}[t_{\mathrm{req}\text{-}P}-\delta_P].\mathsf{ekRec}\gets\mathsf{true} \\ \mathsf{else\ if}\;\neg\mathsf{ACK}[t_{\mathrm{req}\text{-}P}].\mathsf{ctRec}\wedge b=1\;\mathsf{then} \\ \quad L_{\mathrm{ch}}\gets L_{\mathrm{ch}}\cup\{\mathit{ch}\} \\ \quad \mathit{ct}_{\bar P}\gets\mathsf{Decode}(L_{\mathrm{ch}}) \\ \quad\mathsf{if}\;\mathit{ct}_{\bar P}\ne\bot\;\mathsf{then} \\ \qquad L_{\mathrm{ch}}\gets\emptyset \\ \qquad\mathsf{ACK}[t_{\mathrm{req}\text{-}P}].\mathsf{ctRec}\gets\mathsf{true} \\ \qquad t_{I_{\bar P}}\gets t_{\mathrm{req}\text{-}P} \\ \qquad I_{\bar P}\gets\Decaps(\mathsf{DK}_P[t_{\mathrm{req}\text{-}P}],\mathit{ct}_{\bar P}) \\ \qquad\mathsf{DK}_P[t_{\mathrm{req}\text{-}P}]\gets\bot \\ \mathsf{if}\;\mathsf{ACK}[t_{\mathrm{res}\text{-}P}].\mathsf{ctRec}\;\mathsf{then}\;\mathit{ct}_P\gets\bot \\ \mathsf{if}\;\mathsf{ACK}[t_{\mathrm{res}\text{-}P}+\delta_P].\mathsf{ekRec}\;\mathsf{then}\;\mathit{ek}_P\gets\bot \\ \mathsf{st}_{\mathrm{res}}\gets(t_{\mathrm{res}\text{-}P},\mathsf{EK}_{\bar P},\mathit{ct}_P,i_{\mathrm{ch}}) \\ \mathsf{st}_{\mathrm{req}}\gets(t_{\mathrm{req}\text{-}P},\mathsf{DK}_P,\mathit{ek}_P,L_{\mathrm{ch}}) \\ \mathsf{return}\;((t_{I_{\bar P}},I_{\bar P}),t^{\mathrm{snd}}_{\bar P}, \\ \qquad(\mathsf{st}_{\mathrm{res}},\mathsf{st}_{\mathrm{req}},\mathsf{ACK})) \end{array}

def recv (role : Role) (kem : KEMScheme m K PK SK C) [DecidableEq Sym] (hDet : kem.DeterministicDecaps) (ecEk : ErasureCodePayload PK Sym) (ecCt : ErasureCodePayload C Sym) (st : State PK SK C Sym) (ρ : Message Sym) : Option (Option (ℕ × K) × ℕ × State PK SK C Sym) := do let mut ⟨resEpoch, ekPeer, ct, ich⟩ := st.res let mut ⟨reqEpoch, dk, ek, receivedChunks⟩ := st.req let ⟨ch?, peerResEpoch, peerReqEpoch, sendingEpoch, peerAck, bit?⟩ := ρ let mut localAck := st.ack let mut key? : Option (ℕ × K) := none -- Incorporate the peer's acknowledgements first. if peerAck.ctRec then localAck := { localAck with ctRec := insert peerReqEpoch localAck.ctRec } if peerAck.ekRec then localAck := { localAck with ekRec := insert (peerReqEpoch + role.offset) localAck.ekRec } -- outdated message: retain only the acknowledgement updates if peerResEpoch < reqEpoch then return (none, sendingEpoch, { st with ack := localAck }) -- first message of the new epoch, lines 11-12 if reqEpoch < peerResEpoch then reqEpoch := reqEpoch + 2 -- Captures the relation of "1 removed" epochs -- - if A is requesting the key for epoch t, it receives B's public key for t-1 -- - if B is requesting the key for epoch t, it receives A's public key for t+1 let peerKeyEpoch := reqEpoch - role.offset -- if the peer's encapsulating key has not been received yet, lines 13-19 if (ekPeer peerKeyEpoch).isNone ∧ bit? = some 0 then let (chunks, peerEk?) := insertChunkAndDecode ecEk receivedChunks ch? receivedChunks := chunks if let some peerEk := peerEk? then ekPeer := Function.update ekPeer peerKeyEpoch (some peerEk) receivedChunks := ∅ localAck := { localAck with ekRec := insert peerKeyEpoch localAck.ekRec } -- if ciphertext has not been received and the bit is 1, lines 20-28 else if reqEpoch ∉ localAck.ctRec ∧ bit? = some 1 then let (chunks, peerCt?) := insertChunkAndDecode ecCt receivedChunks ch? receivedChunks := chunks if let some peerCt := peerCt? then -- Paper convention: A missing required key or failed decapsulation should -- fail the whole function (return `none` in our Option), accomplished here by bindings. let secretKey ← dk.lookup reqEpoch let key ← hDet.decapsDet secretKey peerCt receivedChunks := ∅ localAck := { localAck with ctRec := insert reqEpoch localAck.ctRec } key? := some (reqEpoch.toNat, key) dk := dk.filter (fun p => p.1 != reqEpoch) -- deleting the stored material that has been fully delivered (lines 29-32) if resEpoch ∈ localAck.ctRec then ct := none if resEpoch + role.offset ∈ localAck.ekRec then ek := none return (key?, sendingEpoch, { res := ⟨resEpoch, ekPeer, ct, ich⟩ req := ⟨reqEpoch, dk, ek, receivedChunks⟩ ack := localAck })

SCKA scheme instance

/-- Assemble Opp-BiKEM as an SCKA scheme from a KEM with deterministic decapsulation, public-key and ciphertext erasure codes, and randomness-leaking KEM operations. -/ def scheme (kem : KEMScheme m K PK SK C) [DecidableEq Sym] (hDet : kem.DeterministicDecaps) (ecEk : ErasureCodePayload PK Sym) (ecCt : ErasureCodePayload C Sym) (leak : kem.RandLeak) : SCKAScheme m Unit (StA PK SK C Sym) (StB PK SK C Sym) K (Message Sym) (SendRand leak.KeygenRand leak.EncapsRand) where initKeyGen := initKeyGen initA := initA initB := initB sendA := sendA kem ecEk ecCt sendArleak := sendArleak kem ecEk ecCt leak recvA := recvA kem hDet ecEk ecCt sendB := sendB kem ecEk ecCt sendBrleak := sendBrleak kem ecEk ecCt leak recvB := recvB kem hDet ecEk ecCt
Lean code for Definition9.3.1●12 definitions
  • def oppBiKemCKA.initKeyGen.{u} {m : Type → Type u} [Monad m] : m Unit
    def oppBiKemCKA.initKeyGen.{u}
      {m : Type → Type u} [Monad m] : m Unit
    Return the trivial initialization key: OppBiKEM protocol does not need initialization key 
  • def oppBiKemCKA.initA.{u} {m : Type → Type u} [Monad m]
      {PK SK C Sym : Type} : Unit → m (oppBiKemCKA.StA PK SK C Sym)
    def oppBiKemCKA.initA.{u} {m : Type → Type u}
      [Monad m] {PK SK C Sym : Type} :
      Unit → m (oppBiKemCKA.StA PK SK C Sym)
    Initialize A 
  • def oppBiKemCKA.initB.{u} {m : Type → Type u} [Monad m]
      {PK SK C Sym : Type} : Unit → m (oppBiKemCKA.StB PK SK C Sym)
    def oppBiKemCKA.initB.{u} {m : Type → Type u}
      [Monad m] {PK SK C Sym : Type} :
      Unit → m (oppBiKemCKA.StB PK SK C Sym)
    Initialize B 
  • def oppBiKemCKA.vulnA {PK SK C Sym : Type}
      (st : oppBiKemCKA.StA PK SK C Sym) : Finset ℕ
    def oppBiKemCKA.vulnA {PK SK C Sym : Type}
      (st : oppBiKemCKA.StA PK SK C Sym) :
      Finset ℕ
    Positive epochs whose secret decapsulation keys remain in A's state. 
  • def oppBiKemCKA.vulnB {PK SK C Sym : Type}
      (st : oppBiKemCKA.StB PK SK C Sym) : Finset ℕ
    def oppBiKemCKA.vulnB {PK SK C Sym : Type}
      (st : oppBiKemCKA.StB PK SK C Sym) :
      Finset ℕ
    Positive epochs whose secret decapsulation keys remain in B's state. 
  • def oppBiKemCKA.sendA.{u} {m : Type → Type u} [Monad m]
      {K PK SK C Sym : Type} (kem : KEMScheme m K PK SK C)
      (ecEk : ErasureCodePayload PK Sym) (ecCt : ErasureCodePayload C Sym)
      (stA : oppBiKemCKA.StA PK SK C Sym) :
      m
        (Option
          (Option (ℕ × K) ×
            oppBiKemCKA.Message Sym × ℕ × oppBiKemCKA.State PK SK C Sym))
    def oppBiKemCKA.sendA.{u} {m : Type → Type u}
      [Monad m] {K PK SK C Sym : Type}
      (kem : KEMScheme m K PK SK C)
      (ecEk : ErasureCodePayload PK Sym)
      (ecCt : ErasureCodePayload C Sym)
      (stA : oppBiKemCKA.StA PK SK C Sym) :
      m
        (Option
          (Option (ℕ × K) ×
            oppBiKemCKA.Message Sym ×
              ℕ ×
                oppBiKemCKA.State PK SK C
                  Sym))
    Run A's send step. 
  • def oppBiKemCKA.sendArleak.{u} {m : Type → Type u} [Monad m]
      {K PK SK C Sym : Type} (kem : KEMScheme m K PK SK C)
      (ecEk : ErasureCodePayload PK Sym) (ecCt : ErasureCodePayload C Sym)
      (leak : kem.RandLeak) (stA : oppBiKemCKA.StA PK SK C Sym) :
      m
        (Option
          (Option (ℕ × K) ×
            oppBiKemCKA.Message Sym ×
              ℕ ×
                oppBiKemCKA.State PK SK C Sym ×
                  oppBiKemCKA.SendRand leak.KeygenRand leak.EncapsRand))
    def oppBiKemCKA.sendArleak.{u}
      {m : Type → Type u} [Monad m]
      {K PK SK C Sym : Type}
      (kem : KEMScheme m K PK SK C)
      (ecEk : ErasureCodePayload PK Sym)
      (ecCt : ErasureCodePayload C Sym)
      (leak : kem.RandLeak)
      (stA : oppBiKemCKA.StA PK SK C Sym) :
      m
        (Option
          (Option (ℕ × K) ×
            oppBiKemCKA.Message Sym ×
              ℕ ×
                oppBiKemCKA.State PK SK C
                    Sym ×
                  oppBiKemCKA.SendRand
                    leak.KeygenRand
                    leak.EncapsRand))
    Run A's send step, also returning randomness used for key generation and encapsulation. 
  • def oppBiKemCKA.recvA.{u} {m : Type → Type u} [Monad m]
      {K PK SK C Sym : Type} (kem : KEMScheme m K PK SK C) [DecidableEq Sym]
      (hDet : kem.DeterministicDecaps) (ecEk : ErasureCodePayload PK Sym)
      (ecCt : ErasureCodePayload C Sym) (stA : oppBiKemCKA.StA PK SK C Sym)
      (ρ : oppBiKemCKA.Message Sym) :
      Option (Option (ℕ × K) × ℕ × oppBiKemCKA.State PK SK C Sym)
    def oppBiKemCKA.recvA.{u} {m : Type → Type u}
      [Monad m] {K PK SK C Sym : Type}
      (kem : KEMScheme m K PK SK C)
      [DecidableEq Sym]
      (hDet : kem.DeterministicDecaps)
      (ecEk : ErasureCodePayload PK Sym)
      (ecCt : ErasureCodePayload C Sym)
      (stA : oppBiKemCKA.StA PK SK C Sym)
      (ρ : oppBiKemCKA.Message Sym) :
      Option
        (Option (ℕ × K) ×
          ℕ × oppBiKemCKA.State PK SK C Sym)
    Process a message at A (by specializing `recv` function) 
  • def oppBiKemCKA.sendB.{u} {m : Type → Type u} [Monad m]
      {K PK SK C Sym : Type} (kem : KEMScheme m K PK SK C)
      (ecEk : ErasureCodePayload PK Sym) (ecCt : ErasureCodePayload C Sym)
      (stB : oppBiKemCKA.StB PK SK C Sym) :
      m
        (Option
          (Option (ℕ × K) ×
            oppBiKemCKA.Message Sym × ℕ × oppBiKemCKA.State PK SK C Sym))
    def oppBiKemCKA.sendB.{u} {m : Type → Type u}
      [Monad m] {K PK SK C Sym : Type}
      (kem : KEMScheme m K PK SK C)
      (ecEk : ErasureCodePayload PK Sym)
      (ecCt : ErasureCodePayload C Sym)
      (stB : oppBiKemCKA.StB PK SK C Sym) :
      m
        (Option
          (Option (ℕ × K) ×
            oppBiKemCKA.Message Sym ×
              ℕ ×
                oppBiKemCKA.State PK SK C
                  Sym))
    Run B's send step. 
  • def oppBiKemCKA.sendBrleak.{u} {m : Type → Type u} [Monad m]
      {K PK SK C Sym : Type} (kem : KEMScheme m K PK SK C)
      (ecEk : ErasureCodePayload PK Sym) (ecCt : ErasureCodePayload C Sym)
      (leak : kem.RandLeak) (stB : oppBiKemCKA.StB PK SK C Sym) :
      m
        (Option
          (Option (ℕ × K) ×
            oppBiKemCKA.Message Sym ×
              ℕ ×
                oppBiKemCKA.State PK SK C Sym ×
                  oppBiKemCKA.SendRand leak.KeygenRand leak.EncapsRand))
    def oppBiKemCKA.sendBrleak.{u}
      {m : Type → Type u} [Monad m]
      {K PK SK C Sym : Type}
      (kem : KEMScheme m K PK SK C)
      (ecEk : ErasureCodePayload PK Sym)
      (ecCt : ErasureCodePayload C Sym)
      (leak : kem.RandLeak)
      (stB : oppBiKemCKA.StB PK SK C Sym) :
      m
        (Option
          (Option (ℕ × K) ×
            oppBiKemCKA.Message Sym ×
              ℕ ×
                oppBiKemCKA.State PK SK C
                    Sym ×
                  oppBiKemCKA.SendRand
                    leak.KeygenRand
                    leak.EncapsRand))
    Run B's send step, also returning randomness used for key generation and encapsulation. 
  • def oppBiKemCKA.recvB.{u} {m : Type → Type u} [Monad m]
      {K PK SK C Sym : Type} (kem : KEMScheme m K PK SK C) [DecidableEq Sym]
      (hDet : kem.DeterministicDecaps) (ecEk : ErasureCodePayload PK Sym)
      (ecCt : ErasureCodePayload C Sym) (stB : oppBiKemCKA.StB PK SK C Sym)
      (ρ : oppBiKemCKA.Message Sym) :
      Option (Option (ℕ × K) × ℕ × oppBiKemCKA.State PK SK C Sym)
    def oppBiKemCKA.recvB.{u} {m : Type → Type u}
      [Monad m] {K PK SK C Sym : Type}
      (kem : KEMScheme m K PK SK C)
      [DecidableEq Sym]
      (hDet : kem.DeterministicDecaps)
      (ecEk : ErasureCodePayload PK Sym)
      (ecCt : ErasureCodePayload C Sym)
      (stB : oppBiKemCKA.StB PK SK C Sym)
      (ρ : oppBiKemCKA.Message Sym) :
      Option
        (Option (ℕ × K) ×
          ℕ × oppBiKemCKA.State PK SK C Sym)
    Process a message at B (by specializing `recv` function) 
  • def oppBiKemCKA.scheme.{u} {m : Type → Type u} [Monad m]
      {K PK SK C Sym : Type} (kem : KEMScheme m K PK SK C) [DecidableEq Sym]
      (hDet : kem.DeterministicDecaps) (ecEk : ErasureCodePayload PK Sym)
      (ecCt : ErasureCodePayload C Sym) (leak : kem.RandLeak) :
      SCKAScheme m Unit (oppBiKemCKA.StA PK SK C Sym)
        (oppBiKemCKA.StB PK SK C Sym) K (oppBiKemCKA.Message Sym)
        (oppBiKemCKA.SendRand leak.KeygenRand leak.EncapsRand)
    def oppBiKemCKA.scheme.{u} {m : Type → Type u}
      [Monad m] {K PK SK C Sym : Type}
      (kem : KEMScheme m K PK SK C)
      [DecidableEq Sym]
      (hDet : kem.DeterministicDecaps)
      (ecEk : ErasureCodePayload PK Sym)
      (ecCt : ErasureCodePayload C Sym)
      (leak : kem.RandLeak) :
      SCKAScheme m Unit
        (oppBiKemCKA.StA PK SK C Sym)
        (oppBiKemCKA.StB PK SK C Sym) K
        (oppBiKemCKA.Message Sym)
        (oppBiKemCKA.SendRand leak.KeygenRand
          leak.EncapsRand)
    Assemble Opp-BiKEM as an SCKA scheme from a KEM with deterministic decapsulation,
    public-key and ciphertext erasure codes, and randomness-leaking KEM operations. 
Theorem9.3.2
Group: Opp-BiKEM-CKA. (2)
Group member previews
Preview
Definition 9.3.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
Statement uses 3
Statement dependency previews
Preview
Definition 4.1.4
Loading preview
Statement dependency preview content is loaded from the rendered-fragment cache.
used by 0✓L∃∀N

Assume that:

  • \adv is any SCKA correctness adversary making at most q send-oracle queries;

  • the underlying KEM has deterministic decapsulation, and has correctness error at most \varepsilon;

  • and the two erasure codes, for public keys and for ciphertexts, are correct.

Then \Pr\bigl[\Exp{\textsf{cor}}{\textsf{Opp-BiKEM-CKA}}(\adv)=1\bigr] \ge 1-q\varepsilon, i.e., the Opp-BiKEM-CKA protocol is correct with probability at least 1-q\varepsilon.

theorem correctness_true_ge (kem : KEMScheme ProbComp K PK SK C) (hDet : kem.DeterministicDecaps) (ecEk : ErasureCodePayload PK Sym) (ecCt : ErasureCodePayload C Sym) (hEk : ecEk.ec.Correct) (hCt : ecCt.ec.Correct) (leak : kem.RandLeak) (adv : SCKAScheme.SCKACorrectnessAdversary (Message Sym)) (q : ℕ) (hq : SCKAScheme.SendQueryBound adv q) : Pr[= true | SCKAScheme.correctnessExp (scheme kem hDet ecEk ecCt leak) adv] ≥ 1 - (q : ℝ≥0∞) * kem.correctnessError ProbCompRuntime.probComp
Lean code for Theorem9.3.2●1 theorem
  • theorem oppBiKemCKA.correctness_true_ge {K PK SK C Sym : Type} [DecidableEq K]
      [DecidableEq Sym] (kem : KEMScheme ProbComp K PK SK C)
      (hDet : kem.DeterministicDecaps) (ecEk : ErasureCodePayload PK Sym)
      (ecCt : ErasureCodePayload C Sym) (hEk : ecEk.ec.Correct)
      (hCt : ecCt.ec.Correct) (leak : kem.RandLeak)
      (adv : SCKAScheme.SCKACorrectnessAdversary (oppBiKemCKA.Message Sym))
      (q : ℕ) (hq : SCKAScheme.SendQueryBound adv q) :
      Pr[= true |
          (oppBiKemCKA.scheme kem hDet ecEk ecCt leak).correctnessExp adv] ≥
        1 - ↑q * kem.correctnessError ProbCompRuntime.probComp
    theorem oppBiKemCKA.correctness_true_ge
      {K PK SK C Sym : Type} [DecidableEq K]
      [DecidableEq Sym]
      (kem : KEMScheme ProbComp K PK SK C)
      (hDet : kem.DeterministicDecaps)
      (ecEk : ErasureCodePayload PK Sym)
      (ecCt : ErasureCodePayload C Sym)
      (hEk : ecEk.ec.Correct)
      (hCt : ecCt.ec.Correct)
      (leak : kem.RandLeak)
      (adv :
        SCKAScheme.SCKACorrectnessAdversary
          (oppBiKemCKA.Message Sym))
      (q : ℕ)
      (hq : SCKAScheme.SendQueryBound adv q) :
      Pr[= true |
          (oppBiKemCKA.scheme kem hDet ecEk
                ecCt leak).correctnessExp
            adv] ≥
        1 -
          ↑q *
            kem.correctnessError
              ProbCompRuntime.probComp
    Assume:
    
    * `kem` has deterministic decapsulation;
    * `ecEk` and `ecCt` are correct erasure codes;
    * `adv` makes at most `q` `SendA` and `SendB` queries combined.
    
    Then the Opp-BiKEM-CKA correctness game succeeds with probability at least
    `1 - q · kem.correctnessError`. 
Theorem9.3.3
Group: Opp-BiKEM-CKA. (2)
Group member previews
Preview
Definition 9.3.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
Statement uses 3
Statement dependency previews
Preview
Definition 4.1.1
Loading preview
Statement dependency preview content is loaded from the rendered-fragment cache.
used by 0XL∃∀N

\todo

LeanLean anchor pending