open import Function open import Type using (★) open import Data.Product open import Relation.Binary.PropositionalEquality.NP module Cipher.ElGamal.Homomorphic (ℤq : ★) (G : ★) (g : G) (_⊞_ : ℤq → ℤq → ℤq) (_^_ : G → ℤq → G) (_♦_ : G → G → G) (_/_ : G → G → G) where open import Cipher.ElGamal.Generic G ℤq G g _^_ _♦_ _/_ Combine : CipherText → CipherText → CipherText Combine (a , b) (c , d) = (a ♦ c , b ♦ d) Reenc : PubKey → CipherText → (rₑ : ℤq) → CipherText Reenc pk (gʸ , ζ) rₑ = (g ^ rₑ) ♦ gʸ , (pk ^ rₑ) ♦ ζ module HomomorphicCorrectness (/-♦ : ∀ {x y} → (x ♦ y) / x ≡ y) (comm-^ : ∀ {α x y} → (α ^ x)^ y ≡ (α ^ y)^ x) (interchange-♦ : ∀ {a b c d} → (a ♦ b) ♦ (c ♦ d) ≡ ((a ♦ c) ♦ (b ♦ d))) (^-⊞ : ∀ {α x y} → (α ^ x) ♦ (α ^ y) ≡ α ^ (x ⊞ y)) where open FunctionalCorrectness /-♦ comm-^ homomorphic-correctness : ∀ sk m₀ m₁ r₀ r₁ → let pk = PubKeyGen sk in Dec sk (Combine (Enc pk m₀ r₀) (Enc pk m₁ r₁)) ≡ m₀ ♦ m₁ homomorphic-correctness rₖ m₀ m₁ r₀ r₁ = (ap (flip _/_ D) p ∙ ap (_/_ N ∘ flip _^_ rₖ) ^-⊞) ∙ functional-correctness rₖ (r₀ ⊞ r₁) (m₀ ♦ m₁) where D = ((g ^ r₀) ♦ (g ^ r₁))^ rₖ N = ((g ^ rₖ) ^ (r₀ ⊞ r₁)) ♦ (m₀ ♦ m₁) p = interchange-♦ ∙ ap (flip _♦_ (m₀ ♦ m₁)) ^-⊞ module ReencCorrectness (/-♦ : ∀ {x y} → (x ♦ y) / x ≡ y) (comm-^ : ∀ {α x y} → (α ^ x)^ y ≡ (α ^ y)^ x) (interchange-♦ : ∀ {a b c d} → (a ♦ b) ♦ (c ♦ d) ≡ ((a ♦ c) ♦ (b ♦ d))) (^-⊞ : ∀ {α x y} → (α ^ x) ♦ (α ^ y) ≡ α ^ (x ⊞ y)) (g⁰ : G) (g⁰-idl : ∀ x → g⁰ ♦ x ≡ x) (g⁰-idr : ∀ x → x ♦ g⁰ ≡ x) where open HomomorphicCorrectness /-♦ comm-^ interchange-♦ ^-⊞ Reenc-Combine-g⁰ : ∀ pk c r → Reenc pk c r ≡ Combine (Enc pk g⁰ r) c Reenc-Combine-g⁰ pk c r = cong₂ _,_ refl (ap (flip _♦_ (proj₂ c)) (! (g⁰-idr _))) Reenc-correct : ∀ sk m r₀ r₁ → let pk = PubKeyGen sk in Dec sk (Reenc pk (Enc pk m r₁) r₀) ≡ m Reenc-correct rₖ m r₀ r₁ = ap (λ z → (z ♦ (((g ^ rₖ) ^ r₁) ♦ m)) / D) (! (g⁰-idr _)) ∙ homomorphic-correctness rₖ g⁰ m r₀ r₁ ∙ g⁰-idl _ where D = ((g ^ r₀) ♦ (g ^ r₁))^ rₖ