    {-# OPTIONS_HADDOCK hide #-}
    {-# LANGUAGE ExistentialQuantification #-}
    {-# LANGUAGE RankNTypes #-}
    module Network.TLS.Crypto
        ( HashContext
        , HashCtx
        , hashInit
        , hashUpdate
        , hashUpdateSSL
        , hashFinal

        , module Network.TLS.Crypto.DH
        , module Network.TLS.Crypto.IES
        , module Network.TLS.Crypto.Types

        -- * Hash
        , hash
        , Hash(..)
        , hashName
        , hashDigestSize
        , hashBlockSize

        -- * key exchange generic interface
        , PubKey(..)
        , PrivKey(..)
        , PublicKey
        , PrivateKey
        , SignatureParams(..)
        , isKeyExchangeSignatureKey
        , findKeyExchangeSignatureAlg
        , findFiniteFieldGroup
        , findEllipticCurveGroup
        , kxEncrypt
        , kxDecrypt
        , kxSign
        , kxVerify
        , kxCanUseRSApkcs1
        , kxCanUseRSApss
        , kxSupportedPrivKeyEC
        , KxError(..)
        , RSAEncoding(..)
        ) where

    import qualified Crypto.Hash as H
    import qualified Data.ByteString as B
    import qualified Data.ByteArray as B (convert)
    import Crypto.Error
    import Crypto.Number.Basic (numBits)
    import Crypto.Random
    import qualified Crypto.ECC as ECDSA
    import qualified Crypto.PubKey.DH as DH
    import qualified Crypto.PubKey.DSA as DSA
    import qualified Crypto.PubKey.ECC.ECDSA as ECDSA_ECC
    import qualified Crypto.PubKey.ECC.Types as ECC
    import qualified Crypto.PubKey.ECDSA as ECDSA
    import qualified Crypto.PubKey.Ed25519 as Ed25519
    import qualified Crypto.PubKey.Ed448 as Ed448
    import qualified Crypto.PubKey.RSA as RSA
    import qualified Crypto.PubKey.RSA.PKCS15 as RSA
    import qualified Crypto.PubKey.RSA.PSS as PSS

    import Data.X509 (PrivKey(..), PubKey(..), PrivKeyEC(..), PubKeyEC(..),
                      SerializedPoint(..))
    import Data.X509.EC (ecPrivKeyCurveName, ecPubKeyCurveName, unserializePoint)
    import Network.TLS.Crypto.DH
    import Network.TLS.Crypto.IES
    import Network.TLS.Crypto.Types
    import Network.TLS.Imports

    import Data.ASN1.Types
    import Data.ASN1.Encoding
    import Data.ASN1.BinaryEncoding (DER(..), BER(..))

    import Data.Proxy

    {-# DEPRECATED PublicKey "use PubKey" #-}
    type PublicKey = PubKey
    {-# DEPRECATED PrivateKey "use PrivKey" #-}
    type PrivateKey = PrivKey

    data KxError =
          RSAError RSA.Error
        | KxUnsupported
        deriving (Int -> KxError -> ShowS
    [KxError] -> ShowS
    KxError -> String
    (Int -> KxError -> ShowS)
    -> (KxError -> String) -> ([KxError] -> ShowS) -> Show KxError
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> KxError -> ShowS
    showsPrec :: Int -> KxError -> ShowS
    $cshow :: KxError -> String
    show :: KxError -> String
    $cshowList :: [KxError] -> ShowS
    showList :: [KxError] -> ShowS
    Show)

    isKeyExchangeSignatureKey :: KeyExchangeSignatureAlg -> PubKey -> Bool
    isKeyExchangeSignatureKey :: KeyExchangeSignatureAlg -> PubKey -> Bool
    isKeyExchangeSignatureKey = KeyExchangeSignatureAlg -> PubKey -> Bool
    f
      where
        f :: KeyExchangeSignatureAlg -> PubKey -> Bool
    f KeyExchangeSignatureAlg
    KX_RSA   (PubKeyRSA     PublicKey
    _)   = Bool
    True
        f KeyExchangeSignatureAlg
    KX_DSS   (PubKeyDSA     PublicKey
    _)   = Bool
    True
        f KeyExchangeSignatureAlg
    KX_ECDSA (PubKeyEC      PubKeyEC
    _)   = Bool
    True
        f KeyExchangeSignatureAlg
    KX_ECDSA (PubKeyEd25519 PublicKey
    _)   = Bool
    True
        f KeyExchangeSignatureAlg
    KX_ECDSA (PubKeyEd448   PublicKey
    _)   = Bool
    True
        f KeyExchangeSignatureAlg
    _        PubKey
    _                   = Bool
    False

    findKeyExchangeSignatureAlg :: (PubKey, PrivKey) -> Maybe KeyExchangeSignatureAlg
    findKeyExchangeSignatureAlg :: (PubKey, PrivKey) -> Maybe KeyExchangeSignatureAlg
    findKeyExchangeSignatureAlg (PubKey, PrivKey)
    keyPair =
        case (PubKey, PrivKey)
    keyPair of
            (PubKeyRSA     PublicKey
    _, PrivKeyRSA      PrivateKey
    _)  -> KeyExchangeSignatureAlg -> Maybe KeyExchangeSignatureAlg
    forall a. a -> Maybe a
    Just KeyExchangeSignatureAlg
    KX_RSA
            (PubKeyDSA     PublicKey
    _, PrivKeyDSA      PrivateKey
    _)  -> KeyExchangeSignatureAlg -> Maybe KeyExchangeSignatureAlg
    forall a. a -> Maybe a
    Just KeyExchangeSignatureAlg
    KX_DSS
            (PubKeyEC      PubKeyEC
    _, PrivKeyEC       PrivKeyEC
    _)  -> KeyExchangeSignatureAlg -> Maybe KeyExchangeSignatureAlg
    forall a. a -> Maybe a
    Just KeyExchangeSignatureAlg
    KX_ECDSA
            (PubKeyEd25519 PublicKey
    _, PrivKeyEd25519  SecretKey
    _)  -> KeyExchangeSignatureAlg -> Maybe KeyExchangeSignatureAlg
    forall a. a -> Maybe a
    Just KeyExchangeSignatureAlg
    KX_ECDSA
            (PubKeyEd448   PublicKey
    _, PrivKeyEd448    SecretKey
    _)  -> KeyExchangeSignatureAlg -> Maybe KeyExchangeSignatureAlg
    forall a. a -> Maybe a
    Just KeyExchangeSignatureAlg
    KX_ECDSA
            (PubKey, PrivKey)
    _                                     -> Maybe KeyExchangeSignatureAlg
    forall a. Maybe a
    Nothing

    findFiniteFieldGroup :: DH.Params -> Maybe Group
    findFiniteFieldGroup :: Params -> Maybe Group
    findFiniteFieldGroup Params
    params = (Integer, Integer) -> [((Integer, Integer), Group)] -> Maybe Group
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup (Params -> (Integer, Integer)
    pg Params
    params) [((Integer, Integer), Group)]
    table
      where
        pg :: Params -> (Integer, Integer)
    pg (DH.Params Integer
    p Integer
    g Int
    _) = (Integer
    p, Integer
    g)

        table :: [((Integer, Integer), Group)]
    table = [ (Params -> (Integer, Integer)
    pg Params
    prms, Group
    grp) | Group
    grp <- [Group]
    availableFFGroups
                                 , let Just Params
    prms = Group -> Maybe Params
    dhParamsForGroup Group
    grp
                ]

    findEllipticCurveGroup :: PubKeyEC -> Maybe Group
    findEllipticCurveGroup :: PubKeyEC -> Maybe Group
    findEllipticCurveGroup PubKeyEC
    ecPub =
        case PubKeyEC -> Maybe CurveName
    ecPubKeyCurveName PubKeyEC
    ecPub of
            Just CurveName
    ECC.SEC_p256r1 -> Group -> Maybe Group
    forall a. a -> Maybe a
    Just Group
    P256
            Just CurveName
    ECC.SEC_p384r1 -> Group -> Maybe Group
    forall a. a -> Maybe a
    Just Group
    P384
            Just CurveName
    ECC.SEC_p521r1 -> Group -> Maybe Group
    forall a. a -> Maybe a
    Just Group
    P521
            Maybe CurveName
    _                   -> Maybe Group
    forall a. Maybe a
    Nothing

    -- functions to use the hidden class.
    hashInit :: Hash -> HashContext
    hashInit :: Hash -> HashContext
    hashInit Hash
    MD5      = ContextSimple -> HashContext
    HashContext (ContextSimple -> HashContext) -> ContextSimple -> HashContext
    forall a b. (a -> b) -> a -> b
    $ Context MD5 -> ContextSimple
    forall alg. HashAlgorithm alg => Context alg -> ContextSimple
    ContextSimple (Context MD5
    forall a. HashAlgorithm a => Context a
    H.hashInit :: H.Context H.MD5)
    hashInit Hash
    SHA1     = ContextSimple -> HashContext
    HashContext (ContextSimple -> HashContext) -> ContextSimple -> HashContext
    forall a b. (a -> b) -> a -> b
    $ Context SHA1 -> ContextSimple
    forall alg. HashAlgorithm alg => Context alg -> ContextSimple
    ContextSimple (Context SHA1
    forall a. HashAlgorithm a => Context a
    H.hashInit :: H.Context H.SHA1)
    hashInit Hash
    SHA224   = ContextSimple -> HashContext
    HashContext (ContextSimple -> HashContext) -> ContextSimple -> HashContext
    forall a b. (a -> b) -> a -> b
    $ Context SHA224 -> ContextSimple
    forall alg. HashAlgorithm alg => Context alg -> ContextSimple
    ContextSimple (Context SHA224
    forall a. HashAlgorithm a => Context a
    H.hashInit :: H.Context H.SHA224)
    hashInit Hash
    SHA256   = ContextSimple -> HashContext
    HashContext (ContextSimple -> HashContext) -> ContextSimple -> HashContext
    forall a b. (a -> b) -> a -> b
    $ Context SHA256 -> ContextSimple
    forall alg. HashAlgorithm alg => Context alg -> ContextSimple
    ContextSimple (Context SHA256
    forall a. HashAlgorithm a => Context a
    H.hashInit :: H.Context H.SHA256)
    hashInit Hash
    SHA384   = ContextSimple -> HashContext
    HashContext (ContextSimple -> HashContext) -> ContextSimple -> HashContext
    forall a b. (a -> b) -> a -> b
    $ Context SHA384 -> ContextSimple
    forall alg. HashAlgorithm alg => Context alg -> ContextSimple
    ContextSimple (Context SHA384
    forall a. HashAlgorithm a => Context a
    H.hashInit :: H.Context H.SHA384)
    hashInit Hash
    SHA512   = ContextSimple -> HashContext
    HashContext (ContextSimple -> HashContext) -> ContextSimple -> HashContext
    forall a b. (a -> b) -> a -> b
    $ Context SHA512 -> ContextSimple
    forall alg. HashAlgorithm alg => Context alg -> ContextSimple
    ContextSimple (Context SHA512
    forall a. HashAlgorithm a => Context a
    H.hashInit :: H.Context H.SHA512)
    hashInit Hash
    SHA1_MD5 = Context SHA1 -> Context MD5 -> HashContext
    HashContextSSL Context SHA1
    forall a. HashAlgorithm a => Context a
    H.hashInit Context MD5
    forall a. HashAlgorithm a => Context a
    H.hashInit

    hashUpdate :: HashContext -> B.ByteString -> HashCtx
    hashUpdate :: HashContext -> ByteString -> HashContext
    hashUpdate (HashContext (ContextSimple Context alg
    h)) ByteString
    b = ContextSimple -> HashContext
    HashContext (ContextSimple -> HashContext) -> ContextSimple -> HashContext
    forall a b. (a -> b) -> a -> b
    $ Context alg -> ContextSimple
    forall alg. HashAlgorithm alg => Context alg -> ContextSimple
    ContextSimple (Context alg -> ByteString -> Context alg
    forall ba a.
    (ByteArrayAccess ba, HashAlgorithm a) =>
    Context a -> ba -> Context a
    H.hashUpdate Context alg
    h ByteString
    b)
    hashUpdate (HashContextSSL Context SHA1
    sha1Ctx Context MD5
    md5Ctx) ByteString
    b =
        Context SHA1 -> Context MD5 -> HashContext
    HashContextSSL (Context SHA1 -> ByteString -> Context SHA1
    forall ba a.
    (ByteArrayAccess ba, HashAlgorithm a) =>
    Context a -> ba -> Context a
    H.hashUpdate Context SHA1
    sha1Ctx ByteString
    b) (Context MD5 -> ByteString -> Context MD5
    forall ba a.
    (ByteArrayAccess ba, HashAlgorithm a) =>
    Context a -> ba -> Context a
    H.hashUpdate Context MD5
    md5Ctx ByteString
    b)

    hashUpdateSSL :: HashCtx
                  -> (B.ByteString,B.ByteString) -- ^ (for the md5 context, for the sha1 context)
                  -> HashCtx
    hashUpdateSSL :: HashContext -> (ByteString, ByteString) -> HashContext
    hashUpdateSSL (HashContext ContextSimple
    _) (ByteString, ByteString)
    _ = String -> HashContext
    forall a. HasCallStack => String -> a
    error String
    "internal error: update SSL without a SSL Context"
    hashUpdateSSL (HashContextSSL Context SHA1
    sha1Ctx Context MD5
    md5Ctx) (ByteString
    b1,ByteString
    b2) =
        Context SHA1 -> Context MD5 -> HashContext
    HashContextSSL (Context SHA1 -> ByteString -> Context SHA1
    forall ba a.
    (ByteArrayAccess ba, HashAlgorithm a) =>
    Context a -> ba -> Context a
    H.hashUpdate Context SHA1
    sha1Ctx ByteString
    b2) (Context MD5 -> ByteString -> Context MD5
    forall ba a.
    (ByteArrayAccess ba, HashAlgorithm a) =>
    Context a -> ba -> Context a
    H.hashUpdate Context MD5
    md5Ctx ByteString
    b1)

    hashFinal :: HashCtx -> B.ByteString
    hashFinal :: HashContext -> ByteString
    hashFinal (HashContext (ContextSimple Context alg
    h)) = Digest alg -> ByteString
    forall bin bout.
    (ByteArrayAccess bin, ByteArray bout) =>
    bin -> bout
    B.convert (Digest alg -> ByteString) -> Digest alg -> ByteString
    forall a b. (a -> b) -> a -> b
    $ Context alg -> Digest alg
    forall a. HashAlgorithm a => Context a -> Digest a
    H.hashFinalize Context alg
    h
    hashFinal (HashContextSSL Context SHA1
    sha1Ctx Context MD5
    md5Ctx) =
        [ByteString] -> ByteString
    B.concat [Digest MD5 -> ByteString
    forall bin bout.
    (ByteArrayAccess bin, ByteArray bout) =>
    bin -> bout
    B.convert (Context MD5 -> Digest MD5
    forall a. HashAlgorithm a => Context a -> Digest a
    H.hashFinalize Context MD5
    md5Ctx), Digest SHA1 -> ByteString
    forall bin bout.
    (ByteArrayAccess bin, ByteArray bout) =>
    bin -> bout
    B.convert (Context SHA1 -> Digest SHA1
    forall a. HashAlgorithm a => Context a -> Digest a
    H.hashFinalize Context SHA1
    sha1Ctx)]

    data Hash = MD5 | SHA1 | SHA224 | SHA256 | SHA384 | SHA512 | SHA1_MD5
        deriving (Int -> Hash -> ShowS
    [Hash] -> ShowS
    Hash -> String
    (Int -> Hash -> ShowS)
    -> (Hash -> String) -> ([Hash] -> ShowS) -> Show Hash
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Hash -> ShowS
    showsPrec :: Int -> Hash -> ShowS
    $cshow :: Hash -> String
    show :: Hash -> String
    $cshowList :: [Hash] -> ShowS
    showList :: [Hash] -> ShowS
    Show,Hash -> Hash -> Bool
    (Hash -> Hash -> Bool) -> (Hash -> Hash -> Bool) -> Eq Hash
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Hash -> Hash -> Bool
    == :: Hash -> Hash -> Bool
    $c/= :: Hash -> Hash -> Bool
    /= :: Hash -> Hash -> Bool
    Eq)

    data HashContext =
          HashContext ContextSimple
        | HashContextSSL (H.Context H.SHA1) (H.Context H.MD5)

    instance Show HashContext where
        show :: HashContext -> String
    show HashContext
    _ = String
    "hash-context"

    data ContextSimple = forall alg . H.HashAlgorithm alg => ContextSimple (H.Context alg)

    type HashCtx = HashContext

    hash :: Hash -> B.ByteString -> B.ByteString
    hash :: Hash -> ByteString -> ByteString
    hash Hash
    MD5 ByteString
    b      = Digest MD5 -> ByteString
    forall bin bout.
    (ByteArrayAccess bin, ByteArray bout) =>
    bin -> bout
    B.convert (Digest MD5 -> ByteString)
    -> (ByteString -> Digest MD5) -> ByteString -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (ByteString -> Digest MD5
    forall ba a.
    (ByteArrayAccess ba, HashAlgorithm a) =>
    ba -> Digest a
    H.hash :: B.ByteString -> H.Digest H.MD5) (ByteString -> ByteString) -> ByteString -> ByteString
    forall a b. (a -> b) -> a -> b
    $ ByteString
    b
    hash Hash
    SHA1 ByteString
    b     = Digest SHA1 -> ByteString
    forall bin bout.
    (ByteArrayAccess bin, ByteArray bout) =>
    bin -> bout
    B.convert (Digest SHA1 -> ByteString)
    -> (ByteString -> Digest SHA1) -> ByteString -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (ByteString -> Digest SHA1
    forall ba a.
    (ByteArrayAccess ba, HashAlgorithm a) =>
    ba -> Digest a
    H.hash :: B.ByteString -> H.Digest H.SHA1) (ByteString -> ByteString) -> ByteString -> ByteString
    forall a b. (a -> b) -> a -> b
    $ ByteString
    b
    hash Hash
    SHA224 ByteString
    b   = Digest SHA224 -> ByteString
    forall bin bout.
    (ByteArrayAccess bin, ByteArray bout) =>
    bin -> bout
    B.convert (Digest SHA224 -> ByteString)
    -> (ByteString -> Digest SHA224) -> ByteString -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (ByteString -> Digest SHA224
    forall ba a.
    (ByteArrayAccess ba, HashAlgorithm a) =>
    ba -> Digest a
    H.hash :: B.ByteString -> H.Digest H.SHA224) (ByteString -> ByteString) -> ByteString -> ByteString
    forall a b. (a -> b) -> a -> b
    $ ByteString
    b
    hash Hash
    SHA256 ByteString
    b   = Digest SHA256 -> ByteString
    forall bin bout.
    (ByteArrayAccess bin, ByteArray bout) =>
    bin -> bout
    B.convert (Digest SHA256 -> ByteString)
    -> (ByteString -> Digest SHA256) -> ByteString -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (ByteString -> Digest SHA256
    forall ba a.
    (ByteArrayAccess ba, HashAlgorithm a) =>
    ba -> Digest a
    H.hash :: B.ByteString -> H.Digest H.SHA256) (ByteString -> ByteString) -> ByteString -> ByteString
    forall a b. (a -> b) -> a -> b
    $ ByteString
    b
    hash Hash
    SHA384 ByteString
    b   = Digest SHA384 -> ByteString
    forall bin bout.
    (ByteArrayAccess bin, ByteArray bout) =>
    bin -> bout
    B.convert (Digest SHA384 -> ByteString)
    -> (ByteString -> Digest SHA384) -> ByteString -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (ByteString -> Digest SHA384
    forall ba a.
    (ByteArrayAccess ba, HashAlgorithm a) =>
    ba -> Digest a
    H.hash :: B.ByteString -> H.Digest H.SHA384) (ByteString -> ByteString) -> ByteString -> ByteString
    forall a b. (a -> b) -> a -> b
    $ ByteString
    b
    hash Hash
    SHA512 ByteString
    b   = Digest SHA512 -> ByteString
    forall bin bout.
    (ByteArrayAccess bin, ByteArray bout) =>
    bin -> bout
    B.convert (Digest SHA512 -> ByteString)
    -> (ByteString -> Digest SHA512) -> ByteString -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (ByteString -> Digest SHA512
    forall ba a.
    (ByteArrayAccess ba, HashAlgorithm a) =>
    ba -> Digest a
    H.hash :: B.ByteString -> H.Digest H.SHA512) (ByteString -> ByteString) -> ByteString -> ByteString
    forall a b. (a -> b) -> a -> b
    $ ByteString
    b
    hash Hash
    SHA1_MD5 ByteString
    b =
        [ByteString] -> ByteString
    B.concat [Digest MD5 -> ByteString
    forall bin bout.
    (ByteArrayAccess bin, ByteArray bout) =>
    bin -> bout
    B.convert (ByteString -> Digest MD5
    md5Hash ByteString
    b), Digest SHA1 -> ByteString
    forall bin bout.
    (ByteArrayAccess bin, ByteArray bout) =>
    bin -> bout
    B.convert (ByteString -> Digest SHA1
    sha1Hash ByteString
    b)]
      where
        sha1Hash :: B.ByteString -> H.Digest H.SHA1
        sha1Hash :: ByteString -> Digest SHA1
    sha1Hash = ByteString -> Digest SHA1
    forall ba a.
    (ByteArrayAccess ba, HashAlgorithm a) =>
    ba -> Digest a
    H.hash
        md5Hash :: B.ByteString -> H.Digest H.MD5
        md5Hash :: ByteString -> Digest MD5
    md5Hash = ByteString -> Digest MD5
    forall ba a.
    (ByteArrayAccess ba, HashAlgorithm a) =>
    ba -> Digest a
    H.hash

    hashName :: Hash -> String
    hashName :: Hash -> String
    hashName = Hash -> String
    forall a. Show a => a -> String
    show

    -- | Digest size in bytes.
    hashDigestSize :: Hash -> Int
    hashDigestSize :: Hash -> Int
    hashDigestSize Hash
    MD5    = Int
    16
    hashDigestSize Hash
    SHA1   = Int
    20
    hashDigestSize Hash
    SHA224 = Int
    28
    hashDigestSize Hash
    SHA256 = Int
    32
    hashDigestSize Hash
    SHA384 = Int
    48
    hashDigestSize Hash
    SHA512 = Int
    64
    hashDigestSize Hash
    SHA1_MD5 = Int
    36

    hashBlockSize :: Hash -> Int
    hashBlockSize :: Hash -> Int
    hashBlockSize Hash
    MD5    = Int
    64
    hashBlockSize Hash
    SHA1   = Int
    64
    hashBlockSize Hash
    SHA224 = Int
    64
    hashBlockSize Hash
    SHA256 = Int
    64
    hashBlockSize Hash
    SHA384 = Int
    128
    hashBlockSize Hash
    SHA512 = Int
    128
    hashBlockSize Hash
    SHA1_MD5 = Int
    64

    {- key exchange methods encrypt and decrypt for each supported algorithm -}

    generalizeRSAError :: Either RSA.Error a -> Either KxError a
    generalizeRSAError :: forall a. Either Error a -> Either KxError a
    generalizeRSAError (Left Error
    e)  = KxError -> Either KxError a
    forall a b. a -> Either a b
    Left (Error -> KxError
    RSAError Error
    e)
    generalizeRSAError (Right a
    x) = a -> Either KxError a
    forall a b. b -> Either a b
    Right a
    x

    kxEncrypt :: MonadRandom r => PublicKey -> ByteString -> r (Either KxError ByteString)
    kxEncrypt :: forall (r :: * -> *).
    MonadRandom r =>
    PubKey -> ByteString -> r (Either KxError ByteString)
    kxEncrypt (PubKeyRSA PublicKey
    pk) ByteString
    b = Either Error ByteString -> Either KxError ByteString
    forall a. Either Error a -> Either KxError a
    generalizeRSAError (Either Error ByteString -> Either KxError ByteString)
    -> r (Either Error ByteString) -> r (Either KxError ByteString)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> PublicKey -> ByteString -> r (Either Error ByteString)
    forall (m :: * -> *).
    MonadRandom m =>
    PublicKey -> ByteString -> m (Either Error ByteString)
    RSA.encrypt PublicKey
    pk ByteString
    b
    kxEncrypt PubKey
    _              ByteString
    _ = Either KxError ByteString -> r (Either KxError ByteString)
    forall a. a -> r a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (KxError -> Either KxError ByteString
    forall a b. a -> Either a b
    Left KxError
    KxUnsupported)

    kxDecrypt :: MonadRandom r => PrivateKey -> ByteString -> r (Either KxError ByteString)
    kxDecrypt :: forall (r :: * -> *).
    MonadRandom r =>
    PrivKey -> ByteString -> r (Either KxError ByteString)
    kxDecrypt (PrivKeyRSA PrivateKey
    pk) ByteString
    b = Either Error ByteString -> Either KxError ByteString
    forall a. Either Error a -> Either KxError a
    generalizeRSAError (Either Error ByteString -> Either KxError ByteString)
    -> r (Either Error ByteString) -> r (Either KxError ByteString)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> PrivateKey -> ByteString -> r (Either Error ByteString)
    forall (m :: * -> *).
    MonadRandom m =>
    PrivateKey -> ByteString -> m (Either Error ByteString)
    RSA.decryptSafer PrivateKey
    pk ByteString
    b
    kxDecrypt PrivKey
    _               ByteString
    _ = Either KxError ByteString -> r (Either KxError ByteString)
    forall a. a -> r a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (KxError -> Either KxError ByteString
    forall a b. a -> Either a b
    Left KxError
    KxUnsupported)

    data RSAEncoding = RSApkcs1 | RSApss deriving (Int -> RSAEncoding -> ShowS
    [RSAEncoding] -> ShowS
    RSAEncoding -> String
    (Int -> RSAEncoding -> ShowS)
    -> (RSAEncoding -> String)
    -> ([RSAEncoding] -> ShowS)
    -> Show RSAEncoding
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> RSAEncoding -> ShowS
    showsPrec :: Int -> RSAEncoding -> ShowS
    $cshow :: RSAEncoding -> String
    show :: RSAEncoding -> String
    $cshowList :: [RSAEncoding] -> ShowS
    showList :: [RSAEncoding] -> ShowS
    Show,RSAEncoding -> RSAEncoding -> Bool
    (RSAEncoding -> RSAEncoding -> Bool)
    -> (RSAEncoding -> RSAEncoding -> Bool) -> Eq RSAEncoding
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: RSAEncoding -> RSAEncoding -> Bool
    == :: RSAEncoding -> RSAEncoding -> Bool
    $c/= :: RSAEncoding -> RSAEncoding -> Bool
    /= :: RSAEncoding -> RSAEncoding -> Bool
    Eq)

    -- | Test the RSASSA-PKCS1 length condition described in RFC 8017 section 9.2,
    -- i.e. @emLen >= tLen + 11@.  Lengths are in bytes.
    kxCanUseRSApkcs1 :: RSA.PublicKey -> Hash -> Bool
    kxCanUseRSApkcs1 :: PublicKey -> Hash -> Bool
    kxCanUseRSApkcs1 PublicKey
    pk Hash
    h = PublicKey -> Int
    RSA.public_size PublicKey
    pk Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    tLen Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    11
      where
        tLen :: Int
    tLen = Hash -> Int
    forall {a}. Num a => Hash -> a
    prefixSize Hash
    h Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Hash -> Int
    hashDigestSize Hash
    h

        prefixSize :: Hash -> a
    prefixSize Hash
    MD5    = a
    18
        prefixSize Hash
    SHA1   = a
    15
        prefixSize Hash
    SHA224 = a
    19
        prefixSize Hash
    SHA256 = a
    19
        prefixSize Hash
    SHA384 = a
    19
        prefixSize Hash
    SHA512 = a
    19
        prefixSize Hash
    _      = String -> a
    forall a. HasCallStack => String -> a
    error (Hash -> String
    forall a. Show a => a -> String
    show Hash
    h String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " is not supported for RSASSA-PKCS1")

    -- | Test the RSASSA-PSS length condition described in RFC 8017 section 9.1.1,
    -- i.e. @emBits >= 8hLen + 8sLen + 9@.  Lengths are in bits.
    kxCanUseRSApss :: RSA.PublicKey -> Hash -> Bool
    kxCanUseRSApss :: PublicKey -> Hash -> Bool
    kxCanUseRSApss PublicKey
    pk Hash
    h = Integer -> Int
    numBits (PublicKey -> Integer
    RSA.public_n PublicKey
    pk) Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    16 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    * Hash -> Int
    hashDigestSize Hash
    h Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    10

    -- Signature algorithm and associated parameters.
    --
    -- FIXME add RSAPSSParams
    data SignatureParams =
          RSAParams      Hash RSAEncoding
        | DSSParams
        | ECDSAParams    Hash
        | Ed25519Params
        | Ed448Params
        deriving (Int -> SignatureParams -> ShowS
    [SignatureParams] -> ShowS
    SignatureParams -> String
    (Int -> SignatureParams -> ShowS)
    -> (SignatureParams -> String)
    -> ([SignatureParams] -> ShowS)
    -> Show SignatureParams
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> SignatureParams -> ShowS
    showsPrec :: Int -> SignatureParams -> ShowS
    $cshow :: SignatureParams -> String
    show :: SignatureParams -> String
    $cshowList :: [SignatureParams] -> ShowS
    showList :: [SignatureParams] -> ShowS
    Show,SignatureParams -> SignatureParams -> Bool
    (SignatureParams -> SignatureParams -> Bool)
    -> (SignatureParams -> SignatureParams -> Bool)
    -> Eq SignatureParams
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: SignatureParams -> SignatureParams -> Bool
    == :: SignatureParams -> SignatureParams -> Bool
    $c/= :: SignatureParams -> SignatureParams -> Bool
    /= :: SignatureParams -> SignatureParams -> Bool
    Eq)

    -- Verify that the signature matches the given message, using the
    -- public key.
    --

    kxVerify :: PublicKey -> SignatureParams -> ByteString -> ByteString -> Bool
    kxVerify :: PubKey -> SignatureParams -> ByteString -> ByteString -> Bool
    kxVerify (PubKeyRSA PublicKey
    pk) (RSAParams Hash
    alg RSAEncoding
    RSApkcs1) ByteString
    msg ByteString
    sign   = Hash -> PublicKey -> ByteString -> ByteString -> Bool
    rsaVerifyHash Hash
    alg PublicKey
    pk ByteString
    msg ByteString
    sign
    kxVerify (PubKeyRSA PublicKey
    pk) (RSAParams Hash
    alg RSAEncoding
    RSApss)   ByteString
    msg ByteString
    sign   = Hash -> PublicKey -> ByteString -> ByteString -> Bool
    rsapssVerifyHash Hash
    alg PublicKey
    pk ByteString
    msg ByteString
    sign
    kxVerify (PubKeyDSA PublicKey
    pk) SignatureParams
    DSSParams                ByteString
    msg ByteString
    signBS =

        case ByteString -> Maybe Signature
    dsaToSignature ByteString
    signBS of
            Just Signature
    sig -> SHA1 -> PublicKey -> Signature -> ByteString -> Bool
    forall msg hash.
    (ByteArrayAccess msg, HashAlgorithm hash) =>
    hash -> PublicKey -> Signature -> msg -> Bool
    DSA.verify SHA1
    H.SHA1 PublicKey
    pk Signature
    sig ByteString
    msg
            Maybe Signature
    _        -> Bool
    False
      where
            dsaToSignature :: ByteString -> Maybe DSA.Signature
            dsaToSignature :: ByteString -> Maybe Signature
    dsaToSignature ByteString
    b =
                case BER -> ByteString -> Either ASN1Error [ASN1]
    forall a.
    ASN1Decoding a =>
    a -> ByteString -> Either ASN1Error [ASN1]
    decodeASN1' BER
    BER ByteString
    b of
                    Left ASN1Error
    _     -> Maybe Signature
    forall a. Maybe a
    Nothing
                    Right [ASN1]
    asn1 ->
                        case [ASN1]
    asn1 of
                            Start ASN1ConstructionType
    Sequence:IntVal Integer
    r:IntVal Integer
    s:End ASN1ConstructionType
    Sequence:[ASN1]
    _ ->
                                Signature -> Maybe Signature
    forall a. a -> Maybe a
    Just DSA.Signature { sign_r :: Integer
    DSA.sign_r = Integer
    r, sign_s :: Integer
    DSA.sign_s = Integer
    s }
                            [ASN1]
    _ ->
                                Maybe Signature
    forall a. Maybe a
    Nothing
    kxVerify (PubKeyEC PubKeyEC
    key) (ECDSAParams Hash
    alg) ByteString
    msg ByteString
    sigBS =
        Bool -> Maybe Bool -> Bool
    forall a. a -> Maybe a -> a
    fromMaybe Bool
    False (Maybe Bool -> Bool) -> Maybe Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ Maybe (Maybe Bool) -> Maybe Bool
    forall (m :: * -> *) a. Monad m => m (m a) -> m a
    join (Maybe (Maybe Bool) -> Maybe Bool)
    -> Maybe (Maybe Bool) -> Maybe Bool
    forall a b. (a -> b) -> a -> b
    $
            PubKeyEC
    -> (forall curve.
        EllipticCurveECDSA curve =>
        Proxy curve -> PublicKey curve -> Maybe Bool)
    -> (PublicKey -> Maybe Bool)
    -> Maybe Bool
    -> Maybe (Maybe Bool)
    forall a.
    PubKeyEC
    -> (forall curve.
        EllipticCurveECDSA curve =>
        Proxy curve -> PublicKey curve -> a)
    -> (PublicKey -> a)
    -> a
    -> Maybe a
    withPubKeyEC PubKeyEC
    key Proxy curve -> Point curve -> Maybe Bool
    forall curve.
    EllipticCurveECDSA curve =>
    Proxy curve -> PublicKey curve -> Maybe Bool
    forall {curve} {proxy :: * -> *}.
    EllipticCurveECDSA curve =>
    proxy curve -> Point curve -> Maybe Bool
    verifyProxy PublicKey -> Maybe Bool
    verifyClassic Maybe Bool
    forall a. Maybe a
    Nothing
      where
        decodeSignatureASN1 :: (Integer -> Integer -> a) -> Maybe a
    decodeSignatureASN1 Integer -> Integer -> a
    buildRS =
            case BER -> ByteString -> Either ASN1Error [ASN1]
    forall a.
    ASN1Decoding a =>
    a -> ByteString -> Either ASN1Error [ASN1]
    decodeASN1' BER
    BER ByteString
    sigBS of
                Left ASN1Error
    _  -> Maybe a
    forall a. Maybe a
    Nothing
                Right [Start ASN1ConstructionType
    Sequence,IntVal Integer
    r,IntVal Integer
    s,End ASN1ConstructionType
    Sequence] ->
                    a -> Maybe a
    forall a. a -> Maybe a
    Just (Integer -> Integer -> a
    buildRS Integer
    r Integer
    s)
                Right [ASN1]
    _ -> Maybe a
    forall a. Maybe a
    Nothing
        verifyProxy :: proxy curve -> Point curve -> Maybe Bool
    verifyProxy proxy curve
    prx Point curve
    pubkey = do
            (Integer, Integer)
    rs <- (Integer -> Integer -> (Integer, Integer))
    -> Maybe (Integer, Integer)
    forall {a}. (Integer -> Integer -> a) -> Maybe a
    decodeSignatureASN1 (,)
            Signature curve
    signature <- CryptoFailable (Signature curve) -> Maybe (Signature curve)
    forall a. CryptoFailable a -> Maybe a
    maybeCryptoError (CryptoFailable (Signature curve) -> Maybe (Signature curve))
    -> CryptoFailable (Signature curve) -> Maybe (Signature curve)
    forall a b. (a -> b) -> a -> b
    $ proxy curve
    -> (Integer, Integer) -> CryptoFailable (Signature curve)
    forall curve (proxy :: * -> *).
    EllipticCurveECDSA curve =>
    proxy curve
    -> (Integer, Integer) -> CryptoFailable (Signature curve)
    ECDSA.signatureFromIntegers proxy curve
    prx (Integer, Integer)
    rs
            Point curve -> Signature curve -> ByteString -> Bool
    verifyF <- (forall hash.
     HashAlgorithm hash =>
     hash -> Point curve -> Signature curve -> ByteString -> Bool)
    -> Maybe (Point curve -> Signature curve -> ByteString -> Bool)
    forall a. (forall hash. HashAlgorithm hash => hash -> a) -> Maybe a
    withAlg (proxy curve
    -> hash -> Point curve -> Signature curve -> ByteString -> Bool
    forall curve msg hash (proxy :: * -> *).
    (EllipticCurveECDSA curve, ByteArrayAccess msg,
     HashAlgorithm hash) =>
    proxy curve
    -> hash -> PublicKey curve -> Signature curve -> msg -> Bool
    ECDSA.verify proxy curve
    prx)
            Bool -> Maybe Bool
    forall a. a -> Maybe a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Bool -> Maybe Bool) -> Bool -> Maybe Bool
    forall a b. (a -> b) -> a -> b
    $ Point curve -> Signature curve -> ByteString -> Bool
    verifyF Point curve
    pubkey Signature curve
    signature ByteString
    msg
        verifyClassic :: PublicKey -> Maybe Bool
    verifyClassic PublicKey
    pubkey = do
            Signature
    signature <- (Integer -> Integer -> Signature) -> Maybe Signature
    forall {a}. (Integer -> Integer -> a) -> Maybe a
    decodeSignatureASN1 Integer -> Integer -> Signature
    ECDSA_ECC.Signature
            PublicKey -> Signature -> ByteString -> Bool
    verifyF <- (forall hash.
     HashAlgorithm hash =>
     hash -> PublicKey -> Signature -> ByteString -> Bool)
    -> Maybe (PublicKey -> Signature -> ByteString -> Bool)
    forall a. (forall hash. HashAlgorithm hash => hash -> a) -> Maybe a
    withAlg hash -> PublicKey -> Signature -> ByteString -> Bool
    forall hash.
    HashAlgorithm hash =>
    hash -> PublicKey -> Signature -> ByteString -> Bool
    forall msg hash.
    (ByteArrayAccess msg, HashAlgorithm hash) =>
    hash -> PublicKey -> Signature -> msg -> Bool
    ECDSA_ECC.verify
            Bool -> Maybe Bool
    forall a. a -> Maybe a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Bool -> Maybe Bool) -> Bool -> Maybe Bool
    forall a b. (a -> b) -> a -> b
    $ PublicKey -> Signature -> ByteString -> Bool
    verifyF PublicKey
    pubkey Signature
    signature ByteString
    msg
        withAlg :: (forall hash . H.HashAlgorithm hash => hash -> a) -> Maybe a
        withAlg :: forall a. (forall hash. HashAlgorithm hash => hash -> a) -> Maybe a
    withAlg forall hash. HashAlgorithm hash => hash -> a
    f = case Hash
    alg of
                        Hash
    MD5    -> a -> Maybe a
    forall a. a -> Maybe a
    Just (MD5 -> a
    forall hash. HashAlgorithm hash => hash -> a
    f MD5
    H.MD5)
                        Hash
    SHA1   -> a -> Maybe a
    forall a. a -> Maybe a
    Just (SHA1 -> a
    forall hash. HashAlgorithm hash => hash -> a
    f SHA1
    H.SHA1)
                        Hash
    SHA224 -> a -> Maybe a
    forall a. a -> Maybe a
    Just (SHA224 -> a
    forall hash. HashAlgorithm hash => hash -> a
    f SHA224
    H.SHA224)
                        Hash
    SHA256 -> a -> Maybe a
    forall a. a -> Maybe a
    Just (SHA256 -> a
    forall hash. HashAlgorithm hash => hash -> a
    f SHA256
    H.SHA256)
                        Hash
    SHA384 -> a -> Maybe a
    forall a. a -> Maybe a
    Just (SHA384 -> a
    forall hash. HashAlgorithm hash => hash -> a
    f SHA384
    H.SHA384)
                        Hash
    SHA512 -> a -> Maybe a
    forall a. a -> Maybe a
    Just (SHA512 -> a
    forall hash. HashAlgorithm hash => hash -> a
    f SHA512
    H.SHA512)
                        Hash
    _      -> Maybe a
    forall a. Maybe a
    Nothing
    kxVerify (PubKeyEd25519 PublicKey
    key) SignatureParams
    Ed25519Params ByteString
    msg ByteString
    sigBS =
        case ByteString -> CryptoFailable Signature
    forall ba. ByteArrayAccess ba => ba -> CryptoFailable Signature
    Ed25519.signature ByteString
    sigBS of
            CryptoPassed Signature
    sig -> PublicKey -> ByteString -> Signature -> Bool
    forall ba.
    ByteArrayAccess ba =>
    PublicKey -> ba -> Signature -> Bool
    Ed25519.verify PublicKey
    key ByteString
    msg Signature
    sig
            CryptoFailable Signature
    _                -> Bool
    False
    kxVerify (PubKeyEd448 PublicKey
    key) SignatureParams
    Ed448Params ByteString
    msg ByteString
    sigBS =
        case ByteString -> CryptoFailable Signature
    forall ba. ByteArrayAccess ba => ba -> CryptoFailable Signature
    Ed448.signature ByteString
    sigBS of
            CryptoPassed Signature
    sig -> PublicKey -> ByteString -> Signature -> Bool
    forall ba.
    ByteArrayAccess ba =>
    PublicKey -> ba -> Signature -> Bool
    Ed448.verify PublicKey
    key ByteString
    msg Signature
    sig
            CryptoFailable Signature
    _                -> Bool
    False
    kxVerify PubKey
    _              SignatureParams
    _         ByteString
    _   ByteString
    _    = Bool
    False

    -- Sign the given message using the private key.
    --
    kxSign :: MonadRandom r
           => PrivateKey
           -> PublicKey
           -> SignatureParams
           -> ByteString
           -> r (Either KxError ByteString)
    kxSign :: forall (r :: * -> *).
    MonadRandom r =>
    PrivKey
    -> PubKey
    -> SignatureParams
    -> ByteString
    -> r (Either KxError ByteString)
    kxSign (PrivKeyRSA PrivateKey
    pk) (PubKeyRSA PublicKey
    _) (RSAParams Hash
    hashAlg RSAEncoding
    RSApkcs1) ByteString
    msg =
        Either Error ByteString -> Either KxError ByteString
    forall a. Either Error a -> Either KxError a
    generalizeRSAError (Either Error ByteString -> Either KxError ByteString)
    -> r (Either Error ByteString) -> r (Either KxError ByteString)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Hash -> PrivateKey -> ByteString -> r (Either Error ByteString)
    forall (m :: * -> *).
    MonadRandom m =>
    Hash -> PrivateKey -> ByteString -> m (Either Error ByteString)
    rsaSignHash Hash
    hashAlg PrivateKey
    pk ByteString
    msg
    kxSign (PrivKeyRSA PrivateKey
    pk) (PubKeyRSA PublicKey
    _) (RSAParams Hash
    hashAlg RSAEncoding
    RSApss) ByteString
    msg =
        Either Error ByteString -> Either KxError ByteString
    forall a. Either Error a -> Either KxError a
    generalizeRSAError (Either Error ByteString -> Either KxError ByteString)
    -> r (Either Error ByteString) -> r (Either KxError ByteString)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Hash -> PrivateKey -> ByteString -> r (Either Error ByteString)
    forall (m :: * -> *).
    MonadRandom m =>
    Hash -> PrivateKey -> ByteString -> m (Either Error ByteString)
    rsapssSignHash Hash
    hashAlg PrivateKey
    pk ByteString
    msg
    kxSign (PrivKeyDSA PrivateKey
    pk) (PubKeyDSA PublicKey
    _) SignatureParams
    DSSParams ByteString
    msg = do
        Signature
    sign <- PrivateKey -> SHA1 -> ByteString -> r Signature
    forall msg hash (m :: * -> *).
    (ByteArrayAccess msg, HashAlgorithm hash, MonadRandom m) =>
    PrivateKey -> hash -> msg -> m Signature
    DSA.sign PrivateKey
    pk SHA1
    H.SHA1 ByteString
    msg
        Either KxError ByteString -> r (Either KxError ByteString)
    forall a. a -> r a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (ByteString -> Either KxError ByteString
    forall a b. b -> Either a b
    Right (ByteString -> Either KxError ByteString)
    -> ByteString -> Either KxError ByteString
    forall a b. (a -> b) -> a -> b
    $ DER -> [ASN1] -> ByteString
    forall a. ASN1Encoding a => a -> [ASN1] -> ByteString
    encodeASN1' DER
    DER ([ASN1] -> ByteString) -> [ASN1] -> ByteString
    forall a b. (a -> b) -> a -> b
    $ Signature -> [ASN1]
    dsaSequence Signature
    sign)
      where dsaSequence :: Signature -> [ASN1]
    dsaSequence Signature
    sign = [ASN1ConstructionType -> ASN1
    Start ASN1ConstructionType
    Sequence,Integer -> ASN1
    IntVal (Signature -> Integer
    DSA.sign_r Signature
    sign),Integer -> ASN1
    IntVal (Signature -> Integer
    DSA.sign_s Signature
    sign),ASN1ConstructionType -> ASN1
    End ASN1ConstructionType
    Sequence]
    kxSign (PrivKeyEC PrivKeyEC
    pk) (PubKeyEC PubKeyEC
    _) (ECDSAParams Hash
    hashAlg) ByteString
    msg =
        case PrivKeyEC
    -> (forall curve.
        EllipticCurveECDSA curve =>
        Proxy curve
        -> PrivateKey curve -> r (Either KxError (Integer, Integer)))
    -> (CurveName -> r (Either KxError (Integer, Integer)))
    -> r (Either KxError (Integer, Integer))
    -> Maybe (r (Either KxError (Integer, Integer)))
    forall a.
    PrivKeyEC
    -> (forall curve.
        EllipticCurveECDSA curve =>
        Proxy curve -> PrivateKey curve -> a)
    -> (CurveName -> a)
    -> a
    -> Maybe a
    withPrivKeyEC PrivKeyEC
    pk Proxy curve
    -> Scalar curve -> r (Either KxError (Integer, Integer))
    forall curve.
    EllipticCurveECDSA curve =>
    Proxy curve
    -> PrivateKey curve -> r (Either KxError (Integer, Integer))
    forall {m :: * -> *} {curve} {proxy :: * -> *}.
    (MonadRandom m, EllipticCurveECDSA curve) =>
    proxy curve
    -> Scalar curve -> m (Either KxError (Integer, Integer))
    doSign (r (Either KxError (Integer, Integer))
    -> CurveName -> r (Either KxError (Integer, Integer))
    forall a b. a -> b -> a
    const r (Either KxError (Integer, Integer))
    forall {b}. r (Either KxError b)
    unsupported) r (Either KxError (Integer, Integer))
    forall {b}. r (Either KxError b)
    unsupported of
            Maybe (r (Either KxError (Integer, Integer)))
    Nothing  -> r (Either KxError ByteString)
    forall {b}. r (Either KxError b)
    unsupported
            Just r (Either KxError (Integer, Integer))
    run -> ((Integer, Integer) -> ByteString)
    -> Either KxError (Integer, Integer) -> Either KxError ByteString
    forall a b. (a -> b) -> Either KxError a -> Either KxError b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (Integer, Integer) -> ByteString
    encode (Either KxError (Integer, Integer) -> Either KxError ByteString)
    -> r (Either KxError (Integer, Integer))
    -> r (Either KxError ByteString)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> r (Either KxError (Integer, Integer))
    run
      where encode :: (Integer, Integer) -> ByteString
    encode (Integer
    r, Integer
    s) = DER -> [ASN1] -> ByteString
    forall a. ASN1Encoding a => a -> [ASN1] -> ByteString
    encodeASN1' DER
    DER
                [ ASN1ConstructionType -> ASN1
    Start ASN1ConstructionType
    Sequence, Integer -> ASN1
    IntVal Integer
    r, Integer -> ASN1
    IntVal Integer
    s, ASN1ConstructionType -> ASN1
    End ASN1ConstructionType
    Sequence ]
            doSign :: proxy curve
    -> Scalar curve -> m (Either KxError (Integer, Integer))
    doSign proxy curve
    prx Scalar curve
    privkey = do
                Maybe (Signature curve)
    msig <- proxy curve
    -> Hash
    -> Scalar curve
    -> ByteString
    -> m (Maybe (Signature curve))
    forall (m :: * -> *) curve (proxy :: * -> *).
    (MonadRandom m, EllipticCurveECDSA curve) =>
    proxy curve
    -> Hash
    -> Scalar curve
    -> ByteString
    -> m (Maybe (Signature curve))
    ecdsaSignHash proxy curve
    prx Hash
    hashAlg Scalar curve
    privkey ByteString
    msg
                Either KxError (Integer, Integer)
    -> m (Either KxError (Integer, Integer))
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Either KxError (Integer, Integer)
     -> m (Either KxError (Integer, Integer)))
    -> Either KxError (Integer, Integer)
    -> m (Either KxError (Integer, Integer))
    forall a b. (a -> b) -> a -> b
    $ case Maybe (Signature curve)
    msig of
                             Maybe (Signature curve)
    Nothing   -> KxError -> Either KxError (Integer, Integer)
    forall a b. a -> Either a b
    Left KxError
    KxUnsupported
                             Just Signature curve
    sign -> (Integer, Integer) -> Either KxError (Integer, Integer)
    forall a b. b -> Either a b
    Right (proxy curve -> Signature curve -> (Integer, Integer)
    forall curve (proxy :: * -> *).
    EllipticCurveECDSA curve =>
    proxy curve -> Signature curve -> (Integer, Integer)
    ECDSA.signatureToIntegers proxy curve
    prx Signature curve
    sign)
            unsupported :: r (Either KxError b)
    unsupported = Either KxError b -> r (Either KxError b)
    forall a. a -> r a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Either KxError b -> r (Either KxError b))
    -> Either KxError b -> r (Either KxError b)
    forall a b. (a -> b) -> a -> b
    $ KxError -> Either KxError b
    forall a b. a -> Either a b
    Left KxError
    KxUnsupported
    kxSign (PrivKeyEd25519 SecretKey
    pk) (PubKeyEd25519 PublicKey
    pub) SignatureParams
    Ed25519Params ByteString
    msg =
        Either KxError ByteString -> r (Either KxError ByteString)
    forall a. a -> r a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Either KxError ByteString -> r (Either KxError ByteString))
    -> Either KxError ByteString -> r (Either KxError ByteString)
    forall a b. (a -> b) -> a -> b
    $ ByteString -> Either KxError ByteString
    forall a b. b -> Either a b
    Right (ByteString -> Either KxError ByteString)
    -> ByteString -> Either KxError ByteString
    forall a b. (a -> b) -> a -> b
    $ Signature -> ByteString
    forall bin bout.
    (ByteArrayAccess bin, ByteArray bout) =>
    bin -> bout
    B.convert (Signature -> ByteString) -> Signature -> ByteString
    forall a b. (a -> b) -> a -> b
    $ SecretKey -> PublicKey -> ByteString -> Signature
    forall ba.
    ByteArrayAccess ba =>
    SecretKey -> PublicKey -> ba -> Signature
    Ed25519.sign SecretKey
    pk PublicKey
    pub ByteString
    msg
    kxSign (PrivKeyEd448 SecretKey
    pk) (PubKeyEd448 PublicKey
    pub) SignatureParams
    Ed448Params ByteString
    msg =
        Either KxError ByteString -> r (Either KxError ByteString)
    forall a. a -> r a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Either KxError ByteString -> r (Either KxError ByteString))
    -> Either KxError ByteString -> r (Either KxError ByteString)
    forall a b. (a -> b) -> a -> b
    $ ByteString -> Either KxError ByteString
    forall a b. b -> Either a b
    Right (ByteString -> Either KxError ByteString)
    -> ByteString -> Either KxError ByteString
    forall a b. (a -> b) -> a -> b
    $ Signature -> ByteString
    forall bin bout.
    (ByteArrayAccess bin, ByteArray bout) =>
    bin -> bout
    B.convert (Signature -> ByteString) -> Signature -> ByteString
    forall a b. (a -> b) -> a -> b
    $ SecretKey -> PublicKey -> ByteString -> Signature
    forall ba.
    ByteArrayAccess ba =>
    SecretKey -> PublicKey -> ba -> Signature
    Ed448.sign SecretKey
    pk PublicKey
    pub ByteString
    msg
    kxSign PrivKey
    _ PubKey
    _ SignatureParams
    _ ByteString
    _ =
        Either KxError ByteString -> r (Either KxError ByteString)
    forall a. a -> r a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (KxError -> Either KxError ByteString
    forall a b. a -> Either a b
    Left KxError
    KxUnsupported)

    rsaSignHash :: MonadRandom m => Hash -> RSA.PrivateKey -> ByteString -> m (Either RSA.Error ByteString)
    rsaSignHash :: forall (m :: * -> *).
    MonadRandom m =>
    Hash -> PrivateKey -> ByteString -> m (Either Error ByteString)
    rsaSignHash Hash
    SHA1_MD5 PrivateKey
    pk ByteString
    msg = Maybe MD5
    -> PrivateKey -> ByteString -> m (Either Error ByteString)
    forall hashAlg (m :: * -> *).
    (HashAlgorithmASN1 hashAlg, MonadRandom m) =>
    Maybe hashAlg
    -> PrivateKey -> ByteString -> m (Either Error ByteString)
    RSA.signSafer Maybe MD5
    noHash PrivateKey
    pk ByteString
    msg
    rsaSignHash Hash
    MD5 PrivateKey
    pk ByteString
    msg      = Maybe MD5
    -> PrivateKey -> ByteString -> m (Either Error ByteString)
    forall hashAlg (m :: * -> *).
    (HashAlgorithmASN1 hashAlg, MonadRandom m) =>
    Maybe hashAlg
    -> PrivateKey -> ByteString -> m (Either Error ByteString)
    RSA.signSafer (MD5 -> Maybe MD5
    forall a. a -> Maybe a
    Just MD5
    H.MD5) PrivateKey
    pk ByteString
    msg
    rsaSignHash Hash
    SHA1 PrivateKey
    pk ByteString
    msg     = Maybe SHA1
    -> PrivateKey -> ByteString -> m (Either Error ByteString)
    forall hashAlg (m :: * -> *).
    (HashAlgorithmASN1 hashAlg, MonadRandom m) =>
    Maybe hashAlg
    -> PrivateKey -> ByteString -> m (Either Error ByteString)
    RSA.signSafer (SHA1 -> Maybe SHA1
    forall a. a -> Maybe a
    Just SHA1
    H.SHA1) PrivateKey
    pk ByteString
    msg
    rsaSignHash Hash
    SHA224 PrivateKey
    pk ByteString
    msg   = Maybe SHA224
    -> PrivateKey -> ByteString -> m (Either Error ByteString)
    forall hashAlg (m :: * -> *).
    (HashAlgorithmASN1 hashAlg, MonadRandom m) =>
    Maybe hashAlg
    -> PrivateKey -> ByteString -> m (Either Error ByteString)
    RSA.signSafer (SHA224 -> Maybe SHA224
    forall a. a -> Maybe a
    Just SHA224
    H.SHA224) PrivateKey
    pk ByteString
    msg
    rsaSignHash Hash
    SHA256 PrivateKey
    pk ByteString
    msg   = Maybe SHA256
    -> PrivateKey -> ByteString -> m (Either Error ByteString)
    forall hashAlg (m :: * -> *).
    (HashAlgorithmASN1 hashAlg, MonadRandom m) =>
    Maybe hashAlg
    -> PrivateKey -> ByteString -> m (Either Error ByteString)
    RSA.signSafer (SHA256 -> Maybe SHA256
    forall a. a -> Maybe a
    Just SHA256
    H.SHA256) PrivateKey
    pk ByteString
    msg
    rsaSignHash Hash
    SHA384 PrivateKey
    pk ByteString
    msg   = Maybe SHA384
    -> PrivateKey -> ByteString -> m (Either Error ByteString)
    forall hashAlg (m :: * -> *).
    (HashAlgorithmASN1 hashAlg, MonadRandom m) =>
    Maybe hashAlg
    -> PrivateKey -> ByteString -> m (Either Error ByteString)
    RSA.signSafer (SHA384 -> Maybe SHA384
    forall a. a -> Maybe a
    Just SHA384
    H.SHA384) PrivateKey
    pk ByteString
    msg
    rsaSignHash Hash
    SHA512 PrivateKey
    pk ByteString
    msg   = Maybe SHA512
    -> PrivateKey -> ByteString -> m (Either Error ByteString)
    forall hashAlg (m :: * -> *).
    (HashAlgorithmASN1 hashAlg, MonadRandom m) =>
    Maybe hashAlg
    -> PrivateKey -> ByteString -> m (Either Error ByteString)
    RSA.signSafer (SHA512 -> Maybe SHA512
    forall a. a -> Maybe a
    Just SHA512
    H.SHA512) PrivateKey
    pk ByteString
    msg

    rsapssSignHash :: MonadRandom m => Hash -> RSA.PrivateKey -> ByteString -> m (Either RSA.Error ByteString)
    rsapssSignHash :: forall (m :: * -> *).
    MonadRandom m =>
    Hash -> PrivateKey -> ByteString -> m (Either Error ByteString)
    rsapssSignHash Hash
    SHA256 PrivateKey
    pk ByteString
    msg = PSSParams SHA256 ByteString ByteString
    -> PrivateKey -> ByteString -> m (Either Error ByteString)
    forall hash (m :: * -> *).
    (HashAlgorithm hash, MonadRandom m) =>
    PSSParams hash ByteString ByteString
    -> PrivateKey -> ByteString -> m (Either Error ByteString)
    PSS.signSafer (SHA256 -> PSSParams SHA256 ByteString ByteString
    forall seed output hash.
    (ByteArrayAccess seed, ByteArray output, HashAlgorithm hash) =>
    hash -> PSSParams hash seed output
    PSS.defaultPSSParams SHA256
    H.SHA256) PrivateKey
    pk ByteString
    msg
    rsapssSignHash Hash
    SHA384 PrivateKey
    pk ByteString
    msg = PSSParams SHA384 ByteString ByteString
    -> PrivateKey -> ByteString -> m (Either Error ByteString)
    forall hash (m :: * -> *).
    (HashAlgorithm hash, MonadRandom m) =>
    PSSParams hash ByteString ByteString
    -> PrivateKey -> ByteString -> m (Either Error ByteString)
    PSS.signSafer (SHA384 -> PSSParams SHA384 ByteString ByteString
    forall seed output hash.
    (ByteArrayAccess seed, ByteArray output, HashAlgorithm hash) =>
    hash -> PSSParams hash seed output
    PSS.defaultPSSParams SHA384
    H.SHA384) PrivateKey
    pk ByteString
    msg
    rsapssSignHash Hash
    SHA512 PrivateKey
    pk ByteString
    msg = PSSParams SHA512 ByteString ByteString
    -> PrivateKey -> ByteString -> m (Either Error ByteString)
    forall hash (m :: * -> *).
    (HashAlgorithm hash, MonadRandom m) =>
    PSSParams hash ByteString ByteString
    -> PrivateKey -> ByteString -> m (Either Error ByteString)
    PSS.signSafer (SHA512 -> PSSParams SHA512 ByteString ByteString
    forall seed output hash.
    (ByteArrayAccess seed, ByteArray output, HashAlgorithm hash) =>
    hash -> PSSParams hash seed output
    PSS.defaultPSSParams SHA512
    H.SHA512) PrivateKey
    pk ByteString
    msg
    rsapssSignHash Hash
    _ PrivateKey
    _ ByteString
    _         = String -> m (Either Error ByteString)
    forall a. HasCallStack => String -> a
    error String
    "rsapssSignHash: unsupported hash"

    rsaVerifyHash :: Hash -> RSA.PublicKey -> ByteString -> ByteString -> Bool
    rsaVerifyHash :: Hash -> PublicKey -> ByteString -> ByteString -> Bool
    rsaVerifyHash Hash
    SHA1_MD5 = Maybe MD5 -> PublicKey -> ByteString -> ByteString -> Bool
    forall hashAlg.
    HashAlgorithmASN1 hashAlg =>
    Maybe hashAlg -> PublicKey -> ByteString -> ByteString -> Bool
    RSA.verify Maybe MD5
    noHash
    rsaVerifyHash Hash
    MD5      = Maybe MD5 -> PublicKey -> ByteString -> ByteString -> Bool
    forall hashAlg.
    HashAlgorithmASN1 hashAlg =>
    Maybe hashAlg -> PublicKey -> ByteString -> ByteString -> Bool
    RSA.verify (MD5 -> Maybe MD5
    forall a. a -> Maybe a
    Just MD5
    H.MD5)
    rsaVerifyHash Hash
    SHA1     = Maybe SHA1 -> PublicKey -> ByteString -> ByteString -> Bool
    forall hashAlg.
    HashAlgorithmASN1 hashAlg =>
    Maybe hashAlg -> PublicKey -> ByteString -> ByteString -> Bool
    RSA.verify (SHA1 -> Maybe SHA1
    forall a. a -> Maybe a
    Just SHA1
    H.SHA1)
    rsaVerifyHash Hash
    SHA224   = Maybe SHA224 -> PublicKey -> ByteString -> ByteString -> Bool
    forall hashAlg.
    HashAlgorithmASN1 hashAlg =>
    Maybe hashAlg -> PublicKey -> ByteString -> ByteString -> Bool
    RSA.verify (SHA224 -> Maybe SHA224
    forall a. a -> Maybe a
    Just SHA224
    H.SHA224)
    rsaVerifyHash Hash
    SHA256   = Maybe SHA256 -> PublicKey -> ByteString -> ByteString -> Bool
    forall hashAlg.
    HashAlgorithmASN1 hashAlg =>
    Maybe hashAlg -> PublicKey -> ByteString -> ByteString -> Bool
    RSA.verify (SHA256 -> Maybe SHA256
    forall a. a -> Maybe a
    Just SHA256
    H.SHA256)
    rsaVerifyHash Hash
    SHA384   = Maybe SHA384 -> PublicKey -> ByteString -> ByteString -> Bool
    forall hashAlg.
    HashAlgorithmASN1 hashAlg =>
    Maybe hashAlg -> PublicKey -> ByteString -> ByteString -> Bool
    RSA.verify (SHA384 -> Maybe SHA384
    forall a. a -> Maybe a
    Just SHA384
    H.SHA384)
    rsaVerifyHash Hash
    SHA512   = Maybe SHA512 -> PublicKey -> ByteString -> ByteString -> Bool
    forall hashAlg.
    HashAlgorithmASN1 hashAlg =>
    Maybe hashAlg -> PublicKey -> ByteString -> ByteString -> Bool
    RSA.verify (SHA512 -> Maybe SHA512
    forall a. a -> Maybe a
    Just SHA512
    H.SHA512)

    rsapssVerifyHash :: Hash -> RSA.PublicKey -> ByteString -> ByteString -> Bool
    rsapssVerifyHash :: Hash -> PublicKey -> ByteString -> ByteString -> Bool
    rsapssVerifyHash Hash
    SHA256 = PSSParams SHA256 ByteString ByteString
    -> PublicKey -> ByteString -> ByteString -> Bool
    forall hash.
    HashAlgorithm hash =>
    PSSParams hash ByteString ByteString
    -> PublicKey -> ByteString -> ByteString -> Bool
    PSS.verify (SHA256 -> PSSParams SHA256 ByteString ByteString
    forall seed output hash.
    (ByteArrayAccess seed, ByteArray output, HashAlgorithm hash) =>
    hash -> PSSParams hash seed output
    PSS.defaultPSSParams SHA256
    H.SHA256)
    rsapssVerifyHash Hash
    SHA384 = PSSParams SHA384 ByteString ByteString
    -> PublicKey -> ByteString -> ByteString -> Bool
    forall hash.
    HashAlgorithm hash =>
    PSSParams hash ByteString ByteString
    -> PublicKey -> ByteString -> ByteString -> Bool
    PSS.verify (SHA384 -> PSSParams SHA384 ByteString ByteString
    forall seed output hash.
    (ByteArrayAccess seed, ByteArray output, HashAlgorithm hash) =>
    hash -> PSSParams hash seed output
    PSS.defaultPSSParams SHA384
    H.SHA384)
    rsapssVerifyHash Hash
    SHA512 = PSSParams SHA512 ByteString ByteString
    -> PublicKey -> ByteString -> ByteString -> Bool
    forall hash.
    HashAlgorithm hash =>
    PSSParams hash ByteString ByteString
    -> PublicKey -> ByteString -> ByteString -> Bool
    PSS.verify (SHA512 -> PSSParams SHA512 ByteString ByteString
    forall seed output hash.
    (ByteArrayAccess seed, ByteArray output, HashAlgorithm hash) =>
    hash -> PSSParams hash seed output
    PSS.defaultPSSParams SHA512
    H.SHA512)
    rsapssVerifyHash Hash
    _      = String -> PublicKey -> ByteString -> ByteString -> Bool
    forall a. HasCallStack => String -> a
    error String
    "rsapssVerifyHash: unsupported hash"

    noHash :: Maybe H.MD5
    noHash :: Maybe MD5
    noHash = Maybe MD5
    forall a. Maybe a
    Nothing

    ecdsaSignHash :: (MonadRandom m, ECDSA.EllipticCurveECDSA curve)
                  => proxy curve -> Hash -> ECDSA.Scalar curve -> ByteString -> m (Maybe (ECDSA.Signature curve))
    ecdsaSignHash :: forall (m :: * -> *) curve (proxy :: * -> *).
    (MonadRandom m, EllipticCurveECDSA curve) =>
    proxy curve
    -> Hash
    -> Scalar curve
    -> ByteString
    -> m (Maybe (Signature curve))
    ecdsaSignHash proxy curve
    prx Hash
    SHA1   Scalar curve
    pk ByteString
    msg   = Signature curve -> Maybe (Signature curve)
    forall a. a -> Maybe a
    Just (Signature curve -> Maybe (Signature curve))
    -> m (Signature curve) -> m (Maybe (Signature curve))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> proxy curve
    -> Scalar curve -> SHA1 -> ByteString -> m (Signature curve)
    forall curve (m :: * -> *) msg hash (proxy :: * -> *).
    (EllipticCurveECDSA curve, MonadRandom m, ByteArrayAccess msg,
     HashAlgorithm hash) =>
    proxy curve
    -> PrivateKey curve -> hash -> msg -> m (Signature curve)
    ECDSA.sign proxy curve
    prx Scalar curve
    pk SHA1
    H.SHA1   ByteString
    msg
    ecdsaSignHash proxy curve
    prx Hash
    SHA224 Scalar curve
    pk ByteString
    msg   = Signature curve -> Maybe (Signature curve)
    forall a. a -> Maybe a
    Just (Signature curve -> Maybe (Signature curve))
    -> m (Signature curve) -> m (Maybe (Signature curve))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> proxy curve
    -> Scalar curve -> SHA224 -> ByteString -> m (Signature curve)
    forall curve (m :: * -> *) msg hash (proxy :: * -> *).
    (EllipticCurveECDSA curve, MonadRandom m, ByteArrayAccess msg,
     HashAlgorithm hash) =>
    proxy curve
    -> PrivateKey curve -> hash -> msg -> m (Signature curve)
    ECDSA.sign proxy curve
    prx Scalar curve
    pk SHA224
    H.SHA224 ByteString
    msg
    ecdsaSignHash proxy curve
    prx Hash
    SHA256 Scalar curve
    pk ByteString
    msg   = Signature curve -> Maybe (Signature curve)
    forall a. a -> Maybe a
    Just (Signature curve -> Maybe (Signature curve))
    -> m (Signature curve) -> m (Maybe (Signature curve))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> proxy curve
    -> Scalar curve -> SHA256 -> ByteString -> m (Signature curve)
    forall curve (m :: * -> *) msg hash (proxy :: * -> *).
    (EllipticCurveECDSA curve, MonadRandom m, ByteArrayAccess msg,
     HashAlgorithm hash) =>
    proxy curve
    -> PrivateKey curve -> hash -> msg -> m (Signature curve)
    ECDSA.sign proxy curve
    prx Scalar curve
    pk SHA256
    H.SHA256 ByteString
    msg
    ecdsaSignHash proxy curve
    prx Hash
    SHA384 Scalar curve
    pk ByteString
    msg   = Signature curve -> Maybe (Signature curve)
    forall a. a -> Maybe a
    Just (Signature curve -> Maybe (Signature curve))
    -> m (Signature curve) -> m (Maybe (Signature curve))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> proxy curve
    -> Scalar curve -> SHA384 -> ByteString -> m (Signature curve)
    forall curve (m :: * -> *) msg hash (proxy :: * -> *).
    (EllipticCurveECDSA curve, MonadRandom m, ByteArrayAccess msg,
     HashAlgorithm hash) =>
    proxy curve
    -> PrivateKey curve -> hash -> msg -> m (Signature curve)
    ECDSA.sign proxy curve
    prx Scalar curve
    pk SHA384
    H.SHA384 ByteString
    msg
    ecdsaSignHash proxy curve
    prx Hash
    SHA512 Scalar curve
    pk ByteString
    msg   = Signature curve -> Maybe (Signature curve)
    forall a. a -> Maybe a
    Just (Signature curve -> Maybe (Signature curve))
    -> m (Signature curve) -> m (Maybe (Signature curve))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> proxy curve
    -> Scalar curve -> SHA512 -> ByteString -> m (Signature curve)
    forall curve (m :: * -> *) msg hash (proxy :: * -> *).
    (EllipticCurveECDSA curve, MonadRandom m, ByteArrayAccess msg,
     HashAlgorithm hash) =>
    proxy curve
    -> PrivateKey curve -> hash -> msg -> m (Signature curve)
    ECDSA.sign proxy curve
    prx Scalar curve
    pk SHA512
    H.SHA512 ByteString
    msg
    ecdsaSignHash proxy curve
    _   Hash
    _      Scalar curve
    _  ByteString
    _     = Maybe (Signature curve) -> m (Maybe (Signature curve))
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (Signature curve)
    forall a. Maybe a
    Nothing

    -- Currently we generate ECDSA signatures in constant time for P256 only.
    kxSupportedPrivKeyEC :: PrivKeyEC -> Bool
    kxSupportedPrivKeyEC :: PrivKeyEC -> Bool
    kxSupportedPrivKeyEC PrivKeyEC
    privkey =
        case PrivKeyEC -> Maybe CurveName
    ecPrivKeyCurveName PrivKeyEC
    privkey of
            Just CurveName
    ECC.SEC_p256r1 -> Bool
    True
            Maybe CurveName
    _                   -> Bool
    False

    -- Perform a public-key operation with a parameterized ECC implementation when
    -- available, otherwise fallback to the classic ECC implementation.
    withPubKeyEC :: PubKeyEC
                 -> (forall curve . ECDSA.EllipticCurveECDSA curve => Proxy curve -> ECDSA.PublicKey curve -> a)
                 -> (ECDSA_ECC.PublicKey -> a)
                 -> a
                 -> Maybe a
    withPubKeyEC :: forall a.
    PubKeyEC
    -> (forall curve.
        EllipticCurveECDSA curve =>
        Proxy curve -> PublicKey curve -> a)
    -> (PublicKey -> a)
    -> a
    -> Maybe a
    withPubKeyEC PubKeyEC
    pubkey forall curve.
    EllipticCurveECDSA curve =>
    Proxy curve -> PublicKey curve -> a
    withProxy PublicKey -> a
    withClassic a
    whenUnknown =
        case PubKeyEC -> Maybe CurveName
    ecPubKeyCurveName PubKeyEC
    pubkey of
            Maybe CurveName
    Nothing             -> a -> Maybe a
    forall a. a -> Maybe a
    Just a
    whenUnknown
            Just CurveName
    ECC.SEC_p256r1 ->
                CryptoFailable a -> Maybe a
    forall a. CryptoFailable a -> Maybe a
    maybeCryptoError (CryptoFailable a -> Maybe a) -> CryptoFailable a -> Maybe a
    forall a b. (a -> b) -> a -> b
    $ Proxy Curve_P256R1 -> PublicKey Curve_P256R1 -> a
    forall curve.
    EllipticCurveECDSA curve =>
    Proxy curve -> PublicKey curve -> a
    withProxy Proxy Curve_P256R1
    p256 (Point -> a) -> CryptoFailable Point -> CryptoFailable a
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Proxy Curve_P256R1
    -> ByteString -> CryptoFailable (PublicKey Curve_P256R1)
    forall curve bs (proxy :: * -> *).
    (EllipticCurve curve, ByteArray bs) =>
    proxy curve -> bs -> CryptoFailable (PublicKey curve)
    ECDSA.decodePublic Proxy Curve_P256R1
    p256 ByteString
    bs
            Just CurveName
    curveName      ->
                let curve :: Curve
    curve = CurveName -> Curve
    ECC.getCurveByName CurveName
    curveName
                    pub :: Maybe Point
    pub   = Curve -> SerializedPoint -> Maybe Point
    unserializePoint Curve
    curve SerializedPoint
    pt
                 in PublicKey -> a
    withClassic (PublicKey -> a) -> (Point -> PublicKey) -> Point -> a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Curve -> Point -> PublicKey
    ECDSA_ECC.PublicKey Curve
    curve (Point -> a) -> Maybe Point -> Maybe a
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Maybe Point
    pub
      where pt :: SerializedPoint
    pt@(SerializedPoint ByteString
    bs) = PubKeyEC -> SerializedPoint
    pubkeyEC_pub PubKeyEC
    pubkey

    -- Perform a private-key operation with a parameterized ECC implementation when
    -- available.  Calls for an unsupported curve can be prevented with
    -- kxSupportedEcPrivKey.
    withPrivKeyEC :: PrivKeyEC
                  -> (forall curve . ECDSA.EllipticCurveECDSA curve => Proxy curve -> ECDSA.PrivateKey curve -> a)
                  -> (ECC.CurveName -> a)
                  -> a
                  -> Maybe a
    withPrivKeyEC :: forall a.
    PrivKeyEC
    -> (forall curve.
        EllipticCurveECDSA curve =>
        Proxy curve -> PrivateKey curve -> a)
    -> (CurveName -> a)
    -> a
    -> Maybe a
    withPrivKeyEC PrivKeyEC
    privkey forall curve.
    EllipticCurveECDSA curve =>
    Proxy curve -> PrivateKey curve -> a
    withProxy CurveName -> a
    withUnsupported a
    whenUnknown =
        case PrivKeyEC -> Maybe CurveName
    ecPrivKeyCurveName PrivKeyEC
    privkey of
            Maybe CurveName
    Nothing             -> a -> Maybe a
    forall a. a -> Maybe a
    Just a
    whenUnknown
            Just CurveName
    ECC.SEC_p256r1 ->
                -- Private key should rather be stored as bytearray and converted
                -- using ECDSA.decodePrivate, unfortunately the data type chosen in
                -- x509 was Integer.
                CryptoFailable a -> Maybe a
    forall a. CryptoFailable a -> Maybe a
    maybeCryptoError (CryptoFailable a -> Maybe a) -> CryptoFailable a -> Maybe a
    forall a b. (a -> b) -> a -> b
    $ Proxy Curve_P256R1 -> PrivateKey Curve_P256R1 -> a
    forall curve.
    EllipticCurveECDSA curve =>
    Proxy curve -> PrivateKey curve -> a
    withProxy Proxy Curve_P256R1
    p256 (Scalar -> a) -> CryptoFailable Scalar -> CryptoFailable a
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Proxy Curve_P256R1
    -> Integer -> CryptoFailable (PrivateKey Curve_P256R1)
    forall curve (proxy :: * -> *).
    EllipticCurveBasepointArith curve =>
    proxy curve -> Integer -> CryptoFailable (Scalar curve)
    forall (proxy :: * -> *).
    proxy Curve_P256R1
    -> Integer -> CryptoFailable (PrivateKey Curve_P256R1)
    ECDSA.scalarFromInteger Proxy Curve_P256R1
    p256 Integer
    d
            Just CurveName
    curveName      -> a -> Maybe a
    forall a. a -> Maybe a
    Just (a -> Maybe a) -> a -> Maybe a
    forall a b. (a -> b) -> a -> b
    $ CurveName -> a
    withUnsupported CurveName
    curveName
      where d :: Integer
    d = PrivKeyEC -> Integer
    privkeyEC_priv PrivKeyEC
    privkey

    p256 :: Proxy ECDSA.Curve_P256R1
    p256 :: Proxy Curve_P256R1
    p256 = Proxy Curve_P256R1
    forall {k} (t :: k). Proxy t
    Proxy