{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}

module Bench.Crypto.VRF (
  benchmarks,
) where

import Data.ByteString (ByteString)
import Data.Proxy

import Control.DeepSeq

import Cardano.Crypto.VRF.Class
import Cardano.Crypto.VRF.Praos hiding (Seed)
import Cardano.Crypto.VRF.Simple

import Criterion

import Bench.Crypto.BenchData

benchmarks :: Benchmark
benchmarks :: Benchmark
benchmarks =
  String -> [Benchmark] -> Benchmark
bgroup
    String
"VRF"
    [ Proxy SimpleVRF -> String -> Benchmark
forall (proxy :: * -> *) v.
(VRFAlgorithm v, ContextVRF v ~ (), Signable v ByteString,
 NFData (CertVRF v), NFData (SignKeyVRF v), NFData (VerKeyVRF v)) =>
proxy v -> String -> Benchmark
benchVRF (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @SimpleVRF) String
"SimpleVRF"
    , Proxy PraosVRF -> String -> Benchmark
forall (proxy :: * -> *) v.
(VRFAlgorithm v, ContextVRF v ~ (), Signable v ByteString,
 NFData (CertVRF v), NFData (SignKeyVRF v), NFData (VerKeyVRF v)) =>
proxy v -> String -> Benchmark
benchVRF (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @PraosVRF) String
"PraosVRF"
    ]

benchVRF ::
  forall proxy v.
  ( VRFAlgorithm v
  , ContextVRF v ~ ()
  , Signable v ByteString
  , NFData (CertVRF v)
  , NFData (SignKeyVRF v)
  , NFData (VerKeyVRF v)
  ) =>
  proxy v ->
  [Char] ->
  Benchmark
benchVRF :: forall (proxy :: * -> *) v.
(VRFAlgorithm v, ContextVRF v ~ (), Signable v ByteString,
 NFData (CertVRF v), NFData (SignKeyVRF v), NFData (VerKeyVRF v)) =>
proxy v -> String -> Benchmark
benchVRF proxy v
_ String
lbl =
  String -> [Benchmark] -> Benchmark
bgroup
    String
lbl
    [ String -> Benchmarkable -> Benchmark
bench String
"genKey" (Benchmarkable -> Benchmark) -> Benchmarkable -> Benchmark
forall a b. (a -> b) -> a -> b
$
        (Seed -> SignKeyVRF v) -> Seed -> Benchmarkable
forall b a. NFData b => (a -> b) -> a -> Benchmarkable
nf (forall v. VRFAlgorithm v => Seed -> SignKeyVRF v
genKeyVRF @v) Seed
testSeed
    , IO (SignKeyVRF v) -> (SignKeyVRF v -> Benchmark) -> Benchmark
forall env. NFData env => IO env -> (env -> Benchmark) -> Benchmark
env (SignKeyVRF v -> IO (SignKeyVRF v)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (forall v. VRFAlgorithm v => Seed -> SignKeyVRF v
genKeyVRF @v Seed
testSeed)) ((SignKeyVRF v -> Benchmark) -> Benchmark)
-> (SignKeyVRF v -> Benchmark) -> Benchmark
forall a b. (a -> b) -> a -> b
$ \SignKeyVRF v
signKey ->
        String -> Benchmarkable -> Benchmark
bench String
"eval" (Benchmarkable -> Benchmark) -> Benchmarkable -> Benchmark
forall a b. (a -> b) -> a -> b
$
          (SignKeyVRF v -> (OutputVRF v, CertVRF v))
-> SignKeyVRF v -> Benchmarkable
forall b a. NFData b => (a -> b) -> a -> Benchmarkable
nf (forall v a.
(VRFAlgorithm v, HasCallStack, Signable v a) =>
ContextVRF v -> a -> SignKeyVRF v -> (OutputVRF v, CertVRF v)
evalVRF @v () ByteString
typicalMsg) SignKeyVRF v
signKey
    , IO (VerKeyVRF v, CertVRF v)
-> ((VerKeyVRF v, CertVRF v) -> Benchmark) -> Benchmark
forall env. NFData env => IO env -> (env -> Benchmark) -> Benchmark
env
        ( let (SignKeyVRF v
sk, VerKeyVRF v
vk) = forall v. VRFAlgorithm v => Seed -> (SignKeyVRF v, VerKeyVRF v)
genKeyPairVRF @v Seed
testSeed
              (OutputVRF v
_output, CertVRF v
cert) = forall v a.
(VRFAlgorithm v, HasCallStack, Signable v a) =>
ContextVRF v -> a -> SignKeyVRF v -> (OutputVRF v, CertVRF v)
evalVRF @v () ByteString
typicalMsg SignKeyVRF v
sk
           in (VerKeyVRF v, CertVRF v) -> IO (VerKeyVRF v, CertVRF v)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (VerKeyVRF v
vk, CertVRF v
cert)
        )
        (((VerKeyVRF v, CertVRF v) -> Benchmark) -> Benchmark)
-> ((VerKeyVRF v, CertVRF v) -> Benchmark) -> Benchmark
forall a b. (a -> b) -> a -> b
$ \ ~(VerKeyVRF v
vk, CertVRF v
cert) ->
          String -> Benchmarkable -> Benchmark
bench String
"verify" (Benchmarkable -> Benchmark) -> Benchmarkable -> Benchmark
forall a b. (a -> b) -> a -> b
$
            (CertVRF v -> Maybe (OutputVRF v)) -> CertVRF v -> Benchmarkable
forall b a. NFData b => (a -> b) -> a -> Benchmarkable
nf (ContextVRF v
-> VerKeyVRF v -> ByteString -> CertVRF v -> Maybe (OutputVRF v)
forall a.
(HasCallStack, Signable v a) =>
ContextVRF v
-> VerKeyVRF v -> a -> CertVRF v -> Maybe (OutputVRF v)
forall v a.
(VRFAlgorithm v, HasCallStack, Signable v a) =>
ContextVRF v
-> VerKeyVRF v -> a -> CertVRF v -> Maybe (OutputVRF v)
verifyVRF () VerKeyVRF v
vk ByteString
typicalMsg) CertVRF v
cert
    ]