{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}

-- | Verifiable Random Function (VRF) implemented as FFI wrappers around the
-- implementation in <https://github.com/input-output-hk/libsodium>
module Cardano.Crypto.VRF.Praos (
  -- * VRFAlgorithm API
  PraosVRF,

  -- * Key sizes
  certSizeVRF,
  signKeySizeVRF,
  verKeySizeVRF,
  vrfKeySizeVRF,

  -- * Seed and key generation
  Seed,
  genSeed,
  keypairFromSeed,

  -- * Conversions
  outputBytes,
  proofBytes,
  skBytes,
  vkBytes,
  skToVerKey,
  skToSeed,
  proofFromBytes,
  skFromBytes,
  vkFromBytes,
  vkToBatchCompat,
  skToBatchCompat,
  outputToBatchCompat,

  -- * Core VRF operations
  prove,
  verify,
  SignKeyVRF (..),
  VerKeyVRF (..),
  CertVRF (..),

  -- * Internal types
  Proof,
  SignKey,
  VerKey,
  Output,
)
where

import Cardano.Binary (
  FromCBOR (..),
  ToCBOR (..),
 )
import Cardano.Crypto.RandomBytes (randombytes_buf)
import Cardano.Crypto.Seed (getBytesFromSeedT)
import Cardano.Crypto.Util (SignableRepresentation (..))
import Cardano.Crypto.VRF.Class
import qualified Cardano.Crypto.VRF.PraosBatchCompat as BC
import Control.DeepSeq (NFData (..))
import Control.Monad (void)
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import qualified Data.ByteString.Unsafe as BS
import Data.Coerce (coerce)
import Data.Maybe (fromMaybe)
import Data.Proxy (Proxy (..))
import Foreign.C.Types
import Foreign.ForeignPtr
import Foreign.Marshal.Alloc
import Foreign.Marshal.Utils
import Foreign.Ptr
import GHC.Generics (Generic)
import NoThunks.Class (NoThunks, OnlyCheckWhnf (..), OnlyCheckWhnfNamed (..))
import System.IO.Unsafe (unsafePerformIO)

-- Value types.
--
-- These are all transparent to the Haskell side of things, all we ever do
-- with these is pass pointers to them around. We don't want to know anything
-- about them, hence, we make them uninhabited.
--
-- The actual values are kept entirely in C memory, allocated when a value is
-- created, and freed when the value's finalizer runs.
--
-- The reason we have them at all, rather than duplicating C's void pointers,
-- is because we want to distinguish them at the type level.

data SeedValue
data SignKeyValue
data VerKeyValue
data ProofValue
data OutputValue

-- Type aliases for raw pointers
--
-- These will not leave this module, they are only here for our convenience,
-- so we can afford to not newtype them.

type SeedPtr = Ptr SeedValue
type SignKeyPtr = Ptr SignKeyValue
type VerKeyPtr = Ptr VerKeyValue
type ProofPtr = Ptr ProofValue
type OutputPtr = Ptr OutputValue

-- The exported (via the 'VRFAlgorithm' typeclass) types.
--
-- These are wrappers around 'ForeignPtr's; we don't export the constructors,
-- so callers have to go through our blessed API to create any of them. This
-- way we can make sure that we always allocate the correct sizes, and attach
-- finalizers that automatically free the memory for us.

-- | A random seed, used to derive a key pair.
newtype Seed = Seed {Seed -> ForeignPtr SeedValue
unSeed :: ForeignPtr SeedValue}
  deriving (Context -> Seed -> IO (Maybe ThunkInfo)
Proxy Seed -> String
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
showTypeOf :: Proxy Seed -> String
$cshowTypeOf :: Proxy Seed -> String
wNoThunks :: Context -> Seed -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> Seed -> IO (Maybe ThunkInfo)
noThunks :: Context -> Seed -> IO (Maybe ThunkInfo)
$cnoThunks :: Context -> Seed -> IO (Maybe ThunkInfo)
NoThunks) via OnlyCheckWhnf Seed

-- | Signing key. In this implementation, the signing key is actually a 64-byte
-- value that contains both the 32-byte signing key and the corresponding
-- 32-byte verification key.
newtype SignKey = SignKey {SignKey -> ForeignPtr SignKeyValue
unSignKey :: ForeignPtr SignKeyValue}
  deriving (forall x. Rep SignKey x -> SignKey
forall x. SignKey -> Rep SignKey x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SignKey x -> SignKey
$cfrom :: forall x. SignKey -> Rep SignKey x
Generic)
  deriving (Context -> SignKey -> IO (Maybe ThunkInfo)
Proxy SignKey -> String
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
showTypeOf :: Proxy SignKey -> String
$cshowTypeOf :: Proxy SignKey -> String
wNoThunks :: Context -> SignKey -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> SignKey -> IO (Maybe ThunkInfo)
noThunks :: Context -> SignKey -> IO (Maybe ThunkInfo)
$cnoThunks :: Context -> SignKey -> IO (Maybe ThunkInfo)
NoThunks) via OnlyCheckWhnf SignKey

instance NFData SignKey where
  rnf :: SignKey -> ()
rnf SignKey
a = seq :: forall a b. a -> b -> b
seq SignKey
a ()

-- | Verification key.
newtype VerKey = VerKey {VerKey -> ForeignPtr VerKeyValue
unVerKey :: ForeignPtr VerKeyValue}
  deriving (forall x. Rep VerKey x -> VerKey
forall x. VerKey -> Rep VerKey x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep VerKey x -> VerKey
$cfrom :: forall x. VerKey -> Rep VerKey x
Generic)
  deriving (Context -> VerKey -> IO (Maybe ThunkInfo)
Proxy VerKey -> String
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
showTypeOf :: Proxy VerKey -> String
$cshowTypeOf :: Proxy VerKey -> String
wNoThunks :: Context -> VerKey -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> VerKey -> IO (Maybe ThunkInfo)
noThunks :: Context -> VerKey -> IO (Maybe ThunkInfo)
$cnoThunks :: Context -> VerKey -> IO (Maybe ThunkInfo)
NoThunks) via OnlyCheckWhnf VerKey

instance NFData VerKey where
  rnf :: VerKey -> ()
rnf VerKey
a = seq :: forall a b. a -> b -> b
seq VerKey
a ()

