{-# OPTIONS --without-K --copatterns #-}
open import Type
open import Data.Two
open import Data.Maybe
open import Data.Product
open import Data.One
open import Data.Two
open import Control.Strategy renaming (run to runStrategy; map to mapStrategy)
open import Function
open import Relation.Binary
open import Relation.Binary.PropositionalEquality
import Game.IND-CPA-dagger
import Game.IND-CPA
module Game.Transformation.CPA-CPAd
(PubKey : ★)
(SecKey : ★)
(Message : ★)
(CipherText : ★)
(Rₑ Rₖ Rₐ† : ★)
(KeyGen : Rₖ → PubKey × SecKey)
(Enc : PubKey → Message → Rₑ → CipherText)
(Dec : SecKey → CipherText → Message)
where
Rₐ = Rₑ × Rₐ†
module CPA = Game.IND-CPA PubKey SecKey Message CipherText Rₑ Rₖ Rₐ 𝟙 KeyGen Enc
module CPA† = Game.IND-CPA-dagger PubKey SecKey Message CipherText Rₑ Rₖ Rₐ† 𝟙 KeyGen Enc
open CPA using (EXP; R; Adversary; module Adversary)
open CPA† using () renaming (EXP to EXP†; R to R†; Adversary to Adversary†; module Adversary to Adversary†)
R→R† : R → R†
R→R† ((rₑ′ , rₐ†) , rₖ , rₑ , _) = rₐ† , rₖ , rₑ , rₑ′ , _
R†→R : R† → R
R†→R (rₐ† , rₖ , rₑ , rₑ′ , _) = (rₑ′ , rₐ†) , rₖ , rₑ , _
[rₑ↔rₑ′]† : R† → R†
[rₑ↔rₑ′]† (rₐ† , rₖ , rₑ , rₑ′ , _) = (rₐ† , rₖ , rₑ′ , rₑ , _)
[rₑ↔rₑ′] : R → R
[rₑ↔rₑ′] ((rₑ′ , rₐ†) , rₖ , rₑ , _) = ((rₑ , rₐ†) , rₖ , rₑ′ , _)
[rₑ↔rₑ′]-inv : ∀ r → [rₑ↔rₑ′] ([rₑ↔rₑ′] r) ≡ r
[rₑ↔rₑ′]-inv r = refl
module Transformations (A† : Adversary†) where
module A† = Adversary† A†
m† = A†.m
b′† = A†.b′
m : Rₐ → PubKey → 𝟚 → Message
m (_ , rₐ†) = m† rₐ†
fix[t=_] : (t : 𝟚) → Adversary
fix[t= t ] = record { m = m ; b′ = b′ }
where
b′ : ∀ _ _ _ → _
b′ (rₑ , rₐ†) pk cb = b′† rₐ† pk cb (Enc pk (m† rₐ† pk t) rₑ)
fix[b=_] : (b : 𝟚) → Adversary
fix[b= b ] = record { m = m ; b′ = b′ }
where
b′ : ∀ _ _ _ → _
b′ (rₑ , rₐ†) pk ct = b′† rₐ† pk (Enc pk (m† rₐ† pk b) rₑ) ct
fix[t=]-prop : ∀ b t r → EXP b fix[t= t ] r ≡ EXP† b t A† (R→R† r)
fix[t=]-prop _ _ _ = refl
fix[b=]-prop : ∀ b t r → EXP t fix[b= b ] r ≡ EXP† b t A† ([rₑ↔rₑ′]† (R→R† r))
fix[b=]-prop _ _ _ = refl
open import Relation.Binary.PropositionalEquality
module _
(Dist : ★)
(0d : Dist)
(dist : (f g : R → 𝟚) → Dist)
(dist-comm : (f g : R → 𝟚) → dist f g ≡ dist g f)
(dist-≗ : {f g : R → 𝟚} → f ≗ g → dist f g ≡ 0d)
(Negligible : Dist → ★)
(0d-Negigible : ∀ {d} → d ≡ 0d → Negligible d)
(_+Dist_ : Dist → Dist → Dist)
(+Dist-Negligible : ∀ {x y} → Negligible x → Negligible y → Negligible (x +Dist y))
(neg-dist-trans : {f g h : R → 𝟚} → Negligible (dist f g) → Negligible (dist g h) → Negligible (dist f h))
(CPA-secure : ∀ b A → Negligible (dist (EXP b A) (EXP (not b) A)))
where
_~_ : (f g : R → 𝟚) → ★
f ~ g = Negligible (dist f g)
_~†_ : (f g : R† → 𝟚) → ★
f ~† g = (f ∘ R→R†) ~ (g ∘ R→R†)
infixr 5 _∙_
_∙_ : Transitive _~_
_∙_ = neg-dist-trans
!_ : Symmetric _~_
!_ {f} {g} = subst Negligible (dist-comm f g)
≗→~ : {f g : R → 𝟚} → f ≗ g → f ~ g
≗→~ {f} {g} f≗g = 0d-Negigible (dist-≗ f≗g)
module _ (A† : Adversary†)
(SUI : (f : R → R) (f-iso : f ∘ f ≗ id) (h : R → 𝟚) → (h ∘ f) ~ h)
where
open Transformations A†
CPA†-secure : EXP† 0₂ 1₂ A† ~† EXP† 1₂ 0₂ A†
CPA†-secure = CPA-secure 0₂ fix[t= 1₂ ]
∙ SUI [rₑ↔rₑ′] [rₑ↔rₑ′]-inv _
∙ CPA-secure 1₂ fix[b= 1₂ ]
∙ ≗→~ (λ r → fix[b=]-prop 1₂ 0₂ r)
∙ SUI [rₑ↔rₑ′] [rₑ↔rₑ′]-inv _