    {-# LANGUAGE CPP #-}
    {-# LANGUAGE ForeignFunctionInterface #-}

    #if __GLASGOW_HASKELL__ >= 702
    {-# LANGUAGE Trustworthy #-}
    {-# LANGUAGE StandaloneDeriving #-}
    {-# LANGUAGE DeriveGeneric #-}
    #endif

    -- |
    -- Module      : Crypto.Sign.Ed25519
    -- Copyright   : (c) Austin Seipp 2013-2015
    -- License     : MIT
    --
    -- Maintainer  : aseipp@pobox.com
    -- Stability   : experimental
    -- Portability : portable
    --
    -- This module provides bindings to the Ed25519 public-key signature
    -- system, including detached signatures. The documentation should be
    -- self explanatory with complete examples.
    --
    -- Below the basic documentation you'll find API, performance and
    -- security notes, which you may want to read carefully before
    -- continuing. (Nonetheless, @Ed25519@ is one of the easiest-to-use
    -- signature systems around, and is simple to get started with for
    -- building more complex protocols. But the below details are highly
    -- educational and should help adjust your expectations properly.)
    --
    -- For more reading on the underlying implementation and theory
    -- (including how to get a copy of the Ed25519 software),
    -- visit <http://ed25519.cr.yp.to>. There are two papers that discuss
    -- the design of EdDSA/Ed25519 in detail:
    --
    --   * <http://ed25519.cr.yp.to/ed25519-20110926.pdf "High-speed high-security signatures"> -
    --   The original specification by Bernstein, Duif, Lange, Schwabe,
    --   and Yang.
    --
    --   * <http://ed25519.cr.yp.to/eddsa-20150704.pdf "EdDSA for more curves"> -
    --   An extension of the original EdDSA specification allowing it to
    --   be used with more curves (such as Ed41417, or Ed488), as well as
    --   defining the support for __message prehashing__. The original
    --   EdDSA is easily derived from the extended version through a few
    --   parameter defaults. (This package won't consider non-Ed25519
    --   EdDSA systems any further.)
    --
    module Crypto.Sign.Ed25519
           ( -- * A crash course introduction
             -- $intro

             -- * Keypair creation
             -- $creatingkeys
             PublicKey(..)          -- :: *
           , SecretKey(..)          -- :: *
           , createKeypair          -- :: IO (PublicKey, SecretKey)
           , createKeypairFromSeed_ -- :: ByteString -> Maybe (PublicKey, SecretKey)
           , createKeypairFromSeed  -- :: ByteString -> (PublicKey, SecretKey)
           , toPublicKey            -- :: SecretKey -> PublicKey

             -- * Signing and verifying messages
             -- $signatures
           , sign                 -- :: SecretKey -> ByteString -> ByteString
           , verify               -- :: PublicKey -> ByteString -> Bool

             -- * Detached signatures
             -- $detachedsigs
           , Signature(..)        -- :: *
           , dsign                -- :: SecretKey -> ByteString -> Signature
           , dverify              -- :: PublicKey -> ByteString -> Signature -> Bool
             -- ** Deprecated interface
             -- | The below interface is deprecated but functionally
             -- equivalent to the above; it simply has \"worse\" naming and will
             -- eventually be removed.
           , sign'                -- :: SecretKey -> ByteString -> Signature
           , verify'              -- :: PublicKey -> ByteString -> Signature -> Bool

             -- * Security, design and implementation notes
             -- $security

             -- ** EdDSA background and properties
             -- $background

             -- *** Generation of psuedo-random seeds
             -- $seedgen

             -- ** Performance and implementation
             -- $performance

             -- ** Secure @'SecretKey'@ storage
             -- $keystorage

             -- ** Prehashing and large input messages
             -- $prehashing
           ) where
    import           Foreign.C.Types
    import           Foreign.ForeignPtr       (withForeignPtr)
    import           Foreign.Marshal.Alloc    (alloca)
    import           Foreign.Ptr
    import           Foreign.Storable

    import           System.IO.Unsafe         (unsafePerformIO)

    import           Data.Maybe               (fromMaybe)

    import           Data.ByteString          as S
    import           Data.ByteString.Internal as SI
    import           Data.ByteString.Unsafe   as SU
    import           Data.Word

    #if __GLASGOW_HASKELL__ >= 702
    import           GHC.Generics             (Generic)
    #endif

    -- Doctest setup with some examples

    -- $setup
    -- >>> :set -XOverloadedStrings
    -- >>> import Data.ByteString.Char8
    -- >>> let hash        x = x
    -- >>> let readBigFile x = return x

    --------------------------------------------------------------------------------
    -- Key creation

    -- $creatingkeys
    --
    -- Ed25519 signatures start off life by having a keypair created,
    -- using @'createKeypair'@ or @'createKeypairFromSeed_'@, which gives
    -- you back a @'SecretKey'@ you can use for signing messages, and a
    -- @'PublicKey'@ your users can use to verify you in fact authored the
    -- messages.
    --
    -- Ed25519 is a /deterministic signature system/, meaning that you may
    -- always recompute a @'PublicKey'@ and a @'SecretKey'@ from an
    -- initial, 32-byte input seed. Despite that, the default interface
    -- almost all clients will wish to use is simply @'createKeypair'@,
    -- which uses an Operating System provided source of secure randomness
    -- to seed key creation. (For more information, see the security notes
    -- at the bottom of this page.)

    -- | A @'PublicKey'@ created by @'createKeypair'@.
    --
    -- @since 0.0.1.0
    newtype PublicKey = PublicKey { PublicKey -> ByteString
    unPublicKey :: ByteString
                                    -- ^ Unwrapper for getting the raw
                                    -- @'ByteString'@ in a
                                    -- @'PublicKey'@. In general you
                                    -- should not make any assumptions
                                    -- about the underlying blob; this is
                                    -- only provided for interoperability.
                                  }
            deriving (PublicKey -> PublicKey -> Bool
    (PublicKey -> PublicKey -> Bool)
    -> (PublicKey -> PublicKey -> Bool) -> Eq PublicKey
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: PublicKey -> PublicKey -> Bool
    $c/= :: PublicKey -> PublicKey -> Bool
    == :: PublicKey -> PublicKey -> Bool
    $c== :: PublicKey -> PublicKey -> Bool
    Eq, Int -> PublicKey -> ShowS
    [PublicKey] -> ShowS
    PublicKey -> String
    (Int -> PublicKey -> ShowS)
    -> (PublicKey -> String)
    -> ([PublicKey] -> ShowS)
    -> Show PublicKey
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [PublicKey] -> ShowS
    $cshowList :: [PublicKey] -> ShowS
    show :: PublicKey -> String
    $cshow :: PublicKey -> String
    showsPrec :: Int -> PublicKey -> ShowS
    $cshowsPrec :: Int -> PublicKey -> ShowS
    Show, Eq PublicKey
    Eq PublicKey =>
    (PublicKey -> PublicKey -> Ordering)
    -> (PublicKey -> PublicKey -> Bool)
    -> (PublicKey -> PublicKey -> Bool)
    -> (PublicKey -> PublicKey -> Bool)
    -> (PublicKey -> PublicKey -> Bool)
    -> (PublicKey -> PublicKey -> PublicKey)
    -> (PublicKey -> PublicKey -> PublicKey)
    -> Ord PublicKey
    PublicKey -> PublicKey -> Bool
    PublicKey -> PublicKey -> Ordering
    PublicKey -> PublicKey -> PublicKey
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    min :: PublicKey -> PublicKey -> PublicKey
    $cmin :: PublicKey -> PublicKey -> PublicKey
    max :: PublicKey -> PublicKey -> PublicKey
    $cmax :: PublicKey -> PublicKey -> PublicKey
    >= :: PublicKey -> PublicKey -> Bool
    $c>= :: PublicKey -> PublicKey -> Bool
    > :: PublicKey -> PublicKey -> Bool
    $c> :: PublicKey -> PublicKey -> Bool
    <= :: PublicKey -> PublicKey -> Bool
    $c<= :: PublicKey -> PublicKey -> Bool
    < :: PublicKey -> PublicKey -> Bool
    $c< :: PublicKey -> PublicKey -> Bool
    compare :: PublicKey -> PublicKey -> Ordering
    $ccompare :: PublicKey -> PublicKey -> Ordering
    $cp1Ord :: Eq PublicKey
    Ord)

    -- | A @'SecretKey'@ created by @'createKeypair'@. __Be sure to keep this__
    -- __safe!__
    --
    -- @since 0.0.1.0
    newtype SecretKey = SecretKey { SecretKey -> ByteString
    unSecretKey :: ByteString
                                    -- ^ Unwrapper for getting the raw
                                    -- @'ByteString'@ in a
                                    -- @'SecretKey'@. In general you
                                    -- should not make any assumptions
                                    -- about the underlying blob; this is
                                    -- only provided for interoperability.
                                  }
            deriving (SecretKey -> SecretKey -> Bool
    (SecretKey -> SecretKey -> Bool)
    -> (SecretKey -> SecretKey -> Bool) -> Eq SecretKey
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: SecretKey -> SecretKey -> Bool
    $c/= :: SecretKey -> SecretKey -> Bool
    == :: SecretKey -> SecretKey -> Bool
    $c== :: SecretKey -> SecretKey -> Bool
    Eq, Int -> SecretKey -> ShowS
    [SecretKey] -> ShowS
    SecretKey -> String
    (Int -> SecretKey -> ShowS)
    -> (SecretKey -> String)
    -> ([SecretKey] -> ShowS)
    -> Show SecretKey
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [SecretKey] -> ShowS
    $cshowList :: [SecretKey] -> ShowS
    show :: SecretKey -> String
    $cshow :: SecretKey -> String
    showsPrec :: Int -> SecretKey -> ShowS
    $cshowsPrec :: Int -> SecretKey -> ShowS
    Show, Eq SecretKey
    Eq SecretKey =>
    (SecretKey -> SecretKey -> Ordering)
    -> (SecretKey -> SecretKey -> Bool)
    -> (SecretKey -> SecretKey -> Bool)
    -> (SecretKey -> SecretKey -> Bool)
    -> (SecretKey -> SecretKey -> Bool)
    -> (SecretKey -> SecretKey -> SecretKey)
    -> (SecretKey -> SecretKey -> SecretKey)
    -> Ord SecretKey
    SecretKey -> SecretKey -> Bool
    SecretKey -> SecretKey -> Ordering
    SecretKey -> SecretKey -> SecretKey
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    min :: SecretKey -> SecretKey -> SecretKey
    $cmin :: SecretKey -> SecretKey -> SecretKey
    max :: SecretKey -> SecretKey -> SecretKey
    $cmax :: SecretKey -> SecretKey -> SecretKey
    >= :: SecretKey -> SecretKey -> Bool
    $c>= :: SecretKey -> SecretKey -> Bool
    > :: SecretKey -> SecretKey -> Bool
    $c> :: SecretKey -> SecretKey -> Bool
    <= :: SecretKey -> SecretKey -> Bool
    $c<= :: SecretKey -> SecretKey -> Bool
    < :: SecretKey -> SecretKey -> Bool
    $c< :: SecretKey -> SecretKey -> Bool
    compare :: SecretKey -> SecretKey -> Ordering
    $ccompare :: SecretKey -> SecretKey -> Ordering
    $cp1Ord :: Eq SecretKey
    Ord)

    #if __GLASGOW_HASKELL__ >= 702
    deriving instance Generic PublicKey
    deriving instance Generic SecretKey
    #endif

    -- | Randomly generate a @'SecretKey'@ and @'PublicKey'@ for doing
    -- authenticated signing and verification. This essentically calls
    -- @'createKeypairFromSeed_'@ with a randomly generated 32-byte seed,
    -- the source of which is operating-system dependent (see security
    -- notes below). However, internally it is implemented more
    -- efficiently (with less allocations and copies).
    --
    -- If you wish to use your own seed (for design purposes so you may
    -- recreate keys, due to high paranoia, or because you have your own
    -- source of randomness), please use @'createKeypairFromSeed_'@
    -- instead.
    --
    -- @since 0.0.1.0
    createKeypair :: IO (PublicKey, SecretKey)
    createKeypair :: IO (PublicKey, SecretKey)
    createKeypair = do
      ForeignPtr Word8
    pk <- Int -> IO (ForeignPtr Word8)
    forall a. Int -> IO (ForeignPtr a)
    SI.mallocByteString Int
    cryptoSignPUBLICKEYBYTES
      ForeignPtr Word8
    sk <- Int -> IO (ForeignPtr Word8)
    forall a. Int -> IO (ForeignPtr a)
    SI.mallocByteString Int
    cryptoSignSECRETKEYBYTES

      ()
    _ <- ForeignPtr Word8 -> (Ptr Word8 -> IO ()) -> IO ()
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    withForeignPtr ForeignPtr Word8
    pk ((Ptr Word8 -> IO ()) -> IO ()) -> (Ptr Word8 -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \ppk :: Ptr Word8
    ppk -> do
        ()
    _ <- ForeignPtr Word8 -> (Ptr Word8 -> IO ()) -> IO ()
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    withForeignPtr ForeignPtr Word8
    sk ((Ptr Word8 -> IO ()) -> IO ()) -> (Ptr Word8 -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \psk :: Ptr Word8
    psk -> do
          CInt
    _ <- Ptr Word8 -> Ptr Word8 -> IO CInt
    c_crypto_sign_keypair Ptr Word8
    ppk Ptr Word8
    psk
          () -> IO ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
        () -> IO ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

      (PublicKey, SecretKey) -> IO (PublicKey, SecretKey)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (ByteString -> PublicKey
    PublicKey (ByteString -> PublicKey) -> ByteString -> PublicKey
    forall a b. (a -> b) -> a -> b
    $ ForeignPtr Word8 -> Int -> Int -> ByteString
    SI.fromForeignPtr ForeignPtr Word8
    pk 0 Int
    cryptoSignPUBLICKEYBYTES,
              ByteString -> SecretKey
    SecretKey (ByteString -> SecretKey) -> ByteString -> SecretKey
    forall a b. (a -> b) -> a -> b
    $ ForeignPtr Word8 -> Int -> Int -> ByteString
    SI.fromForeignPtr ForeignPtr Word8
    sk 0 Int
    cryptoSignSECRETKEYBYTES)

    -- | Generate a deterministic @'PublicKey'@ and @'SecretKey'@ from a
    -- given 32-byte seed, allowing you to recreate a keypair at any point
    -- in time, providing you have the seed available.
    --
    -- If the input seed is not 32 bytes in length,
    -- @'createKeypairFromSeed_'@ returns @'Nothing'@. Otherwise, it
    -- always returns @'Just' (pk, sk)@ for the given seed.
    --
    -- __/NOTE/__: This function will replace @'createKeypairFromSeed'@ in
    -- the future.
    --
    -- @since 0.0.4.0
    createKeypairFromSeed_ :: ByteString                  -- ^ 32-byte seed
                          -> Maybe (PublicKey, SecretKey) -- ^ Resulting keypair
    createKeypairFromSeed_ :: ByteString -> Maybe (PublicKey, SecretKey)
    createKeypairFromSeed_ seed :: ByteString
    seed
      | ByteString -> Int
    S.length ByteString
    seed Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Int
    cryptoSignSEEDBYTES = Maybe (PublicKey, SecretKey)
    forall a. Maybe a
    Nothing
      | Bool
    otherwise = IO (Maybe (PublicKey, SecretKey)) -> Maybe (PublicKey, SecretKey)
    forall a. IO a -> a
    unsafePerformIO (IO (Maybe (PublicKey, SecretKey)) -> Maybe (PublicKey, SecretKey))
    -> IO (Maybe (PublicKey, SecretKey))
    -> Maybe (PublicKey, SecretKey)
    forall a b. (a -> b) -> a -> b
    $ do
        ForeignPtr Word8
    pk <- Int -> IO (ForeignPtr Word8)
    forall a. Int -> IO (ForeignPtr a)
    SI.mallocByteString Int
    cryptoSignPUBLICKEYBYTES
        ForeignPtr Word8
    sk <- Int -> IO (ForeignPtr Word8)
    forall a. Int -> IO (ForeignPtr a)
    SI.mallocByteString Int
    cryptoSignSECRETKEYBYTES

        ()
    _ <- ByteString -> (CString -> IO ()) -> IO ()
    forall a. ByteString -> (CString -> IO a) -> IO a
    SU.unsafeUseAsCString ByteString
    seed ((CString -> IO ()) -> IO ()) -> (CString -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \pseed :: CString
    pseed -> do
          ()
    _ <- ForeignPtr Word8 -> (Ptr Word8 -> IO ()) -> IO ()
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    withForeignPtr ForeignPtr Word8
    pk ((Ptr Word8 -> IO ()) -> IO ()) -> (Ptr Word8 -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \ppk :: Ptr Word8
    ppk -> do
            ()
    _ <- ForeignPtr Word8 -> (Ptr Word8 -> IO ()) -> IO ()
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    withForeignPtr ForeignPtr Word8
    sk ((Ptr Word8 -> IO ()) -> IO ()) -> (Ptr Word8 -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \psk :: Ptr Word8
    psk -> do
              CInt
    _ <- Ptr Word8 -> Ptr Word8 -> CString -> IO CInt
    c_crypto_sign_seed_keypair Ptr Word8
    ppk Ptr Word8
    psk CString
    pseed
              () -> IO ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
            () -> IO ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
          () -> IO ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

        Maybe (PublicKey, SecretKey) -> IO (Maybe (PublicKey, SecretKey))
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe (PublicKey, SecretKey) -> IO (Maybe (PublicKey, SecretKey)))
    -> Maybe (PublicKey, SecretKey)
    -> IO (Maybe (PublicKey, SecretKey))
    forall a b. (a -> b) -> a -> b
    $ (PublicKey, SecretKey) -> Maybe (PublicKey, SecretKey)
    forall a. a -> Maybe a
    Just (ByteString -> PublicKey
    PublicKey (ByteString -> PublicKey) -> ByteString -> PublicKey
    forall a b. (a -> b) -> a -> b
    $ ForeignPtr Word8 -> Int -> Int -> ByteString
    SI.fromForeignPtr ForeignPtr Word8
    pk 0 Int
    cryptoSignPUBLICKEYBYTES,
                       ByteString -> SecretKey
    SecretKey (ByteString -> SecretKey) -> ByteString -> SecretKey
    forall a b. (a -> b) -> a -> b
    $ ForeignPtr Word8 -> Int -> Int -> ByteString
    SI.fromForeignPtr ForeignPtr Word8
    sk 0 Int
    cryptoSignSECRETKEYBYTES)

    -- | Generate a deterministic @'PublicKey'@ and @'SecretKey'@ from a
    -- given 32-byte seed, allowing you to recreate a keypair at any point
    -- in time, providing you have the seed available.
    --
    -- Note that this will @'error'@ if the given input is not 32 bytes in
    -- length, so you must be careful with this input.
    --
    -- @since 0.0.3.0
    createKeypairFromSeed :: ByteString             -- ^ 32-byte seed
                          -> (PublicKey, SecretKey) -- ^ Resulting keypair
    createKeypairFromSeed :: ByteString -> (PublicKey, SecretKey)
    createKeypairFromSeed seed :: ByteString
    seed
      = (PublicKey, SecretKey)
    -> Maybe (PublicKey, SecretKey) -> (PublicKey, SecretKey)
    forall a. a -> Maybe a -> a
    fromMaybe (String -> (PublicKey, SecretKey)
    forall a. HasCallStack => String -> a
    error "seed has incorrect length") (ByteString -> Maybe (PublicKey, SecretKey)
    createKeypairFromSeed_ ByteString
    seed)
    {-# DEPRECATED createKeypairFromSeed "This function is unsafe as it can @'fail'@ with an invalid input. Use @'createKeypairWithSeed_'@ instead." #-}

    -- | Derive the @'PublicKey'@ for a given @'SecretKey'@. This is a
    -- convenience which allows (for example) using @'createKeypair'@ and
    -- only ever storing the returned @'SecretKey'@ for any future
    -- operations.
    --
    -- @since 0.0.3.0
    toPublicKey :: SecretKey -- ^ Any valid @'SecretKey'@
                -> PublicKey -- ^ Corresponding @'PublicKey'@
    toPublicKey :: SecretKey -> PublicKey
    toPublicKey = ByteString -> PublicKey
    PublicKey (ByteString -> PublicKey)
    -> (SecretKey -> ByteString) -> SecretKey -> PublicKey
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> ByteString -> ByteString
    S.drop Int
    prefixBytes  (ByteString -> ByteString)
    -> (SecretKey -> ByteString) -> SecretKey -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . SecretKey -> ByteString
    unSecretKey
      where prefixBytes :: Int
    prefixBytes = Int
    cryptoSignSECRETKEYBYTES Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    cryptoSignPUBLICKEYBYTES

    --------------------------------------------------------------------------------
    -- Default, non-detached API

    -- $signatures
    --
    -- By default, the Ed25519 interface computes a /signed message/ given
    -- a @'SecretKey'@ and an input message. A /signed message/ consists
    -- of an Ed25519 signature (of unspecified format), followed by the
    -- input message.  This means that given an input message of @M@
    -- bytes, you get back a message of @M+N@ bytes where @N@ is a
    -- constant (the size of the Ed25519 signature blob).
    --
    -- The default interface in this package reflects that. As a result,
    -- any time you use @'sign'@ or @'verify'@ you will be given back the
    -- full input, and then some.
    --

    -- | Sign a message with a particular @'SecretKey'@. Note that the resulting
    -- signed message contains both the message itself, and the signature
    -- attached. If you only want the signature of a given input string,
    -- please see @'dsign'@.
    --
    -- @since 0.0.1.0
    sign :: SecretKey
         -- ^ Signers @'SecretKey'@
         -> ByteString
         -- ^ Input message
         -> ByteString
         -- ^ Resulting signed message
    sign :: SecretKey -> ByteString -> ByteString
    sign (SecretKey sk :: ByteString
    sk) xs :: ByteString
    xs =
      IO ByteString -> ByteString
    forall a. IO a -> a
    unsafePerformIO (IO ByteString -> ByteString)
    -> ((CStringLen -> IO ByteString) -> IO ByteString)
    -> (CStringLen -> IO ByteString)
    -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> (CStringLen -> IO ByteString) -> IO ByteString
    forall a. ByteString -> (CStringLen -> IO a) -> IO a
    SU.unsafeUseAsCStringLen ByteString
    xs ((CStringLen -> IO ByteString) -> ByteString)
    -> (CStringLen -> IO ByteString) -> ByteString
    forall a b. (a -> b) -> a -> b
    $ \(mstr :: CString
    mstr,mlen :: Int
    mlen) ->
        ByteString -> (CString -> IO ByteString) -> IO ByteString
    forall a. ByteString -> (CString -> IO a) -> IO a
    SU.unsafeUseAsCString ByteString
    sk ((CString -> IO ByteString) -> IO ByteString)
    -> (CString -> IO ByteString) -> IO ByteString
    forall a b. (a -> b) -> a -> b
    $ \psk :: CString
    psk ->
          Int -> (Ptr Word8 -> IO Int) -> IO ByteString
    SI.createAndTrim (Int
    mlenInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    cryptoSignBYTES) ((Ptr Word8 -> IO Int) -> IO ByteString)
    -> (Ptr Word8 -> IO Int) -> IO ByteString
    forall a b. (a -> b) -> a -> b
    $ \out :: Ptr Word8
    out ->
            (Ptr CULLong -> IO Int) -> IO Int
    forall a b. Storable a => (Ptr a -> IO b) -> IO b
    alloca ((Ptr CULLong -> IO Int) -> IO Int)
    -> (Ptr CULLong -> IO Int) -> IO Int
    forall a b. (a -> b) -> a -> b
    $ \smlen :: Ptr CULLong
    smlen -> do
              CULLong
    _ <- Ptr Word8
    -> Ptr CULLong -> CString -> CULLong -> CString -> IO CULLong
    c_crypto_sign Ptr Word8
    out Ptr CULLong
    smlen CString
    mstr (Int -> CULLong
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    mlen) CString
    psk
              CULLong -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (CULLong -> Int) -> IO CULLong -> IO Int
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` Ptr CULLong -> IO CULLong
    forall a. Storable a => Ptr a -> IO a
    peek Ptr CULLong
    smlen
    {-# INLINE sign #-}

    -- | Verifies a signed message against a @'PublicKey'@. Note that the input
    -- message must be generated by @'sign'@ (that is, it is the message
    -- itself plus its signature). If you want to verify an arbitrary
    -- signature against an arbitrary message, please see @'dverify'@.
    --
    -- @since 0.0.1.0
    verify :: PublicKey
           -- ^ Signers @'PublicKey'@
           -> ByteString
           -- ^ Signed message
           -> Bool
           -- ^ Verification result
    verify :: PublicKey -> ByteString -> Bool
    verify (PublicKey pk :: ByteString
    pk) xs :: ByteString
    xs =
      IO Bool -> Bool
    forall a. IO a -> a
    unsafePerformIO (IO Bool -> Bool)
    -> ((CStringLen -> IO Bool) -> IO Bool)
    -> (CStringLen -> IO Bool)
    -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> (CStringLen -> IO Bool) -> IO Bool
    forall a. ByteString -> (CStringLen -> IO a) -> IO a
    SU.unsafeUseAsCStringLen ByteString
    xs ((CStringLen -> IO Bool) -> Bool)
    -> (CStringLen -> IO Bool) -> Bool
    forall a b. (a -> b) -> a -> b
    $ \(smstr :: CString
    smstr,smlen :: Int
    smlen) ->
        ByteString -> (CString -> IO Bool) -> IO Bool
    forall a. ByteString -> (CString -> IO a) -> IO a
    SU.unsafeUseAsCString ByteString
    pk ((CString -> IO Bool) -> IO Bool)
    -> (CString -> IO Bool) -> IO Bool
    forall a b. (a -> b) -> a -> b
    $ \ppk :: CString
    ppk ->
          (Ptr CULLong -> IO Bool) -> IO Bool
    forall a b. Storable a => (Ptr a -> IO b) -> IO b
    alloca ((Ptr CULLong -> IO Bool) -> IO Bool)
    -> (Ptr CULLong -> IO Bool) -> IO Bool
    forall a b. (a -> b) -> a -> b
    $ \pmlen :: Ptr CULLong
    pmlen -> do
            ForeignPtr Word8
    out <- Int -> IO (ForeignPtr Word8)
    forall a. Int -> IO (ForeignPtr a)
    SI.mallocByteString Int
    smlen
            CInt
    r <- ForeignPtr Word8 -> (Ptr Word8 -> IO CInt) -> IO CInt
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    withForeignPtr ForeignPtr Word8
    out ((Ptr Word8 -> IO CInt) -> IO CInt)
    -> (Ptr Word8 -> IO CInt) -> IO CInt
    forall a b. (a -> b) -> a -> b
    $ \pout :: Ptr Word8
    pout ->
                   Ptr Word8
    -> Ptr CULLong -> CString -> CULLong -> CString -> IO CInt
    c_crypto_sign_open Ptr Word8
    pout Ptr CULLong
    pmlen CString
    smstr (Int -> CULLong
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    smlen) CString
    ppk

            Bool -> IO Bool
    forall (m :: * -> *) a. Monad m => a -> m a
    return (CInt
    r CInt -> CInt -> Bool
    forall a. Eq a => a -> a -> Bool
    == 0)
    {-# INLINE verify #-}

    --------------------------------------------------------------------------------
    -- Detached signature support

    -- $detachedsigs
    --
    -- This package also provides an alternative interface for /detached/
    -- /signatures/, which is more in-line with what you might
    -- traditionally expect from a signing API. In this mode, the
    -- @'dsign'@ and @'dverify'@ interfaces simply return a constant-sized
    -- blob, representing the Ed25519 signature of the input message.
    --
    -- This allows users to independently download, verify or attach
    -- signatures to messages in any way they see fit - for example, by
    -- providing a tarball file to download, with a corresponding @.sig@
    -- file containing the Ed25519 signature from the author.

    -- | A @'Signature'@ which is detached from the message it signed.
    --
    -- @since 0.0.1.0
    newtype Signature = Signature { Signature -> ByteString
    unSignature :: ByteString
                                    -- ^ Unwrapper for getting the raw
                                    -- @'ByteString'@ in a
                                    -- @'Signature'@. In general you
                                    -- should not make any assumptions
                                    -- about the underlying blob; this is
                                    -- only provided for interoperability.
                                  }
            deriving (Signature -> Signature -> Bool
    (Signature -> Signature -> Bool)
    -> (Signature -> Signature -> Bool) -> Eq Signature
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: Signature -> Signature -> Bool
    $c/= :: Signature -> Signature -> Bool
    == :: Signature -> Signature -> Bool
    $c== :: Signature -> Signature -> Bool
    Eq, Int -> Signature -> ShowS
    [Signature] -> ShowS
    Signature -> String
    (Int -> Signature -> ShowS)
    -> (Signature -> String)
    -> ([Signature] -> ShowS)
    -> Show Signature
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [Signature] -> ShowS
    $cshowList :: [Signature] -> ShowS
    show :: Signature -> String
    $cshow :: Signature -> String
    showsPrec :: Int -> Signature -> ShowS
    $cshowsPrec :: Int -> Signature -> ShowS
    Show, Eq Signature
    Eq Signature =>
    (Signature -> Signature -> Ordering)
    -> (Signature -> Signature -> Bool)
    -> (Signature -> Signature -> Bool)
    -> (Signature -> Signature -> Bool)
    -> (Signature -> Signature -> Bool)
    -> (Signature -> Signature -> Signature)
    -> (Signature -> Signature -> Signature)
    -> Ord Signature
    Signature -> Signature -> Bool
    Signature -> Signature -> Ordering
    Signature -> Signature -> Signature
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    min :: Signature -> Signature -> Signature
    $cmin :: Signature -> Signature -> Signature
    max :: Signature -> Signature -> Signature
    $cmax :: Signature -> Signature -> Signature
    >= :: Signature -> Signature -> Bool
    $c>= :: Signature -> Signature -> Bool
    > :: Signature -> Signature -> Bool
    $c> :: Signature -> Signature -> Bool
    <= :: Signature -> Signature -> Bool
    $c<= :: Signature -> Signature -> Bool
    < :: Signature -> Signature -> Bool
    $c< :: Signature -> Signature -> Bool
    compare :: Signature -> Signature -> Ordering
    $ccompare :: Signature -> Signature -> Ordering
    $cp1Ord :: Eq Signature
    Ord)

    #if __GLASGOW_HASKELL__ >= 702
    deriving instance Generic Signature
    #endif

    -- | Sign a message with a particular @'SecretKey'@, only returning the
    -- @'Signature'@ without the message.
    --
    -- @since 0.0.4.0
    dsign :: SecretKey
          -- ^ Signers @'SecretKey'@
          -> ByteString
          -- ^ Input message
          -> Signature
          -- ^ Message @'Signature'@, without the message
    dsign :: SecretKey -> ByteString -> Signature
    dsign sk :: SecretKey
    sk xs :: ByteString
    xs =
      let sm :: ByteString
    sm = SecretKey -> ByteString -> ByteString
    sign SecretKey
    sk ByteString
    xs
          l :: Int
    l  = ByteString -> Int
    S.length ByteString
    sm
      in ByteString -> Signature
    Signature (ByteString -> Signature) -> ByteString -> Signature
    forall a b. (a -> b) -> a -> b
    $! Int -> ByteString -> ByteString
    S.take (Int
    l Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - ByteString -> Int
    S.length ByteString
    xs) ByteString
    sm
    {-# INLINE dsign #-}

    -- | Verify a message with a detached @'Signature'@ against a given
    -- @'PublicKey'@.
    --
    -- @since 0.0.4.0
    dverify :: PublicKey
            -- ^ Signers @'PublicKey'@
            -> ByteString
            -- ^ Raw input message
            -> Signature
            -- ^ Message @'Signature'@
            -> Bool
            -- ^ Verification result
    dverify :: PublicKey -> ByteString -> Signature -> Bool
    dverify pk :: PublicKey
    pk xs :: ByteString
    xs (Signature sig :: ByteString
    sig) = PublicKey -> ByteString -> Bool
    verify PublicKey
    pk (ByteString
    sig ByteString -> ByteString -> ByteString
    `S.append` ByteString
    xs)
    {-# INLINE dverify #-}

    -- | Sign a message with a particular @'SecretKey'@, only returning the
    -- @'Signature'@ without the message. Simply an alias for @'dsign'@.
    --
    -- @since 0.0.1.0
    sign' :: SecretKey
          -- ^ Signers @'SecretKey'@
          -> ByteString
          -- ^ Input message
          -> Signature
          -- ^ Message @'Signature'@, without the message
    sign' :: SecretKey -> ByteString -> Signature
    sign' sk :: SecretKey
    sk xs :: ByteString
    xs = SecretKey -> ByteString -> Signature
    dsign SecretKey
    sk ByteString
    xs
    {-# DEPRECATED sign' "@'sign''@ will be removed in a future release; use @'dsign'@ instead." #-}

    -- | Verify a message with a detached @'Signature'@ against a given
    -- @'PublicKey'@. Simply an alias for @'dverify'@.
    --
    -- @since 0.0.1.0
    verify' :: PublicKey
            -- ^ Signers @'PublicKey'@
            -> ByteString
            -- ^ Raw input message
            -> Signature
            -- ^ Message @'Signature'@
            -> Bool
            -- ^ Verification result
    verify' :: PublicKey -> ByteString -> Signature -> Bool
    verify' pk :: PublicKey
    pk xs :: ByteString
    xs sig :: Signature
    sig = PublicKey -> ByteString -> Signature -> Bool
    dverify PublicKey
    pk ByteString
    xs Signature
    sig
    {-# DEPRECATED verify' "@'verify''@ will be removed in a future release; use @'dverify'@ instead." #-}

    --------------------------------------------------------------------------------
    -- FFI binding

    cryptoSignSECRETKEYBYTES :: Int
    cryptoSignSECRETKEYBYTES :: Int
    cryptoSignSECRETKEYBYTES = 64

    cryptoSignPUBLICKEYBYTES :: Int
    cryptoSignPUBLICKEYBYTES :: Int
    cryptoSignPUBLICKEYBYTES = 32

    cryptoSignBYTES :: Int
    cryptoSignBYTES :: Int
    cryptoSignBYTES = 64

    cryptoSignSEEDBYTES :: Int
    cryptoSignSEEDBYTES :: Int
    cryptoSignSEEDBYTES = 32

    foreign import ccall unsafe "ed25519_sign_seed_keypair"
      c_crypto_sign_seed_keypair :: Ptr Word8 -> Ptr Word8
                                 -> Ptr CChar -> IO CInt

    foreign import ccall unsafe "ed25519_sign_keypair"
      c_crypto_sign_keypair :: Ptr Word8 -> Ptr Word8 -> IO CInt

    foreign import ccall unsafe "ed25519_sign"
      c_crypto_sign :: Ptr Word8 -> Ptr CULLong ->
                       Ptr CChar -> CULLong -> Ptr CChar -> IO CULLong

    foreign import ccall unsafe "ed25519_sign_open"
      c_crypto_sign_open :: Ptr Word8 -> Ptr CULLong ->
                            Ptr CChar -> CULLong -> Ptr CChar -> IO CInt

    --------------------------------------------------------------------------------
    -- Documentation and notes

    -- $intro
    --
    -- The simplest use of this library is one where you probably need to
    -- sign short messages, so they can be verified independently. That's
    -- easily done by first creating a keypair with @'createKeypair'@, and
    -- using @'sign'@ to create a signed message. Then, you can distribute
    -- your public key and the signed message, and any recipient can
    -- verify that message:
    --
    -- >>> (pk, sk) <- createKeypair
    -- >>> let msg = sign sk "Hello world"
    -- >>> verify pk msg
    -- True
    --
    -- This interface is fine if your messages are small and simple binary
    -- blobs you want to verify in an opaque manner, but internally it
    -- creates a copy of the input message. Often, you'll want the
    -- signature independently of the message, and that can be done with
    -- @'dsign'@ and @'dverify'@. Naturally, verification fails if the
    -- message is incorrect:
    --
    -- >>> (pk, sk) <- createKeypair
    -- >>> let msg = "Hello world" :: ByteString
    -- >>> let sig = dsign sk msg
    -- >>> dverify pk msg sig
    -- True
    -- >>> dverify pk "Hello world" sig
    -- True
    -- >>> dverify pk "Goodbye world" sig
    -- False
    --
    -- Finally, it's worth keeping in mind this package doesn't expose any
    -- kind of incremental interface, and signing/verification can be
    -- expensive. So, if you're dealing with __large inputs__, you can
    -- hash the input with a robust, fast cryptographic hash, and then
    -- sign that (for example, the @hash@ function below could be
    -- __SHA-512__ or __BLAKE2b__):
    --
    -- >>> (pk, sk) <- createKeypair
    -- >>> msg <- readBigFile "blob.tar.gz" :: IO ByteString
    -- >>> let sig = dsign sk (hash msg)
    -- >>> dverify pk (hash msg) sig
    -- True
    --
    -- See the notes at the bottom of this module for more on message
    -- prehashing (as it acts slightly differently in an EdDSA system).

    -- $security
    --
    -- Included below are some notes on the security aspects of the
    -- Ed25519 signature system, its implementation and design, this
    -- package, and suggestions for how you might use it properly.

    -- $background
    --
    -- Ed25519 is a specific instantiation of the __EdDSA__ digital
    -- signature scheme - a high performance, secure-by-design variant of
    -- Schnorr signatures based on "Twisted Edwards Curves" (hence the
    -- name __Ed__DSA). The (__extended__) EdDSA system is defined by an
    -- elliptic curve:
    --
    -- > ax^2 + y^2 = 1 + d*x^2*y^2
    --
    -- along with several other parameters, chosen by the implementation
    -- in question. These parameters include @a@, @d@, and a field @GF(p)@
    -- where @p@ is prime. Ed25519 specifically uses @d = -121665/121666@,
    -- @a = -1@, and the finite field @GF((2^155)-19)@, where @(2^155)-19@
    -- is a prime number (which is also the namesake of the algorithm in
    -- question, as Ed__25519__). This yields the equation:
    --
    -- > -x^2 + y^2 = 1 - (121665/121666)*x^2*y^2
    --
    -- This curve is \'birationally equivalent\' to the well-known
    -- Montgomery curve \'Curve25519\', which means that EdDSA shares the
    -- same the difficult problem as Curve25519: that of the Elliptic
    -- Curve Discrete Logarithm Problem (ECDLP). Ed25519 is currently
    -- still the recommended EdDSA curve for most deployments.
    --
    -- As Ed25519 is an elliptic curve algorithm, the security level
    -- (i.e. number of computations taken to find a solution to the ECDLP
    -- with the fastest known attacks) is roughly half the key size in
    -- bits, as it stands. As Ed25519 features 32-byte keys, the security
    -- level of Ed25519 is thus @2^((32*8)/2) = 2^128@, far beyond any
    -- attacker capability (modulo major breakthroughs for the ECDLP,
    -- which would likely catastrophically be applicable to other systems
    -- too).
    --
    -- Ed25519 designed to meet the standard notion of unforgeability for
    -- a public-key signature scheme under chosen-message attacks. This
    -- means that even should the attacker be able to request someone sign
    -- any arbitrary message of their choice (hence /chosen-message/),
    -- they are still not capable of any forgery what-so-ever, even the
    -- weakest kind of \'existential forgery\'.

    -- $seedgen
    --
    -- Seed generation as done by @'createKeypair'@ uses Operating System
    -- provided APIs for generating cryptographically secure psuedo-random
    -- data to be used as an Ed25519 key seed. Your own deterministic keys
    -- may be generated using @'createKeypairFromSeed_'@, provided you have
    -- your own cryptographically secure psuedo-random data from
    -- somewhere.
    --
    -- On __Linux__, __OS X__ and __other Unix__ machines, the
    -- @\/dev\/urandom@ device is consulted internally in order to generate
    -- random data. In the current implementation, a global file
    -- descriptor is used through the lifetime of the program to
    -- periodically get psuedo-random data.
    --
    -- On __Windows__, the @CryptGenRandom@ API is used internally. This
    -- does not require file handles of any kind, and should work on all
    -- versions of Windows. (Windows may instead use @RtlGenRandom@ in the
    -- future for even less overhead.)
    --
    -- In the future, there are plans for this package to internally take
    -- advantage of better APIs when they are available; for example, on
    -- Linux 3.17 and above, @getrandom(2)@ provides psuedo-random data
    -- directly through the internal pool provided by @\/dev\/urandom@,
    -- without a file descriptor. Similarly, OpenBSD provides the
    -- @arc4random(3)@ family of functions, which internally uses a data
    -- generator based on ChaCha20. These should offer somewhat better
    -- efficiency, and also avoid file-descriptor exhaustion attacks which
    -- could lead to denial of service in some scenarios.

    -- $performance
    --
    -- Ed25519 is exceptionally fast, although the implementation provided
    -- by this package is not the fastest possible implementation. Indeed,
    -- it is rather slow, even by non-handwritten-assembly standards of
    -- speed. That said, it should still be competitive with most other
    -- signature schemes: the underlying implementation is @ref10@ from
    -- <http://bench.cr.yp.to/ SUPERCOP>, authored by Daniel J. Bernstein,
    -- which is within the
    -- <http://bench.cr.yp.to/impl-sign/ed25519.html realm of competition>
    -- against some assembly implementations (only 2x slower), and much
    -- faster than the slow reference implementation (25x slower). When up
    -- <http://bench.cr.yp.to/web-impl/amd64-skylake-crypto_sign.html against RSA>
    -- signatures (ronald3072) on a modern Intel machine, it is still __15x__
    -- faster at signing messages /at the same 128-bit security level/.
    --
    -- On the author's Sandy Bridge i5-2520M 2.50GHz CPU, the benchmarking
    -- code included with the library reports the following numbers for
    -- the Haskell interface:
    --
    -- @
    -- benchmarking deterministic key generation
    -- time                 250.0 μs   (249.8 μs .. 250.3 μs)
    --                      1.000 R²   (1.000 R² .. 1.000 R²)
    -- mean                 250.0 μs   (249.9 μs .. 250.2 μs)
    -- std dev              467.0 ns   (331.7 ns .. 627.9 ns)
    --
    -- benchmarking signing a 256 byte message
    -- time                 273.2 μs   (273.0 μs .. 273.4 μs)
    --                      1.000 R²   (1.000 R² .. 1.000 R²)
    -- mean                 273.3 μs   (273.1 μs .. 273.5 μs)
    -- std dev              616.2 ns   (374.1 ns .. 998.8 ns)
    --
    -- benchmarking verifying a signature
    -- time                 635.7 μs   (634.6 μs .. 637.3 μs)
    --                      1.000 R²   (1.000 R² .. 1.000 R²)
    -- mean                 635.4 μs   (635.0 μs .. 636.0 μs)
    -- std dev              1.687 μs   (999.3 ns .. 2.487 μs)
    --
    -- benchmarking roundtrip 256-byte sign/verify
    -- time                 923.6 μs   (910.0 μs .. 950.6 μs)
    --                      0.998 R²   (0.996 R² .. 1.000 R²)
    -- mean                 913.2 μs   (910.6 μs .. 923.0 μs)
    -- std dev              15.93 μs   (1.820 μs .. 33.72 μs)
    -- @
    --
    -- In the future, this package will hopefully provide an opt-in (or
    -- possibly default) implementation of
    -- <https://github.com/floodyberry/ed25519-donna ed25519-donna>, which
    -- should dramatically increase speed at no cost for many/all
    -- platforms.

    -- $keystorage
    --
    -- By default, keys are not encrypted in any meaningful manner with
    -- any mechanism, and this package does not provide any means of doing
    -- so. As a result, your secret keys are only as secure as the
    -- computing environment housing them - a server alone out on the
    -- hostile internet, or a USB stick that's susceptable to theft.
    --
    -- If you wish to add some security to your keys, a very simple and
    -- effective way is __to add a password to your @'SecretKey'@ with a__
    -- __KDF and a hash__. How does this work?
    --
    --   * First, hash the secret key you have generated. Use this as a
    --   __checksum__ of the original key. Truncating this hash to save
    --   space is acceptable; see below for more details and boring
    --   hemming and hawing.
    --
    --   * Given an input password, use a KDF to stretch it to the length
    --   of a @'SecretKey'@.
    --
    --   * XOR the @'SecretKey'@ bytewise, directly with the output of
    --   your chosen KDF.
    --
    --   * Attach the checksum you generated to the resulting encrypted
    --   key, and store it as you like.
    --
    -- In this mode, your key is XOR'd with the psuedo-random result of a
    -- KDF, which will stretch simple passwords like "I am the robot" into
    -- a suitable amount of psuedo-random data for a given secret key to
    -- be encrypted with. Decryption is simply the act of taking the
    -- password, generating the psuedo-random stream again, XORing the key
    -- bytewise, and validating the checksum. In this sense, you are
    -- simply using a KDF as a short stream cipher.
    --
    -- __Recommendation__: Encrypt keys by stretching a password with
    -- __scrypt__ (or __yescrypt__), using better-than-default parameters.
    -- (These being @N = 2^14@, @r = 8@, @p = 1@; the default results in
    -- 16mb of memory per invocation, and this is the recommended default
    -- for 'interactive systems'; signing keys may be loaded on-startup
    -- for some things however, so it may be profitable to increase
    -- security as well as memory use in these cases. For example, at @N =
    -- 2^18@, @r = 10@ and @p = 2@, you'll get 320mb of memory per use,
    -- which may be acceptable for dramatic security increases. See
    -- elsewhere for exact memory use.) Checksums may be computed with an
    -- exceptionally fast hash such as __BLAKE2b__.
    --
    -- __Bonus points__: Print that resulting checksum + key out on a
    -- piece of paper (~100 bytes, tops), and put /that/ somewhere safe.
    --
    -- __Q__: What is the hash needed for? __A__: A simple file integrity
    -- check. Rather than invoke complicated methods of verifying if an
    -- ed25519 keypair is valid (as it is simply an opaque binary blob,
    -- for all intents and purposes), especially after 'streaming
    -- decryption', it's far easier to simply compute and compare against
    -- a checksum of the original to determine if decryption with your
    -- password worked.
    --
    -- __Q__: Wait, why is it OK to truncate the hash here? That sounds
    -- scary. Won't that open up collisions or something like that if they
    -- stole my encrypted key?  __A__: No. The hash in this case is only
    -- used as a checksum to see if the password is legitimate after
    -- running the KDF and XORing with the result. Think about how the
    -- \'challenge\' itself is chosen: if you know @H(m)@, do you want to
    -- find @m@ itself, or simply find @m'@ where @H(m') = H(m)@?  To
    -- forge a signature, you want the original key, @m@. Suppose given an
    -- input of 256-bits, we hashed it and truncated to one bit. Finding
    -- collisions would be easy: you would only need to try a few times to
    -- find a collision or preimage. But you probably found @m'@ such that
    -- @H(m') = H(m)@ - you didn't necessarily find @m@ itself. In this
    -- sense, finding collisions or preimages of the hash is not useful to
    -- the attacker, because you must find the unique @m@.
    --
    -- __Q__: Okay, why use hashes at all? Why not CRC32? __A__: You could
    -- do that, it wouldn't change much. You can really use any kind of
    -- error detecting code you want. The thing is, some hashes such as
    -- __BLAKE2__ are very fast in things like software (not every CPU has
    -- CRC instructions, not all software uses CRC instructions), and
    -- you're likely to already have a fast, modern hash function sitting
    -- around anyway if you're signing stuff with Ed25519. Why not use it?

    -- $prehashing
    --
    -- __Message prehashing__ (although not an official term in any right)
    -- is the idea of first taking an input @x@, using a
    -- __cryptographically secure__ hash function @H@ to calculate @y =
    -- H(x)@, and then generating a signature via @Sign(secretKey,
    -- y)@. The idea is that signing is often expensive, while hashing is
    -- often extremely fast. As a result, signing the hash of a message
    -- (which should be indistinguishable from a truly random function) is
    -- often faster than simply signing the full message alone, and in
    -- larger cases can save a significant amount of CPU cycles. However,
    -- internally Ed25519 uses a hash function @H@ already to hash the
    -- input message for computing the signature. Thus, there is a
    -- question - is it appropriate or desireable to hash the input
    -- already if this is the case?
    --
    -- Generally speaking, it's OK to prehash messages before giving them
    -- to Ed25519. However, there is a caveat. In the paper
    -- <http://ed25519.cr.yp.to/eddsa-20150704.pdf "EdDSA for more curves">,
    -- the authors of the original EdDSA enhance the specification by
    -- extending it with a message prehash function, @H'@, along with an
    -- internal hash @H@. Here, the prehash @H'@ is simply applied to the
    -- original message first before anything else. The original EdDSA
    -- specification (and the implementation in /this package/) was a
    -- trivial case of this enhancement: it was implicit that @H'@ is
    -- simply the identity function. We call the case where @H'@ is the
    -- identity function __PureEdDSA__, while the case where @H'@ is a
    -- cryptographic hash function is known as __HashEdDSA__. (Thus, the
    -- interfaces @'sign'@ and @'dsign'@ implement PureEdDSA - while they can
    -- be converted to HashEdDSA by simply hashing the @'ByteString'@
    -- first with some other function.)
    --
    -- However, the authors note that HashEdDSA suffers from a weakness
    -- that PureEdDSA does not - PureEdDSA is resiliant to collision
    -- attacks in the underlying hash function @H@, while HashEdDSA is
    -- vulnerable to collisions in @H'@. This is an important
    -- distinction. Assume that the attacker finds a collision such that
    -- @H'(x) = H'(y)@, and then gets convinces a signer to HashEdDSA-sign
    -- @x@ - the attacker may then forge this signature and use it as the
    -- same signature as for the message @y@. For a hash function of
    -- @N@-bits of output, a collision attack takes roughly @2^(N/2)@
    -- operations.
    --
    -- Ed25519 internally sets @H = SHA-512@ anyway, which has no known
    -- collision attacks or weaknesses in any meaningful sense. It is
    -- however slower compared to other, more modern hash functions, and
    -- is used on the input message in its entirety (and there are no
    -- plans to switch the internal implementation of this package, or the
    -- standard Ed25519 away from @H = SHA-512@).
    --
    -- But note: /all other hash-then-sign constructions suffer from/
    -- /this/, in the sense they are all vulnerable to collision attacks
    -- in @H'@, should you prehash the message. In fact, PureEdDSA is
    -- unique (as far as I am aware) in that it is immune to collision
    -- attacks in @H@ - should a collision be found, it would not suffer
    -- from these forgeries. By this view, it's arguable that /depending/
    -- on the HashEdDSA construction (for efficiency or size purposes)
    -- when using EdDSA is somewhat less robust, even if SHA-512 or
    -- whatever is not very fast. Despite that, just about any /modern/
    -- /hash/ you pick is going to be collision resistant to a fine degree
    -- (say, 256 bits of output, therefore collisions 'at best' happen in
    -- @2^128@ operations), so in practice this robustness issue may not
    -- be that big of a deal.
    --
    -- However, the more pertinent issue is that due to the current design
    -- of the API which requires the entire blob to sign up front, using
    -- the HashEdDSA construction is often much more convenient, faster
    -- and sometimes /necessary/ too. For example, when signing very large
    -- messages (such as creating a very large @tar.gz@ file which you
    -- wish to sign after creation), it is often convenient and possible
    -- to use \'incremental\' hashing APIs to incrementally consume data
    -- blocks from the input in a constant amount of memory. At the end of
    -- consumption, you can \'finalize\' the data blocks and get back a
    -- final N-bit hash, and sign this hash all in a constant amount of
    -- memory. With the current API, using PureDSA would require you
    -- loading the entire file up front to either sign, or verify it. This
    -- is especially unoptimal for possibly smaller, low-memory systems
    -- (where decompression, hashing or verification are all best done in
    -- constant space if possible).
    --
    -- Beware however, that if you do this sort of incremental hashing for
    -- large blobs, you are __taking untrusted data__ and hashing it
    -- __before checking the signature__ - be __exceptionally careful__
    -- with data from a possibly untrustworthy source until you can verify
    -- the signature.
    --
    -- So, __some basic guidelines are__:
    --
    --   - If you are simply not worried about efficiency very much, just
    --   use __PureEdDSA__ (i.e.  just use @'sign'@ and @'verify'@
    --   directly).
    --
    --   - If you have __lots of small messages__, use __PureEdDSA__ (i.e.
    --   just use @'sign'@ and @'verify'@ directly).
    --
    --   - If you have to sign/verify __large messages__, possibly __in__
    --   __an incremental fashion__, use __HashEdDSA__ with __a fast__
    --   __hash__ (i.e.  just hash a message before using @'sign'@ or
    --   @'verify'@ on it).
    --
    --       - A hash like __BLAKE2b__ is recommended. Fast and very secure.
    --
    --       - Remember: __never touch input data in any form until you__
    --       __are done hashing it and verifying the signature__.
    --
    -- As a result, you should be safe hashing your input before passing
    -- it to @'sign'@ or @'dsign'@ in this library if you desire, and it may
    -- save you CPU cycles for large inputs. It should be no different
    -- than the typical /hash-then-sign/ construction you see elsewhere,
    -- with the same downfalls. Should you do this, an extremely
    -- fast-yet-secure hash such as __BLAKE2b__ is recommended, which is
    -- even faster than MD5 or SHA-1 (and __do not ever use MD5 or__
    -- __SHA-1__, on that note - they suffer from collision attacks).