{-# 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"
    [ 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 {k} (t :: k). Proxy t
Proxy @SimpleVRF) String
"SimpleVRF"
    , 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 {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" forall a b. (a -> b) -> a -> b
$
        forall b a. NFData b => (a -> b) -> a -> Benchmarkable
nf (forall v. VRFAlgorithm v => Seed -> SignKeyVRF v
genKeyVRF @v) Seed
testSeed
    , forall env. NFData env => IO env -> (env -> Benchmark) -> Benchmark
env (forall (m :: * -> *) a. Monad m => a -> m a
return (forall v. VRFAlgorithm v => Seed -> SignKeyVRF v
genKeyVRF @v Seed
testSeed)) forall a b. (a -> b) -> a -> b
$ \SignKeyVRF v
signKey ->
        String -> Benchmarkable -> Benchmark
bench String
"eval" forall a b. (a -> b) -> a -> b
$
          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
    , 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 forall (m :: * -> *) a. Monad m => a -> m a
return (VerKeyVRF v
vk, CertVRF v
cert)
        )
        forall a b. (a -> b) -> a -> b
$ \ ~(VerKeyVRF v
vk, CertVRF v
cert) ->
          String -> Benchmarkable -> Benchmark
bench String
"verify" forall a b. (a -> b) -> a -> b
$
            forall b a. NFData b => (a -> b) -> a -> Benchmarkable
nf (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
    ]