{-| Module : Crypto.Lol.Benchmarks.CycBenches Description : Benchmarks for the 'Cyc' interface. Copyright : (c) Eric Crockett, 2011-2017 Chris Peikert, 2011-2017 License : GPL-3 Maintainer : ecrockett0@email.com Stability : experimental Portability : POSIX Benchmarks for the 'Cyc' interface. -} {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE PartialTypeSignatures #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# OPTIONS_GHC -fno-warn-partial-type-signatures #-} module Crypto.Lol.Benchmarks.CycBenches (cycBenches1, cycBenches2) where import Control.Applicative import Control.Monad.Random hiding (lift) import Crypto.Lol import Crypto.Lol.Types import Crypto.Lol.Utils.Benchmarks (Benchmark, bgroup, mkBench, mkBenchIO) import Crypto.Random -- must come after imports {-# ANN module "HLint: ignore Use camelCase" #-} -- | Benchmarks for single-index 'Cyc' operations. -- There must be a CRT basis for \(O_m\) over @r@. {-# INLINABLE cycBenches1 #-} cycBenches1 :: forall t m r gen . _ => Proxy '(t,m,r) -> Proxy gen -> Benchmark cycBenches1 ptmr pgen = let z = zero :: Cyc t m r errorBench = mkBenchIO "error" (bench_errRounded ptmr pgen 0.1) benches = ($ z) <$> [ mkBench "zipWith (*)" (bench_mul z), mkBench "crt" bench_crt, mkBench "crtInv" bench_crtInv, mkBench "l" bench_l, mkBench "lInv" bench_lInv, mkBench "*g Pow" bench_mulgPow, mkBench "*g Dec" bench_mulgDec, mkBench "*g CRT" bench_mulgCRT, mkBench "divG Pow" bench_divGPow, mkBench "divG Dec" bench_divGDec, mkBench "divG CRT" bench_divGCRT, mkBench "lift" bench_liftPow] in bgroup "Cyc" (benches ++ [errorBench]) -- | Benchmarks for inter-ring 'Cyc' operations. -- There must be a CRT basis for \(O_{m'}\) over @r@. {-# INLINABLE cycBenches2 #-} cycBenches2 :: forall t m m' r . _ => Proxy '(t,m,m',r) -> Benchmark cycBenches2 ptmmr = let z' = zero :: Cyc t m' r z = zero :: Cyc t m r benches = [ mkBench "twacePow" (bench_twacePow ptmmr) z', mkBench "twaceDec" (bench_twaceDec ptmmr) z', mkBench "twaceCRT" (bench_twaceCRT ptmmr) z', mkBench "embedPow" (bench_embedPow ptmmr) z, mkBench "embedDec" (bench_embedDec ptmmr) z, mkBench "embedCRT" (bench_embedCRT ptmmr) z] in bgroup "Cyc" benches {-# INLINABLE bench_mul #-} -- no CRT conversion, just coefficient-wise multiplication bench_mul :: _ => Cyc t m r -> Cyc t m r -> Cyc t m r bench_mul a b = adviseCRT a * adviseCRT b {-# INLINABLE bench_crt #-} -- convert input from Pow basis to CRT basis bench_crt :: _ => Cyc t m r -> Cyc t m r bench_crt = adviseCRT . advisePow {-# INLINABLE bench_crtInv #-} -- convert input from CRT basis to Pow basis bench_crtInv :: _ => Cyc t m r -> Cyc t m r bench_crtInv = advisePow . adviseCRT {-# INLINABLE bench_l #-} -- convert input from Dec basis to Pow basis bench_l :: _ => Cyc t m r -> Cyc t m r bench_l = advisePow . adviseDec {-# INLINABLE bench_lInv #-} -- convert input from Pow basis to Dec basis bench_lInv :: _ => Cyc t m r -> Cyc t m r bench_lInv = adviseDec . advisePow {-# INLINE bench_liftPow #-} -- lift an element in the Pow basis bench_liftPow :: _ => Cyc t m r -> Cyc t m r' bench_liftPow = liftPow . advisePow {-# INLINABLE bench_mulgPow #-} -- multiply by g when input is in Pow basis bench_mulgPow :: _ => Cyc t m r -> Cyc t m r bench_mulgPow = mulG . advisePow {-# INLINABLE bench_mulgDec #-} -- multiply by g when input is in Dec basis bench_mulgDec :: _ => Cyc t m r -> Cyc t m r bench_mulgDec = mulG . adviseDec {-# INLINABLE bench_mulgCRT #-} -- multiply by g when input is in CRT basis bench_mulgCRT :: _ => Cyc t m r -> Cyc t m r bench_mulgCRT = mulG . adviseCRT {-# INLINABLE bench_divGPow #-} -- divide by g when input is in Pow basis bench_divGPow :: _ => Cyc t m r -> Maybe (Cyc t m r) bench_divGPow = divG . advisePow . mulG {-# INLINABLE bench_divGDec #-} -- divide by g when input is in Dec basis bench_divGDec :: _ => Cyc t m r -> Maybe (Cyc t m r) bench_divGDec = divG . adviseDec . mulG {-# INLINABLE bench_divGCRT #-} -- divide by g when input is in CRT basis bench_divGCRT :: _ => Cyc t m r -> Maybe (Cyc t m r) bench_divGCRT = divG . adviseCRT {-# INLINABLE bench_errRounded #-} -- generate a rounded error term bench_errRounded :: forall t m r gen . _ => Proxy '(t,m,r) -> Proxy gen -> Double -> IO (Cyc t m (LiftOf r)) bench_errRounded _ _ v = do gen <- newGenIO let e = roundedGaussian v :: Rand (CryptoRand gen) (Cyc t m (LiftOf r)) return $ evalRand e gen {-# INLINE bench_twacePow #-} bench_twacePow :: forall t m m' r . _ => Proxy '(t,m,m',r) -> Cyc t m' r -> Cyc t m r bench_twacePow _ = (twace :: Cyc t m' r -> Cyc t m r) . advisePow {-# INLINE bench_twaceDec #-} bench_twaceDec :: forall t m m' r . _ => Proxy '(t,m,m',r) -> Cyc t m' r -> Cyc t m r bench_twaceDec _ = (twace :: Cyc t m' r -> Cyc t m r) . adviseDec {-# INLINE bench_twaceCRT #-} bench_twaceCRT :: forall t m m' r . _ => Proxy '(t,m,m',r) -> Cyc t m' r -> Cyc t m r bench_twaceCRT _ = (twace :: Cyc t m' r -> Cyc t m r) . adviseCRT {-# INLINE bench_embedPow #-} bench_embedPow :: forall t m m' r . _ => Proxy '(t,m,m',r) -> Cyc t m r -> Cyc t m' r bench_embedPow _ = (advisePow . embed :: Cyc t m r -> Cyc t m' r) . advisePow {-# INLINE bench_embedDec #-} bench_embedDec :: forall t m m' r . _ => Proxy '(t,m,m',r) -> Cyc t m r -> Cyc t m' r bench_embedDec _ = (adviseDec . embed :: Cyc t m r -> Cyc t m' r) . adviseDec {-# INLINE bench_embedCRT #-} bench_embedCRT :: forall t m m' r . _ => Proxy '(t,m,m',r) -> Cyc t m r -> Cyc t m' r bench_embedCRT _ = (adviseCRT . embed :: Cyc t m r -> Cyc t m' r) . adviseCRT