{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE PartialTypeSignatures #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE RebindableSyntax #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -fno-warn-partial-type-signatures #-}
module Crypto.Lol.Applications.Examples.SymmBGV (bgvMain) where
import Crypto.Lol hiding ((^))
import Crypto.Lol.Applications.SymmBGV
import Crypto.Lol.Types
import Algebra.Ring ((^))
import Control.Monad.Random (getRandom)
type PTIndex = F128
type CTIndex = $(fType $ 2^7 * 7 * 13)
type PTZq = ZqBasic PP8 Int64
type Zq q = ZqBasic q Int64
type CTZq1 = Zq 536937857
type CTZq2 = (Zq 536972801, CTZq1)
type CTZq3 = (Zq 537054337, CTZq2)
type KSGad = TrivGad
type CTRing1 d t = CT d PTIndex PTZq (Cyc t CTIndex CTZq1)
type CTRing2 d t = CT d PTIndex PTZq (Cyc t CTIndex CTZq2)
type SKRing t = Cyc t CTIndex (LiftOf PTZq)
bgvMain :: forall t . (forall m r . (Fact m, Eq r) => Eq (t m r), _)
=> Proxy t -> IO ()
bgvMain _ = do
plaintext <- getRandom
sk :: SK (SKRing t) <- genSK (1 :: Double)
ciphertext :: CTRing1 _ t <- encrypt sk plaintext
let ct1 = mulPublic 2 ciphertext
pt1 = decrypt sk ct1
print $ "Test1 (expect TRUE): " ++ show (2*plaintext == pt1)
hint :: KSHint KSGad (Cyc t CTIndex CTZq2) <- ksQuadCircHint sk
let ct2 = modSwitch $ keySwitchQuadCirc hint $ modSwitch $ mulCT ciphertext ciphertext
pt2 = decrypt sk (ct2 :: CTRing1 _ t)
print $ "Test2 (expect FALSE): " ++ show (plaintext*plaintext == pt2)
hint' :: KSHint KSGad (Cyc t CTIndex CTZq3) <- ksQuadCircHint sk
ciphertext' :: CTRing2 _ t <- encrypt sk plaintext
let ct3 = keySwitchQuadCirc hint' $ modSwitch $ mulCT ciphertext' ciphertext'
pt3 = decrypt sk ct3
ct3' = modSwitch ct3 :: CTRing1 _ t
pt3' = decrypt sk ct3'
print $ "Test3 (expect TRUE): " ++ show ((plaintext*plaintext == pt3) && (pt3' == pt3))