-- | A proof, as constructed by the 'prove' function.
newtype Proof = Proof {Proof -> ForeignPtr ProofValue
unProof :: ForeignPtr ProofValue}
  deriving (forall x. Rep Proof x -> Proof
forall x. Proof -> Rep Proof x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Proof x -> Proof
$cfrom :: forall x. Proof -> Rep Proof x
Generic)
  deriving (Context -> Proof -> IO (Maybe ThunkInfo)
Proxy Proof -> String
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
showTypeOf :: Proxy Proof -> String
$cshowTypeOf :: Proxy Proof -> String
wNoThunks :: Context -> Proof -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> Proof -> IO (Maybe ThunkInfo)
noThunks :: Context -> Proof -> IO (Maybe ThunkInfo)
$cnoThunks :: Context -> Proof -> IO (Maybe ThunkInfo)
NoThunks) via OnlyCheckWhnf Proof

instance NFData Proof where
  rnf :: Proof -> ()
rnf Proof
a = seq :: forall a b. a -> b -> b
seq Proof
a ()

-- | Hashed output of a proof verification, as returned by the 'verify'
-- function.
newtype Output = Output {Output -> ForeignPtr OutputValue
unOutput :: ForeignPtr OutputValue}
  deriving (forall x. Rep Output x -> Output
forall x. Output -> Rep Output x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Output x -> Output
$cfrom :: forall x. Output -> Rep Output x
Generic)
  deriving (Context -> Output -> IO (Maybe ThunkInfo)
Proxy Output -> String
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
showTypeOf :: Proxy Output -> String
$cshowTypeOf :: Proxy Output -> String
wNoThunks :: Context -> Output -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> Output -> IO (Maybe ThunkInfo)
noThunks :: Context -> Output -> IO (Maybe ThunkInfo)
$cnoThunks :: Context -> Output -> IO (Maybe ThunkInfo)
NoThunks) via OnlyCheckWhnf Output

-- Raw low-level FFI bindings.
--
foreign import ccall "crypto_vrf_ietfdraft03_bytes" crypto_vrf_bytes :: CSize

foreign import ccall "crypto_vrf_ietfdraft03_publickeybytes" crypto_vrf_publickeybytes :: CSize

foreign import ccall "crypto_vrf_ietfdraft03_secretkeybytes" crypto_vrf_secretkeybytes :: CSize

foreign import ccall "crypto_vrf_ietfdraft03_seedbytes" crypto_vrf_seedbytes :: CSize

foreign import ccall "crypto_vrf_ietfdraft03_outputbytes" crypto_vrf_outputbytes :: CSize

foreign import ccall "crypto_vrf_ietfdraft03_keypair_from_seed"
  crypto_vrf_keypair_from_seed :: VerKeyPtr -> SignKeyPtr -> SeedPtr -> IO CInt

foreign import ccall "crypto_vrf_ietfdraft03_sk_to_pk"
  crypto_vrf_sk_to_pk :: VerKeyPtr -> SignKeyPtr -> IO ()

foreign import ccall "crypto_vrf_ietfdraft03_sk_to_seed"
  crypto_vrf_sk_to_seed :: SeedPtr -> SignKeyPtr -> IO ()

foreign import ccall "crypto_vrf_ietfdraft03_prove"
  crypto_vrf_prove :: ProofPtr -> SignKeyPtr -> Ptr CChar -> CULLong -> IO CInt

foreign import ccall "crypto_vrf_ietfdraft03_verify"
  crypto_vrf_verify :: OutputPtr -> VerKeyPtr -> ProofPtr -> Ptr CChar -> CULLong -> IO CInt

foreign import ccall "crypto_vrf_ietfdraft03_proof_to_hash"
  crypto_vrf_proof_to_hash :: OutputPtr -> ProofPtr -> IO CInt

-- Key size constants

certSizeVRF :: Int
certSizeVRF :: Int
certSizeVRF = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$! CSize
crypto_vrf_bytes

signKeySizeVRF :: Int
signKeySizeVRF :: Int
signKeySizeVRF = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$! CSize
crypto_vrf_secretkeybytes

verKeySizeVRF :: Int
verKeySizeVRF :: Int
verKeySizeVRF = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$! CSize
crypto_vrf_publickeybytes

vrfKeySizeVRF :: Int
vrfKeySizeVRF :: Int
vrfKeySizeVRF = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$! CSize
crypto_vrf_outputbytes

-- | Allocate a 'Seed' and attach a finalizer. The allocated memory will not be initialized.
mkSeed :: IO Seed
mkSeed :: IO Seed
mkSeed = do
  Ptr SeedValue
ptr <- forall a. Int -> IO (Ptr a)
mallocBytes (forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
crypto_vrf_seedbytes)
  ForeignPtr SeedValue -> Seed
Seed forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr forall a. FinalizerPtr a
finalizerFree Ptr SeedValue
ptr

-- | Generate a random seed.
-- Uses 'randombytes_buf' to create random data.
--
-- This function provides an alternative way of generating seeds specifically
-- for the 'PraosVRF' algorithm. Unlike the 'genKeyPairVRF' method, which uses
-- a 'ByteString'-based 'Cardano.Crypto.Seed.Seed', this seed generation method
-- bypasses the GHC heap, keeping the seed in C-allocated memory instead.
--
-- This provides two advantages:
-- 1. It avoids the overhead of unnecessary GHC-side heap allocations.
-- 2. It avoids leaking the seed via the GHC heap; the 'Seed' type itself
--    takes care of zeroing out its memory upon finalization.
genSeed :: IO Seed
genSeed :: IO Seed
genSeed = do
  Seed
seed <- IO Seed
mkSeed
  forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr (Seed -> ForeignPtr SeedValue
unSeed Seed
seed) forall a b. (a -> b) -> a -> b
$ \Ptr SeedValue
ptr ->
    forall a. Ptr a -> CSize -> IO ()
randombytes_buf Ptr SeedValue
ptr CSize
crypto_vrf_seedbytes
  forall (m :: * -> *) a. Monad m => a -> m a
return Seed
seed

copyFromByteString :: Ptr a -> ByteString -> Int -> IO ()
copyFromByteString :: forall a. Ptr a -> ByteString -> Int -> IO ()
copyFromByteString Ptr a
ptr ByteString
bs Int
lenExpected =
  forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.unsafeUseAsCStringLen ByteString
bs forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
cstr, Int
lenActual) ->
    if Int
lenActual forall a. Ord a => a -> a -> Bool
>= Int
lenExpected
      then forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes (forall a b. Ptr a -> Ptr b
castPtr Ptr a
ptr) Ptr CChar
cstr Int
lenExpected
      else
        forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$
          String
"Invalid input size, expected at least "
            forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show Int
lenExpected
            forall a. Semigroup a => a -> a -> a
<> String
", but got "
            forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show Int
lenActual

seedFromBytes :: ByteString -> Seed
seedFromBytes :: ByteString -> Seed
seedFromBytes ByteString
bs = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ do
  Seed
seed <- IO Seed
mkSeed
  forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr (Seed -> ForeignPtr SeedValue
unSeed Seed
seed) forall a b. (a -> b) -> a -> b
$ \Ptr SeedValue
ptr ->
    forall a. Ptr a -> ByteString -> Int -> IO ()
