{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE RoleAnnotations #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
module Cardano.Crypto.Libsodium.DSIGN (
    SodiumDSIGNAlgorithm (..),
    naclSignDSIGN,
    naclVerifyDSIGN,
    naclForgetSignKeyDSIGN,
    SodiumSignKeyDSIGN,
    SodiumVerKeyDSIGN,
    SodiumSigDSIGN,
) where

import Control.Monad (unless)
import Data.Proxy (Proxy (..))
import Foreign.C.Error (errnoToIOError, getErrno)
import Foreign.Ptr (Ptr, castPtr, nullPtr)
import Data.Type.Equality ((:~:)(..))
import GHC.IO.Exception (ioException)
import GHC.TypeLits
import System.IO.Unsafe (unsafeDupablePerformIO)

import qualified Data.ByteString as BS

import Cardano.Foreign
import Cardano.Crypto.DSIGN
import Cardano.Crypto.PinnedSizedBytes
import Cardano.Crypto.Libsodium.C
import Cardano.Crypto.Libsodium.Memory.Internal
import Cardano.Crypto.Libsodium.MLockedBytes.Internal
import Cardano.Crypto.Util (SignableRepresentation (..))

-- TODO: these could be newtypes, then we wouldn't need proxy args
type SodiumSignKeyDSIGN v = MLockedSizedBytes (SizeSignKeyDSIGN v)
type SodiumVerKeyDSIGN v = PinnedSizedBytes (SizeVerKeyDSIGN v)
type SodiumSigDSIGN v = PinnedSizedBytes (SizeSigDSIGN v)

class (DSIGNAlgorithm v, ContextDSIGN v ~ (), Signable v ~ SignableRepresentation) => SodiumDSIGNAlgorithm v where
    naclSignDSIGNPtr
        :: Proxy v
        -> Ptr a -> Int
        -> SodiumSignKeyDSIGN v
        -> IO (SodiumSigDSIGN v)

    naclVerifyDSIGNPtr
        :: Proxy v
        -> SodiumVerKeyDSIGN v
        -> Ptr a -> Int
        -> SodiumSigDSIGN v
        -> IO (Either String ())

    naclGenKeyDSIGN
        :: Proxy v
        -> MLockedSizedBytes (SeedSizeDSIGN v)
        -> SodiumSignKeyDSIGN v

    naclDeriveVerKeyDSIGN
        :: Proxy v
        -> SodiumSignKeyDSIGN v
        -> SodiumVerKeyDSIGN v

naclForgetSignKeyDSIGN
    :: Proxy v
    -> SodiumSignKeyDSIGN v
    -> IO ()
naclForgetSignKeyDSIGN :: Proxy v -> SodiumSignKeyDSIGN v -> IO ()
naclForgetSignKeyDSIGN Proxy v
_ (MLSB MLockedForeignPtr (PinnedSizedBytes (SizeSignKeyDSIGN v))
mfp) =
  MLockedForeignPtr (PinnedSizedBytes (SizeSignKeyDSIGN v)) -> IO ()
forall a. MLockedForeignPtr a -> IO ()
finalizeMLockedForeignPtr MLockedForeignPtr (PinnedSizedBytes (SizeSignKeyDSIGN v))
mfp

naclSignDSIGN
    :: (SodiumDSIGNAlgorithm v, SignableRepresentation a)
    => Proxy v
    -> a
    -> SodiumSignKeyDSIGN v
    -> SodiumSigDSIGN v
naclSignDSIGN :: Proxy v -> a -> SodiumSignKeyDSIGN v -> SodiumSigDSIGN v
naclSignDSIGN Proxy v
pv a
a SodiumSignKeyDSIGN v
sk = IO (SodiumSigDSIGN v) -> SodiumSigDSIGN v
forall a. IO a -> a
unsafeDupablePerformIO (IO (SodiumSigDSIGN v) -> SodiumSigDSIGN v)
-> IO (SodiumSigDSIGN v) -> SodiumSigDSIGN v
forall a b. (a -> b) -> a -> b
$ do
    let bs :: ByteString
bs = a -> ByteString
forall a. SignableRepresentation a => a -> ByteString
getSignableRepresentation a
a
    ByteString
-> (CStringLen -> IO (SodiumSigDSIGN v)) -> IO (SodiumSigDSIGN v)
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.useAsCStringLen ByteString
bs ((CStringLen -> IO (SodiumSigDSIGN v)) -> IO (SodiumSigDSIGN v))
-> (CStringLen -> IO (SodiumSigDSIGN v)) -> IO (SodiumSigDSIGN v)
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
ptr,Int
len) ->
        Proxy v