copyFromByteString Ptr SeedValue
ptr ByteString
bs (forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
crypto_vrf_seedbytes)
  forall (m :: * -> *) a. Monad m => a -> m a
return Seed
seed

-- | Convert a proof verification output hash into a 'ByteString' that we can
-- inspect.
outputBytes :: Output -> ByteString
outputBytes :: Output -> ByteString
outputBytes (Output ForeignPtr OutputValue
op) = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr OutputValue
op forall a b. (a -> b) -> a -> b
$ \Ptr OutputValue
ptr ->
  CStringLen -> IO ByteString
BS.packCStringLen (forall a b. Ptr a -> Ptr b
castPtr Ptr OutputValue
ptr, forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
crypto_vrf_outputbytes)

-- | Convert a proof into a 'ByteString' that we can inspect.
proofBytes :: Proof -> ByteString
proofBytes :: Proof -> ByteString
proofBytes (Proof ForeignPtr ProofValue
op) = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr ProofValue
op forall a b. (a -> b) -> a -> b
$ \Ptr ProofValue
ptr ->
  CStringLen -> IO ByteString
BS.packCStringLen (forall a b. Ptr a -> Ptr b
castPtr Ptr ProofValue
ptr, Int
certSizeVRF)

-- | Convert a verification key into a 'ByteString' that we can inspect.
vkBytes :: VerKey -> ByteString
vkBytes :: VerKey -> ByteString
vkBytes (VerKey ForeignPtr VerKeyValue
op) = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr VerKeyValue
op forall a b. (a -> b) -> a -> b
$ \Ptr VerKeyValue
ptr ->
  CStringLen -> IO ByteString
BS.packCStringLen (forall a b. Ptr a -> Ptr b
castPtr Ptr VerKeyValue
ptr, Int
verKeySizeVRF)

-- | Convert a signing key into a 'ByteString' that we can inspect.
skBytes :: SignKey -> ByteString
skBytes :: SignKey -> ByteString
skBytes (SignKey ForeignPtr SignKeyValue
op) = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr SignKeyValue
op forall a b. (a -> b) -> a -> b
$ \Ptr SignKeyValue
ptr ->
  CStringLen -> IO ByteString
BS.packCStringLen (forall a b. Ptr a -> Ptr b
castPtr Ptr SignKeyValue
ptr, Int
signKeySizeVRF)

instance Show Proof where
  show :: Proof -> String
show = forall a. Show a => a -> String
show forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proof -> ByteString
proofBytes

instance Eq Proof where
  Proof
a == :: Proof -> Proof -> Bool
== Proof
b = Proof -> ByteString
proofBytes Proof
a forall a. Eq a => a -> a -> Bool
== Proof -> ByteString
proofBytes Proof
b

instance ToCBOR Proof where
  toCBOR :: Proof -> Encoding
toCBOR = forall a. ToCBOR a => a -> Encoding
toCBOR forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proof -> ByteString
proofBytes
  encodedSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size) -> Proxy Proof -> Size
encodedSizeExpr forall t. ToCBOR t => Proxy t -> Size
_ Proxy Proof
_ =
    forall a.
ToCBOR a =>
(forall t. ToCBOR t => Proxy t -> Size) -> Proxy a -> Size
encodedSizeExpr (\Proxy t
_ -> forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
certSizeVRF) (forall {k} (t :: k). Proxy t
Proxy :: Proxy ByteString)

instance FromCBOR Proof where
  fromCBOR :: forall s. Decoder s Proof
fromCBOR = forall a s. FromCBOR a => Decoder s a
fromCBOR forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *). MonadFail m => ByteString -> m Proof
proofFromBytes

instance Show SignKey where
  show :: SignKey -> String
show = forall a. Show a => a -> String
show forall b c a. (b -> c) -> (a -> b) -> a -> c
. SignKey -> ByteString
skBytes

instance Eq SignKey where
  SignKey
a == :: SignKey -> SignKey -> Bool
== SignKey
b = SignKey -> ByteString
skBytes SignKey
a forall a. Eq a => a -> a -> Bool
== SignKey -> ByteString
skBytes SignKey
b

instance ToCBOR SignKey where
  toCBOR :: SignKey -> Encoding
toCBOR = forall a. ToCBOR a => a -> Encoding
toCBOR forall b c a. (b -> c) -> (a -> b) -> a -> c
. SignKey -> ByteString
skBytes
  encodedSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size) -> Proxy SignKey -> Size
encodedSizeExpr forall t. ToCBOR t => Proxy t -> Size
_ Proxy SignKey
_ =
    forall a.
ToCBOR a =>
(forall t. ToCBOR t => Proxy t -> Size) -> Proxy a -> Size
encodedSizeExpr (\Proxy t
_ -> forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
signKeySizeVRF) (forall {k} (t :: k). Proxy t
Proxy :: Proxy ByteString)

instance FromCBOR SignKey where
  fromCBOR :: forall s. Decoder s SignKey
fromCBOR = forall a s. FromCBOR a => Decoder s a
fromCBOR forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *). MonadFail m => ByteString -> m SignKey
skFromBytes

instance Show VerKey where
  show :: VerKey -> String
show = forall a. Show a => a -> String
show forall b c a. (b -> c) -> (a -> b) -> a -> c
. VerKey -> ByteString
vkBytes

instance Eq VerKey where
  VerKey
a == :: VerKey -> VerKey -> Bool
== VerKey
b = VerKey -> ByteString
vkBytes VerKey
a forall a. Eq a => a -> a -> Bool
== VerKey -> ByteString
vkBytes VerKey
b

instance ToCBOR VerKey where
  toCBOR :: VerKey -> Encoding
toCBOR = forall a. ToCBOR a => a -> Encoding
toCBOR forall b c a. (b -> c) -> (a -> b) -> a -> c
. VerKey -> ByteString
vkBytes
  encodedSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size) -> Proxy VerKey -> Size
encodedSizeExpr forall t. ToCBOR t => Proxy t -> Size
_ Proxy VerKey
_ =
    forall a.
ToCBOR a =>
(forall t. ToCBOR t => Proxy t -> Size) -> Proxy a -> Size
encodedSizeExpr (\Proxy t
_ -> forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
verKeySizeVRF) (forall {k} (t :: k). Proxy t
Proxy :: Proxy ByteString)

instance FromCBOR VerKey where
  fromCBOR :: forall s. Decoder s VerKey
fromCBOR = forall a s. FromCBOR a => Decoder s a
fromCBOR forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *). MonadFail m => ByteString -> m VerKey
vkFromBytes

-- | Allocate a Verification Key and attach a finalizer. The allocated memory will
-- not be initialized.
mkVerKey :: IO VerKey
mkVerKey :: IO VerKey
mkVerKey = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ForeignPtr VerKeyValue -> VerKey
VerKey forall a b. (a -> b) -> a -> b
$ forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr forall a. FinalizerPtr a
finalizerFree forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. Int -> IO (Ptr a)
mallocBytes Int
verKeySizeVRF

-- | Allocate a Signing Key and attach a finalizer. The allocated memory will
-- not be initialized.
mkSignKey :: IO SignKey
mkSignKey :: IO SignKey
mkSignKey = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ForeignPtr SignKeyValue -> SignKey
SignKey forall a b. (a -> b) -> a -> b
$ forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr forall a. FinalizerPtr a
finalizerFree forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. Int -> IO (Ptr a)
mallocBytes Int
signKeySizeVRF

-- | Allocate a Proof and attach a finalizer. The allocated memory will
-- not be initialized.
mkProof :: IO Proof
mkProof :: IO Proof
mkProof = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ForeignPtr ProofValue -> Proof
Proof forall a b. (a -> b) -> a -> b
$ forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr forall a. FinalizerPtr a
finalizerFree forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. Int -> IO (Ptr a)
mallocBytes Int
certSizeVRF

proofFromBytes :: MonadFail m => ByteString -> m Proof
proofFromBytes :: forall (m :: * -> *). MonadFail m => ByteString -> m Proof
proofFromBytes ByteString
bs
  | Int
bsLen forall a. Eq a => a -> a -> Bool
/= Int
certSizeVRF =
      forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$
        String
"Invalid proof length "
          forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show @Int Int
bsLen
          forall a. Semigroup a => a -> a -> a
<> String
", expecting "
          forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show @Int Int
certSizeVRF
  | Bool
otherwise = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$! forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ do
      Proof
proof <- IO Proof
mkProof
      forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr (Proof -> ForeignPtr ProofValue
unProof Proof
proof) forall a b. (a -> b) -> a -> b
$ \Ptr ProofValue
ptr ->
        forall a. Ptr a -> ByteString -> Int -> IO ()
copyFromByteString Ptr ProofValue
ptr ByteString
bs Int
certSizeVRF
      forall (m :: * -> *) a. Monad m => a -> m a
return Proof
proof
  where
    bsLen :: Int
bsLen = ByteString -> Int
BS.length ByteString
bs

skFromBytes :: MonadFail m => ByteString -> m SignKey
skFromBytes :: forall (m :: * -> *). MonadFail m => ByteString -> m SignKey
skFromBytes ByteString
bs = do
  if Int
bsLen forall a. Eq a => a -> a -> Bool
/= Int
signKeySizeVRF
    then
      forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$
        String
"Invalid SignKey length "
          forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show @Int Int
bsLen
          forall a. Semigroup a => a -> a -> a
<> String
", expecting "
          forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show @Int Int
signKeySizeVRF
    else forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$! forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ do
      SignKey
sk <- IO SignKey
mkSignKey
      forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr (SignKey -> ForeignPtr SignKeyValue
unSignKey SignKey
sk) forall a b. (a -> b) -> a -> b
$ \Ptr SignKeyValue
ptr ->
        forall a. Ptr a -> ByteString -> Int -> IO ()
copyFromByteString Ptr SignKeyValue
ptr ByteString
bs Int
signKeySizeVRF
      forall (m :: * -> *) a. Monad m => a -> m a
return SignKey
sk
  where
    bsLen :: Int
bsLen = ByteString -> Int
BS.length ByteString
bs

vkFromBytes :: MonadFail m => ByteString -> m VerKey
vkFromBytes :: forall (m :: * -> *). MonadFail m => ByteString -> m VerKey
vkFromBytes ByteString
bs = do
  if Int
bsLen forall a. Eq a => a -> a -> Bool
/= Int
verKeySizeVRF
    then
      forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$
        String
"Invalid VerKey length "
          forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show @Int Int
bsLen
          forall a. Semigroup a => a -> a -> a
<> String
", expecting "
          forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show @Int Int
verKeySizeVRF
    else forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$! forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ do
      VerKey
pk <- IO VerKey
mkVerKey
      forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr (VerKey -> ForeignPtr VerKeyValue
unVerKey VerKey
pk) forall a b. (a -> b) -> a -> b
$ \Ptr VerKeyValue
ptr ->
        forall a. Ptr a -> ByteString -> Int -> IO ()
copyFromByteString Ptr VerKeyValue
ptr ByteString
bs Int
verKeySizeVRF
      forall (m :: * -> *) a. Monad m => a -> m a
return VerKey
pk
  where
    bsLen :: Int
bsLen = ByteString -> Int
BS.length ByteString
bs

-- | Allocate an Output and attach a finalizer. The allocated memory will
-- not be initialized.
mkOutput :: IO Output
mkOutput :: IO Output
mkOutput = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ForeignPtr OutputValue -> Output
Output forall a b. (a -> b) -> a -> b
$ forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr forall a. FinalizerPtr a
finalizerFree forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. Int -> IO (Ptr a)
mallocBytes (forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
crypto_vrf_outputbytes)

-- | Derive a key pair (Sign + Verify) from a seed.
keypairFromSeed :: Seed -> (VerKey, SignKey)
keypairFromSeed :: Seed -> (VerKey, SignKey)
keypairFromSeed Seed
seed =
  forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr (Seed -> ForeignPtr SeedValue
unSeed Seed
seed) forall a b. (a -> b) -> a -> b
$ \Ptr SeedValue
sptr -> do
    VerKey
pk <- IO VerKey
mkVerKey
    SignKey
sk <- IO SignKey
mkSignKey
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr (VerKey -> ForeignPtr VerKeyValue
unVerKey VerKey
pk) forall a b. (a -> b) -> a -> b
$ \Ptr VerKeyValue
pkPtr -> do
      forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr (SignKey -> ForeignPtr SignKeyValue
unSignKey SignKey
sk) forall a b. (a -> b) -> a -> b
$ \Ptr SignKeyValue
skPtr -> do
        forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ Ptr VerKeyValue -> Ptr SignKeyValue -> Ptr SeedValue -> IO CInt
crypto_vrf_keypair_from_seed Ptr VerKeyValue
pkPtr Ptr SignKeyValue
skPtr Ptr SeedValue
sptr
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ VerKey
pk seq :: forall a b. a -> b -> b
`seq` SignKey
sk seq :: forall a b. a -> b -> b
`seq` (VerKey
pk, SignKey
sk)