-> Ptr CChar
-> Int
-> SodiumSignKeyDSIGN v
-> IO (SodiumSigDSIGN v)
forall v a.
SodiumDSIGNAlgorithm v =>
Proxy v
-> Ptr a -> Int -> SodiumSignKeyDSIGN v -> IO (SodiumSigDSIGN v)
naclSignDSIGNPtr Proxy v
pv Ptr CChar
ptr Int
len SodiumSignKeyDSIGN v
sk

naclVerifyDSIGN
    :: (SodiumDSIGNAlgorithm v, SignableRepresentation a)
    => Proxy v
    -> SodiumVerKeyDSIGN v
    -> a
    -> SodiumSigDSIGN v
    -> Either String ()
naclVerifyDSIGN :: Proxy v
-> SodiumVerKeyDSIGN v -> a -> SodiumSigDSIGN v -> Either String ()
naclVerifyDSIGN Proxy v
pv SodiumVerKeyDSIGN v
vk a
a SodiumSigDSIGN v
sig = IO (Either String ()) -> Either String ()
forall a. IO a -> a
unsafeDupablePerformIO (IO (Either String ()) -> Either String ())
-> IO (Either String ()) -> Either String ()
forall a b. (a -> b) -> a -> b
$ do
    let bs :: ByteString
bs = a -> ByteString
forall a. SignableRepresentation a => a -> ByteString
getSignableRepresentation a
a
    ByteString
-> (CStringLen -> IO (Either String ())) -> IO (Either String ())
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.useAsCStringLen ByteString
bs ((CStringLen -> IO (Either String ())) -> IO (Either String ()))
-> (CStringLen -> IO (Either String ())) -> IO (Either String ())
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
ptr,Int
len) ->
        Proxy v
-> SodiumVerKeyDSIGN v
-> Ptr CChar
-> Int
-> SodiumSigDSIGN v
-> IO (Either String ())
forall v a.
SodiumDSIGNAlgorithm v =>
Proxy v
-> SodiumVerKeyDSIGN v
-> Ptr a
-> Int
-> SodiumSigDSIGN v
-> IO (Either String ())
naclVerifyDSIGNPtr Proxy v
pv SodiumVerKeyDSIGN v
vk Ptr CChar
ptr Int
len SodiumSigDSIGN v
sig

-------------------------------------------------------------------------------
-- Ed25519 instance
-------------------------------------------------------------------------------

instance SodiumDSIGNAlgorithm Ed25519DSIGN where
    naclGenKeyDSIGN :: Proxy Ed25519DSIGN
-> MLockedSizedBytes (SeedSizeDSIGN Ed25519DSIGN)
-> SodiumSignKeyDSIGN Ed25519DSIGN
naclGenKeyDSIGN Proxy Ed25519DSIGN
_ = MLockedSizedBytes (SeedSizeDSIGN Ed25519DSIGN)
-> SodiumSignKeyDSIGN Ed25519DSIGN
forall a. a -> a
id

    naclDeriveVerKeyDSIGN :: Proxy Ed25519DSIGN
-> SodiumSignKeyDSIGN Ed25519DSIGN
-> SodiumVerKeyDSIGN Ed25519DSIGN
naclDeriveVerKeyDSIGN Proxy Ed25519DSIGN
_ SodiumSignKeyDSIGN Ed25519DSIGN
seed = IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES)
-> PinnedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
forall a. IO a -> a
unsafeDupablePerformIO (IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES)
 -> PinnedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES)
-> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES)
-> PinnedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
forall a b. (a -> b) -> a -> b
$
        MLockedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
-> (SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
    -> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES))
-> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES)
forall (n :: Nat) r.
MLockedSizedBytes n -> (SizedPtr n -> IO r) -> IO r
mlsbUseAsSizedPtr MLockedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
SodiumSignKeyDSIGN Ed25519DSIGN
seed ((SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
  -> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES))
 -> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES))
-> (SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
    -> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES))
-> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES)
forall a b. (a -> b) -> a -> b
$ \SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
seedPtr ->
        (SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES
 -> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES))
-> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES)
forall (n :: Nat) b. KnownNat n => (SizedPtr n -> IO b) -> IO b
mlockedAllocaSized ((SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES
  -> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES))
 -> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES))
-> (SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES
    -> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES))
-> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES)
forall a b. (a -> b) -> a -> b
$ \SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES
skPtr ->
        (SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES -> IO ())
-> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES)
forall (n :: Nat).
KnownNat n =>
(SizedPtr n -> IO ()) -> IO (PinnedSizedBytes n)
psbCreateSized ((SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES -> IO ())
 -> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES))
-> (SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES -> IO ())
-> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES)
forall a b. (a -> b) -> a -> b
$ \SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
pkPtr -> do
            Int
res <- SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
-> SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES
-> SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
-> IO Int
c_crypto_sign_ed25519_seed_keypair SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
pkPtr SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES
skPtr SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
seedPtr
            Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Int
res Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
                Errno
errno <- IO Errno
getErrno
                IOException -> IO ()
forall a. IOException -> IO a
ioException (IOException -> IO ()) -> IOException -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> Errno -> Maybe Handle -> Maybe String -> IOException
errnoToIOError String
"naclDeriveVerKeyDSIGN @Ed25519DSIGN: c_crypto_sign_ed25519_seed_keypair" Errno
errno Maybe Handle
forall a. Maybe a
Nothing Maybe String
forall a. Maybe a
Nothing

    naclSignDSIGNPtr :: Proxy Ed25519DSIGN
-> Ptr a
-> Int
-> SodiumSignKeyDSIGN Ed25519DSIGN
-> IO (SodiumSigDSIGN Ed25519DSIGN)
naclSignDSIGNPtr Proxy Ed25519DSIGN
_ Ptr a
ptr Int
len SodiumSignKeyDSIGN Ed25519DSIGN
seed =
        MLockedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
-> (SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
    -> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_SECRETKEYBYTES))
-> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_SECRETKEYBYTES)
forall (n :: Nat) r.
MLockedSizedBytes n -> (SizedPtr n -> IO r) -> IO r
mlsbUseAsSizedPtr MLockedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
SodiumSignKeyDSIGN Ed25519DSIGN
seed ((SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
  -> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_SECRETKEYBYTES))
 -> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_SECRETKEYBYTES))
-> (SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
    -> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_SECRETKEYBYTES))
-> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_SECRETKEYBYTES)
forall a b. (a -> b) -> a -> b
$ \SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
seedPtr ->
        (SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES
 -> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_SECRETKEYBYTES))
-> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_SECRETKEYBYTES)
forall (n :: Nat) b. KnownNat n => (SizedPtr n -> IO b) -> IO b
mlockedAllocaSized ((SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES
  -> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_SECRETKEYBYTES))
 -> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_SECRETKEYBYTES))
-> (SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES
    -> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_SECRETKEYBYTES))
-> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_SECRETKEYBYTES)
forall a b. (a -> b) -> a -> b
$ \SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES
skPtr ->
        (SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
 -> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_SECRETKEYBYTES))
-> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_SECRETKEYBYTES)
forall (n :: Nat) b. KnownNat n => (SizedPtr n -> IO b) -> IO b
allocaSized ((SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
  -> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_SECRETKEYBYTES))
 -> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_SECRETKEYBYTES))
-> (SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
    -> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_SECRETKEYBYTES))
-> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_SECRETKEYBYTES)
forall a b. (a -> b) -> a -> b
$ \SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
pkPtr -> do
            -- copy paste
            Int
res <- SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
-> SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES
-> SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
-> IO Int
c_crypto_sign_ed25519_seed_keypair SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
pkPtr SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES
skPtr SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
seedPtr
            Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Int
res Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
                Errno
errno <- IO Errno
getErrno
                IOException -> IO ()
forall a. IOException -> IO a
ioException (IOException -> IO ()) -> IOException -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> Errno -> Maybe Handle -> Maybe String -> IOException
errnoToIOError String
"naclDeriveVerKeyDSIGN @Ed25519DSIGN: c_crypto_sign_ed25519_seed_keypair" Errno
errno Maybe Handle
forall a. Maybe a
Nothing Maybe String
forall a. Maybe a
Nothing

            (SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES -> IO ())
-> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_SECRETKEYBYTES)
forall (n :: Nat).
KnownNat n =>
(SizedPtr n -> IO ()) -> IO (PinnedSizedBytes n)
psbCreateSized ((SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES -> IO ())
 -> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_SECRETKEYBYTES))
-> (SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES -> IO ())
-> IO (PinnedSizedBytes CRYPTO_SIGN_ED25519_SECRETKEYBYTES)
forall a b. (a -> b) -> a -> b
$ \SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES
sigPtr -> do
                Int
res2 <- SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES
-> Ptr CULLong
-> Ptr CUChar
-> CULLong
-> SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES
-> IO Int
c_crypto_sign_ed25519_detached SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES
sigPtr Ptr CULLong
forall a. Ptr a
nullPtr (Ptr a -> Ptr CUChar
forall a b. Ptr a -> Ptr b
castPtr Ptr a
ptr) (Int -> CULLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len) SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES
skPtr
                Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Int
res2 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
                    Errno
errno <- IO Errno
getErrno
                    IOException -> IO ()
forall a. IOException -> IO a
ioException (IOException -> IO ()) -> IOException -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> Errno -> Maybe Handle -> Maybe String -> IOException
errnoToIOError String
"naclDeriveVerKeyDSIGN @Ed25519DSIGN: c_crypto_sign_ed25519_seed_keypair" Errno
errno Maybe Handle
forall a. Maybe a
Nothing Maybe String
forall a. Maybe a
Nothing

    naclVerifyDSIGNPtr :: Proxy Ed25519DSIGN