-- | Derive a Verification Key from a Signing Key.
skToVerKey :: SignKey -> VerKey
skToVerKey :: SignKey -> VerKey
skToVerKey SignKey
sk =
  forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr (SignKey -> ForeignPtr SignKeyValue
unSignKey SignKey
sk) forall a b. (a -> b) -> a -> b
$ \Ptr SignKeyValue
skPtr -> do
    VerKey
pk <- IO VerKey
mkVerKey
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr (VerKey -> ForeignPtr VerKeyValue
unVerKey VerKey
pk) forall a b. (a -> b) -> a -> b
$ \Ptr VerKeyValue
pkPtr -> do
      Ptr VerKeyValue -> Ptr SignKeyValue -> IO ()
crypto_vrf_sk_to_pk Ptr VerKeyValue
pkPtr Ptr SignKeyValue
skPtr
    forall (m :: * -> *) a. Monad m => a -> m a
return VerKey
pk

-- | Get the seed used to generate a given Signing Key
skToSeed :: SignKey -> Seed
skToSeed :: SignKey -> Seed
skToSeed SignKey
sk =
  forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr (SignKey -> ForeignPtr SignKeyValue
unSignKey SignKey
sk) forall a b. (a -> b) -> a -> b
$ \Ptr SignKeyValue
skPtr -> do
    Seed
seed <- IO Seed
mkSeed
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr (Seed -> ForeignPtr SeedValue
unSeed Seed
seed) forall a b. (a -> b) -> a -> b
$ \Ptr SeedValue
seedPtr ->
      Ptr SeedValue -> Ptr SignKeyValue -> IO ()
crypto_vrf_sk_to_seed Ptr SeedValue
seedPtr Ptr SignKeyValue
skPtr
    forall (m :: * -> *) a. Monad m => a -> m a
return Seed
seed

-- | Construct a proof from a Signing Key and a message.
-- Returns 'Just' the proof on success, 'Nothing' if the signing key could not
-- be decoded.
prove :: SignKey -> ByteString -> Maybe Proof
prove :: SignKey -> ByteString -> Maybe Proof
prove SignKey
sk ByteString
msg =
  forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr (SignKey -> ForeignPtr SignKeyValue
unSignKey SignKey
sk) forall a b. (a -> b) -> a -> b
$ \Ptr SignKeyValue
skPtr -> do
      Proof
proof <- IO Proof
mkProof
      forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.useAsCStringLen ByteString
msg forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
m, Int
mlen) -> do
        forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr (Proof -> ForeignPtr ProofValue
unProof Proof
proof) forall a b. (a -> b) -> a -> b
$ \Ptr ProofValue
proofPtr -> do
          Ptr ProofValue
-> Ptr SignKeyValue -> Ptr CChar -> CULLong -> IO CInt
crypto_vrf_prove Ptr ProofValue
proofPtr Ptr SignKeyValue
skPtr Ptr CChar
m (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
mlen) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
            CInt
0 -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$! Proof
proof
            CInt
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing

-- | Construct a BatchCompat vkey from praos, non-batchcompat
vkToBatchCompat :: VerKeyVRF PraosVRF -> VerKeyVRF BC.PraosBatchCompatVRF
vkToBatchCompat :: VerKeyVRF PraosVRF -> VerKeyVRF PraosBatchCompatVRF
vkToBatchCompat VerKeyVRF PraosVRF
praosVk =
  case forall v. VRFAlgorithm v => ByteString -> Maybe (VerKeyVRF v)
rawDeserialiseVerKeyVRF (forall v. VRFAlgorithm v => VerKeyVRF v -> ByteString
rawSerialiseVerKeyVRF VerKeyVRF PraosVRF
praosVk) of
    Just VerKeyVRF PraosBatchCompatVRF
vk -> VerKeyVRF PraosBatchCompatVRF
vk
    Maybe (VerKeyVRF PraosBatchCompatVRF)
Nothing -> forall a. HasCallStack => String -> a
error String
"VerKeyVRF: Unable to convert PraosVK to BatchCompatVK."

-- | Construct a BatchCompat skey from praos, non-batchcompat
skToBatchCompat :: SignKeyVRF PraosVRF -> SignKeyVRF BC.PraosBatchCompatVRF
skToBatchCompat :: SignKeyVRF PraosVRF -> SignKeyVRF PraosBatchCompatVRF
skToBatchCompat SignKeyVRF PraosVRF
praosSk =
  case forall v. VRFAlgorithm v => ByteString -> Maybe (SignKeyVRF v)
rawDeserialiseSignKeyVRF (forall v. VRFAlgorithm v => SignKeyVRF v -> ByteString
rawSerialiseSignKeyVRF SignKeyVRF PraosVRF
praosSk) of
    Just SignKeyVRF PraosBatchCompatVRF
sk -> SignKeyVRF PraosBatchCompatVRF
sk
    Maybe (SignKeyVRF PraosBatchCompatVRF)
Nothing -> forall a. HasCallStack => String -> a
error String
"SignKeyVRF: Unable to convert PraosSK to BatchCompatSK."

-- | Construct a BatchCompat output from praos, non-batchcompat
outputToBatchCompat :: OutputVRF PraosVRF -> OutputVRF BC.PraosBatchCompatVRF
outputToBatchCompat :: OutputVRF PraosVRF -> OutputVRF PraosBatchCompatVRF
outputToBatchCompat OutputVRF PraosVRF
praosOutput =
  if Int
vrfKeySizeVRF forall a. Eq a => a -> a -> Bool
/= Int
BC.vrfKeySizeVRF
    then forall a. HasCallStack => String -> a
error String
"OutputVRF: Unable to convert PraosSK to BatchCompatSK."
    else
      forall v. ByteString -> OutputVRF v
OutputVRF (forall v. OutputVRF v -> ByteString
getOutputVRFBytes OutputVRF PraosVRF
praosOutput)

-- | Verify a VRF proof and validate the Verification Key. Returns 'Just' a hash of
-- the verification result on success, 'Nothing' if the verification did not
-- succeed.
--
-- For a given verification key and message, there are many possible proofs but only
-- one possible output hash.
verify :: VerKey -> Proof -> ByteString -> Maybe Output
verify :: VerKey -> Proof -> ByteString -> Maybe Output
verify VerKey
pk Proof
proof ByteString
msg =
  forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr (VerKey -> ForeignPtr VerKeyValue
unVerKey VerKey
pk) forall a b. (a -> b) -> a -> b
$ \Ptr VerKeyValue
pkPtr -> do
      forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr (Proof -> ForeignPtr ProofValue
unProof Proof
proof) forall a b. (a -> b) -> a -> b
$ \Ptr ProofValue
proofPtr -> do
        Output
output <- IO Output
mkOutput
        forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.useAsCStringLen ByteString
msg forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
m, Int
mlen) -> do
          forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr (Output -> ForeignPtr OutputValue
unOutput Output
output) forall a b. (a -> b) -> a -> b
$ \Ptr OutputValue
outputPtr -> do
            Ptr OutputValue
-> Ptr VerKeyValue
-> Ptr ProofValue
-> Ptr CChar
-> CULLong
-> IO CInt
crypto_vrf_verify Ptr OutputValue
outputPtr Ptr VerKeyValue
pkPtr Ptr ProofValue
proofPtr Ptr CChar
m (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
mlen) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
              CInt
0 -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$! Output
output
              CInt
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing

outputFromProof :: Proof -> Maybe Output
outputFromProof :: Proof -> Maybe Output
outputFromProof (Proof ForeignPtr ProofValue
p) =
  forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr ProofValue
p forall a b. (a -> b) -> a -> b
$ \Ptr ProofValue
ptr -> do
      Output
output <- IO Output
mkOutput
      forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr (Output -> ForeignPtr OutputValue
unOutput Output
output) forall a b. (a -> b) -> a -> b
$ \Ptr OutputValue
outputPtr -> do
        Ptr OutputValue -> Ptr ProofValue -> IO CInt
crypto_vrf_proof_to_hash Ptr OutputValue
outputPtr Ptr ProofValue
ptr forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
          CInt
0 -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$! Output
output
          CInt
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing

data PraosVRF