-> SodiumVerKeyDSIGN Ed25519DSIGN
-> Ptr a
-> Int
-> SodiumSigDSIGN Ed25519DSIGN
-> IO (Either String ())
naclVerifyDSIGNPtr Proxy Ed25519DSIGN
_ SodiumVerKeyDSIGN Ed25519DSIGN
vk Ptr a
ptr Int
len SodiumSigDSIGN Ed25519DSIGN
sig =
        PinnedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
-> (SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
    -> IO (Either String ()))
-> IO (Either String ())
forall (n :: Nat) r.
PinnedSizedBytes n -> (SizedPtr n -> IO r) -> IO r
psbUseAsSizedPtr PinnedSizedBytes CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
SodiumVerKeyDSIGN Ed25519DSIGN
vk ((SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
  -> IO (Either String ()))
 -> IO (Either String ()))
-> (SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
    -> IO (Either String ()))
-> IO (Either String ())
forall a b. (a -> b) -> a -> b
$ \SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
vkPtr ->
        PinnedSizedBytes CRYPTO_SIGN_ED25519_SECRETKEYBYTES
-> (SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES
    -> IO (Either String ()))
-> IO (Either String ())
forall (n :: Nat) r.
PinnedSizedBytes n -> (SizedPtr n -> IO r) -> IO r
psbUseAsSizedPtr PinnedSizedBytes CRYPTO_SIGN_ED25519_SECRETKEYBYTES
SodiumSigDSIGN Ed25519DSIGN
sig ((SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES
  -> IO (Either String ()))
 -> IO (Either String ()))
-> (SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES
    -> IO (Either String ()))
-> IO (Either String ())
forall a b. (a -> b) -> a -> b
$ \SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES
sigPtr -> do
            Int
res <- SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES
-> Ptr CUChar
-> CULLong
-> SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
-> IO Int
c_crypto_sign_ed25519_verify_detached SizedPtr CRYPTO_SIGN_ED25519_SECRETKEYBYTES
sigPtr (Ptr a -> Ptr CUChar
forall a b. Ptr a -> Ptr b
castPtr Ptr a
ptr) (Int -> CULLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len) SizedPtr CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
vkPtr
            if Int
res Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
            then Either String () -> IO (Either String ())
forall (m :: * -> *) a. Monad m => a -> m a
return (() -> Either String ()
forall a b. b -> Either a b
Right ())
            else do
                -- errno <- getErrno
                Either String () -> IO (Either String ())
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> Either String ()
forall a b. a -> Either a b
Left  String
"Verification failed")

_testEd25519a :: SeedSizeDSIGN Ed25519DSIGN :~: CRYPTO_SIGN_ED25519_SEEDBYTES
_testEd25519a :: SeedSizeDSIGN Ed25519DSIGN :~: CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
_testEd25519a = SeedSizeDSIGN Ed25519DSIGN :~: CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
forall k (a :: k). a :~: a
Refl

_testEd25519b :: SizeSignKeyDSIGN Ed25519DSIGN + SizeVerKeyDSIGN Ed25519DSIGN :~: CRYPTO_SIGN_ED25519_SECRETKEYBYTES
_testEd25519b :: (SizeSignKeyDSIGN Ed25519DSIGN + SizeVerKeyDSIGN Ed25519DSIGN)
:~: CRYPTO_SIGN_ED25519_SECRETKEYBYTES
_testEd25519b = (SizeSignKeyDSIGN Ed25519DSIGN + SizeVerKeyDSIGN Ed25519DSIGN)
:~: CRYPTO_SIGN_ED25519_SECRETKEYBYTES
forall k (a :: k). a :~: a
Refl

_testEd25519c :: SizeVerKeyDSIGN Ed25519DSIGN :~: CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
_testEd25519c :: SizeVerKeyDSIGN Ed25519DSIGN :~: CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
_testEd25519c = SizeVerKeyDSIGN Ed25519DSIGN :~: CRYPTO_SIGN_ED25519_PUBLICKEYBYTES
forall k (a :: k). a :~: a
Refl

_testEd25519d :: SizeSigDSIGN Ed25519DSIGN :~: CRYPTO_SIGN_ED25519_BYTES
_testEd25519d :: SizeSigDSIGN Ed25519DSIGN :~: CRYPTO_SIGN_ED25519_SECRETKEYBYTES
_testEd25519d = SizeSigDSIGN Ed25519DSIGN :~: CRYPTO_SIGN_ED25519_SECRETKEYBYTES
forall k (a :: k). a :~: a
Refl