instance VRFAlgorithm PraosVRF where
  newtype VerKeyVRF PraosVRF = VerKeyPraosVRF VerKey
    deriving stock (Int -> VerKeyVRF PraosVRF -> ShowS
[VerKeyVRF PraosVRF] -> ShowS
VerKeyVRF PraosVRF -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [VerKeyVRF PraosVRF] -> ShowS
$cshowList :: [VerKeyVRF PraosVRF] -> ShowS
show :: VerKeyVRF PraosVRF -> String
$cshow :: VerKeyVRF PraosVRF -> String
showsPrec :: Int -> VerKeyVRF PraosVRF -> ShowS
$cshowsPrec :: Int -> VerKeyVRF PraosVRF -> ShowS
Show, VerKeyVRF PraosVRF -> VerKeyVRF PraosVRF -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: VerKeyVRF PraosVRF -> VerKeyVRF PraosVRF -> Bool
$c/= :: VerKeyVRF PraosVRF -> VerKeyVRF PraosVRF -> Bool
== :: VerKeyVRF PraosVRF -> VerKeyVRF PraosVRF -> Bool
$c== :: VerKeyVRF PraosVRF -> VerKeyVRF PraosVRF -> Bool
Eq, forall x. Rep (VerKeyVRF PraosVRF) x -> VerKeyVRF PraosVRF
forall x. VerKeyVRF PraosVRF -> Rep (VerKeyVRF PraosVRF) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep (VerKeyVRF PraosVRF) x -> VerKeyVRF PraosVRF
$cfrom :: forall x. VerKeyVRF PraosVRF -> Rep (VerKeyVRF PraosVRF) x
Generic)
    deriving newtype (Typeable (VerKeyVRF PraosVRF)
VerKeyVRF PraosVRF -> Encoding
(forall t. ToCBOR t => Proxy t -> Size)
-> Proxy [VerKeyVRF PraosVRF] -> Size
(forall t. ToCBOR t => Proxy t -> Size)
-> Proxy (VerKeyVRF PraosVRF) -> Size
forall a.
Typeable a
-> (a -> Encoding)
-> ((forall t. ToCBOR t => Proxy t -> Size) -> Proxy a -> Size)
-> ((forall t. ToCBOR t => Proxy t -> Size) -> Proxy [a] -> Size)
-> ToCBOR a
encodedListSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy [VerKeyVRF PraosVRF] -> Size
$cencodedListSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy [VerKeyVRF PraosVRF] -> Size
encodedSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy (VerKeyVRF PraosVRF) -> Size
$cencodedSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy (VerKeyVRF PraosVRF) -> Size
toCBOR :: VerKeyVRF PraosVRF -> Encoding
$ctoCBOR :: VerKeyVRF PraosVRF -> Encoding
ToCBOR, Typeable (VerKeyVRF PraosVRF)
Proxy (VerKeyVRF PraosVRF) -> Text
forall s. Decoder s (VerKeyVRF PraosVRF)
forall a.
Typeable a
-> (forall s. Decoder s a) -> (Proxy a -> Text) -> FromCBOR a
label :: Proxy (VerKeyVRF PraosVRF) -> Text
$clabel :: Proxy (VerKeyVRF PraosVRF) -> Text
fromCBOR :: forall s. Decoder s (VerKeyVRF PraosVRF)
$cfromCBOR :: forall s. Decoder s (VerKeyVRF PraosVRF)
FromCBOR)
    deriving (Context -> VerKeyVRF PraosVRF -> IO (Maybe ThunkInfo)
Proxy (VerKeyVRF PraosVRF) -> String
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
showTypeOf :: Proxy (VerKeyVRF PraosVRF) -> String
$cshowTypeOf :: Proxy (VerKeyVRF PraosVRF) -> String
wNoThunks :: Context -> VerKeyVRF PraosVRF -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> VerKeyVRF PraosVRF -> IO (Maybe ThunkInfo)
noThunks :: Context -> VerKeyVRF PraosVRF -> IO (Maybe ThunkInfo)
$cnoThunks :: Context -> VerKeyVRF PraosVRF -> IO (Maybe ThunkInfo)
NoThunks) via OnlyCheckWhnfNamed "VerKeyVRF PraosVRF" VerKey
    deriving newtype (VerKeyVRF PraosVRF -> ()
forall a. (a -> ()) -> NFData a
rnf :: VerKeyVRF PraosVRF -> ()
$crnf :: VerKeyVRF PraosVRF -> ()
NFData)

  newtype SignKeyVRF PraosVRF = SignKeyPraosVRF SignKey
    deriving stock (Int -> SignKeyVRF PraosVRF -> ShowS
[SignKeyVRF PraosVRF] -> ShowS
SignKeyVRF PraosVRF -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SignKeyVRF PraosVRF] -> ShowS
$cshowList :: [SignKeyVRF PraosVRF] -> ShowS
show :: SignKeyVRF PraosVRF -> String
$cshow :: SignKeyVRF PraosVRF -> String
showsPrec :: Int -> SignKeyVRF PraosVRF -> ShowS
$cshowsPrec :: Int -> SignKeyVRF PraosVRF -> ShowS
Show, SignKeyVRF PraosVRF -> SignKeyVRF PraosVRF -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SignKeyVRF PraosVRF -> SignKeyVRF PraosVRF -> Bool
$c/= :: SignKeyVRF PraosVRF -> SignKeyVRF PraosVRF -> Bool
== :: SignKeyVRF PraosVRF -> SignKeyVRF PraosVRF -> Bool
$c== :: SignKeyVRF PraosVRF -> SignKeyVRF PraosVRF -> Bool
Eq, forall x. Rep (SignKeyVRF PraosVRF) x -> SignKeyVRF PraosVRF
forall x. SignKeyVRF PraosVRF -> Rep (SignKeyVRF PraosVRF) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep (SignKeyVRF PraosVRF) x -> SignKeyVRF PraosVRF
$cfrom :: forall x. SignKeyVRF PraosVRF -> Rep (SignKeyVRF PraosVRF) x
Generic)
    deriving newtype (Typeable (SignKeyVRF PraosVRF)
SignKeyVRF PraosVRF -> Encoding
(forall t. ToCBOR t => Proxy t -> Size)
-> Proxy [SignKeyVRF PraosVRF] -> Size
(forall t. ToCBOR t => Proxy t -> Size)
-> Proxy (SignKeyVRF PraosVRF) -> Size
forall a.
Typeable a
-> (a -> Encoding)
-> ((forall t. ToCBOR t => Proxy t -> Size) -> Proxy a -> Size)
-> ((forall t. ToCBOR t => Proxy t -> Size) -> Proxy [a] -> Size)
-> ToCBOR a
encodedListSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy [SignKeyVRF PraosVRF] -> Size
$cencodedListSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy [SignKeyVRF PraosVRF] -> Size
encodedSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy (SignKeyVRF PraosVRF) -> Size
$cencodedSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy (SignKeyVRF PraosVRF) -> Size
toCBOR :: SignKeyVRF PraosVRF -> Encoding
$ctoCBOR :: SignKeyVRF PraosVRF -> Encoding
ToCBOR, Typeable (SignKeyVRF PraosVRF)
Proxy (SignKeyVRF PraosVRF) -> Text
forall s. Decoder s (SignKeyVRF PraosVRF)
forall a.
Typeable a
-> (forall s. Decoder s a) -> (Proxy a -> Text) -> FromCBOR a
label :: Proxy (SignKeyVRF PraosVRF) -> Text
$clabel :: Proxy (SignKeyVRF PraosVRF) -> Text
fromCBOR :: forall s. Decoder s (SignKeyVRF PraosVRF)
$cfromCBOR :: forall s. Decoder s (SignKeyVRF PraosVRF)
FromCBOR)
    deriving (Context -> SignKeyVRF PraosVRF -> IO (Maybe ThunkInfo)
Proxy (SignKeyVRF PraosVRF) -> String
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
showTypeOf :: Proxy (SignKeyVRF PraosVRF) -> String
$cshowTypeOf :: Proxy (SignKeyVRF PraosVRF) -> String
wNoThunks :: Context -> SignKeyVRF PraosVRF -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> SignKeyVRF PraosVRF -> IO (Maybe ThunkInfo)
noThunks :: Context -> SignKeyVRF PraosVRF -> IO (Maybe ThunkInfo)
$cnoThunks :: Context -> SignKeyVRF PraosVRF -> IO (Maybe ThunkInfo)
NoThunks) via OnlyCheckWhnfNamed "SignKeyVRF PraosVRF" SignKey
    deriving newtype (SignKeyVRF PraosVRF -> ()
forall a. (a -> ()) -> NFData a
rnf :: SignKeyVRF PraosVRF -> ()
$crnf :: SignKeyVRF PraosVRF -> ()
NFData)

  newtype CertVRF PraosVRF = CertPraosVRF Proof
    deriving stock (Int -> CertVRF PraosVRF -> ShowS
[CertVRF PraosVRF] -> ShowS
CertVRF PraosVRF -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CertVRF PraosVRF] -> ShowS
$cshowList :: [CertVRF PraosVRF] -> ShowS
show :: CertVRF PraosVRF -> String
$cshow :: CertVRF PraosVRF -> String
showsPrec :: Int -> CertVRF PraosVRF -> ShowS
$cshowsPrec :: Int -> CertVRF PraosVRF -> ShowS
Show, CertVRF PraosVRF -> CertVRF PraosVRF -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CertVRF PraosVRF -> CertVRF PraosVRF -> Bool
$c/= :: CertVRF PraosVRF -> CertVRF PraosVRF -> Bool
== :: CertVRF PraosVRF -> CertVRF PraosVRF -> Bool
$c== :: CertVRF PraosVRF -> CertVRF PraosVRF -> Bool
Eq, forall x. Rep (CertVRF PraosVRF) x -> CertVRF PraosVRF
forall x. CertVRF PraosVRF -> Rep (CertVRF PraosVRF) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep (CertVRF PraosVRF) x -> CertVRF PraosVRF
$cfrom :: forall x. CertVRF PraosVRF -> Rep (CertVRF PraosVRF) x
Generic)
    deriving newtype (Typeable (CertVRF PraosVRF)
CertVRF PraosVRF -> Encoding
(forall t. ToCBOR t => Proxy t -> Size)
-> Proxy [CertVRF PraosVRF] -> Size
(forall t. ToCBOR t => Proxy t -> Size)
-> Proxy (CertVRF PraosVRF) -> Size
forall a.
Typeable a
-> (a -> Encoding)
-> ((forall t. ToCBOR t => Proxy t -> Size) -> Proxy a -> Size)
-> ((forall t. ToCBOR t => Proxy t -> Size) -> Proxy [a] -> Size)
-> ToCBOR a
encodedListSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy [CertVRF PraosVRF] -> Size
$cencodedListSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy [CertVRF PraosVRF] -> Size
encodedSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy (CertVRF PraosVRF) -> Size
$cencodedSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy (CertVRF PraosVRF) -> Size
toCBOR :: CertVRF PraosVRF -> Encoding
$ctoCBOR :: CertVRF PraosVRF -> Encoding
ToCBOR, Typeable (CertVRF PraosVRF)
Proxy (CertVRF PraosVRF) -> Text
forall s. Decoder s (CertVRF PraosVRF)
forall a.
Typeable a
-> (forall s. Decoder s a) -> (Proxy a -> Text) -> FromCBOR a
label :: Proxy (CertVRF PraosVRF) -> Text
$clabel :: Proxy (CertVRF PraosVRF) -> Text
fromCBOR :: forall s. Decoder s (CertVRF PraosVRF)
$cfromCBOR :: forall s. Decoder s (CertVRF PraosVRF)
FromCBOR)
    deriving (Context -> CertVRF PraosVRF -> IO (Maybe ThunkInfo)
Proxy (CertVRF PraosVRF) -> String
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
showTypeOf :: Proxy (CertVRF PraosVRF) -> String
$cshowTypeOf :: Proxy (CertVRF PraosVRF) -> String
wNoThunks :: Context -> CertVRF PraosVRF -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> CertVRF PraosVRF -> IO (Maybe ThunkInfo)
noThunks :: Context -> CertVRF PraosVRF -> IO (Maybe ThunkInfo)
$cnoThunks :: Context -> CertVRF PraosVRF -> IO (Maybe ThunkInfo)
NoThunks) via OnlyCheckWhnfNamed "CertKeyVRF PraosVRF" Proof
    deriving newtype (CertVRF PraosVRF -> ()
forall a. (a -> ()) -> NFData a
rnf :: CertVRF PraosVRF -> ()
$crnf :: CertVRF PraosVRF -> ()
NFData)

  type Signable PraosVRF = SignableRepresentation

  algorithmNameVRF :: forall (proxy :: * -> *). proxy PraosVRF -> String
algorithmNameVRF = forall a b. a -> b -> a
const String
"PraosVRF"

  deriveVerKeyVRF :: SignKeyVRF PraosVRF -> VerKeyVRF PraosVRF
deriveVerKeyVRF = coerce :: forall a b. Coercible a b => a -> b
coerce SignKey -> VerKey
skToVerKey

  evalVRF :: forall a.
(HasCallStack, Signable PraosVRF a) =>
ContextVRF PraosVRF
-> a
-> SignKeyVRF PraosVRF
-> (OutputVRF PraosVRF, CertVRF PraosVRF)
evalVRF = \ContextVRF PraosVRF
_ a
msg (SignKeyPraosVRF SignKey
sk) ->
    let msgBS :: ByteString
msgBS = forall a. SignableRepresentation a => a -> ByteString
getSignableRepresentation a
msg
        !proof :: Proof
proof = forall a. a -> Maybe a -> a
fromMaybe (forall a. HasCallStack => String -> a
error String
"Invalid Key") forall a b. (a -> b) -> a -> b
$ SignKey -> ByteString -> Maybe Proof
prove SignKey
sk ByteString
msgBS
        !output :: ByteString
output = forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall a. HasCallStack => String -> a
error String
"Invalid Proof") Output -> ByteString
outputBytes forall a b. (a -> b) -> a -> b
$ Proof -> Maybe Output
outputFromProof Proof
proof
     in (forall v. ByteString -> OutputVRF v
OutputVRF ByteString
output, Proof -> CertVRF PraosVRF
CertPraosVRF Proof
proof)

  verifyVRF :: forall a.
(HasCallStack, Signable PraosVRF a) =>
ContextVRF PraosVRF
-> VerKeyVRF PraosVRF
-> a
-> CertVRF PraosVRF
-> Maybe (OutputVRF PraosVRF)
verifyVRF = \ContextVRF PraosVRF
_ (VerKeyPraosVRF VerKey
pk) a
msg (CertPraosVRF Proof
proof) ->
    (forall v. ByteString -> OutputVRF v
OutputVRF forall b c a. (b -> c) -> (a -> b) -> a -> c
. Output -> ByteString
outputBytes) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> VerKey -> Proof -> ByteString -> Maybe Output
verify VerKey
pk Proof
proof (forall a. SignableRepresentation a => a -> ByteString
getSignableRepresentation a
msg)

  sizeOutputVRF :: forall (proxy :: * -> *). proxy PraosVRF -> Word
sizeOutputVRF proxy PraosVRF
_ = forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
crypto_vrf_outputbytes
  seedSizeVRF :: forall (proxy :: * -> *). proxy PraosVRF -> Word
seedSizeVRF proxy PraosVRF
_ = forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
crypto_vrf_seedbytes

  genKeyPairVRF :: Seed -> (SignKeyVRF PraosVRF, VerKeyVRF PraosVRF)
genKeyPairVRF = \Seed
cryptoseed ->
    let seed :: Seed
seed = ByteString -> Seed
seedFromBytes forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word -> Seed -> (ByteString, Seed)
getBytesFromSeedT (forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
crypto_vrf_seedbytes) forall a b. (a -> b) -> a -> b
$ Seed
cryptoseed
        !(!VerKey
pk, !SignKey
sk) = Seed -> (VerKey, SignKey)
keypairFromSeed Seed
seed
     in (SignKey -> SignKeyVRF PraosVRF
SignKeyPraosVRF SignKey
sk, VerKey -> VerKeyVRF PraosVRF
VerKeyPraosVRF VerKey
pk)

  rawSerialiseVerKeyVRF :: VerKeyVRF PraosVRF -> ByteString
rawSerialiseVerKeyVRF (VerKeyPraosVRF VerKey
pk) = VerKey -> ByteString
vkBytes VerKey
pk
  rawSerialiseSignKeyVRF :: SignKeyVRF PraosVRF -> ByteString
rawSerialiseSignKeyVRF (SignKeyPraosVRF SignKey
sk) = SignKey -> ByteString
skBytes SignKey
sk
  rawSerialiseCertVRF :: CertVRF PraosVRF -> ByteString
rawSerialiseCertVRF (CertPraosVRF Proof
proof) = Proof -> ByteString
proofBytes Proof
proof
  rawDeserialiseVerKeyVRF :: ByteString -> Maybe (VerKeyVRF PraosVRF)
rawDeserialiseVerKeyVRF = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap VerKey -> VerKeyVRF PraosVRF
VerKeyPraosVRF forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). MonadFail m => ByteString -> m VerKey
vkFromBytes
  {-# INLINE rawDeserialiseVerKeyVRF #-}
  rawDeserialiseSignKeyVRF :: ByteString -> Maybe (SignKeyVRF PraosVRF)
rawDeserialiseSignKeyVRF = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SignKey -> SignKeyVRF PraosVRF
SignKeyPraosVRF forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). MonadFail m => ByteString -> m SignKey
skFromBytes
  rawDeserialiseCertVRF :: ByteString -> Maybe (CertVRF PraosVRF)
rawDeserialiseCertVRF = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Proof -> CertVRF PraosVRF
CertPraosVRF forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). MonadFail m => ByteString -> m Proof
proofFromBytes
  {-# INLINE rawDeserialiseCertVRF #-}

  sizeVerKeyVRF :: forall (proxy :: * -> *). proxy PraosVRF -> Word
sizeVerKeyVRF proxy PraosVRF
_ = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
verKeySizeVRF
  sizeSignKeyVRF :: forall (proxy :: * -> *). proxy PraosVRF -> Word
sizeSignKeyVRF proxy PraosVRF
_ = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
signKeySizeVRF
  sizeCertVRF :: forall (proxy :: * -> *). proxy PraosVRF -> Word
sizeCertVRF proxy PraosVRF
_ = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
certSizeVRF